Skip to content

ctx init

Creates the .contexo/ knowledge tree for a project and connects the AI coding agents on your machine to it.

Once per project, from the repository root, before anything else. It needs no login and never contacts a Contexo server — every step is a local file write — so it is safe to run while you are still deciding whether you want Contexo at all (ctx detach reverses it).

Two things trip people up. First, ctx init does not log you in or attach a remote repo; straight after it you have a local knowledge base and nothing else, which is exactly what ctx status reports below. Second, everything is written relative to the current directory (or --root), so running it from a subdirectory quietly gives you a second, useless .contexo/. Run it where your .git is.

Re-running is safe. It is idempotent by design: existing config, seed files, MCP entries and hooks are left alone, so ctx init is a reasonable way to pick up an agent you installed after the fact (though ctx mcp install and ctx hooks install are the targeted tools for that).

Terminal window
ctx init
ctx init --root path/to/project
ctx init --no-gitignore
ctx init --no-mcp --no-hooks
ctx init --no-vscode
FlagTypeDefaultDescription
--no-cursorboolfalseskip auto-wiring Cursor (.cursor/mcp.json) even when Cursor is detected
--no-gitignoreboolfalseskip adding .contexo/ to .gitignore
--no-hooksboolfalseskip registering the Claude Code Stop hook for per-turn capture
--no-mcpboolfalseskip wiring the MCP server into agent configs (.mcp.json, .cursor/mcp.json, .vscode/mcp.json)
--no-vscodeboolfalseskip auto-wiring VS Code (.vscode/mcp.json) even when VS Code is detected
FlagTypeDefaultDescription
--rootstringproject root directory (default: current directory)

A few of these do less — or more — than their one-liners suggest:

  • --no-cursor only skips Cursor’s MCP entry. Cursor’s capture hooks are governed by --no-hooks, not by --no-cursor, so ctx init --no-cursor on a machine with Cursor installed still writes .cursor/hooks.json. Use --no-hooks as well if you want no .cursor/ directory at all.
  • --no-hooks skips all three capture integrations, not just Claude Code’s: no Stop hook in .claude/settings.json, no .codex/hooks.json, no .cursor/hooks.json.
  • --no-mcp implies no Cursor or VS Code MCP entry, and also suppresses the “Codex detected” hint. It does not affect hooks.
  • --no-vscode only skips VS Code’s .vscode/mcp.json. VS Code has no capture hooks, so there is nothing else to skip.
  • --root is a global flag and is resolved before anything is created; every path on this page is relative to it.
Terminal window
ctx init
ctx init
── SETUP
  Wired Claude Code (.mcp.json) — restart your agent to load the contexo server
  Cursor detected — wired .cursor/mcp.json
  VS Code detected — wired .vscode/mcp.json
  .vscode/ is usually committed: teammates need ctx on PATH
  Created .gitignore with .contexo/
  Installed Contexo capture Stop-hook in .claude/settings.json
  Restart Claude Code (or open a new session) so the hook is picked up.
  Installed Cursor capture hooks (.cursor/hooks.json: beforeSubmitPrompt + afterAgentResponse)

✔ Initialized .contexo in ~/projects/acme-api

── 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 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.

The per-file lines come first, then the summary: where .contexo/ landed, an integration table for this project, and the guide for agents Contexo does not wire itself. This run was in a fresh git repo with Cursor and VS Code installed and no Codex on PATH.

Terminal window
ctx status
ctx status
contexo  ○ not authenticated

── REMOTE
server     https://api.contexo.live  (from default)
repo       (none — run 'ctx remote set-repo <id>')
auth       no (run 'ctx auth login')
▲ server: status: not authenticated
try  ctx auth login

── KNOWLEDGE
pages      0
last pull  (never)
captures   none pending

✔ no local changes (server not checked)

No server, no repo, not authenticated. ctx init is local-only; wiring up the remote is ctx login followed by ctx remote set-repo.

Terminal window
ctx mcp status
ctx mcp status
── 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 guide

This is the same table ctx init prints at the end, on demand. Useful after you install a new agent, or when an agent claims it cannot see the contexo server.

Everything below is a local file write. ctx init contacts no Contexo server and makes no git commit. The only network traffic it can produce is the update nudge every ctx command runs after it succeeds — an at-most-once-per-24h GitHub releases lookup, skipped when stdout is not a TTY or when CONTEXO_NO_UPDATE_CHECK or CI is set.

