Skip to content

HTTP API Reference

Chronicle exposes three mounts on one local port: /api (the REST API), /share (public redacted pages), and /mcp (the aggregating MCP server). This page is a route-level reference for contributors and anyone scripting against a running instance.

Everything is served from a single origin — http://localhost:4173 in dev (npm run dev) or http://localhost:41730 in desktop/standalone — and the exact same Express apps back all three run modes (see Architecture overview). Requests are local only; the standalone server binds 127.0.0.1.

Mounts

MountSourceWhat it serves
/apiserver/api.jsThe REST API — every route below unless noted
/shareserver/shares.jsPublic, redacted, tokenized session pages (HTML)
/mcpserver/mcp/hub.jsThe aggregating MCP server (Streamable HTTP, JSON-RPC)

Note: /mcp (the MCP protocol endpoint) is distinct from the /api/mcp/* routes (the management REST API that lists services and drives takeover). Downstream MCP clients talk to /mcp; the Chronicle UI talks to /api/mcp/*. See MCP & Skills internals.

All paths in the tables below are relative to /api — e.g. GET /projects is GET http://localhost:41730/api/projects.

Import & scan

MethodPathPurpose
GET/scanDiscover importable sessions across all six tools (grouped by logical project)
POST/importImport selected sessions into the SQLite store (replaceSession per session)

Projects

MethodPathPurpose
GET/projectsList projects with live git pill info (repoInfo runs git per call)
GET/projects/:idProject analytics home; accepts ?days=N to scope the time range
PATCH/projects/:idRename a project
DELETE/projects/:idDelete a project and its sessions from Chronicle
POST/projects/:id/associateAssociate a virtual (e.g. Gemini) project to a real repo path
POST/projects/:id/syncRe-scan and re-import all of a project's sessions
POST/projects/:id/unlinkUndo an association

Sessions

MethodPathPurpose
GET/sessions/:id/messagesThe full message list for a session
PATCH/sessions/:idRename a session (sets the user name override)
DELETE/sessions/:idDelete the Chronicle copy of a session
DELETE/sessions/:id/source-fileDelete the underlying source log (only where one file = one session)
POST/sessions/:id/syncRe-import just this session (⇧⌘U in the UI)
GET/sessions/:id/causalityRead→change causality analysis (analyzeCausality)
GET/sessions/:id/liveSSE stream — live message tail (see below)
GET/sessions/:id/security-checkScan the session for secrets (scanSession payload)
GET/sessions/:id/export-redactedExport the session as redacted Markdown
POST/sessions/:id/shareMint a share token (redacted copy frozen at creation)
GET/sessions/:id/replay-planBuild the replay step plan (buildPlan)

The live SSE stream

GET /api/sessions/:id/live is not JSON — it upgrades to text/event-stream and pushes data: frames. Frames are either { type: 'status', status: 'live' | 'stopped', ... } or { type: 'messages', events: [...] }. The watcher auto-stops when the connection closes. See Security, Live & Replay internals.

Git

MethodPathPurpose
GET/git/atThe nearest commit at-or-before a timestamp (commitAt)
GET/git/treeThe file tree at a commit (treeAt)
GET/git/fileA file's contents at a commit + its previous version for diff (fileAt)

These are read-only wrappers over server/git.js, which shells out to git. See Git snapshot engine.

MethodPathPurpose
GET/searchLIKE-based full-text search over messages.text + tool_input, grouped per session (empty query → recent sessions)

Live

MethodPathPurpose
GET/live/statusList active live watchers (liveStatus)

Security

MethodPathPurpose
GET/security/rulesList redaction/allow rules
POST/security/rulesAdd a custom rule
PATCH/security/rules/:idEnable/disable a rule
DELETE/security/rules/:idDelete a rule
GET/security/interceptionsRecent pre-tool-use interception records
POST/security/pretooluseScan a tool call; returns { decision: 'allow' | 'block', ... } (called by the hook)
POST/security/install-hookInstall the Claude Code PreToolUse hook (backs up settings first)

Skills

MethodPathPurpose
GET/skillsList central skills (with per-tool link status)
GET/skills/scanScan tool dirs for importable/managed/duplicate/broken skills
POST/skills/importImport a scanned skill into the central store
POST/skills/githubImport skills from a public GitHub repo (shallow clone, records SHA)
GET/skills/:idSkill detail + SKILL.md content
PATCH/skills/:idUpdate local metadata (tags, rating)
DELETE/skills/:idDelete a skill (?removeFiles=1 to remove central files)
POST/skills/:id/linkSymlink the skill into a tool's dir
POST/skills/:id/unlinkRemove a Chronicle-created symlink
GET/skills/:id/snapshotsList version snapshots
POST/skills/:id/restoreRestore a snapshot
POST/skills/:id/check-upstreamCompare recorded SHA to the remote tip (ls-remote)

MCP management

These manage the registry and drive the hub; they are separate from the /mcp protocol endpoint.

MethodPathPurpose
GET/mcp/servicesList registered services (secrets masked)
POST/mcp/servicesAdd/update a service
PATCH/mcp/services/:idUpdate a service (enable, scope, credential, tool policy)
DELETE/mcp/services/:idRemove a service
GET/mcp/scanScan tool configs, classified New/Updated/Conflict/Unchanged
POST/mcp/takeoverImport scanned services (backs up source configs first)
GET/mcp/statusHub status (protocol version, service/session counts)
GET/mcp/toolsAggregated tool list (aggregateTools('*')) — Inspector
POST/mcp/callInvoke a namespaced service__tool — Inspector
GET/mcp/logThe hub's JSON-RPC ring-buffer log — Inspector

Replay

MethodPathPurpose
GET/replay/previewPreview an upcoming step's diff against sandbox state
POST/replay/startCreate/seed the sandbox from the session-start snapshot
POST/replay/stepExecute one step ({ confirmCommand } required for Bash)
POST/replay/openOpen the sandbox in the OS file browser

Feedback

MethodPathPurpose
POST/feedbackAppend to ~/.chronicle/feedback.log and forward to the hosted relay

Shares management

MethodPathPurpose
GET/sharesList share tokens (views, expiry)
DELETE/shares/:idRevoke a share

And on the /share mount:

MethodPathPurpose
GET/share/:tokenThe public redacted HTML page (404 once expired/revoked)

Data shapes

Message and session rows follow the normalized event model — see Data model for the SQLite schema, the kind enum (user \| assistant \| thinking \| tool_use \| tool_result, plus note), and how replaceSession() makes import idempotent while preserving the user-set name.

One shape worth flagging here: the per-session sessions.usage column is JSON keyed by model, with split cache-write buckets:

json
{
  "claude-opus-4-8": {
    "input": 12000,
    "output": 3400,
    "cacheWrite5m": 800,
    "cacheWrite1h": 0,
    "cacheRead": 45000
  }
}

Cost is computed locally from this by src/models.js (a static price table) — the logs carry tokens, never dollars.

Released under the MIT License.