Quickstart
You need the ctx binary, a project directory, and an
MCP-capable coding agent (Claude Code, Cursor, Codex, anything else that speaks
MCP over stdio).
-
Initialize the project
Section titled “Initialize the project”From the project root:
Terminal window ctx initctx init Wired Claude Code (.mcp.json) — restart your agent to load the contexo server Cursor detected — wired .cursor/mcp.json 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 for this project: AGENT MCP SERVER CAPTURE (STOP HOOK) Claude Code wired (.mcp.json) installed Cursor wired (.cursor/mcp.json) installed 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 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"] } 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 — 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.One command did five things: created
.contexo/, wired Contexo’s MCP server into Claude Code’s./.mcp.jsonand — because Cursor was detected here — into./.cursor/mcp.json, installed capture hooks for both, and added.contexo/to.gitignore. It is idempotent; re-running leaves existing entries alone. -
Check where you stand
Section titled “Check where you stand”Terminal window ctx statusctx status Initialized: yes Server: (none — run 'ctx remote set <url>') Repo: (none — run 'ctx remote set-repo <id>') Authenticated: no Local pages: 0 Last pull: (never) Pages never pushed: 0Local knowledge works from here on — your agent can already write and read pages. The next two steps are only about sharing them.
-
Sign in
Section titled “Sign in”Terminal window ctx loginOn a terminal, this opens the dashboard at
https://app.contexo.live, has you sign in, mints a personal access token, and hands it back to the CLI over a loopback redirect. The token lands in.contexo/credentials.jsonwith mode0600, and the server defaults tohttps://api.contexo.liveif you haven’t configured one.No browser available?
ctx login --no-browserprompts you to paste a token, andctx login --token <pat>skips the interaction entirely — the form CI wants. Self-hosting: add--server https://contexo.internal. -
Point at a repo
Section titled “Point at a repo”Terminal window ctx remote set-repo acme-apictx remote set-repo acme-api Repo: acme-apiThe repo doesn’t have to exist yet: the first push to an unknown repo id creates it on the server and makes you its owner (subject to your plan’s repo cap). If you’re joining a project that already exists, use the invite key a teammate minted instead —
ctx join ctxi_…— which sets the repo id for you. -
Have your agent write a page
Section titled “Have your agent write a page”Ask in natural language:
“Write up how our Stripe trials and proration work as a Contexo concept page, including an Agent Reasoning section for what we rejected.”
The agent calls
ctx_write_page:{"slug": "stripe-subscription","type": "concept","tags": ["stripe", "billing"],"related": ["webhook-retries"],"reasoning_summary": "How trials, proration and webhooks fit together in acme-api.","body": "## Concepts\n\nTrials are created with `trial_period_days`…\n\n## Agent Reasoning\n\nConsidered modelling trials as 100%-off coupons…\n"}Parameter Type Required Description agentstringno Defaults to 'claude' authorstringno Defaults to credentials user_name bodystringyes Markdown body (no frontmatter) reasoning_summarystringno One-line distillation for the index relatedarray<string>no slugstringyes kebab-case identifier, e.g. 'stripe-subscription' sourcesarray<string>no raw session slugs cited tagsarray<string>no typeconcept | entity | source | analysisyes The tool replies with the path it wrote (
Wrote wiki/concepts/stripe-subscription.md) and regeneratesindex.mdandtags.md. On disk:.contexo/wiki/concepts/stripe-subscription.md ---schema: ctx.page.v1slug: stripe-subscriptiontype: conceptauthor: devagent: claudecreated: 2026-07-20T10:04:00Zupdated: 2026-07-20T10:04:00Zparent_sha: ""related:- webhook-retriestags:- stripe- billingreasoning_summary: How trials, proration and webhooks fit together in acme-api.---## ConceptsTrials are created with `trial_period_days` on the subscription, not with a100%-off coupon. Proration is disabled on downgrades.## Agent ReasoningConsidered modelling trials as 100%-off coupons so the billing code had onepath; rejected because refunds then reconcile against a zero-amount invoiceand the finance export double-counts them.## Open QuestionsWhether to prorate on upgrade-then-immediate-downgrade inside one period.You never write that frontmatter.
authorcomes from your credentials,agentfrom the tool call, timestamps from the clock, and there is notitlefield — the slug is the name. -
Push it
Section titled “Push it”Terminal window ctx pushctx push --yes About to push 1 page(s) to acme-api: [NEW] wiki/concepts/stripe-subscription.md Pushed 1 page(s); HEAD=a4b2c1d3Push previews the batch first —
[NEW]or[EDIT]per page — and prompts for confirmation only when it would alter pages that already exist on the server. That’s the prompt--yesskips (the capture above used it); a batch of brand-new pages goes straight through.--dry-runprints the same preview and sends nothing.HEADis the commit sha on the server. The page is now versioned, attributed, and pullable. -
On your teammate’s machine
Section titled “On your teammate’s machine”They run
ctx initin their clone,ctx login, andctx joinwith an invite key fromctx invite mint. Then:Terminal window ctx pullctx pull Pulled 1 page(s); HEAD=a4b2c1d3Pull asks only for what changed since the sha of their last pull (
--fullignores that and re-fetches everything), writes those pages into their local.contexo/, and regeneratesindex.mdandtags.md. With nothing new it printsAlready up to date.
What their agent sees
Section titled “What their agent sees”Nothing has to be pasted into a prompt. Their agent lists the Contexo MCP
resources, reads ctx://index — the regenerated index, one line per page with
the reasoning_summary, tags, author and date — and opens
ctx://wiki/stripe-subscription when the topic comes up. If the page cites a
source, ctx://raw/<session-id> has the full reasoning trail behind it.
The practical difference: their agent starts the Stripe conversation knowing trials are not coupons, and knowing why.
- Connect your agent — Codex, other MCP clients, and what
ctx initdoesn’t wire - The daily flow — how this looks once it’s habit
- Teams — invites, members, activity
ctx push/ctx pull— every flag
