Skip to main content
Glama
Miyamura80

agent-prompt-capture

by Miyamura80

agent-prompt-capture

Local-only telemetry for the prompts you send to your coding agents and chat UIs. Hooks in Claude Code, Codex CLI and OpenCode, plus a Chrome extension for claude.ai and chatgpt.com, feed every prompt you submit into a PII scrubber that runs before anything is written to disk; the scrubbed text lands in a SQLite database under your home directory, and a stdio MCP server (apc mcp) lets an agent read it back and answer "where did my week go, and what should I do differently". Nothing leaves the machine: the browser extension posts only to 127.0.0.1, the listener binds loopback and refuses anything else without an explicit flag, there is no account, no sync and no outbound network call anywhere in the package.

How it fits together

 LOCAL AGENT CLIs                       BROWSER (Chrome MV3 extension)
 +-----------------------------+       +------------------------------+
 | Claude Code  hooks          |       | claude.ai          (chat)    |
 | Codex CLI    hooks.json     |       | claude.ai/code               |
 | OpenCode     plugin         |       | chatgpt.com        (chat)    |
 +--------------+--------------+       | chatgpt.com/codex            |
                |                      |  account allowlist enforced  |
   stdin or argv JSON                  +---------------+--------------+
   apc capture <target>                                |
                |            POST http://127.0.0.1:47821/v1/prompts
                |            X-APC-Token: <token>   ->   apc serve
                v                                       v
 +--------------+---------------------------------------+-------------+
 |  INGEST    adapters -> RawPrompt / RawTurnEnd, allowlist check     |
 +---------------------------------+----------------------------------+
                                   v
 +---------------------------------+----------------------------------+
 |  PII SCRUB (pii.py)   raw text never reaches disk -> [EMAIL_1]     |
 +---------------------------------+----------------------------------+
                                   v
 +---------------------------------+----------------------------------+
 |  STORE   $APC_HOME/prompts.db   SQLite + FTS5 (+ turn_end_ts)      |
 +---------------------------------+----------------------------------+
                                   v
 +---------------------------------+----------------------------------+
 |  apc mcp   stdio MCP: 9 tools, 3 resources    and the `apc` CLI    |
 +--------------------------------------------------------------------+

source id

where it comes from

transport

claude_code

Claude Code UserPromptSubmit + Stop hooks

stdin JSON to apc capture

codex_cli

Codex CLI hooks.json, or the legacy notify

stdin or argv JSON

opencode

OpenCode plugin chat.message + session.idle

stdin JSON

claude_web

Chrome extension on claude.ai

HTTP POST to the listener

claude_code_web

Chrome extension on claude.ai/code

HTTP POST to the listener

chatgpt_web

Chrome extension on chatgpt.com

HTTP POST to the listener

codex_cloud

Chrome extension on chatgpt.com/codex

HTTP POST to the listener

ARCHITECTURE.md holds the contracts; docs/research/hook-specs.md holds the verified hook payloads.

Related MCP server: Codex History Hub

Quickstart

git clone https://github.com/gatlingx/Agent-Prompt-Capture-MCP && cd Agent-Prompt-Capture-MCP
uv tool install .                 # puts `apc` on your PATH
apc install claude-code           # and/or: apc install codex, apc install opencode
apc doctor                        # checks home, db, token, listener, hooks
claude mcp add agent-prompt-capture -- apc mcp

The package is not on PyPI yet, so uvx agent-prompt-capture does not work. If you would rather not install it, uvx --from /path/to/Agent-Prompt-Capture-MCP apc <args> runs the same CLI from a clone, and works anywhere apc is written below.

Then register the MCP server with whichever clients you use.

Claude Code cc

claude mcp add agent-prompt-capture -- apc mcp

Codex CLI, in ~/.codex/config.toml (check the docs: this one could not be verified against developers.openai.com from the machine this was written on)

[mcp_servers.agent-prompt-capture]
command = "apc"
args = ["mcp"]

OpenCode, in opencode.json oc

{
  "mcp": {
    "agent-prompt-capture": { "type": "local", "command": ["apc", "mcp"] }
  }
}

Claude Desktop, in claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows) cd

