Skip to content
Tadoru
English
Esc
navigateopen⌘Jpreview
On this page

MCP server

The read-only MCP (Model Context Protocol) server exposed by tadoru mcp — tools, schemas, errors, and registration.

tadoru mcp exposes recorded activity to MCP clients — terminal agents (Claude Code, Codex, opencode, Hermes) and, crucially, shell-less clients (Claude Desktop, ChatGPT connectors) for which MCP is the only path.

Server name tadoru
Start command tadoru mcp
Transport stdio only (JSON-RPC 2.0 over stdin/stdout) — zero network surface
Capabilities tools only; resources / prompts are not provided yet (see future)

Role and boundary. The server is a read-only view over the local store. It runs as an independent process from the recording daemon and cannot start or stop recording, and cannot change configuration — including the capture-time filters. The app / bundle_id arguments of query_events are query-time narrowing over already-stored data, not a privacy boundary.

Shared conventions — time expressions, event types, the event envelope — match the CLI reference and event reference.

Tools

All three tools are read-only and side-effect free.

get_timeline

Returns the LLM-ready timeline for a range. Equivalent to tadoru timeline. The tool agents call most.

Input

Parameter Type Default Description
since string "1h" Start of range; relative (15m, 2h, 1d) or RFC3339
until string now End of range
format "markdown" or "structured" "markdown" Output shape
token_budget integer 4000 Approximate token cap; content is coarsened to fit
granularity "coarse" or "fine" "coarse" Session-level or per-interaction

Output (format: "markdown")

{
  "range": { "since": "2026-08-16T08:00:00Z", "until": "2026-08-16T09:00:00Z" },
  "format": "markdown",
  "content": "## 08:12-08:31 Safari — Reviewing PR #42\n- Viewed 3 files on GitHub\n- Wrote 2 comments\n...",
  "token_estimate": 3810,
  "truncated": false
}

With format: "structured", the result matches the sessions[] structure of timeline --format json in the CLI reference.

query_events

Returns raw events matching the given conditions. Equivalent to tadoru query. For fine-grained verification or extracting specific apps/types.

Input

Parameter Type Default Description
since string "15m" Start of range
until string now End of range
types string[] Event types; wildcards like browser.* allowed
app string Filter by app name
bundle_id string Filter by bundle ID
limit integer 200 (max 1000) Max events

Output

{
  "range": { "since": "2026-08-16T08:45:00Z", "until": "2026-08-16T09:00:00Z" },
  "count": 42,
  "truncated": false,
  "events": [
    {
      "v": 1, "id": "evt_01J...", "ts": "2026-08-16T08:46:12.120Z", "mono_ns": 128374651234,
      "source": "macos.applescript", "type": "browser.navigate",
      "app": { "name": "Google Chrome", "bundle_id": "com.google.Chrome", "pid": 501 },
      "window": { "title": "PR #42", "id": 42 },
      "element": null,
      "data": { "url": "https://github.com/...", "tab_title": "PR #42", "mode": "normal" },
      "redaction": { "applied": false, "rules": [] }
    }
  ]
}

truncated: true when limit was exceeded. Event contents are already privacy-processed at capture time (secure-field exclusion, redaction) — the MCP layer never adds back anything that was excluded.

get_status

Lightweight check for agents: is recording running? A subset of tadoru status.

Input: none ({})

Output

{
  "running": true,
  "paused": false,
  "last_event_ts": "2026-08-16T08:59:58Z",
  "events_dropped": 2,
  "degraded": { "eventtap": "1 degraded collector operation observed" },
  "retention_hours": 48,
  "oldest_event_ts": "2026-08-14T09:00:00Z",
  "capture": { "sources": ["app", "window", "ui", "input", "browser"], "text_content": false },
  "permissions_ok": true
}
Field Meaning
events_dropped Cumulative events dropped by collectors or the recording pipeline
degraded Collector or runtime degradation by component; empty when no degradation is known
permissions_ok The running recorder’s own permission result while its heartbeat is fresh; a local probe when no recorder is running

An agent that sees running: false can tell the user that activity is not currently being recorded, instead of answering from nothing.

Errors

Situation Behavior
Store not initialized / nothing recorded yet get_status returns running: false (not an error); get_timeline / query_events return empty results
Empty because of missing permissions Empty results; distinguishable via permissions_ok: false in get_status
Invalid arguments (bad time expression, …) JSON-RPC error (invalid params)

The MCP server never starts recording or grants permissions. The resolution path for permission problems is the CLI: tadoru doctor (the shipped skills say so explicitly).

Registration

tadoru setup --agent <name> automates all of the below — see agent setup for per-client walkthroughs. The generic stdio-server JSON shape:

{
  "mcpServers": {
    "tadoru": {
      "command": "tadoru",
      "args": ["mcp"]
    }
  }
}

Future extensions

Not provided today; all would sit on the same read-only store view, and write access to the recording daemon will never be added:

  • resources — the recent timeline and current configuration as read-only MCP resources (some clients prefer resources over tools).
  • prompts — a server-provided “resume my work” prompt template.
  • notifications — push on new-session detection, if demand appears.

Security boundary

  • The server itself performs no external transmission (stdio only, no network surface).
  • Once an agent receives tool results, forwarding them to an LLM provider is the agent’s responsibility. Given the sensitivity of activity history, the shipped skill files instruct agents to narrow the requested range before sending.
  • Stored content is privacy-processed at capture time; with the default text_content: false, typed content simply does not exist in the store.

Was this page helpful?