Skip to content

ctx detach

Undoes ctx init: removes the Contexo wiring from your agent configs and, unless you say otherwise, deletes the .contexo/ directory.

Two quite different jobs share this command. The common one is “I evaluated Contexo, get it off my project” — that is the default, and it is destructive on purpose. The other is “keep the knowledge, stop the agents touching it”, which is --keep-knowledge and is the flag you want when you are handing a repo over, debugging a hook, or moving a project between machines.

The mistake to avoid is trusting the unpushed-pages warning as a safety net. It counts pages the local sync state has never seen — pages you edited after pushing them are not counted, and are destroyed silently. If the knowledge matters, run ctx push first and read its output, rather than relying on detach to notice.

Also worth knowing before you run it in a hurry: Codex’s MCP entry is global, so detaching one project removes Contexo from Codex everywhere.

Terminal window
ctx detach
ctx detach --keep-knowledge
ctx detach --yes
ctx detach --root path/to/project --keep-knowledge --yes
FlagTypeDefaultDescription
--keep-knowledgeboolfalsekeep the .contexo/ directory; only remove the wiring (MCP entries, .gitignore line, Stop hook)
--yes, -yboolfalseskip the confirmation prompt
FlagTypeDefaultDescription
--rootstringproject root directory (default: current directory)

--keep-knowledge preserves the entire .contexo/ directory as-is — every page, plus config.json (server URL and repo id), credentials.json (your token), and .sync/state.json (the per-page SHAs push uses for conflict detection). Re-running ctx init later reconnects the agents and everything picks up where it left off, with no re-login and no re-ctx remote set-repo. Without it, all four are gone.

--yes skips the prompt. You need it in any non-interactive context: the prompt reads stdin and treats EOF — a pipe, a CI step, < /dev/null — as “no”, so an unattended ctx detach does nothing and exits 0.

Terminal window
ctx status
ctx status
Initialized: yes
Server: https://contexo.example.com
Repo: acme-api
Authenticated: yes (legacy API key)
User: dev <dev@example.com>
Local pages: 1
Last pull: (never)
Pages never pushed: 0
Pages drifted on server: 0

Pages never pushed: 0 is the number detach’s warning is derived from. It is the never pushed count, not a dirty-working-tree count.

Terminal window
ctx detach --keep-knowledge
ctx detach --keep-knowledge
This will:
  - delete .mcp.json (only contained the contexo entry)
  - delete .cursor/mcp.json (only contained the contexo entry)
  - 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.

Detach always prints the full plan before it touches anything. This run had stdin closed, so the [y/N] prompt read EOF and aborted — nothing was removed. Note that .mcp.json and .cursor/mcp.json are listed for deletion rather than editing: each contained only the contexo entry, so detach would remove the whole file.

Terminal window
ctx detach --yes

Without --keep-knowledge this deletes .contexo/ outright — pages, config, credentials and sync state — in addition to the wiring. The plan is still printed, but it is a receipt, not a checkpoint.

Detach runs in three phases: build a plan by inspecting the filesystem (and, if codex is on PATH, by asking it), print the plan, then execute it. Which files get touched is decided before the prompt, so nothing you do while it waits for an answer changes the list.

What each item does:

Target Action
.mcp.json drops mcpServers.contexo; deletes the file when that entry was the only server and mcpServers was the only top-level key
.cursor/mcp.json same rule
~/.codex/config.toml runs codex mcp remove contexoglobal, only when codex is on PATH and codex mcp get contexo succeeds
.gitignore removes the .contexo/ (or .contexo) line plus the Contexo comment header directly above it, then trims the trailing blank line that leaves behind; every other line is preserved verbatim
.claude/settings.json removes only the Stop hook entry tagged _contexo: contexo-capture-turn, then drops the group, the Stop key and the hooks key as each is emptied. The file itself is never deleted
.codex/hooks.json removes the ctx capture turn --agent codex entries; deletes the file if nothing else remains
.cursor/hooks.json removes the ctx capture turn --agent cursor entries; deletes the file if only the version key would be left
.contexo/ recursive delete — omitted with --keep-knowledge

Nothing on the server changes. Pages you pushed stay in the server’s git repo, the repo keeps existing, and members, invites and activity are untouched. Detach makes no Contexo API call; the only process it launches is codex. To come back, run ctx init, ctx login and ctx remote set-repo, then ctx pull your knowledge back down.

Only the Claude hook is removed by marker. Its entry carries _contexo: contexo-capture-turn, so a Stop hook you wrote by hand that happens to run ctx capture turn is left in place. The Codex and Cursor hooks carry no marker — they are matched on the exact command string (ctx capture turn --agent codex / --agent cursor), so a hand-written hook running precisely that command is removed along with Contexo’s.

Partial failures do not stop the run. Each step that fails prints warning: <step>: <error> on stderr and the rest continue; detach then exits non-zero with the first error and suppresses the final Detach complete. line. Re-running is safe — the plan is rebuilt from what is actually on disk.

Aborted. when you did not answer anything — stdin was not a terminal. Pass --yes.

The plan omits .mcp.json even though it has a contexo entry — the file is not valid JSON. Detach parses it to decide, and an unparseable config is treated as “no entry here”: no warning, no edit, nothing removed. Fix the JSON and re-run, or delete the entry by hand.

warning: codex mcp remove: agentwire: codex mcp remove: exit status 1 — detach confirmed the entry exists (via codex mcp get contexo) but the codex CLI refused to remove it, typically because its global config is not writable. Check with ctx mcp status, then retry with ctx mcp uninstall --tool=codex.

warning: remove .contexo/: … — a file under .contexo/ could not be deleted. On Windows this is almost always an open handle from an agent session still running ctx mcp. Close it and re-run ctx detach --yes; everything else in the plan has already been applied.

  • ctx init — what detach reverses
  • ctx push — run this before a destructive detach
  • ctx mcp — remove a single agent’s MCP entry instead of everything
  • ctx hooks — remove a single agent’s capture hooks instead of everything