Skip to content

Wire your coding agent to Carabase

Point your local coding agent — Claude Code, Codex CLI, Cursor, or Gemini CLI — at Carabase over MCP, and every coding session is grounded in your knowledge mesh and project history instead of the model’s parametric memory. The agent can answer “what did we decide about X”, pull the folio for the repo it’s working in, and cite your real data.

The fast path is one command:

Terminal window
carabase mcp pair --client claude-code

It mints a per-client token and prints the exact config to paste. The rest of this page explains what it did and the manual alternative.

When a coding agent has the Carabase MCP server wired in, it reaches two kinds of context over the same transport:

  1. Your knowledge mesh — semantic / graph / lexical / metadata / visual search, entity resolution, memory traversal, folio reads. “Find the term-sheet clause about good-leaver”, “who owns the retrieval pipeline” — answered from your real data.
  2. Per-project context — if you’ve bound a repo to a project folio, the agent can read that folio and its decision records for the exact codebase it’s working in, recovering prior sessions and “why is it this way” before it starts.
Terminal window
carabase mcp pair [--client claude-code|codex|cursor|gemini-cli|openclaw|generic] [--read-only] [--label <name>] [--force]
  • --client — which config snippet to print. Omit it (or pass generic) to get the raw connection facts as JSON, enough to wire any MCP client by hand.
  • --read-only — mint a read-only token. The host then denies write tools (commit_to_folio, folio edits, …) for that client server-side. Tokens are read-write by default; opt into read-only for an agent you don’t want mutating your mesh — see Security.
  • --label — the name shown in the admin MCP Clients page (so you can see which agent each token belongs to and revoke it later). Defaults from --client.
  • --force — for claude-code and codex, pair first looks at the client’s own user config (~/.claude.json, ~/.codex/config.toml). If a carabase server is already there it mints nothing and tells you what exists (URL and which headers are set — never their values) and how to remove it, because claude mcp add refuses a name that already exists and the fresh token would be stranded. --force mints anyway and prints a snippet that replaces the entry (remove, then add).

The token is shown once. If you lose it, revoke it (carabase mcp clients revoke, below, or the admin MCP Clients page) and re-pair.

With no --client, pair prints the connection facts directly:

Terminal window
carabase mcp pair --read-only --label my-laptop
{
"transport": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"x-workspace-id": "<your-workspace-id>",
"Authorization": "Bearer <token>"
},
"read_only": true
}

Any MCP-over-HTTP client can be wired from those four facts. The --client presets below are just convenience formatting of the same thing.

The host exposes its MCP surface over Streamable HTTP at …/mcp:

From URL
The same machine the host runs on http://localhost:3000/mcp
Another machine on your tailnet https://<host>.<tailnet>.ts.net/mcp

<host>.<tailnet>.ts.net is the host’s Tailscale MagicDNS name. There are no public ports — only your tailnet peers can reach it. carabase mcp pair targets, in order: --base-url, CARABASE_BASE_URL, the host you signed in to with carabase auth login (recorded in ~/.carabase/auth.json), then http://localhost:3000. So on a different machine, carabase auth login --base-url https://<host>.<tailnet>.ts.net once is enough — every later pair prints the tailnet URL. Pass --base-url to override; if you have signed in to several hosts for the same workspace, pair asks you to.

Every request is workspace-scoped. A per-client bearer token binds the workspace itself, so the x-workspace-id header is optional; on a single-tenant host a header-less client also resolves to your one workspace. The presets below include the header anyway — it’s explicit and silences a fallback warning.

If you’d rather paste by hand, here’s what each preset prints (<workspace-id> and <token> are filled in for you by pair).

--scope user makes the server available in every repo you open, not just one:

Terminal window
claude mcp add --transport http --scope user carabase \
http://localhost:3000/mcp \
--header "x-workspace-id: <workspace-id>" \
--header "Authorization: Bearer <token>"
claude mcp list # → carabase: … (HTTP) - ✔ Connected

Add to ~/.codex/config.toml:

[mcp_servers.carabase]
url = "http://localhost:3000/mcp"
http_headers = { "x-workspace-id" = "<workspace-id>", "Authorization" = "Bearer <token>" }

Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
"mcpServers": {
"carabase": {
"url": "http://localhost:3000/mcp",
"headers": {
"x-workspace-id": "<workspace-id>",
"Authorization": "Bearer <token>"
}
}
}
}

Merge into ~/.gemini/settings.json (user scope — never a project-local .gemini/):

{
"mcpServers": {
"carabase": {
"httpUrl": "http://localhost:3000/mcp",
"headers": {
"x-workspace-id": "<workspace-id>",
"Authorization": "Bearer <token>"
}
}
}
}

Note the key is httpUrl, not url — Gemini CLI’s streamable-HTTP transport uses a different field name than Cursor’s.

Security — read before sharing a tailnet

Section titled “Security — read before sharing a tailnet”

The /mcp gate is fail-open when no token exists: on a machine only you use (loopback, or a private single-user tailnet) you reach the surface with no token at all. That window is read-only — an unauthenticated session gets the whole read surface, but the write tools (commit_to_folio, folio edits, session capture, …) are absent from tools/list and denied at dispatch. So if you want a coding agent to write into your mesh, mint a token: carabase mcp pair without --read-only gives it the write surface. (Carabase’s own built-in chat agent is unaffected either way — the host gives the co-located gateway its own credential.)

Minting is also the right move if other people or untrusted devices share your tailnet. Minting the first token turns the gate on, and from then on every /mcp request must present a valid bearer. Use --read-only for any agent you don’t want writing — a read-only token authenticates but is denied write tools, enforced server-side (a shell-capable agent can’t bypass it by dropping a header).

Manage tokens (list which agent holds which, revoke a lost one) with carabase mcp clients, or in the admin MCP Clients page:

Terminal window
carabase mcp clients list # active keys; --all adds revoked, --kind filters, --json for scripts
carabase mcp clients revoke <id-or-8-char-prefix> # shows the key and asks first; --yes skips the question
carabase mcp clients revoke --stale --kind codex # every other codex key recorded against this Mac

The list never shows token values. Its IN USE BY column names the agent on this Mac whose config holds each key (the CLI hashes each config’s key locally and asks the host which key that is; the key itself never leaves the machine), and revoke warns before it disconnects one — carabase harness register <agent> mints a replacement. --stale keeps whatever key the agent is using and any key used in the last 24 hours (--include-recent overrides), and refuses outright when it can’t tell which key the agent is using.

Wiring the server is half of it — the habit is the other half. Encode it in your repo’s CLAUDE.md / AGENTS.md and your global agent config so the agent does it unprompted:

  • Start by recalling context. Before changing code in a repo with a project folio, read the folio (carabase_read_folio) and its decisions (carabase_list_folio_decisions).
  • Ground claims in retrieval. For anything about your data or history, query the mesh (carabase_route_and_execute is the good default) rather than guessing.
  • Hydrate before quoting. Tool hits return snippets plus a carabase://artifact/{id}; read the full body before quoting a clause or figure.

The server also serves these habits in-band — the MCP instructions carry a retrieval playbook (hydrate before quoting; folios first for preference questions; lexical search for named entities; decompose recommendation queries) and routed search pages end with a standing reminder — so an agent gets the basics even before you encode them in its config. Encoding them locally still helps: config guidance survives clients that ignore server instructions.

With AI session capture enabled (ai_session_capture_enabled, default-off, privacy-first), your coding sessions flow back into the matching project folio as evidence — so today’s session becomes tomorrow’s recalled context. Read context in → write session out → richer context next time.