{
  "mcpServers": {
    "agent-prompt-capture": { "command": "apc", "args": ["mcp"] }
  }
}

If apc is not on the PATH of the app you are configuring, use the absolute path from which apc.

Browser capture

CLI hooks cover the three terminal agents. Everything you type into claude.ai or chatgpt.com needs the Chrome extension and the local listener.

  1. Run the listener. In the foreground:

    apc serve            # binds 127.0.0.1:47821, ctrl-c to stop

    As a background service, copy one of the units in docs/service/:

    # Linux (systemd user unit)
    mkdir -p ~/.config/systemd/user
    cp docs/service/apc-listener.service ~/.config/systemd/user/
    systemctl --user daemon-reload
    systemctl --user enable --now apc-listener
    
    # macOS (launchd user agent)
    cp docs/service/com.agent-prompt-capture.listener.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/com.agent-prompt-capture.listener.plist

    Both units hard-code a path to apc; replace it with the output of which apc.

  2. Print the shared secret the extension needs:

    apc token            # `apc token --rotate` issues a new one
  3. Load the extension: chrome://extensions -> Developer mode -> Load unpacked -> pick the extension/ directory. Fill in the server URL, the token and the allowlist in its Options page. Full walkthrough and troubleshooting: extension/README.md.

  4. Set the allowlist in both places: [capture].allowed_accounts in config.toml and Allowed accounts in the extension Options. They are two different checks. The extension one stops a prompt from ever leaving the page when the detected account is not yours, and the listener one is the authority that decides what gets stored, so a stale or tampered extension still cannot write someone else's prompts into your database. An empty list on either side captures nothing.

The four web sources are claude_web (claude.ai chat), claude_code_web (claude.ai/code), chatgpt_web (chatgpt.com chat) and codex_cloud (chatgpt.com/codex). Claude Code on the web does not read your local ~/.claude/settings.json and does not run your hooks, so the extension is the only way to capture claude_code_web prompts. Do not try to solve that one with a hook; the cloud VM is a different machine with no apc on it.

Asking your agent where your time went

Once the MCP server is registered, ask in plain language. The tool each question lands on:

What they ask

Tool

"Which projects ate my week?"

time_summary (group_by="project")

"Am I most productive in the morning or after lunch?"

time_summary (group_by="hour_of_day" or "weekday")

"What did I do yesterday? Write my standup."

daily_digest (date="2026-09-18")

"When was I actually at the keyboard today?"

activity_timeline (bucket="hour")

"Have I asked about this migration before?"

search_prompts (FTS5 syntax)

"How many sessions did I start on this repo, and how long?"

list_sessions, then time_summary (group_by="session")

"Am I using Codex more than Claude Code now?"

prompt_stats (group_by="source")

"Show me the last ten things I asked about auth."

search_prompts then list_prompts

The activity-session heuristic. Nothing about duration is stored. Activity sessions are recomputed on every read from prompt timestamps and, where a source gives one, the turn-end timestamp:

  • Prompts are walked in time order. A gap longer than idle_gap_minutes (default 30) since the end of the previous event starts a new activity session.

  • A session is credited with (last end - first start) + tail_minutes (default 5), so the minutes you spend reading the last answer are not lost.

  • Agent time is turn_end_ts - ts: how long the agent worked. Think time is the gap from one turn ending to the next prompt in the same session: how long they spent reading, deciding and typing.

  • A context switch is a consecutive pair of prompts inside one activity session whose project differs.

What it cannot tell you. Browser sources have no turn-end signal at all, so agent time and think time are unknown for anything captured by the extension and those prompts contribute only their timestamps. Work you do without prompting an agent is invisible. The tail credit is a guess, not a measurement. Treat the numbers as a shape of the week, not a stopwatch.

CLI reference

Every subcommand of apc. --since / --until / --before take ISO 8601, a bare date (2026-09-19), or a relative duration meaning "that long ago": 30m, 24h, 7d, 2w, 3mo, 1y.

Command

Flags

What it does

apc --version

print the version

apc capture <claude-code|codex|opencode> [payload]

read hook JSON from the trailing argument (Codex notify) or stdin, ingest it. Never prints, never raises, always exits 0

