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:

  1. MCP (Model Context Protocol) — For common read/write operations
  2. 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

ToolPurpose
list_peopleList all people in the system
list_projectsList projects (includes client info)
list_allocationsList time/effort allocations
list_positionsList person-to-project assignments
list_rolesList available roles (CSO, SL, IC, etc.)
list_groupsList organizational groups
list_senioritiesList seniority levels
list_sitesList office/site locations
list_skillsList skill categories
list_statusesList employment statuses
list_tasksList tasks
list_time_entriesList logged time entries

Write Operations

ToolPurpose
create_positionAssign a person to a project with a role
update_positionModify an existing position (role, dates, etc.)
create_allocationCreate time/effort allocation
delete_allocationRemove an allocation

Single Resource Operations

ToolPurpose
get_personGet details for a specific person
get_positionGet details for a specific position

5. Direct API Usage

Base URL

https://api.operating.app/v1

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/json

Common 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

OperationMCPDirect APINotes
List peopleREST: GET /v1/persons (not /people)
Create / update personvariesREST: 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 projectsUse MCP
List positionsUse MCP
Update positionUse MCP
Create positionUse MCP
Create projectMust use API
Archive projectMust use API
Update clientMust use API
Create clientMust use API
List clientsUse API
Delete projectUse API
Delete clientUse 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 MCP list_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-title

Requires 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:

SkillPurposeUser
operating-client-health-auditAudit CSO/SL assignments, project alignmentHead of Delivery
operating-allocation-validatorValidate allocation end dates, overallocationHead of Delivery, SLs
operating-cso-sl-dashboardGenerate CSO/SL coverage matrixHead of Delivery
operating-role-taxonomy-auditAudit role usage, suggest archivalHead of Delivery
operating-project-sow-alignerValidate project-to-SOW alignmentSLs, Head of Delivery
operating-capacity-reporterTeam capacity and availabilityHead 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


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 title PATCH example; optional fields note; CSO/SL workflow points to GET /v1/competence-roles; Supabase → Operating title sync via knowledge/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 roles GET /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