ctx mcp
ctx mcp is Contexo’s MCP server: with no subcommand it speaks JSON-RPC over
stdio and hands the calling agent this project’s knowledge base. Its
subcommands write that same server into each agent’s own config file.
When you’d reach for it
Section titled “When you’d reach for it”You rarely type the bare command — the agent spawns it. You reach for the
subcommands when an agent showed up after ctx init ran, when you want Codex
wired (the one agent Contexo never wires silently, because its MCP config is
global), or when the agent lists a contexo server with no tools and you need
to know whether the problem is the wiring or the directory it was launched in.
Two things trip people up. Agents read their MCP config at startup, so every
wiring change needs an agent restart before it means anything. And the entry
Contexo writes is literally {"command": "ctx", "args": ["mcp"]} (for VS Code,
the same command with --root ${workspaceFolder} added) — so ctx has to be
on the PATH the agent sees, which on macOS GUI apps is often not the PATH
your shell sees.
Synopsis
Section titled “Synopsis”ctx mcp # run the server over stdio (agents invoke this)ctx mcp install [--tool=…] # wire it into an agent's configctx mcp uninstall [--tool=…] # remove that wiringctx mcp status # what's wired for this projectctx mcp guide # config recipes for every other harnessctx mcp takes no flags.
Inherited from the root command:
| Flag | Type | Default | Description |
|---|---|---|---|
--root | string | project root directory (default: current directory) |
--root is more load-bearing here than on other commands. The bare server
resolves its project exactly once, at startup, from --root or the process’s
working directory — and never re-checks. Agents launch ctx mcp with the
project as the working directory, so you normally don’t need it; a harness that
spawns MCP servers from a fixed directory does. VS Code does not promise a
working directory, which is why the entry Contexo writes for it passes
--root ${workspaceFolder}.
How it works
Section titled “How it works”Bare ctx mcp opens the page store at <root>/.contexo, then reads
newline-delimited JSON-RPC 2.0 from stdin and writes exactly one JSON response
line to stdout per request (input lines up to 10 MB). It handles initialize,
tools/list, tools/call, resources/list and resources/read; every other
method returns -32601 method not found. It reports protocol version
2024-11-05 and serverInfo.name = "contexo", and it stores the
clientInfo.name you send in initialize, which is how a pull gets attributed
to the agent that made it.
All 10 tools and 5 resources are served from that
one process — there is no daemon and no port. Most of the work is local disk;
ctx_push, ctx_pull, ctx_history, ctx_diff and ctx_evolution call the
Contexo server, and reads of ctx://wiki/{slug} fire a best-effort drift check
against it (cached for 60s, silently skipped when offline).
The dormant server
Section titled “The dormant server”If <root>/.contexo does not exist, the server does not fail. It runs
dormant: initialize succeeds, tools/list and resources/list return
empty arrays, and everything else answers
-32601 method not available (no .contexo project in this directory).
That exists because of Codex. Codex’s MCP config is global, so a single
~/.codex/config.toml entry launches ctx mcp in every directory you open
Codex in. A server that exited non-zero in unrelated repos would surface as a
broken integration on every launch; a server with zero tools is honest and
quiet. The practical consequence: if an agent shows contexo connected but
with no tools, you are outside a Contexo project (or the agent’s working
directory isn’t the project root). Run ctx init, then restart the agent.
Common errors
Section titled “Common errors”| Message | Cause and fix |
|---|---|
mcp: open store: … (did you run 'ctx init'?) |
.contexo exists but can’t be opened as a directory — usually a stray .contexo file, or a permissions problem. A merely missing .contexo goes dormant instead of erroring. |
mcp install: not a Contexo project (run 'ctx init' first) |
ctx mcp install refuses to wire an agent to a project that doesn’t exist yet. uninstall, status and guide have no such check. |
unknown --tool "x" (want claude, cursor, vscode, codex, or all) |
Typo in --tool. Accepted values are exactly claude, cursor, vscode, codex, all (and empty, which means all). |
.vscode/mcp.json is not strict JSON (comments or trailing commas?); left it untouched. Add this entry by hand: |
Your .vscode/mcp.json has comments or trailing commas, which VS Code allows but a rewrite would destroy. Contexo prints the entry for you to paste into servers. With --tool=vscode this also fails the command; under --tool=all the other agents are still wired. |
ctx mcp install
Section titled “ctx mcp install”Writes the contexo MCP server into an agent’s config.
ctx mcp install # claude + cursor, plus vscode and codex if detectedctx mcp install --tool=claude # ./.mcp.jsonctx mcp install --tool=cursor # ./.cursor/mcp.jsonctx mcp install --tool=vscode # ./.vscode/mcp.jsonctx mcp install --tool=codex -y # ~/.codex/config.toml, no prompt| Flag | Type | Default | Description |
|---|---|---|---|
--tool | string | all | agent to wire: claude|cursor|vscode|codex|all |
--yes, -y | bool | false | skip confirmation prompts (e.g. Codex's global config) |
Each agent reads MCP servers from a different place, and only one of them is global:
| Agent | Config it reads | Scope | How Contexo writes it |
|---|---|---|---|
| Claude Code | ./.mcp.json |
project | merges the JSON itself |
| Cursor | ./.cursor/mcp.json |
project | merges the JSON itself |
| VS Code | ./.vscode/mcp.json |
project | merges the JSON itself, under servers |
| Codex | ~/.codex/config.toml |
global | shells out to codex mcp add contexo -- ctx mcp |
Contexo never parses Codex’s TOML — that file’s format is Codex’s business, so
wiring and unwiring both go through the codex CLI. That is also why Codex
must be on PATH to be wired at all: wiring it means running codex mcp add.
Claude and Cursor get no detection here — each is just a project-local JSON
file, harmless to write for an agent you don’t run.
VS Code’s file uses its own format: a servers key instead of mcpServers,
and an entry that names its transport and passes the project root:
{ "servers": { "contexo": { "type": "stdio", "command": "ctx", "args": ["mcp", "--root", "${workspaceFolder}"] } }}VS Code reads that file as JSON with comments. Contexo merges into it only when it is strict JSON; otherwise it leaves the file alone and prints the entry for you to add (see Common errors).
--tool=all (the default) wires Claude and Cursor unconditionally, adds VS
Code when it is detected (a ~/.vscode directory or code on PATH), and adds
Codex only when that binary is present — an absent one is skipped silently.
Ask for VS Code explicitly with --tool=vscode and it is wired whether it is
detected or not. Ask for Codex explicitly and a missing binary is an error:
mcp install codex: Codex CLI not found (`codex` not on PATH).
The JSON merge is idempotent and preserves every other key in the file — but it
is not a “leave what’s there” merge: if the existing contexo entry differs in
any way from {"command": "ctx", "args": ["mcp"]} (or, for VS Code, from the
entry above), it is replaced. Custom
tweaks (an absolute path to ctx, an env block) are silently reverted by the
next ctx mcp install or ctx init. An entry that already matches is left
untouched and reported as already wired.
Adds Contexo's MCP server so an agent's tools (ctx_push/pull/write_page,
history/diff, etc.) become available:
claude -> ./.mcp.json (project-local)
cursor -> ./.cursor/mcp.json (project-local)
vscode -> ./.vscode/mcp.json (project-local, key servers)
codex -> ~/.codex/config.toml (GLOBAL — prompts unless --yes)
--tool=all wires the project-local agents (claude, cursor), VS Code when it
is detected (~/.vscode or `code` on PATH), and codex when it is installed.
Usage:
ctx mcp install [flags]
Flags:
-h, --help help for install
--tool string agent to wire: claude|cursor|vscode|codex|all (default "all")
-y, --yes skip confirmation prompts (e.g. Codex's global config)
Global Flags:
--root string project root directory (default: current directory)ctx mcp uninstall
Section titled “ctx mcp uninstall”Removes the contexo entry from an agent’s config.
ctx mcp uninstall # every agentctx mcp uninstall --tool=cursor # just ./.cursor/mcp.jsonctx mcp uninstall --tool=vscode # just ./.vscode/mcp.json| Flag | Type | Default | Description |
|---|---|---|---|
--tool | string | all | agent to unwire: claude|cursor|vscode|codex|all |
Unlike install, this does not require a Contexo project — you can unwire a
directory whose .contexo/ is already gone. For Claude and Cursor it deletes
just the contexo key; if that leaves mcpServers empty and mcpServers was
the only top-level key, the file is deleted rather than left as an empty husk.
Any other key in the file (another MCP server, an unrelated setting) keeps the
file alive. VS Code works the same way under its servers key, with no
detection check: whatever is on disk is cleaned up, and .vscode/ itself is
never removed. A .vscode/mcp.json that is not strict JSON is left alone, with
a warning to remove servers.contexo by hand if it mentions contexo. For
Codex it runs codex mcp remove contexo, but only after checking
codex mcp get contexo — a Codex that isn’t installed, or isn’t wired, prints
nothing to do. instead.
To undo the whole ctx init — MCP entries (the VS Code one included), capture
hooks, the .gitignore line and the knowledge directory — use
ctx detach instead of running these one at a time. Its plan
lists every step before it asks; this run kept the knowledge directory and was
declined at the prompt:
── DETACH PLAN
- delete .mcp.json (only contained the contexo entry)
- delete .cursor/mcp.json (only contained the contexo entry)
- remove the "contexo" entry from .vscode/mcp.json (the file is deleted if nothing else is left)
- remove the .contexo/ line from .gitignore
- remove the Contexo Stop hook from .claude/settings.json
- remove the Contexo capture hooks from .cursor/hooks.json
- (keeping .contexo/ as requested)
Proceed? [y/N]: Aborted.ctx mcp status
Section titled “ctx mcp status”One table showing, per agent, whether the MCP server and the capture hook are wired for this project.
ctx mcp statusctx mcp status takes no flags.
── AGENT INTEGRATIONS
AGENT MCP SERVER CAPTURE (STOP HOOK)
● Claude Code wired (.mcp.json) installed
● Cursor wired (.cursor/mcp.json) installed
● VS Code wired (.vscode/mcp.json) -
○ Codex not installed not installed
Add another agent (Windsurf, OpenCode, Hermes, ...)?
try ctx mcp guideEvery cell is computed live from a different source, which is worth knowing when a row looks wrong:
- Claude Code / Cursor MCP — reads
./.mcp.jsonand./.cursor/mcp.jsonand checks for anmcpServers.contexokey. - VS Code MCP — reads
./.vscode/mcp.jsonand checks for aservers.contexokey. A file with comments or trailing commas showsnot strict JSON (.vscode/mcp.json). - Codex MCP —
not installedmeans thecodexbinary isn’t on PATH; otherwise it shells out tocodex mcp get contexoand reportswired (~/.codex, global)ornot wired (~/.codex, global). - Capture — reads three different files:
.claude/settings.json,.codex/hooks.json,.cursor/hooks.json. Seectx hooks.
ctx mcp status reports what is on disk now, not what the running agent
loaded. A row that says wired while the agent still shows no contexo server
means the agent hasn’t been restarted since the wiring changed.
ctx mcp guide
Section titled “ctx mcp guide”Prints config recipes for agents Contexo doesn’t wire directly.
ctx mcp guidectx mcp guide takes no flags.
── ADD CONTEXO TO ANOTHER AGENT OR HARNESS
Contexo's MCP server is a standard stdio server: command "ctx", args ["mcp"].
Add that to the agent's own MCP config — same server everywhere; only the
file and format differ:
AGENT CONFIG FORMAT / HOW
Claude Code ./.mcp.json JSON mcpServers — ctx mcp install --tool=claude
Cursor ./.cursor/mcp.json JSON mcpServers — ctx mcp install --tool=cursor
VS Code ./.vscode/mcp.json JSON servers — ctx mcp install --tool=vscode
Codex ~/.codex/config.toml TOML [mcp_servers.contexo] — ctx mcp install --tool=codex
Windsurf ~/.codeium/windsurf/mcp_config.json JSON mcpServers
OpenCode ./opencode.json JSON mcp: { contexo: { type: "local", command: ["ctx","mcp"] } }
Hermes config.yaml YAML mcp_servers: { contexo: { command: ctx, args: [mcp] } }
OpenClaw (CLI-managed) run the `openclaw mcp` command
JSON mcpServers entry: "contexo": { "command": "ctx", "args": ["mcp"] }
VS Code servers entry: "contexo": { "type": "stdio", "command": "ctx", "args": ["mcp", "--root", "${workspaceFolder}"] }
Any other MCP client: add the same server; see its docs for the exact path.
Capture (the Stop hook): Claude Code, Codex, and Cursor are supported.
try ctx hooks install --tool=claude|codex|cursor|all
Claude parses its transcript; Codex and Cursor pair their prompt + response
hooks inline. Other MCP-capable harnesses get the tools now; capture as they
expose a stop/turn-end hook.This is static text — it needs no project and makes no network call, so it
works anywhere. The same guide is printed at the end of ctx init;
ctx mcp status only points at it. Every row is the same server (command: "ctx",
args: ["mcp"], plus --root ${workspaceFolder} for VS Code); only the file and
the surrounding syntax change, which is why “add Contexo to my agent” is a config
question and never a build question.
See also
Section titled “See also”ctx init— creates.contexo/and does this wiring for youctx hooks— the other half of agent integration: per-turn capturectx detach— remove every wirectx initadded- MCP reference — the tools this server exposes