apc serve

--host, --port, --allow-remote

run the loopback HTTP listener for the extension. Non-loopback hosts are refused unless --allow-remote

apc mcp

run the stdio MCP server

apc install <claude-code|codex|opencode>

--dry-run, --legacy

write the hook config, idempotently. --legacy is Codex only

apc uninstall <claude-code|codex|opencode>

remove what install wrote

apc token

--rotate

print the listener token, or generate a new one

apc list

--source, --since, --until, --project, --session-id, --account, --limit (20), --offset (0), --json

list captured prompts, newest first

apc search <query>

--source, --since, --until, --limit (20), --json

FTS5 full-text search

apc stats

--group-by source|day|week|project|account|session (source), --since, --until, --json

prompt and character counts

apc time

--since (7d), --until, --group-by project|source|day|hour_of_day|weekday|session (project), --json

active minutes, agent minutes, average think time, context switches

apc digest [DATE]

--json

one local day: sessions, samples, top terms. Defaults to today

apc export

--format jsonl|csv (jsonl), --source, --since, --until, --limit (100000), --output/-o

dump records to stdout or a file

apc purge

--before, --source, --yes

delete records. Refuses to run with neither --before nor --source; needs --yes when stdin is not a terminal

apc doctor

check home, config, database, token, log, allowlist, listener and every hook install

Configuration

$APC_HOME/config.toml, default ~/.agent-prompt-capture/config.toml. The file is optional: a missing or unparseable one falls back to these defaults.

[capture]
# Browser sources are captured ONLY for these accounts, matched case-insensitively.
# An empty list captures nothing from the browser. CLI sources ignore this list.
allowed_accounts = []
# Source ids to drop entirely, e.g. ["chatgpt_web", "codex_cloud"].
disabled_sources = []

[accounts]
# Optional aliases, so the stored `account` column never holds a raw address.
# Anything without an alias is stored as "sha256:<first 12 hex chars>".
# "me@work.com" = "work"

[pii]
# Extra literal terms to redact: your name, employer, codenames. Case-insensitive,
# word-bounded, replaced with [USER_TERM_n].
extra_terms = []
# Extra Python regexes, replaced with [CUSTOM_n]. An invalid one is logged and skipped.
extra_patterns = []
# Optional NER-based person/location detection. Needs the `ner` extra
# (presidio-analyzer, spacy); if it is missing this logs a warning and continues.
enable_ner = false

[server]
host = "127.0.0.1"
port = 47821

[time]
idle_gap_minutes = 30   # a longer gap starts a new activity session
tail_minutes = 5        # credited after the last event of an activity session

Environment variables:

Variable

Read by

Effect

APC_HOME

everything

the runtime directory. Default ~/.agent-prompt-capture, created mode 0700

APC_DEBUG=1

logging

DEBUG level, and a stderr handler in addition to apc.log

CLAUDE_CONFIG_DIR

apc install/uninstall/doctor claude-code

directory holding settings.json. Default ~/.claude

CODEX_HOME

apc install/uninstall/doctor codex

directory holding hooks.json and config.toml. Default ~/.codex

XDG_CONFIG_HOME

apc install/uninstall/doctor opencode

base for opencode/plugin/. Default ~/.config

Privacy

Prompt text is scrubbed in memory and only the scrubbed text is written. Captured: the scrubbed prompt, a timestamp, the source, the session id, an aliased or hashed account, a scrubbed working directory and project name, a character count, a per-category count of what was redacted, and source-specific metadata. Never captured: assistant responses, tool calls and their output, file contents, images or attachments (only a count), and raw account addresses.

The scrubber replaces each recognised value with [CATEGORY_N], numbered per prompt so the same value reads as the same placeholder throughout it. The categories, in the order they are applied: private_key, ssh_key, jwt, webhook_url, api_key, url_credentials, credit_card, iban, ssn, email, phone, ipv6, ipv4, mac_address, uk_postcode, home_path, user_term, custom, person, location. Home paths are the exception to the numbering: the username in /Users/x, /home/x or C:\Users\x becomes the fixed [USER].

