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 explicitconfirm: 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.
POST https://your-corveil-host/mcp
X-Corveil-Key: sk-citadel-your-key-here
Content-Type: application/json
Accept: application/json, text/event-streamThere are two ways to authenticate the same endpoint:
| Method | Header | Best for |
|---|---|---|
| Virtual API key | X-Corveil-Key: sk-citadel-… (or x-api-key:) | Headless clients, CI, scripts. Create one under People & Access → API Keys. |
| OAuth 2.0 + DCR | Authorization: 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:
| Credential | ontology_* | 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:
| Tool | Purpose |
|---|---|
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_search | Open-ended search. query plus optional entity_types[], a time_range (since/until), and conversation_id/thread_id to scope to one chat. |
ontology_related | The 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:
| Tool | Purpose |
|---|---|
ontology_entity | The entity's own fields (no edges). |
ontology_context | Full synthesized page + relationships + identity records. |
ontology_graph | Explore connected entities and relationships within N hops. |
ontology_evidence | The source events that produced or mention an entity (newest first). |
ontology_timeline | Those source events in chronological order. |
ontology_history | Per-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_event | The full original content of one source event, by id. |
ontology_source_fetch | The full session transcript behind a session-derived entity. |
ontology_stats | Scalar counts + extraction status for the graph. |
ontology_decisions | The decision / guardrail audit trail. |
ontology_policies | Active 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:
| Tool | Purpose |
|---|---|
ontology_create_entity | Create (or merge into) an entity. Idempotent on entity_type + name. |
ontology_update_entity | Update a known entity's properties, name, or aliases. |
ontology_link | Create a directional relationship between two existing entities. |
ontology_unlink | Remove a relationship (destructive — pass confirm: true). |
ontology_propose_merge | File a reviewable proposal to merge duplicate entities (does not merge). |
ontology_set_content | Write 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
| Tool | Purpose |
|---|---|
insights_recommendations | Activity-derived, actionable recommendations as markdown. Optional limit, offset. |
insights_profiles | Auto-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:
| Area | What it manages |
|---|---|
| Keys & credentials | Virtual API keys, provider credentials |
| Models & pricing | The model registry and pricing |
| Guardrails & prompts | Content guardrails and saved prompts |
| Teams, users & org | Teams, members, invitations, org settings |
| Sensors & jobs | Sensor configuration and scheduled jobs |
| Billing, usage & logs | Billing, usage rollups, request logs |
| Sessions & export | Sessions, 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_confirmationpreview unless you passconfirm: 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-Matchprecondition (a resource'supdated_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)
{
"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)
[mcp_servers.corveil]
url = "https://your-corveil-host/mcp"
http_headers = { "X-Corveil-Key" = "sk-citadel-your-key-here" }Verify the connection
# 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.
- 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. - Choose Connect. The client opens a browser consent screen.
- If you're not already signed in, sign in first. The consent screen shows the scopes the client requested —
mcp.read,mcp.tools, and optionallymcp.write. A client that asks only formcp.readandmcp.toolsstays read-only on the graph and lands theontology_*namespace (the common Claude Desktop / ChatGPT Desktop path).mcp.writeunlocks the write tools on this page; it is not implied bymcp.tools.control_*is never granted on this sign-in. Approve. - 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:
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(orAuthorization: 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 seesontology_*only), or — for theontology_*write tools — your org lacks the write feature, or your OAuth grant does not includemcp.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.