Path What ctx init does Skipped by
.contexo/, .contexo/wiki/concepts/, .contexo/wiki/entities/, .contexo/wiki/analyses/, .contexo/raw/sessions/ created (mkdir -p, mode 0755) never
.contexo/config.json written as {"version": 1} — only if absent never
.contexo/index.md, .contexo/tags.md seeded with empty-section placeholders — only if absent never
.mcp.json merges mcpServers.contexo = {"command": "ctx", "args": ["mcp"]} --no-mcp
.cursor/mcp.json same entry, only when Cursor is detected --no-mcp, --no-cursor
.vscode/mcp.json merges servers.contexo, VS Code’s own format (below), only when VS Code is detected --no-mcp, --no-vscode
.gitignore created (or appended to) with a comment header plus .contexo/, only when <root>/.git exists --no-gitignore
.claude/settings.json appends a Stop hook group running ctx capture turn, tagged _contexo: contexo-capture-turn --no-hooks
.codex/hooks.json Stop + UserPromptSubmit hooks running ctx capture turn --agent codex, only when Codex is detected --no-hooks
.cursor/hooks.json beforeSubmitPrompt + afterAgentResponse hooks running ctx capture turn --agent cursor (adds "version": 1), only when Cursor is detected --no-hooks

Merging, not overwriting. The JSON writers load whatever is already there and add only the contexo key, so other MCP servers and other hooks survive. If the contexo MCP entry is present and identical, nothing is written at all and init says so. The .gitignore edit is skipped entirely when a line already reads .contexo/ or .contexo.

Detection is deliberately asymmetric. Cursor counts as installed if ~/.cursor exists or cursor is on PATH — wiring it only writes harmless project-local files. VS Code is detected the same way: a ~/.vscode directory or code on PATH. Codex must have its binary on PATH; a bare ~/.codex directory is not enough, because other tools create that directory and wiring Codex means shelling out to codex mcp add.

VS Code gets its own format. VS Code (Copilot agent mode) reads workspace MCP servers from .vscode/mcp.json, under a servers key rather than mcpServers, and each entry names its transport. VS Code does not promise to start the server in the project directory, so the entry passes the project root explicitly; VS Code substitutes ${workspaceFolder} itself:

{
"servers": {
"contexo": {
"type": "stdio",
"command": "ctx",
"args": ["mcp", "--root", "${workspaceFolder}"]
}
}
}

Init merges this entry into an existing file and keeps every other server and top-level key. VS Code allows comments and trailing commas in this file, which a strict JSON rewrite would destroy, so a file that is not strict JSON (or whose servers is not an object) is left untouched: init prints the entry above for you to add by hand, and carries on. Any other problem writing the file is also only a warning (run 'ctx mcp install --tool=vscode' later); it never stops init. After wiring it, init reminds you that .vscode/ is usually committed, so teammates need ctx on their PATH.

Codex’s MCP server is never wired by init. It lives in Codex’s global ~/.codex/config.toml, so init only prints a one-line hint and leaves the decision to you:

Terminal window
ctx mcp install --tool=codex

Hook failures are non-fatal. If the Stop hook cannot be installed, init prints Warning: could not install Claude Stop hook: … (run 'ctx hooks install' later) and carries on; the knowledge directory is the load-bearing part. The Codex and Cursor capture hooks warn the same way (Warning: could not install Codex capture hooks: …).

Why the seed files matter. .contexo/index.md and .contexo/tags.md are what the ctx://index and ctx://tags MCP resources read; the index is advertised to agents with priority 1.0. Seeding them means the very first session gets a valid (if empty) index instead of a read error. They are rebuilt from your pages whenever an agent writes a page (ctx_write_page) and on every ctx pull.

init: write .mcp.json: agentwire: parse …: invalid character … — an existing .mcp.json (or .cursor/mcp.json) is not valid JSON. Init refuses to guess and aborts. The .contexo/ tree was created first and survives; the .gitignore line and the hooks come after MCP wiring and never ran. Fix the file, or run ctx init --no-mcp and wire the agent afterwards with ctx mcp install.

.vscode/mcp.json is not strict JSON (comments or trailing commas?); left it untouched. Add this entry by hand: — followed by the entry. Unlike the two files above, this one never aborts init: paste the printed contexo entry into the file’s servers object yourself.

init: create …: permission denied — the project root is not writable. Directory creation is the very first step, so nothing else has been touched.

No .gitignore line and no message about one — the directory has no .git, so the step is skipped silently. Run git init first, then ctx init again (it is idempotent), or add .contexo/ yourself.

Agent shows contexo with zero tools — the agent is running ctx mcp outside a Contexo project. Outside a .contexo/ directory the MCP server starts in dormant mode with no tools rather than failing. Check that the agent’s working directory is the project root you ran ctx init in.

  • ctx detach — reverse everything on this page, including the VS Code entry
  • ctx mcp — wire, unwire, and inspect agent MCP configs on their own
  • ctx hooks — install or remove the capture hooks on their own
  • ctx login — the next step: authenticate and attach a remote repo