Everything lives in $APC_HOME: config.toml, prompts.db, token (mode 0600) and apc.log. apc purge --before 2026-01-01 --yes or apc purge --source chatgpt_web --yes deletes records; deleting prompts.db deletes everything.

Full detail, including the account hashing rule, the dedup hash and the known gaps in the scrubber, is in docs/PRIVACY.md. Read that before you trust the database with anything sensitive.

Per-CLI notes

Claude Code. apc install claude-code merges two hooks into $CLAUDE_CONFIG_DIR/settings.json (default ~/.claude/settings.json): UserPromptSubmit captures the prompt, Stop records when the turn ended so time tracking has an agent duration. Both run apc capture claude-code with a timeout of 10 seconds, well inside Claude Code's 30 second default. The hook always exits 0 with empty stdout, so it can never block, alter or erase the prompt: exit 2 on UserPromptSubmit would erase it, and anything printed to stdout on that event is injected into the model's context. Failures go to apc.log and nowhere else.

Codex CLI. apc install codex merges UserPromptSubmit and Stop into $CODEX_HOME/hooks.json (default ~/.codex/hooks.json), running apc capture codex. The older mechanism is behind a flag: apc install codex --legacy writes notify = ["apc", "capture", "codex"] into the top-level section of ~/.codex/config.toml instead, and leaves an existing notify line belonging to something else alone rather than clobbering it. Pick one. If both are present every turn is captured twice and the two records do not dedupe, because the hook reports session_id and notify reports thread-id; apc doctor prints a warning when it sees both. The notify payload arrives as the last argv argument with stdin closed, which is why apc capture accepts a trailing JSON argument.

OpenCode. apc install opencode copies the plugin to $XDG_CONFIG_HOME/opencode/plugin/agent-prompt-capture.js (default ~/.config/opencode/plugin/). It hooks chat.message for prompts and the session.idle event for turn ends. Three things to know: slash commands are expanded before the plugin sees them, so /foo is captured as the text it expands to and not as /foo; synthetic and ignored parts are dropped, so an @agent mention does not store an instruction the user never wrote; and the capture process is spawned detached and never awaited, because chat.message is awaited by the session loop and anything slow there is latency you feel on every send.

Development

uv sync --dev
uv run ruff check . && uv run ruff format --check .
uv run pytest -q

node extension/scripts/test-prescrub.js   # pre-scrub unit tests
node extension/scripts/smoke.mjs          # loads the unpacked extension against fixtures

uv run python scripts/e2e.py              # end-to-end run in a throwaway HOME

scripts/e2e.py drives the whole pipeline in a temporary HOME/APC_HOME: install the hooks, feed a hook payload through apc capture, POST one through the listener, then read it back over the CLI and the MCP server, without touching your real configuration. It is being written alongside this document, so check its --help before relying on the details.

Limitations and roadmap

  • Browser sources have no turn-end signal, so agent_minutes and think time are blank for anything captured on claude.ai or chatgpt.com. DOM-based turn-end detection is the next thing worth building.

  • Not on PyPI yet, so installation means cloning. Publishing is planned.

  • Chrome only. The listener already accepts moz-extension:// origins, but there is no Firefox build of the extension.

  • Every prompt is treated alike. Per-prompt intent tagging (debugging, feature work, review, learning) would make time_summary far more useful than "minutes per project".

  • The scrubber is regex-first and has known gaps; see docs/PRIVACY.md.

License

MIT. See LICENSE.

<https://code.claude.com/docs/en/mcp> (accessed 2026-09-19). The `--` separator is
required; everything after it is passed to the server untouched.
from <https://opencode.ai/docs/mcp-servers/> (accessed 2026-09-19).
`claude_desktop_config.json`, from
<https://modelcontextprotocol.io/docs/develop/connect-local-servers> (accessed
2026-09-19), which also gives the macOS and Windows file locations.
  1. claude mcp add [options] <name> -- <command> [args...], from

    ↩
  2. "mcp": { "<name>": { "type": "local", "command": [...] } } in opencode.json,

    ↩
  3. "mcpServers": { "<name>": { "command": ..., "args": [...] } } in

    ↩

Available Tools

9 tools
activity_timelineA

