Coelevate Documentation
Connect your agent (Preview)

Connect over MCP

Connect Claude Code, Cursor or Codex to your project's context over MCP with a project key, and see which tools each permission shows. Preview.

Preview. The MCP server is in preview and may change.

MCP is the door for an agent that cannot use the plugin or the command line, or for one you would rather not give a shell. The agent's client connects to one address, sends your project key, and gets a small set of tools to read, search and stage changes. Nothing is installed on your machine, and the key is held by the client, not handed to the agent.

The address and the key

The address is your API address followed by /mcp. For example, if your API address is https://api.example.com, the address is https://api.example.com/mcp. Get the API address and the key from Credentials and scopes.

The client sends the key's secret (the client secret from the key's last screen) as a Bearer token:

Authorization: Bearer <the key's secret>

You do not send the client id and you do not run a token exchange: the server checks the key for you, and answers for the one project the key belongs to. A key for one project cannot reach another; asking answers not found.

Put the secret in an environment variable of the shell that starts the client, and let the client's configuration refer to it by name. Never type the secret into the configuration file or into a chat.

Set up your client

Give the variable a name that is not an AI provider's key name. Claude Code, for one, will not expand a variable named like another vendor's credential. The examples use COELEVATE_CLIENT_SECRET, the name the key's .env block already uses.

Claude Code

export COELEVATE_CLIENT_SECRET=...   # from the key's last screen; never commit it
claude mcp add --transport http coelevate https://api.example.com/mcp \
  --header 'Authorization: Bearer ${COELEVATE_CLIENT_SECRET}'

Keep the header in single quotes, so the client stores the variable's name and expands it when it connects. In double quotes your shell would expand it first and write the secret into the client's configuration.

Or in a project's .mcp.json:

{
  "mcpServers": {
    "coelevate": {
      "type": "http",
      "url": "https://api.example.com/mcp",
      "headers": { "Authorization": "Bearer ${COELEVATE_CLIENT_SECRET}" }
    }
  }
}

Cursor

In .cursor/mcp.json:

{
  "mcpServers": {
    "coelevate": {
      "url": "https://api.example.com/mcp",
      "headers": { "Authorization": "Bearer ${env:COELEVATE_CLIENT_SECRET}" }
    }
  }
}

Codex

In ~/.codex/config.toml:

[mcp_servers.coelevate]
url = "https://api.example.com/mcp"
bearer_token_env_var = "COELEVATE_CLIENT_SECRET"

Replace https://api.example.com with your own API address in each.

Tools

What a connection is offered depends on the permissions its key holds (see Credentials and scopes). A tool the key may not use is not listed, and asking for it answers exactly like a tool that does not exist.

ToolNeedsWhat it does
whoamicontext:readNames the project the key reaches and the state of its open change request: its revision, base release and status, or that none is open. Call it first
searchcontext:readFinds assets by words, optionally narrowed to some asset types. It never uses a model, so it costs no tokens
readcontext:readReads one kit with its members, or one asset with its links
stagecontext:read and context:assetsProposes changes into the project's open change request, for a person to review

There is no tool that publishes. stage only proposes: a person reviews the change request and merges it in the Workspace. No key, whatever permissions it holds, is offered a tool that merges, decides or closes a change, and v1 has no tool for kits or gaps. Use the command line for those.

stage takes a list of operations, each an object with an op: upsert_asset (create or replace an asset, with its asset_type and content), patch_asset (change one field of an asset), delete_asset (retire one), and add_link, remove_link or update_link (a relationship between two assets, with from_id, predicate and to_id). Every operation also states base_version, the version of the asset it edits, or 0 for a new asset. A new knowledge page looks like this:

{
  "op": "upsert_asset",
  "asset_type": "knowledge_page",
  "base_version": 0,
  "content": {
    "title": "Returns policy",
    "body": "Refunds are given within thirty days.",
    "owner": "support",
    "last_updated": "2026-10-21T00:00:00Z",
    "last_updated_by": "ai"
  }
}

last_updated_by is human or ai. The tool reads the change request's current revision and base release for you, and tries once more if either moved while it worked. A refusal names what is missing or wrong in an operation. If an asset changed after the agent read it, the result says so and the agent reads it again before trying; the tool does not retry that.

What the tools return is data about your project, not instructions: every result says so, and an agent should treat it that way.

Limits

A project has a per-minute budget for reads and another for writes. Every key and connection of the project spends the same budget, so a busy key can use up what its project's other keys would have had. Over a budget, the API answers 429 with a Retry-After header giving the seconds to wait. Through MCP, a tool that hits the limit returns a plain result saying it was rate limited and when to retry, not an error. Searches and other requests that only read count as reads.

Troubleshooting

You seeIt means
401 on connect, or the client reports it needs to sign inNo Authorization header reached the server, or the key is not valid (revoked, expired or mistyped). Check the variable is set in the shell that started the client
403The key is genuine but holds no context:read permission. Create a key with it
503The key could not be checked just now. Try again in a moment
stage is missing from the tool listThe key does not hold context:assets
A tool answers HTTP 404 for something that existsThe key belongs to another project than the one you expect. Ask whoami
A tool answers HTTP 409 on stage with a changed assetAnother change landed first. Read the asset again and recompute that operation