Skip to content

Admin API — MCP Keys

The MCP server reads its bearer tokens from the application_keys Mongo collection. These endpoints are the canonical way to manage that collection — write Mongo by hand only if the API isn't reachable.

All endpoints require Admin or SuperAdmin role. An Admin can only manage keys for their own current_project_id; SuperAdmins can manage keys for any project.

Endpoints at a glance

Method Path Purpose
POST /projects/{project_id}/mcp-keys Mint a new key
GET /projects/{project_id}/mcp-keys List active keys (redacted)
GET /projects/{project_id}/mcp-keys/{key_id} Fetch one (redacted)
PATCH /projects/{project_id}/mcp-keys/{key_id} Update RBAC / name / active
DELETE /projects/{project_id}/mcp-keys/{key_id} Soft-revoke (active=false)

POST /projects/{project_id}/mcp-keys

Mint a new MCP application key. The raw bearer token is returned exactly once — save it now or you'll have to mint a new one.

Request

{
  "name": "Acme — production CRM integration",
  "is_supervisor": true,
  "roles": ["Admin"],
  "allowed_agents": [],
  "require_mapping": false
}
Field Type Default Notes
name string (1–120) required Human label for admin recognition
is_supervisor bool true Service-account default. Set false to use allowed_agents
roles list[string] ["Admin"] Role names; used by query_user_activity and any other role-gated tool
allowed_agents list[string] [] Per-agent narrowing when is_supervisor is false
require_mapping bool false Fail-closed when is_supervisor=false and allowed_agents=[]

Response — 201 Created

{
  "id": "<uuid>",
  "key": "AbCdE...",            raw secret, surfaced ONCE
  "key_preview": "AbCdE…",
  "project_id": "...",
  "name": "Acme — production CRM integration",
  "active": true,
  "is_supervisor": true,
  "roles": ["Admin"],
  "allowed_agents": [],
  "require_mapping": false,
  "created_at": "2026-05-12T12:34:56Z",
  "created_by": "<user_id>"
}

Example — supervisor key

curl -X POST https://compass.chordia.ai/projects/$PROJECT_ID/mcp-keys \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme — Alpha+Beta supervisor",
    "is_supervisor": false,
    "roles": ["Supervisor"],
    "allowed_agents": ["Alpha Agent", "Beta Agent"],
    "require_mapping": true
  }'

GET /projects/{project_id}/mcp-keys

List every active key for the project (redacted — no raw secrets).

Query Default
include_revoked false Include active=false keys for audit views

Response — 200 OK

{
  "items": [
    {
      "id": "<uuid>",
      "project_id": "...",
      "name": "Acme — production CRM",
      "key_preview": "AbCdE…",
      "active": true,
      "is_supervisor": true,
      "roles": ["Admin"],
      "allowed_agents": [],
      "require_mapping": false,
      "created_at": "...",
      "created_by": "<user_id>",
      "updated_at": null,
      "last_used_at": null
    }
  ],
  "count": 1
}

PATCH /projects/{project_id}/mcp-keys/{key_id}

Update any subset of RBAC / name / active fields. Omitted fields are left alone.

Useful for:

  • Renaming a key when a customer is rebranded
  • Narrowing an existing supervisor's allowed_agents
  • Re-enabling a revoked key (active=true)
  • Updating roles after a permission change
# Narrow an existing key to only Alpha Agent
curl -X PATCH https://compass.chordia.ai/projects/$PROJECT_ID/mcp-keys/$KEY_ID \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"allowed_agents": ["Alpha Agent"]}'

DELETE /projects/{project_id}/mcp-keys/{key_id}

Soft-revoke. Sets active=false so subsequent auth attempts fail with "Invalid or inactive API key", but preserves the doc so the audit trail (who minted it, when, by whom) survives.

Returns 204 No Content on success, 404 if the key is already revoked or unknown.

The knowledge base is per-project but managed via a separate set of endpoints (also Admin-gated):

GET    /projects/{project_id}/knowledge-base
POST   /projects/{project_id}/knowledge-base/domains
DELETE /projects/{project_id}/knowledge-base/domains/{domain_url}
PUT    /projects/{project_id}/knowledge-base/domains/{domain_url}
PATCH  /projects/{project_id}/knowledge-base
POST   /projects/{project_id}/knowledge-base/test

See src/compass/agentic/knowledge_base.py for the full REST surface.