The shape of the user's activity over time: contiguous buckets, each with start (UTC), local_start, prompt_count, active_minutes and the projects/sources touched. Use it to show when work happened rather than how much. bucket must be one of: hour, day - buckets are aligned to local hours/midnights. since/until accept an ISO 8601 timestamp ('2026-09-19T14:00:00Z'), a bare date ('2026-09-19'), the word 'now', or a relative duration meaning that long ago: '30m', '24h', '7d', '2w', '3mo', '1y'. Omit until for 'up to now'. Defaults: since='24h', until=now. Very wide windows are truncated (the response then carries truncated: true); widen bucket instead of the window.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo24h
untilNo
bucketNohour

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well. It discloses local-hour/midnight alignment, accepted time formats, defaults, and the truncation behavior signaled by `truncated: true`. These are behavioral details an agent could not infer from the schema alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, front-loading the output shape and purpose before moving to parameters and edge cases. Every clause adds useful information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a moderately complex query tool, the description covers output fields, timezone alignment, input formats, defaults, and truncation behavior. Combined with the existing output schema, an agent has everything needed to select and invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description fully compensates by explaining all three parameters: `bucket` options and alignment, `since`/`until` accepted formats and defaults, and the meaning of omitting `until`. Each parameter gets more meaning than its bare schema representation provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly defines the tool's resource as 'the user's activity over time' and its purpose as showing 'when work happened rather than how much.' This distinguishes it from sibling tools like prompt_stats and time_summary even without naming them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly guides when to use the tool: to show the shape of activity rather than volume. It also gives actionable advice on handling wide windows by widening the bucket instead of the window. It doesn't name sibling alternatives explicitly, but the when/not distinction is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

daily_digestA

Everything worth knowing about one local calendar day: first/last activity, active_minutes, the day's activity sessions (project, source, start/end, prompt count and the three shortest prompts as samples), context_switches and top_terms. date is YYYY-MM-DD in this machine's local timezone and defaults to today. Use it for 'what did I do today?' and end-of-day reviews; use time_summary for anything spanning several days.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses the output contents in detail, including the 'three shortest prompts as samples,' and clarifies date semantics: YYYY-MM-DD in the local timezone, defaulting to today. It does not mention auth, rate limits, or explicitly state read-only behavior, but for a read-only digest tool these are minor omissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver output composition, date semantics, and routing guidance with no filler. Every clause adds information the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple—one optional parameter—and the description fully explains that parameter and the return contents. It also names the sibling tool for multi-day queries, making the description self-sufficient for selecting and invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%: the schema only provides a nullable 'date' property with no description. The tool description compensates by specifying the format (YYYY-MM-DD), timezone context, and default-to-today behavior. It does not discuss valid date ranges or how past/future dates behave, but for a single optional parameter the guidance is substantially helpful.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific deliverable—a per-day digest—and enumerates its components (first/last activity, active_minutes, sessions, prompt samples, context_switches, top_terms), making the scope concrete. It also explicitly distinguishes itself from time_summary, which covers multi-day summaries. An agent can clearly tell what this tool returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases: 'what did I do today?' and end-of-day reviews. It also names the alternative tool, time_summary, and the condition that selects it ('anything spanning several days'), providing a clear when-to-use vs. when-not-to-use boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_promptA

Fetch one captured prompt by its id (the id field of any record returned by list_prompts or search_prompts). Returns the record, or {"error": "not_found", "id": ...} when there is no such prompt.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden and covers the key behavior: it returns the record or an explicit not_found error object. This makes the tool's behavior predictable for an agent without over-explaining.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences carry the entire necessary message: what is fetched, how to obtain the id, and the error behavior. There is no filler or redundant restating of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a single required parameter, an output schema, and a clear error contract. The description fully covers the retrieval path and failure mode, leaving no important gap for an agent to guess.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only declares id as a string with no description. The tool description adds crucial meaning by specifying that the id is the id field of any record returned by list_prompts or search_prompts, telling the agent exactly where a valid value comes from.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Fetch one captured prompt by its id.' It clearly distinguishes this single-record getter from the list/search siblings by emphasizing retrieval by id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly connects this tool to list_prompts and search_prompts by noting that the id comes from records returned by those tools. This gives clear context for when to use it, though it does not explicitly state exclusions like 'do not use for listing or searching.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_promptsA

