> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fitsociety.io/llms.txt
> Use this file to discover all available pages before exploring further.

# API Structure

> How FITsociety MCP is structured across company/coach and client AI access.

FITsociety MCP follows the same access-system shape as the QR access API:
create access, validate/use access, audit usage, review signals, and revoke or
rotate credentials.

There are two subject surfaces:

* **Company/coach access** is approved by a Manager or Admin coach and runs in
  company scope.
* **Client AI access** is approved by the authenticated client and is bound to
  that one client through `subjectType: "client"` and `subjectClientId`. The
  company MCP integration feature must be enabled, and the client must be
  connected to the company with client AI access enabled.

## API groups

| Group | Purpose | Main endpoints |
| :- | :- | :- |
| Company management API | Create, inspect, update, preview, rotate, and revoke company/coach MCP access. | `/app/v1/company/mcp/*` |
| Client AI consent API | Approve and revoke client-bound OAuth MCP access. | `/app/v1/client/mcp/oauth/approve`, `/app/v1/client/mcp/grants/:grantId/revoke` |
| Dashboard API | Summarize grants, tool calls, failures, modules, and anomalies. | `GET /app/v1/company/mcp/metrics` |
| Runtime MCP API | Negotiate the official MCP transport, list tools, and execute tool calls. | `POST /mcp/v1` |
| OAuth API | Register clients, authorize, approve consent, and issue tokens. | `/mcp/v1/oauth/*`, `/app/v1/company/mcp/oauth/approve`, `/app/v1/client/mcp/oauth/approve` |
| Audit & Compliance API | Review/export tool-call logs and anomaly events. | `/app/v1/company/mcp/audit*`, `/app/v1/company/mcp/anomalies*` |
| Security & Health API | Check authenticated runtime access and server context. | `GET /mcp/v1/health` |

## QR access comparison

| QR access concept | MCP concept |
| :- | :- |
| Access device key | MCP grant API key |
| Access device | MCP grant / AI client connection |
| QR session token | MCP API key or OAuth access token |
| Scan validation | MCP tool authorization |
| Access decision | JSON-RPC result or JSON-RPC error |
| `AccessLog` | `CompanyMcpToolAuditLog` |
| Access metrics | MCP metrics |
| Device status | Grant status |
| Disable device | Revoke grant |
| Scan anomaly | MCP anomaly |

## End-to-end flows

### API-key grant flow

```txt theme={null}
Manager/Admin creates company/coach grant
-> Backend validates modules, write tools, consent, and expiry
-> Backend stores CompanyMcpGrant with apiKeyHash
-> Backend returns plaintext apiKey once
-> MCP client uses Authorization: Bearer <apiKey>
```

### Company/coach OAuth connection flow

```txt theme={null}
AI client registers OAuth client
-> AI client starts authorization request
-> Coach is redirected to consent screen
-> Coach approves modules/write tools/consent
-> Backend creates CompanyMcpGrant and authorization code
-> AI client exchanges code for access and refresh tokens
```

### Client AI OAuth connection flow

```txt theme={null}
AI client registers OAuth client
-> AI client starts authorization request
-> Client is redirected to client consent screen
-> Backend checks the company MCP feature, client-company relationship, client AI access, and company client MCP policy
-> If any gate is disabled, no grant or authorization code is created
-> Client approves only explicit client_ai_* modules, write tools, and consent
-> Backend creates CompanyMcpGrant with subjectType=client and subjectClientId
-> Backend creates authorization code
-> AI client exchanges code for access and refresh tokens
```

When client AI access is disabled, the client portal may offer a request-access
action. That request is an operational notification to the company; it is not an
OAuth approval and does not create a grant. The company must enable client AI
access before the client can complete MCP consent.

### Tool call flow

```txt theme={null}
MCP client calls POST /mcp/v1
-> Persistent pre-parse IP and parsed IP/bearer-key rate limits are consumed
-> Official @modelcontextprotocol/server v2 transport validates Host and Origin
-> Backend resolves API key or OAuth access token
-> Backend checks grant status, expiry, and company status
-> Backend checks the company MCP feature for every grant
-> Backend checks company/coach owner role or client AI access, policy, and subject binding
-> Backend filters requested tool by subject type, allowedModules, consent, and allowedWriteTools
-> Persistent per-grant query budget and per-company/tool circuit state are checked
-> Write calls require params._meta.idempotencyKey and claim durable replay state
-> Tool executes
-> Write replay result and generic audit metadata are durably persisted
-> A post-mutation replay persistence failure leaves the key processing and returns an error
-> JSON-RPC result is returned
```

The runtime supports modern MCP `2026-07-28` and stateless legacy requests for
`2025-11-25`, `2025-06-18`, `2025-03-26`, and `2024-11-05`. `GET /mcp/v1` is
delegated to the official transport and is not advertised as an SSE
compatibility stream.

### Key rotation flow

