Skip to content

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

  1. From the project root:

    Terminal window
    ctx init
    ctx 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.json and — 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.

  2. Terminal window
    ctx status
    ctx 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: 0

    Local knowledge works from here on — your agent can already write and read pages. The next two steps are only about sharing them.

  3. Terminal window
    ctx login

    On 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.json with mode 0600, and the server defaults to https://api.contexo.live if you haven’t configured one.

    No browser available? ctx login --no-browser prompts you to paste a token, and ctx login --token <pat> skips the interaction entirely — the form CI wants. Self-hosting: add --server https://contexo.internal.

  4. Terminal window
    ctx remote set-repo acme-api
    ctx remote set-repo acme-api
    Repo: acme-api

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

  5. 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"
    }
    ParameterTypeRequiredDescription
    agentstringnoDefaults to 'claude'
    authorstringnoDefaults to credentials user_name
    bodystringyesMarkdown body (no frontmatter)
    reasoning_summarystringnoOne-line distillation for the index
    relatedarray<string>no
    slugstringyeskebab-case identifier, e.g. 'stripe-subscription'
    sourcesarray<string>noraw 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 regenerates index.md and tags.md. On disk:

    .contexo/wiki/concepts/stripe-subscription.md
    ---
    schema: ctx.page.v1
    slug: stripe-subscription
    type: concept
    author: dev
    agent: claude
    created: 2026-07-20T10:04:00Z
    updated: 2026-07-20T10:04:00Z
    parent_sha: ""
    related:
    - webhook-retries
    tags:
    - stripe
    - billing
    reasoning_summary: How trials, proration and webhooks fit together in acme-api.
    ---
    ## Concepts
    Trials are created with `trial_period_days` on the subscription, not with a
    100%-off coupon. Proration is disabled on downgrades.
    ## Agent Reasoning
    Considered modelling trials as 100%-off coupons so the billing code had one
    path; rejected because refunds then reconcile against a zero-amount invoice
    and the finance export double-counts them.
    ## Open Questions
    Whether to prorate on upgrade-then-immediate-downgrade inside one period.

    You never write that frontmatter. author comes from your credentials, agent from the tool call, timestamps from the clock, and there is no title field — the slug is the name.

  6. Terminal window
    ctx push
    ctx push --yes
    About to push 1 page(s) to acme-api:
      [NEW]   wiki/concepts/stripe-subscription.md
    Pushed 1 page(s); HEAD=a4b2c1d3

    Push 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 --yes skips (the capture above used it); a batch of brand-new pages goes straight through. --dry-run prints the same preview and sends nothing.

    HEAD is the commit sha on the server. The page is now versioned, attributed, and pullable.

  7. They run ctx init in their clone, ctx login, and ctx join with an invite key from ctx invite mint. Then:

    Terminal window
    ctx pull
    ctx pull
    Pulled 1 page(s); HEAD=a4b2c1d3

    Pull asks only for what changed since the sha of their last pull (--full ignores that and re-fetches everything), writes those pages into their local .contexo/, and regenerates index.md and tags.md. With nothing new it prints Already up to date.

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.