List captured prompts, newest first (oldest first is not offered; page with offset). Use it to read what the user actually asked, in order, about a project or a session. Prompt text is PII-scrubbed: values appear as [EMAIL_1], [API_KEY_2] and similar placeholders. source must be one of: claude_code, codex_cli, opencode, claude_web, claude_code_web, chatgpt_web, codex_cloud. project, session_id and account are exact matches on the stored value (see list_sessions / list_sources for what exists). limit is capped at 500. since/until accept an ISO 8601 timestamp ('2026-09-19T14:00:00Z'), a bare date ('2026-09-19'), the word 'now', or a relative duration meaning that long ago: '30m', '24h', '7d', '2w', '3mo', '1y'. Omit until for 'up to now'. Returns {prompts: [record...], total: <matching rows ignoring limit/offset>}.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sinceNo
untilNo
offsetNo
sourceNo
accountNo
projectNo
session_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. It transparently reveals PII scrubbing with placeholder examples, the hard limit cap at 500, exact-match semantics for project/session/account, the full since/until date grammar including relative durations, and the unavailability of oldest-first ordering. This is extensive and unusually candid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense; every clause maps to a schema parameter, an invocation constraint, or a user need. It front-loads the core operation and ordering immediately, then systematically covers PII handling, filtering, pagination, date formats, and the return shape without filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 8 parameters, no annotations, and no schema descriptions, the description is remarkably complete. It covers ordering, filtering, paging, source enumeration, exact-match semantics, date parsing variants, and the response envelope, while referencing sibling tools for discoverability. The only minor omission is a direct contrast with search_prompts, but the provided output schema and extreme specificity make the tool safely invocable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description fully compensates. It enumerates every valid source value, explains the exact-match behavior for project/session/account, defines the limit cap, offset paging, and the complete since/until input grammar. Every parameter in the schema is given meaningful semantic context beyond its type and default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List captured prompts, newest first'. It adds behavioral detail (oldest first is not offered, page with offset) and usage context ('read what the user actually asked, in order'), which distinguishes it from search-oriented siblings like search_prompts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: 'Use it to read what the user actually asked, in order, about a project or a session' and points to list_sessions/list_sources for discovering valid exact-match values. However, it does not explicitly state when not to use this tool or contrast it with search_prompts/get_prompt, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_sessionsA

List agent/conversation sessions, most recently active first, with their project, first/last timestamp and prompt count. Use a returned session_id with list_prompts to read one conversation in order. source must be one of: claude_code, codex_cli, opencode, claude_web, claude_code_web, chatgpt_web, codex_cloud. limit is capped at 500.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sourceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and does so well: it discloses ordering, returned fields, source value restrictions, and the limit cap. It does not mention pagination or error behavior, but the stated behaviors are sufficient for a simple read-only list operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, with the primary purpose front-loaded and every sentence adding necessary detail. There is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, optional parameters, and presence of an output schema, the description covers the essential operational details: ordering, returned fields, source constraints, limit cap, and integration with list_prompts. Nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for both parameters. It does: it enumerates valid source values and caps limit at 500. It does not mention defaults, but those are visible in the schema, so the added semantics are meaningful.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List agent/conversation sessions'), includes explicit ordering and output fields, and distinguishes itself from list_prompts by describing the follow-up role of the returned session_id. This makes it unambiguous what the tool returns and how it relates to sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for use by stating the sort order, the fields returned, and the intended chaining with list_prompts via session_id. It does not explicitly contrast with siblings like activity_timeline or time_summary, but the companion usage is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_sourcesA

Which capture sources have prompts, how many, and the first/last timestamp for each. Takes no arguments. Call it first when you are unsure what is being captured at all, or to check whether a source has gone quiet.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It discloses that the tool takes no arguments, lists only sources that have prompts, and provides counts and timestamps, which implies a read-only query. It could state read-only behavior more explicitly, but nothing contradicts the implied safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: the first states the output, the second states the invocation constraint and usage guidance. There is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-argument tool with an output schema, the description is complete: it defines what is returned, confirms no arguments, and explains when to call it. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the description explicitly confirms 'Takes no arguments,' adding clarity beyond the empty schema. This matches the baseline for parameter-less tools and is fully sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool reports: capture sources with prompt counts and first/last timestamps. It is specific about the resource and output dimensions, though it does not explicitly name sibling tools or contrast with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: call it first when unsure what is being captured or to check if a source has gone quiet. It does not include when-not-to-use instructions or name alternative tools, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