```txt theme={null}
Manager/Admin rotates API-key grant
-> Backend generates new apiKey
-> Backend replaces stored apiKeyHash
-> Old API key stops working
-> New plaintext apiKey is returned once
```

### Revocation flow

```txt theme={null}
Manager/Admin revokes company/coach grant, or client revokes own client grant
-> Grant status becomes revoked
-> Static API key stops working if present
-> OAuth tokens linked to the grant are revoked
-> Audit history remains available
```

### Audit review flow

```txt theme={null}
Manager/Admin opens audit list, detail, metrics, or CSV export
-> Backend applies filters like date range, tool, module, status, error, IP, and grant
-> Backend returns company-scoped records only
-> Argument values remain hidden
-> Argument key names and execution metadata are visible
```

### Grant activity flow

```txt theme={null}
Manager/Admin opens one grant
-> Backend loads grant lifecycle events, tool-call audit logs, and anomalies
-> Backend merges them into a reverse-chronological activity timeline
-> UI can show created, updated, rotated, revoked, calls, failures, and anomalies together
```

### Anomaly review flow

```txt theme={null}
Backend records anomaly
-> Dashboard shows open anomaly
-> Manager/Admin reviews event
-> Anomaly status is updated to reviewed or dismissed
```

## Authentication matrix

| Endpoint group | Auth model |
| :- | :- |
| `/app/v1/company/mcp/*` | Coach JWT. Requires company `Manager` or `Admin`. Create/approve endpoints and the client MCP policy endpoints require company MCP access. |
| `POST /app/v1/client/mcp/oauth/approve` | Client JWT. Requires company MCP access. The active client can approve only explicit `client_ai_*` modules when connected to the active company, client AI access is enabled, and the company client MCP policy allows those modules. |
| `POST /app/v1/client/mcp/grants/:grantId/revoke` | Client JWT. The active client can revoke only a grant with matching `subjectType: "client"` and `subjectClientId`. |
| `POST /mcp/v1` | Official MCP v2 transport. Requires `Authorization: Bearer <fsc_...>` or `Authorization: Bearer <fsct_...>`; runtime credentials are header-only. |
| `GET /mcp/v1` | Delegated to the official MCP transport. It is not a compatibility stream and should not be used as a handshake endpoint. |
| `GET /mcp/v1/health` | Same runtime bearer auth; returns resolved grant context. |
| `/mcp/v1/oauth/register` | Public dynamic client registration, rate limited. |
| `/mcp/v1/oauth/authorize` | Public authorization start, rate limited. |
| `/mcp/v1/oauth/token` | OAuth code or refresh-token exchange. |
| `/.well-known/*` | Public OAuth/MCP metadata. |

## Permission matrix

The runtime permission decision is based on these controls:

| Control | Effect |
| :- | :- |
| `companyId` | Scopes every tool call to one company. |
| `subjectType` | Selects the runtime surface. `client` grants can only discover and call client AI modules. |
| `subjectClientId` | Binds client AI grants to one client. Client AI tools cannot switch to another client ID. |
| Client AI access | Required for client AI grants. If disabled, client MCP approval and runtime tool access are blocked. |
| Company client MCP policy | Required for client AI grants. The current policy intersects both new approvals and existing grants at runtime. |
| `allowedModules` | Controls which tool modules are visible and executable. |
| `allowedWriteTools` | Controls exactly which write tools may execute. |
| `readOnly` | Keeps the grant read-only unless write tools are explicitly enabled. |
| `healthDataConsent` | Required for health-sensitive modules. |
| `privateCommunicationConsent` | Required for private communication modules. |
| `status` | Revoked grants cannot authenticate. |
| `expiresAt` | Expired grants cannot authenticate. |
| Owner coach role | Company/coach grant owner must still have active Manager/Admin company access. Client AI grants are client-bound instead of coach-owned. |
| Company status | Blocked companies cannot use MCP. |
| Company MCP availability | Every MCP grant requires company MCP access at runtime. |
| Host and Origin allowlists | Reject requests targeting an unapproved authority or browser origin before runtime authentication. |
| Persistent operational limits | Enforce IP/key rate limits, per-grant query budgets, and per-company/tool circuit state across application instances. Client IPs use a bounded trusted-proxy hop count. |
| Write idempotency | Require `params._meta.idempotencyKey`; completed write results are durably replayed without re-executing the mutation. |

## Response contracts

Management endpoints use the standard app API envelope:

```json theme={null}
{
  "status": 200,
  "error": false,
  "message": "MESSAGE_KEY",
  "data": {}
}
```

Runtime MCP calls use JSON-RPC 2.0:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "request-id",
  "result": {}
}
```

Runtime errors also use JSON-RPC:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "request-id",
  "error": {
    "code": -32602,
    "message": "Unknown or unavailable tool: example_tool"
  }
}
```

## Dashboard contract

`GET /app/v1/company/mcp/metrics` returns:

| Section | Shows |
| :- | :- |
| `meta` | Timeframe, date range, timezone, and active filters. |
| `kpis` | Grant counts, call counts, success/failure rates, read/write split, byte totals, anomaly counts. |
| `charts.volume` | Calls over time. |
| `charts.topTools` | Most-used tools with success/failure counts. |
| `charts.topGrants` | Most active MCP connections. |
| `charts.errorsByCode` | Most common errors. |
| `charts.callsByModule` | Tool usage grouped by module. |
| `charts.readVsWrite` | Read versus write call totals. |
| `recentFailures` | Latest failed calls. |
| `recentAnomalies` | Latest anomaly events. |

Supported filters:

```txt theme={null}
timeframe=day|week|month|year
from=<ISO date or date-time>
to=<ISO date or date-time>
timezone=<IANA timezone>
grantId=<ObjectId>
toolName=<tool name>
moduleName=<module key>
readWrite=read|write
status=success|error
recentLimit=1..25
```

## Audit filters

`GET /app/v1/company/mcp/audit` supports operational filters:

```txt theme={null}
grantId=<ObjectId>
from=<ISO date or date-time>
to=<ISO date or date-time>
toolName=<tool name>
moduleName=<module key>
readWrite=read|write
status=success|error
errorCode=<error key>
requestIp=<IP address>
page=<page number>
limit=<1..100>
```

## Grant activity timeline

`GET /app/v1/company/mcp/grants/:grantId/activity` returns a merged timeline
for one connection. Items have a `source` field:

| Source | Meaning |
| :- | :- |
| `grant_event` | Lifecycle event such as created, updated, consent updated, key rotated, revoked, or OAuth approved. |
| `audit_log` | MCP request/tool-call event. |
| `anomaly` | Security or behavior anomaly linked to the grant. |

This endpoint is intended for the connection detail page, where support or a
coach needs to understand what happened to one MCP connection over time.

## Error categories

| Category | Examples |
| :- | :- |
| Grant validation | `COMPANY_MCP_GRANT_NAME_INVALID`, `COMPANY_MCP_GRANT_MODULES_INVALID`, `COMPANY_MCP_CLIENT_GRANT_MODULES_INVALID`, `COMPANY_MCP_GRANT_EXPIRY_INVALID` |
| Consent validation | `COMPANY_MCP_HEALTH_CONSENT_REQUIRED`, `COMPANY_MCP_PRIVATE_COMM_CONSENT_REQUIRED` |
| Permission validation | `COMPANY_MCP_GRANT_WRITE_TOOLS_INVALID`, `COMPANY_MCP_READ_WRITE_INVALID` |
| Runtime auth | `COMPANY_MCP_KEY_REQUIRED`, `COMPANY_MCP_KEY_INVALID`, `COMPANY_MCP_TOKEN_INVALID` |
| Runtime state | `COMPANY_MCP_FEATURE_DISABLED`, `COMPANY_MCP_COMPANY_BLOCKED`, `COMPANY_MCP_GRANT_OWNER_INACTIVE` |
| Client MCP state | `COMPANY_MCP_CLIENT_AI_DISABLED`, `COMPANY_MCP_CLIENT_MCP_DISABLED`, `COMPANY_MCP_CLIENT_MCP_SCOPE_NOT_ALLOWED`, `COMPANY_MCP_CLIENT_COMPANY_CONNECTION_REQUIRED`, `COMPANY_MCP_CLIENT_SUBJECT_INVALID` |
| OAuth | `invalid_client`, `invalid_redirect_uri`, `invalid_grant`, `unsupported_grant_type` |
| Audit/anomaly | `COMPANY_MCP_AUDIT_LOG_NOT_FOUND`, `COMPANY_MCP_ANOMALY_NOT_FOUND`, `COMPANY_MCP_ANOMALY_STATUS_INVALID` |

## Data model summary

| Model | Role |
| :- | :- |
| `CompanyMcpGrant` | Permission contract between a company and an MCP client. |
| `CompanyMcpToken` | Hashed OAuth access/refresh tokens linked to a grant. |
| `CompanyMcpOauthClient` | Dynamically registered OAuth client metadata. |
| `CompanyMcpOauthCode` | Short-lived PKCE authorization code. |
| `CompanyMcpToolAuditLog` | Per-request/tool-call audit record. |
| `CompanyMcpAnomalyLog` | Security and behavior anomaly record. |
| `CompanyMcpGrantEvent` | Grant lifecycle event record for created, updated, rotated, revoked, OAuth approval, and consent updates. |

## Security rules

* Plaintext API keys are returned once.
* API keys and OAuth tokens are stored as hashes.
* OAuth refresh tokens rotate on use.
* Revoking a grant revokes associated OAuth tokens.
* Audit logs do not expose argument values.
* CSV export excludes `sanitizedArguments`.
* Health modules require explicit health data consent.
* Private communication modules require explicit consent.
* Write access is opt-in per tool.
* Runtime access is checked on every request, not only during grant creation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.