Skip to content

ctx_history

Returns the commit timeline for a single page: sha, author, date, message, newest first.

A page snapshot tells an agent what the team believes. The timeline tells it how long that belief has held and who put it there — the difference between an agent rewriting a sentence three people converged on and an agent correcting a stale note somebody dashed off last week. ctx_history is the cheapest of the three history tools: it moves commit metadata only, no page bodies.

Before editing a page that already exists and has some depth to it. The tool description says exactly that, and the call hands the agent the shas it needs to go one level deeper with ctx_diff. If the question is “what did each of those commits actually change”, skip straight to ctx_evolution — one round-trip instead of ctx_history plus N ctx_diff calls.

ParameterTypeRequiredDescription
limitintegernoMax commits (default 50)
slugstringyesPage slug, e.g. 'stripe-subscription'
typeconcept | entity | source | analysisnoOnly needed when the same slug exists under multiple types
{
"method": "tools/call",
"params": {
"name": "ctx_history",
"arguments": { "slug": "stripe-subscription", "limit": 10 }
}
}

The result is one pre-formatted text block, so the agent has nothing to parse:

{
"content": [
{
"type": "text",
"text": "Commits for wiki/concepts/stripe-subscription.md (newest first):\n\nb7e9f20 2026-07-28 dev — ctx push (1 pages)\na4b2c1d 2026-07-28 dev — ctx push (1 pages)\n"
}
]
}

Each line is sha date author — message, with a 7-character sha and a YYYY-MM-DD date. Those shas are what you feed to ctx_diff’s from / to.

The same timeline through the CLI, which pads the author column and prints 8 characters of sha:

ctx history stripe-subscription
b7e9f204  2026-07-28  dev           ctx push (1 pages)
a4b2c1d3  2026-07-28  dev           ctx push (1 pages)

Commit messages are push messages. ctx push (N pages) is the CLI default and agent push (N pages) is what ctx_push writes when the agent supplies no message, so the message column also tells you which surface a change came through. The author is the pusher’s name from their credentials, not the agent’s.

Resolution is local; the timeline is remote. The server has no concept of a slug, so the tool first stats up to four paths under .contexo/:

type Path it checks
concept wiki/concepts/<slug>.md
entity wiki/entities/<slug>.md
analysis wiki/analyses/<slug>.md
source raw/sessions/<slug>.md

Exactly one hit resolves. Zero hits is an error; more than one is an error asking for type. Only then does the tool GET /v1/repos/{repo}/history/{path} with your bearer token.

limit defaults to 50 and is passed through to git log -n<limit> on the server, which applies no cap of its own — the CLI’s --limit help text (“server caps at a reasonable limit”) overstates the case. Zero or negative falls back to the same 50. ctx_evolution defaults to 20 instead, because each of its entries carries a full diff.

A page with no commits on the server is not an error: the tool returns No commits found for wiki/concepts/<slug>.md as a normal text result.

Each of these comes back as a single text block with isError: true.

ctx_history: server not configured (run 'ctx remote set <url>', 'ctx remote set-repo <id>', 'ctx auth login') — credentials, server URL, or repo id is missing. There is no local fallback: commit history only exists on the server.

ctx_history: slug "…" not found under .contexo/ (looked in wiki/{concepts,entities,analyses}/ and raw/sessions/) — no local file. Check the spelling, then pull.

ctx_history: slug "…" is ambiguous (matches […]); pass type to disambiguate — the same slug exists under two page types.

ctx_history: sync: page history (404): … — the local page resolved but the server rejected the request: wrong repo id, or you are not a member of it.

  • ctx_diff — what changed between two of these shas, section by section
  • ctx_evolution — this timeline with every diff already attached
  • ctx history — the same call from your shell
  • Page evolution — when to reach for which of the three