prompt_statsA

Cheap prompt counts and character totals - no time analysis. Reach for time_summary instead when the question is about time. group_by must be one of: source, day, week, project, account, session ('day' and 'week' bucket by the UTC timestamp, not local time). since/until accept an ISO 8601 timestamp ('2026-09-19T14:00:00Z'), a bare date ('2026-09-19'), the word 'now', or a relative duration meaning that long ago: '30m', '24h', '7d', '2w', '3mo', '1y'. Omit until for 'up to now'. Returns {group_by, groups: [{key, prompt_count, chars}]}.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo
untilNo
group_byNosource

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the tool is 'cheap' (implying low cost), that it does no time analysis, and that day/week bucketing uses UTC timestamps rather than local time. It also explains the semantics of omitting until ('up to now'). With no annotations provided, the description carries the burden and does a good job, though it could mention pagination or limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, front-loading the core purpose and the key alternative. Every sentence adds value: the group_by constraint, the time format spec, and the return shape are all necessary. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, alternatives, parameter semantics, timezone behavior, and return shape. The output schema exists, so the return format note is a helpful summary rather than a requirement. For a 3-parameter tool with no annotations, this is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate. It does: it explains the allowed values for group_by, the accepted formats for since/until, the meaning of relative durations, and the behavior of omitting until. This is far beyond what the bare schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Cheap prompt counts and character totals') and immediately distinguishes itself from the sibling time_summary tool. It clearly states what the tool does and what it does not do, making it easy for an agent to select it correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says to use time_summary instead when the question is about time, providing a clear alternative. It also gives detailed guidance on the group_by values and the since/until formats, including examples and the meaning of relative durations. This is comprehensive usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_promptsA

Full text search over the captured prompt text, best match first. query is SQLite FTS5 syntax: bare words are AND-ed, "quoted phrases" match exactly, foo OR bar, foo NOT bar and refact* prefixes work. A query FTS5 cannot parse is retried as a literal phrase rather than failing. Remember the text is scrubbed, so searching for an email address or a key will never match. source must be one of: claude_code, codex_cli, opencode, claude_web, claude_code_web, chatgpt_web, codex_cloud. since/until accept an ISO 8601 timestamp ('2026-09-19T14:00:00Z'), a bare date ('2026-09-19'), the word 'now', or a relative duration meaning that long ago: '30m', '24h', '7d', '2w', '3mo', '1y'. Omit until for 'up to now'. limit is capped at 500. Each result carries a bm25 rank (lower = better).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
sinceNo
untilNo
sourceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses query parsing behavior (FTS5 syntax, literal fallback), scrubbing caveat (emails/keys never match), source allowed values, time format options, limit cap of 500, and bm25 rank semantics. Exceptionally transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long but every sentence adds value. Front-loads purpose, then logically breaks down query syntax, scrubbing note, source, time formats, limit, and rank. Well-structured and necessary; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a search tool with complex query syntax. Covers query syntax, parameter constraints, scrubbing caveat, and output rank. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains every parameter: query syntax, source enum, since/until formats, and limit cap. This adds significant meaning far beyond the schema and fully compensates for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (search) and resource (captured prompt text), and clarifies it is full-text with best-match-first ranking. This clearly distinguishes it from siblings like list_prompts (which lists prompts) and get_prompt (which fetches a specific one).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context on when to use: for full-text search with fuzzy matching and specific query syntax. It does not explicitly name alternatives or exclusions, but the purpose is self-evident. Could improve by stating when not to use (e.g., exact ID lookup should use get_prompt).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

time_summaryA

