Operating.app API & MCP Setup Guide
Version: 1.6
Date: April 14, 2026
Owner: AI Team
1. Purpose
This guide documents how to interact with Operating.app for resource allocation, project management, and team assignments. Brainforge uses Operating.app for:
- Tracking CSO (Client Success Owner) and SL (Service Lead) assignments
- Managing client projects and SOW alignment
- Resource allocation and position management
- Internal team project tracking
Two interfaces are available:
- MCP (Model Context Protocol) — For common read/write operations
- Direct REST API — For advanced operations not available via MCP
2. When to Use
Use MCP First
- List people, projects, allocations, positions, roles
- Create/update positions (person-to-project assignments)
- Create allocations (time/effort assignments)
- Read existing data (groups, roles, seniorities, skills, etc.)
Use Direct API When MCP Is Insufficient
- Create projects (MCP does not support)
- Archive/delete projects (MCP does not support)
- Create/update/delete clients (MCP does not support)
- Bulk operations requiring direct resource manipulation
3. Credentials
1Password
- Item (human link): Operating API key
- Secret reference:
op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password(vault UUID + item UUID; stable if the item title changes) - Field:
password(API key value)
# Get API key for direct API calls
op read "op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password"Using the API Key
API_KEY=$(op read "op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password")If op read reports an unknown field, run op item get lk4xm23nk3vmwp4squcfindicq and use the field label for the API key in the secret reference (replace the final password segment if the item uses another field).
4. MCP Tools Available
Located at: /Users/uttamkumaran/.cursor/projects/Users-uttamkumaran-Documents-BrainforgeAI-Github-CTA/mcps/user-operating/tools/
Read Operations
| Tool | Purpose |
|---|---|
list_people | List all people in the system |
list_projects | List projects (includes client info) |
list_allocations | List time/effort allocations |
list_positions | List person-to-project assignments |
list_roles | List available roles (CSO, SL, IC, etc.) |
list_groups | List organizational groups |
list_seniorities | List seniority levels |
list_sites | List office/site locations |
list_skills | List skill categories |
list_statuses | List employment statuses |
list_tasks | List tasks |
list_time_entries | List logged time entries |
Write Operations
| Tool | Purpose |
|---|---|
create_position | Assign a person to a project with a role |
update_position | Modify an existing position (role, dates, etc.) |
create_allocation | Create time/effort allocation |
delete_allocation | Remove an allocation |
Single Resource Operations
| Tool | Purpose |
|---|---|
get_person | Get details for a specific person |
get_position | Get details for a specific position |
5. Direct API Usage
Base URL
https://api.operating.app/v1
Web app (deep links)
Log in at https://use.operating.app (see Operating user guide). For documentation and cross-links from the vault, use these URL patterns (SPA; if the page loads the shell only, use cmd+k and search by name):
- Project:
https://use.operating.app/projects/{project_id} - Client:
https://use.operating.app/clients/{client_id}
Example: https://use.operating.app/projects/146949
Authentication
Authorization: Bearer {API_KEY}
Content-Type: application/jsonCommon Operations
List Clients
curl -s "https://api.operating.app/v1/clients" \
-H "Authorization: Bearer $API_KEY" | jq '.data[] | "\(.id): \(.name)"'Update Client Name
curl -s -X PATCH "https://api.operating.app/v1/clients/{client_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "New Client Name"}'Create Project
curl -s -X POST "https://api.operating.app/v1/projects" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Project Name", "clientId": "{client_id}"}'Archive Project
# Note: clientId must be a string, not a number
curl -s -X PATCH "https://api.operating.app/v1/projects/{project_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"archivedAt": "2026-03-25T23:45:00.000Z"}'List Projects for a Client
curl -s "https://api.operating.app/v1/projects?clientId={client_id}" \
-H "Authorization: Bearer $API_KEY" | jq '.data[] | "\(.id): \(.name)"'People (/persons — not /people)
List returns data plus meta (cursor). Competence roles use GET /v1/competence-roles (not /roles).
# List people
curl -s "https://api.operating.app/v1/persons" \
-H "Authorization: Bearer $API_KEY" | jq '.data[] | "\(.id): \(.email // "no-email") \(.fullname)"'
# Create person (then assign positions / allocations)
curl -s -X POST "https://api.operating.app/v1/persons" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Full Name","fullname":"Full Name","email":"name@brainforge.ai"}'
# Update email / display name (partial PATCH)
curl -s -X PATCH "https://api.operating.app/v1/persons/{person_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"name@brainforge.ai","fullname":"Full Name","name":"Full Name"}'
# Archive person (soft-delete for staffing lists)
curl -s -X PATCH "https://api.operating.app/v1/persons/{person_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"archivedAt":"2026-04-14T12:00:00.000Z"}'
# Job title (shown on person profile; often synced from Supabase `team.title` / `team.role`)
curl -s -X PATCH "https://api.operating.app/v1/persons/{person_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"SL - Analytics Engineer - Lead"}'Other person fields you may set via PATCH /v1/persons/{id} when needed (only populate from a trusted source; do not guess HR dates): phone, employmentStart, reportsToPersonId, siteId, employeeId, summaryForStaffing, bio. Confirm shape with GET /v1/persons/{id} before bulk updates.
Hard-delete person: As of April 2026, DELETE /v1/persons/{person_id} returns 404 NOT_FOUND even when GET /v1/persons/{person_id} succeeds. To remove someone from staffing views, use PATCH with archivedAt (see above). To fully purge test or duplicate directory rows, use the Operating web app (if available) or Operating support—do not assume a public REST delete exists.
6. MCP vs API Capability Matrix
| Operation | MCP | Direct API | Notes |
|---|---|---|---|
| List people | ✅ | ✅ | REST: GET /v1/persons (not /people) |
| Create / update person | varies | ✅ | REST: POST /v1/persons, PATCH /v1/persons/{id} (email, name, title, archive, etc.) |
| Delete person (hard) | ❌ | ❌ | REST DELETE returns 404 (Apr 2026); archive via PATCH or use UI / vendor |
| List projects | ✅ | ✅ | Use MCP |
| List positions | ✅ | ✅ | Use MCP |
| Update position | ✅ | ✅ | Use MCP |
| Create position | ✅ | ✅ | Use MCP |
| Create project | ❌ | ✅ | Must use API |
| Archive project | ❌ | ✅ | Must use API |
| Update client | ❌ | ✅ | Must use API |
| Create client | ❌ | ✅ | Must use API |
| List clients | ❌ | ✅ | Use API |
| Delete project | ❌ | ✅ | Use API |
| Delete client | ❌ | ✅ | Use API |
7. Common Workflows
CSO/SL Assignment Updates
Use MCP update_position with competenceRoleId set to the appropriate role ID:
- Role IDs:
GET /v1/competence-roles(or MCPlist_roles) — map names to IDs before patching positions.
Person title from Internal AI Core (team)
Brainforge’s roster of record for job title / role string is Supabase public.team (title preferred, else role). To fill empty Operating titles or reconcile in bulk:
OPERATING_API_KEY=$(op read "op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password")
# Dry-run (from repo root; loads apps/platform/.env.local for Supabase URL + service key)
node knowledge/operations/scripts/operating-sync-person-fields-from-supabase.mjs
# Apply: set `title` only when Operating title is empty
node knowledge/operations/scripts/operating-sync-person-fields-from-supabase.mjs --apply
# Overwrite when Operating title differs from Supabase
node knowledge/operations/scripts/operating-sync-person-fields-from-supabase.mjs --apply --sync-titleRequires NEXT_PUBLIC_SUPABASE_URL (or BF_SUPABASE_URL) and BF_SUPABASE_SERVICE_KEY. Only status = active (or null status) rows are considered; archived Operating persons are skipped.
Client Renaming (HubSpot Alignment)
Use Direct API when renaming clients to match HubSpot:
API_KEY=$(op read "op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password")
curl -s -X PATCH "https://api.operating.app/v1/clients/{id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "New Name"}' | jq '.data.name'Project Restructure (Archive Old, Create New)
# 1. Archive old project
API_KEY=$(op read "op://66hi4dru5dtznpzqwdac23e2fm/lk4xm23nk3vmwp4squcfindicq/password")
NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
curl -s -X PATCH "https://api.operating.app/v1/projects/{old_project_id}" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"archivedAt\": \"$NOW\"}"
# 2. Create new project
curl -s -X POST "https://api.operating.app/v1/projects" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "New Project Name", "clientId": "{client_id}"}'8. Cursor Skills for Operating.app
Located at: .cursor/skills/operating-audit/SKILL.md
Skills available for Head of Delivery and Service Leads:
| Skill | Purpose | User |
|---|---|---|
operating-client-health-audit | Audit CSO/SL assignments, project alignment | Head of Delivery |
operating-allocation-validator | Validate allocation end dates, overallocation | Head of Delivery, SLs |
operating-cso-sl-dashboard | Generate CSO/SL coverage matrix | Head of Delivery |
operating-role-taxonomy-audit | Audit role usage, suggest archival | Head of Delivery |
operating-project-sow-aligner | Validate project-to-SOW alignment | SLs, Head of Delivery |
operating-capacity-reporter | Team capacity and availability | Head of Delivery, SLs |
Usage example:
Run operating-client-health-audit for all clients
Generate CSO/SL dashboard
Run operating-allocation-validator for March 2026
9. API Reference
- Operating.app API Docs: https://operating.readme.io/reference/overview
- MCP Tools:
~/.cursor/projects/*/mcps/user-operating/tools/
10. Version History
- v1.6 (April 14, 2026) — Document that
DELETE /v1/persons/{id}is not available (404); matrix row for hard-delete; archive / UI / support as alternatives. - v1.5 (April 14, 2026) — Person
titlePATCHexample; optional fields note; CSO/SL workflow points toGET /v1/competence-roles; Supabase → Operating title sync viaknowledge/operations/scripts/operating-sync-person-fields-from-supabase.mjs(§7). - v1.4 (April 14, 2026) — Direct API:
GET /v1/persons,POST /v1/persons,PATCH /v1/persons/{id}; competence rolesGET /v1/competence-roles; matrix rows updated (see §5). - v1.3 (April 9, 2026) — 1Password: canonical Operating API key uses vault/item UUID secret reference (see §3) and 1Password item link
- v1.2 (March 26, 2026) — Web app deep-link patterns (
use.operating.app/projects/{id},.../clients/{id}) - v1.1 (March 25, 2026) — Added Cursor skills section for Head of Delivery and SL workflows
- v1.0 (March 25, 2026) — Initial guide documenting MCP tools and Direct API capabilities