agent-prompt-capture
Captures prompts from Codex CLI and chatgpt.com, scrubs PII, and stores them locally for analysis and retrieval.
Stores scrubbed prompt data in a local SQLite database, enabling querying and search via the MCP server.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@agent-prompt-capturesummarize what I worked on yesterday from my captured prompts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 | stdin JSON to |
| Codex CLI | stdin or argv JSON |
| OpenCode plugin | stdin JSON |
| Chrome extension on claude.ai | HTTP POST to the listener |
| Chrome extension on claude.ai/code | HTTP POST to the listener |
| Chrome extension on chatgpt.com | HTTP POST to the listener |
| 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 mcpThe 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 mcpCodex 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.
Run the listener. In the foreground:
apc serve # binds 127.0.0.1:47821, ctrl-c to stopAs 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.plistBoth units hard-code a path to
apc; replace it with the output ofwhich apc.Print the shared secret the extension needs:
apc token # `apc token --rotate` issues a new oneLoad the extension:
chrome://extensions-> Developer mode -> Load unpacked -> pick theextension/directory. Fill in the server URL, the token and the allowlist in its Options page. Full walkthrough and troubleshooting: extension/README.md.Set the allowlist in both places:
[capture].allowed_accountsinconfig.tomland 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?" |
|
"Am I most productive in the morning or after lunch?" |
|
"What did I do yesterday? Write my standup." |
|
"When was I actually at the keyboard today?" |
|
"Have I asked about this migration before?" |
|
"How many sessions did I start on this repo, and how long?" |
|
"Am I using Codex more than Claude Code now?" |
|
"Show me the last ten things I asked about auth." |
|
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
projectdiffers.
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 |
| print the version | |
| read hook JSON from the trailing argument (Codex | |
|
| run the loopback HTTP listener for the extension. Non-loopback hosts are refused unless |
| run the stdio MCP server | |
|
| write the hook config, idempotently. |
| remove what | |
|
| print the listener token, or generate a new one |
|
| list captured prompts, newest first |
|
| FTS5 full-text search |
|
| prompt and character counts |
|
| active minutes, agent minutes, average think time, context switches |
|
| one local day: sessions, samples, top terms. Defaults to today |
|
| dump records to stdout or a file |
|
| delete records. Refuses to run with neither |
| 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 sessionEnvironment variables:
Variable | Read by | Effect |
| everything | the runtime directory. Default |
| logging | DEBUG level, and a stderr handler in addition to |
|
| directory holding |
|
| directory holding |
|
| base for |
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 HOMEscripts/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_minutesand 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_summaryfar 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.
Available Tools
9 toolsactivity_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.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | 24h | |
| until | No | ||
| bucket | No | hour |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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>}.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| until | No | ||
| offset | No | ||
| source | No | ||
| account | No | ||
| project | No | ||
| session_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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}]}.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ||
| until | No | ||
| group_by | No | source |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| since | No | ||
| until | No | ||
| source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | 7d | |
| until | No | ||
| group_by | No | project |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
9 tool updates
v0.1.0- First observed
activity_timeline - First observed
daily_digest - First observed
get_prompt - First observed
list_prompts - First observed
list_sessions - First observed
list_sources - First observed
prompt_stats - First observed
search_prompts - First observed
time_summary
TDQS
Scored across 9 tools
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.
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.
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.
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
Related MCP Connectors
Analytics for MCP servers. Query your tool calls, first-call success, retries and schema cost.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Ingest and search LogsLoom logs from coding agents.
Related MCP Servers
- AlicenseAqualityBmaintenanceA 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.3MIT
- AlicenseAqualityCmaintenanceLocal-first, read-only Codex session aggregator that indexes multiple CODEX_HOME directories into a SQLite database and provides MCP tools for cross-project, archival, and sub-agent history queries.53MIT

roxabi-senseofficial
AlicenseBqualityBmaintenanceLocal workstation attention journal that tracks focus, idle, and agent sessions, exposing timeline data via MCP for AI agents to query current or past activity.5AGPL 3.0- AlicenseCqualityAmaintenanceEnables 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.111199 PyPI114MIT