Where the user's time went. THE tool for any question about time use, focus or workload. Returns per-group active_minutes (wall-clock time around the agent, including a short tail credit), prompt_count, agent_minutes (how long agents were working; 0 where no turn-end signal exists, e.g. browser sources) and avg_think_seconds (the user's read-and-decide gap between an agent finishing and their next prompt), plus total_active_minutes and context_switches (consecutive prompts in one work session on different projects) for the whole window. group_by must be one of: project, source, day, hour_of_day, weekday, session - 'hour_of_day' and 'weekday' use this machine's local timezone. since/until accept an ISO 8601 timestamp ('2026-09-19T14:00:00Z'), a bare date ('2026-09-19'), the word 'now', or a relative duration meaning that long ago: '30m', '24h', '7d', '2w', '3mo', '1y'. Omit until for 'up to now'. Default since is '7d'. All figures are heuristics derived from prompt timestamps and idle gaps, not measured focus time; present them as such.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo7d
untilNo
group_byNoproject

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full transparency burden and does so well. It explicitly warns that all figures are heuristics, not measured focus time, and explains edge cases like agent_minutes being 0 where no turn-end signal exists and browser sources lacking that signal. It also discloses the local-timezone dependency and the inclusion of a short tail credit in active_minutes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Although long, the description is dense and efficiently front-loaded: purpose first, then metric semantics, then parameter semantics, then a critical caveat. Every sentence adds non-obvious information, and nothing is redundant with the input schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with only three simple parameters but complex derived metrics, the description is remarkably complete. It covers defaults, accepted formats, metric definitions, known limitations, timezone handling, and how to present results, making it self-sufficient for an agent to invoke correctly. The output schema can handle the mechanical return structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description fully compensates by explaining every parameter. It enumerates all valid group_by values, gives concrete syntax for since/until (ISO 8601, bare dates, 'now', relative durations), explains the meaning of relative durations, and specifies the default behavior for both parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening 'Where the user's time went. THE tool for any question about time use, focus or workload' gives a specific verb-like purpose and a clear resource scope, and it is immediately distinguishable from sibling tools such as prompt_stats or activity_timeline. The description further reinforces purpose by enumerating the exact metrics returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear practical usage context: defaults, how to omit 'until', valid group_by values, timezone behavior, and relative duration semantics. It positions itself as the tool for time-use questions but does not explicitly name alternatives or say when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updatesv0.1.0
    • First observedactivity_timeline
    • First observeddaily_digest
    • First observedget_prompt
    • First observedlist_prompts
    • First observedlist_sessions
    • First observedlist_sources
    • First observedprompt_stats
    • First observedsearch_prompts
    • First observedtime_summary

TDQS

A4.6/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clear, distinct role: list_prompts/search_prompts/get_prompt for raw access, list_sources/list_sessions for metadata, and the four analytics tools each target a different slice (timeline buckets, counts, time-use groups, single-day digest). Even the overlapping time-related tools have explicitly differentiated use cases.

Naming Consistency4/5

The retrieval tools follow a consistent verb_noun pattern (list_prompts, list_sources, list_sessions, search_prompts, get_prompt), but the analytics tools use plain noun names (activity_timeline, prompt_stats, time_summary, daily_digest). This is predictable and readable, but not a fully uniform convention across the set.

Tool Count5/5

Nine tools is well-scoped for a prompt-capture and analysis server, covering enumeration, search, single-record fetch, metadata discovery, and multiple analytic views without redundancy or bloat.

Completeness5/5

The surface covers the full read-side lifecycle: discover sources/sessions, browse/search/fetch prompts, and analyze activity over time at both aggregate and per-day granularity. For a read-only capture server, there are no obvious gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    A read-only MCP server that exposes local coding-agent session logs as three tools for introspection of recent work, debugging tool failures, and tracking token usage and estimated cost without parsing log files.
    3
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Local workstation attention journal that tracks focus, idle, and agent sessions, exposing timeline data via MCP for AI agents to query current or past activity.
    5
    AGPL 3.0
  • A
    license
    C
    quality
    A
    maintenance
    Enables coding agents to query, compare, and audit local profiler traces, benchmarks, memory captures, and execution evidence without uploading code or data, using CLI and MCP interfaces.
    111
    199 PyPI
    114
    MIT