Skip to content

Corveil MCP (connect a client) ​

Corveil exposes all of its first-party tools as a remote MCP (Model Context Protocol) server at one endpoint: /mcp. Any MCP-aware client — Claude Code, Codex CLI, Claude Desktop, ChatGPT Desktop, Cursor — can point at it, authenticate with a virtual API key or a browser OAuth flow, and call Corveil's tools alongside its own.

Two MCP surfaces

This page is inbound: connect a client to Corveil's own tools at /mcp.

To govern external MCP servers (GitHub, AWS, …) behind Corveil — one org-held credential, RBAC, and audit — see MCP Gateway (govern external servers).

One connection carries three families of tools, delivered as namespaces:

  • ontology_* — read your organizational knowledge graph: the entities, meetings, decisions, and people the gateway has already indexed for your org.
  • insights_* — read generated intelligence: activity-derived recommendations and auto-built user profiles.
  • control_* — operate Corveil itself: models, keys, guardrails, prompts, teams, sensors, org settings, billing. Mutating, and destructive operations require an explicit confirm: true.

Which namespaces you receive depends on how you authenticate — see The three namespaces below. This page is for wiring an external client to the /mcp endpoint.

Endpoint & authentication ​

Streamable HTTP transport. A credential returns only its own organization's data. A request for another organization's data comes back empty.

http
POST https://your-corveil-host/mcp
X-Corveil-Key: sk-citadel-your-key-here
Content-Type: application/json
Accept: application/json, text/event-stream

There are two ways to authenticate the same endpoint:

MethodHeaderBest for
Virtual API keyX-Corveil-Key: sk-citadel-… (or x-api-key:)Headless clients, CI, scripts. Create one under People & Access → API Keys.
OAuth 2.0 + DCRAuthorization: Bearer crv_at_…Interactive clients with native OAuth (Claude Desktop, ChatGPT Desktop, Codex CLI ≥ 0.4). No key ever leaves Corveil — see Connect without an API key.

The two paths are additive: OAuth is purely a keyless alternative for clients that support it, and the API-key path stays as-is for everything else.

The three namespaces ​

A single connection can carry well over a hundred tools. Which of the three namespaces you actually receive is decided by your credential class, so the same endpoint is safe to hand to a browser connector and to a CI key alike:

Credentialontology_*insights_*control_*
Virtual API key / dashboard session✅✅✅ †
OAuth / DCR bearer✅——

† The control_* namespace is offered to a control-capable credential only when the deployment has the control plane enabled.

The consent screen lists mcp.read, mcp.tools, mcp.write, and gateway:invoke. A client that requests only mcp.read + mcp.tools stays read-only on the graph — that is the common Claude Desktop / ChatGPT Desktop path. mcp.write is what "whose grant permits it" means for the write tools already on this page; it is not implied by mcp.tools. gateway:invoke is likewise not implied by mcp.tools: it is required to see and call gateway_list_tools / gateway_call_tool (read-only invoke of MCP servers your org has registered). control_* is still never granted to an OAuth bearer, so a browser-consented connector can never mutate your configuration. Do not request orgs.read or keys.provision on this connection; they are not MCP connector scopes.

Tools you are not entitled to are absent from tools/list and refused on tools/call — knowing a tool's name is not enough to invoke it.

Narrowing the tool list ​

Because one connection can expose the whole first-party surface, you can narrow it to just the namespaces a given agent needs — smaller tool lists keep a model focused and cheaper. Append ?ns= to the URL:

https://your-corveil-host/mcp?ns=ontology,insights

…or send an X-Corveil-MCP-Namespaces: ontology header. Narrowing only ever shrinks the list — a selector can never grant a namespace your credential lacks, and an unrecognized selector yields an empty list rather than everything.

Tool reference ​

Ontology (ontology_*) — read the knowledge graph ​

Three ergonomic primitives cover most work:

ToolPurpose
ontology_lookup"Tell me about X." Resolve an entity by name (+ optional entity_type) or entity_id; returns the synthesized context bundle — properties, 1-hop relationships, identity records, source-event count.
ontology_searchOpen-ended search. query plus optional entity_types[], a time_range (since/until), and conversation_id/thread_id to scope to one chat.
ontology_relatedThe 1..N-hop neighborhood of an entity. entity_id (preferred) or name+entity_type, optional depth (default 1, max 5).

Lower-level reads for drilling into a specific entity or source:

ToolPurpose
ontology_entityThe entity's own fields (no edges).
ontology_contextFull synthesized page + relationships + identity records.
ontology_graphExplore connected entities and relationships within N hops.
ontology_evidenceThe source events that produced or mention an entity (newest first).
ontology_timelineThose source events in chronological order.
ontology_historyPer-entity change history: one attributed, newest-first feed merging the decision/audit log (edits, with a field-level diff) and the source-event timeline. Identify the entity by id, or by type + name. Optional limit (default 50) and offset.
ontology_eventThe full original content of one source event, by id.
ontology_source_fetchThe full session transcript behind a session-derived entity.
ontology_statsScalar counts + extraction status for the graph.
ontology_decisionsThe decision / guardrail audit trail.
ontology_policiesActive organizational policies governing AI usage.

Write tools — present only for callers whose org has the ontology-write feature and whose grant permits it (mcp.write on an OAuth bearer; it is not implied by mcp.tools), and concealed from tools/list otherwise:

ToolPurpose
ontology_create_entityCreate (or merge into) an entity. Idempotent on entity_type + name.
ontology_update_entityUpdate a known entity's properties, name, or aliases.
ontology_linkCreate a directional relationship between two existing entities.
ontology_unlinkRemove a relationship (destructive — pass confirm: true).
ontology_propose_mergeFile a reviewable proposal to merge duplicate entities (does not merge).
ontology_set_contentWrite the entity's synthesized knowledge page (markdown). Replaces any prior page wholesale — fold existing facts in rather than dropping them. Distinct from ontology_update_entity, which sets structured attributes.

Insights (insights_*) — read generated intelligence ​

ToolPurpose
insights_recommendationsActivity-derived, actionable recommendations as markdown. Optional limit, offset.
insights_profilesAuto-built user profiles — expertise, projects, focus areas. Optional user_id; omit for all.

Control (control_*) — operate Corveil itself ​

The control namespace is one tool per control-plane operation — around a hundred of them — named control_<area>_<verb>, e.g. control_keys_list, control_keys_create, control_teams_delete, control_guardrails_update. They span:

AreaWhat it manages
Keys & credentialsVirtual API keys, provider credentials
Models & pricingThe model registry and pricing
Guardrails & promptsContent guardrails and saved prompts
Teams, users & orgTeams, members, invitations, org settings
Sensors & jobsSensor configuration and scheduled jobs
Billing, usage & logsBilling, usage rollups, request logs
Sessions & exportSessions, and request-log and usage exports

Because the set is large and evolves, treat tools/list as the source of truth for the exact names your build and credential expose. Four conventions apply across the namespace:

  • Destructive operations return a requires_confirmation preview unless you pass confirm: true — the mutation never runs on the first, un-confirmed call.
  • Privilege / enable–disable flips require the same confirm: true, but only when the call actually sets the gated field.
  • Idempotent operations accept an optional retry key so a re-sent call returns the original result instead of acting twice.
  • Optimistic concurrency: operations that support it accept an If-Match precondition (a resource's updated_at, or * for "must exist").

Client setup ​

Point the client at /mcp over the HTTP (Streamable HTTP) transport and set the X-Corveil-Key header.

Claude Code (~/.config/claude-code/mcp.json) ​

json
{
  "mcpServers": {
    "corveil": {
      "transport": {
        "type": "http",
        "url": "https://your-corveil-host/mcp",
        "headers": {
          "X-Corveil-Key": "sk-citadel-your-key-here"
        }
      }
    }
  }
}

Codex CLI (~/.codex/config.toml) ​

toml
[mcp_servers.corveil]
url = "https://your-corveil-host/mcp"
http_headers = { "X-Corveil-Key" = "sk-citadel-your-key-here" }

Verify the connection ​

bash
# tools/list returns the namespaces your credential is entitled to.
curl -sS https://your-corveil-host/mcp \
  -H "X-Corveil-Key: sk-citadel-your-key-here" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Connect without an API key (OAuth + DCR) ​

Corveil's MCP endpoint also accepts a browser sign-in, so clients with native OAuth support connect without ever seeing an sk-citadel-… key. The user clicks Connect in their MCP client, a browser opens to a Corveil consent screen, they approve, and the client is authorized.

  1. In the client's "Add remote server" dialog, paste your Corveil host URL — https://your-corveil-host/mcp — and leave the API-key field empty.
  2. Choose Connect. The client opens a browser consent screen.
  3. If you're not already signed in, sign in first. The consent screen shows the scopes the client requested — mcp.read, mcp.tools, and optionally mcp.write. A client that asks only for mcp.read and mcp.tools stays read-only on the graph and lands the ontology_* namespace (the common Claude Desktop / ChatGPT Desktop path). mcp.write unlocks the write tools on this page; it is not implied by mcp.tools. control_* is never granted on this sign-in. Approve.
  4. Manage every authorized client from People & Access → OAuth Clients (page title Clients). Revoking immediately invalidates every outstanding bearer token issued to that application, and disables any gateway API keys it provisioned on your behalf.

Later calls use the issued bearer in place of X-Corveil-Key:

bash
curl -sS https://your-corveil-host/mcp \
  -H "Authorization: Bearer crv_at_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Access tokens last 1 hour. Refresh tokens last 30 days and rotate on every use.

Rate limit & observability ​

Requests share the per-key RPM/TPM rate limit applied to every /v1/* and /mcp surface — bursting from a desktop client will eventually hit the same 429 your other API-key traffic would, under the same global auth + key throttle as /v1/messages and /v1/responses.

Per-tool rate limits and per-call audit are not available on the remote /mcp endpoint.

Troubleshooting ​

  • 401: the X-Corveil-Key (or Authorization: Bearer) is missing, malformed, or revoked. Re-issue under People & Access → API Keys, or re-run the OAuth connect flow.
  • Empty results for a known entity: the entity belongs to another org. Verify the credential's org owns the data.
  • A tool you expected is absent from tools/list: you are not entitled to its namespace with this credential (an OAuth bearer sees ontology_* only), or — for the ontology_* write tools — your org lacks the write feature, or your OAuth grant does not include mcp.write. Re-check the namespace table.
  • control_* tools missing entirely: either you authenticated with an OAuth bearer (control_* is never granted to an OAuth bearer) or the deployment has the control plane disabled.