Skip to main content
Every request to the FITsociety MCP server must present a bearer credential in the Authorization header:
FITsociety supports two runtime credential types: company MCP API keys and OAuth access tokens. Runtime credentials are accepted in this header only. Query-string and body credentials are rejected.

1. Company MCP API keys

Coaches with administrative roles (Manager or Admin) can manually generate static API keys in the company settings panel. Static API keys always create a company/coach grant; they are not used for client AI access.
  • Key Format: Prefixed with fsc_ followed by a secure hex string (e.g., fsc_a1b2c3d4...).
  • Expiration: Configurable up to 365 days (defaults to 90 days).
  • Usage: Provide the plaintext key directly in the Authorization header. It is only shown once at creation time and cannot be retrieved later.

2. OAuth 2.1 Authorization Code Flow

For third-party AI clients, FITsociety implements an OAuth authorization code flow with PKCE (S256) and refresh token rotation. Every authorization-code and refresh-token grant is bound to this exact protected resource:
OAuth can create two grant subject types: Company/coach OAuth requires the company MCP integration feature. Client OAuth requires the same company MCP integration feature, an active client-company relationship, enabled client AI access for that relationship, and the company client MCP policy.

Token Types and Lifetimes

Step 1: Dynamic Client Registration

Before initiating authorization, the client application must register itself.
  • Route: POST /mcp/v1/oauth/register
  • Request Body:
  • Response: Returns a unique client_id (e.g., mcpc_a1b2c3d4...) with client settings.

Step 2: Redirect to Authorize Endpoint

The AI client redirects the signed-in user to the authorization URL, supplying the PKCE challenge parameters.
  • Route: GET /mcp/v1/oauth/authorize
  • Query Parameters:
    • client_id: The registered client ID.
    • redirect_uri: The matching callback URL.
    • response_type: Must be code.
    • code_challenge: The base64url SHA-256 digest of your random code_verifier.
    • code_challenge_method: Must be S256.
    • resource: Must be exactly https://mcp.fitsociety.io/mcp/v1.
    • scope: Space-separated list of requested module keys (e.g. clients bookings for coach access, or client_ai_account client_ai_bookings for client AI access).
    • state: Optional state parameter.
The redirect_uri must exactly match one URI registered for the OAuth client. The same exact URI must be sent again during the authorization-code exchange. The authorize route redirects the signed-in user to the FITsociety consent page.
  1. For company/coach access, a Manager or Admin coach selects modules, write tools, and consent flags. Approving calls POST /app/v1/company/mcp/oauth/approve.
  2. For client AI access, the authenticated client selects only client AI modules and consent flags. The company MCP integration feature must be enabled, the client must have client AI access enabled for the active company relationship, and the company client MCP policy must allow the requested client modules. Approving calls POST /app/v1/client/mcp/oauth/approve.
  3. If the company MCP integration feature is disabled, approval fails with COMPANY_MCP_FEATURE_DISABLED and the token exchange must not continue.
  4. If client AI access is disabled, approval fails with COMPANY_MCP_CLIENT_AI_DISABLED and the token exchange must not continue.
  5. If the company client MCP policy is disabled or no requested module is allowed, approval fails before any grant or authorization code is created.
  6. The backend registers a persistent grant and returns a 10-minute authorization code.
  7. The user is redirected back to the AI client’s redirect_uri?code=<code>&state=<state>.

Step 4: Exchanging the Authorization Code

The client exchanges the code for the credentials.
  • Route: POST /mcp/v1/oauth/token
  • Request Body:
  • Response:

Step 5: Refreshing Tokens & Rotation

When the access token expires, use the refresh token to get a new pair.
  • Route: POST /mcp/v1/oauth/token
  • Request Body:
Refresh Token Rotation (RTR) Each time a refresh token is used, it is immediately revoked. The endpoint returns a brand-new access token and a brand-new refresh token. The client must store and use the new refresh token for the next cycle.
The token endpoint returns Cache-Control: no-store and Pragma: no-cache. Refresh-token rotation is atomic: a refresh token can be claimed only once, including when multiple application instances receive concurrent requests. If an already rotated refresh token is presented again, FITsociety treats it as token-family reuse and revokes the active access and refresh tokens for that grant and OAuth client. The user must authorize the connection again.