---
title: "MCP endpoint"
---

# MCP endpoint

Connect an MCP client to the Context Platform for governed retrieval, policy checks and attribution links, and how the endpoint agent and first-party apps reach the same retrieval.

## The endpoint

`POST /mcp/v1/context` is an MCP server over Streamable HTTP (JSON-RPC 2.0, protocol `2024-11-05`). It is a full path, outside `/api/v1`, served behind the same authentication as the API: the caller is the signed-in person, and an anonymous request is `401`. Every tool call runs as that person, with their permissions.

### Tools

| Tool | Arguments | What it does |
|---|---|---|
| `keystone_context_retrieve` | `query`, `repo_url?`, `project_path?`, `token_budget` (default 2048) | Runs the regular retrieval: authorisation per space, DLP, budget and attribution. `token_budget` must be positive and is capped at 32000 |
| `keystone_policy_check` | `action`, `resource?` | Asks the governance decision point for the caller: `{"decision": "allow"}` or `{"decision": "deny"}`. An error fails closed |
| `keystone_context_attribute` | `attribution_id`, `request_id?` | Records that an AI response used a retrieval: a `context_attribution_link` record in the same evidence chain, idempotent per attribution and response |

`repo_url` (an https, ssh or scp-like git remote) selects the project space that has a codebase source for that repository; with none, the organisation space is used. When two projects hold the repository, the tool answers `context.space.repo_ambiguous` instead of guessing. `project_path` is local to the agent and not used by the server.

Only the person who retrieved, or a `context:space:admin` of the space, may link an attribution. The record is written asynchronously, so `keystone_context_attribute` called immediately after a retrieval may answer `context.attribution.not_found`: retry.

### Tokens

MCP access tokens are a person's tokens. There is no long-lived user-level token for an MCP client: API keys are organisation-level and carry no person, so per-person space authorisation would not be possible with them.

## Other ways to the same retrieval

| Caller | Route | Authentication |
|---|---|---|
| The Editor, the Agents app, the CLI | `POST /api/v1/context/retrieve` | The person's access token; `X-Keystone-Client: name/version` recorded in the attribution |
| MCP clients | `POST /mcp/v1/context` | The person's access token |
| The endpoint agent | `POST /api/v1/context/agent/retrieve`, `GET /api/v1/context/agent/project` | The device token; the server runs the request as the device's bound user, with that user's own permissions |

Local tools never call the agent routes themselves and never get a token: they ask the endpoint agent over its local socket, which accepts only processes of the agent's own operating system user (by peer credentials), and the agent forwards the request with its device token. A revoked device is `410`; an unbound device `403`.

## Capabilities for first-party apps

`GET /api/v1/context/capabilities` (any signed-in member) tells an app which features to offer, without administrator rights. It returns booleans and limits only: `retrieval`, `retrievalMaxTokenBudget`, `retrievalDefaultTokenBudget`, `retrievalMaxPerLevel`, `embeddings`, `indexing`, `attribution`, `collaboration`, `events`, `memory`, `presence`, `lensSharing`, `handoffs`, `pairSessions`, `workRegistry`, `agentFiles`, `agentFilesMaxSizeBytes`, `customShares`, `customSharesMaxFiles`, `customSharesMaxFileSizeBytes`.

A member is true only when the deployment serves the feature **and** the caller's own collaboration policy allows it. A policy that cannot be resolved is `503 context.collab_policy.unavailable`, never a guess. The answer names no URL, key, model or identifier. A client treats a member it does not know as false.
