ephemeral-buffer
Summary: This server is an ephemeral in-memory capture and hybrid search engine for AI coding assistants, letting agents store, index, search, and retrieve command output without polluting context.
Capture command output: Run or wrap shell commands (
execute_and_capture), ingest existing text (capture_text), or read files (capture_file) into a bounded, transient ring buffer.Search captured content: Use hybrid BM25 + semantic vector search, pure BM25 lexical search, or semantic concept search (
search_capture); search returns line-numbered chunks with context.Inspect exact content: Retrieve precise line ranges (
get_capture_slice), compact summaries with previews (get_capture_summary), and list active captures (list_captures).Manage buffer lifecycle: Clear individual or all captures (
clear_captures), view aggregate stats (get_buffer_stats), and adjust semantic index budget at runtime (set_semantic_index_budget).Preflight commands: Get content-free path, symlink, Git-root, and executable-resolution diagnostics without executing the command (
preflight_command).Run durable multi-phase workflows: Start, resume, inspect, and retrieve bounded output from sequential checkpointed command phases (
start_execution,resume_execution,get_execution,get_execution_output,list_executions).Consolidate captures: Merge multiple captures into one bounded, searchable JSON capture preserving source IDs and line numbers (
consolidate_captures).Diagnose the server: Request opt-in runtime metadata, version, platform, uptime, socket mode, buffer limits, embedding readiness, and process memory (
get_runtime_diagnostics).
Parses git diffs and PR diffs into structured file maps, indexing modified files, additions/deletions, and line numbers for precise retrieval.
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., "@ephemeral-buffercapture the test output and search for connection timeout errors"
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.
Ephemeral Buffer MCP Server (ephemeral-buffer)
An ephemeral in-memory command output capture and hybrid search engine (BM25 + Semantic Embeddings) for AI coding assistants (Claude Code, Antigravity, Cursor, etc.).
🎯 The Problem This Solves
When coding agents run commands that generate large outputs (thousands of lines of build logs, test runs, stack traces, JSON dumps), agents face two failure modes:
Context Pollution: Ingesting megabytes of raw text blows out token limits and degrades model reasoning.
Blind Bash Filtering: Agents waste multiple turns running
head,tail,grep, andawktrying to guess error patterns.
Related MCP server: Qurio MCP Server
💡 The Solution
ephemeral-buffer provides a transient in-memory ring buffer with Dual Hybrid Indexing and Content-Aware Structure Parsing:
BM25 Lexical Search (SQLite FTS5): For exact matches on error codes (
NullPointerException,ECONNREFUSED,exit 137, HTTP502). Builds without SQLite FTS5 use a complete token-based Python fallback with lower ranking performance.Dense Semantic Vector Search (FastEmbed ONNX): For fuzzy conceptual queries ("Where did the DB connection pool fail?" or "Why did authentication fail?").
Unified Diff Structural Mapping: Automatically detects git diffs and PR diffs (
gh pr diff,git show,git diff), parses modified files, additions/deletions, and generates a line-indexed file map in the summary.Smart Signal Filtering: Scans command/build/test logs for diagnostic keywords, suppresses false positives in diffs and source code, and accurately captures test runner failures, unhandled exceptions, and merge conflicts. Use
content_type='log'when a plain-text capture should be signal-scanned.Successful test-run summaries such as
OKor25 passedsuppress fixture-only error and failure keywords while retaining the original output for search.Reciprocal Rank Fusion (RRF): Blends lexical and semantic ranking for high precision retrieval.
LRU Capture Eviction: Holds up to 25 captures and 50 MiB of captured content by default, evicting the least recently used captures when either limit is reached.
Thread-Safe Shared Engine: Serializes ingestion, search, LRU updates, eviction, and cleanup across MCP requests and CLI socket clients.
📦 Installation
Requirements
Python 3.10 or newer
A supported MCP client if you want to use the server from an AI coding assistant
Network access on first use if FastEmbed needs to download its embedding model
The package is installed from PyPI as ephemeral-buffer-mcp. It provides both
the MCP server and the ephbuf command-line client.
Recommended: install from PyPI
Create an isolated virtual environment and install the latest published package:
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install ephemeral-buffer-mcpVerify that the CLI is available:
.venv/bin/ephbuf --helpOn Windows, use the equivalent commands from the virtual environment's
Scripts directory:
py -3 -m venv .venv
.venv\Scripts\python.exe -m pip install --upgrade pip
.venv\Scripts\python.exe -m pip install ephemeral-buffer-mcp
.venv\Scripts\ephbuf.exe --helpTo upgrade or remove the package:
.venv/bin/python -m pip install --upgrade ephemeral-buffer-mcp
.venv/bin/python -m pip uninstall ephemeral-buffer-mcpInstall from a source checkout
Use an editable install when developing or testing local changes:
git clone https://github.com/k-rister/ephemeral-buffer-mcp.git
cd ephemeral-buffer-mcp
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -e .The editable install exposes the same ephbuf command and MCP server as the
PyPI installation. The reproducible, locked contributor environment is
documented in Testing the Server.
When launching from a source checkout with run.sh, the launcher prefers
.venv/bin/python, then supports the legacy venv/bin/python layout, before
using an explicit PYTHON override or python3. An invalid PYTHON override
fails with an actionable error.
Start the MCP server manually
The MCP server uses stdio for communication with the MCP host. Start it with the Python interpreter from the environment where the package was installed:
.venv/bin/python -m serverNormally you should let your MCP client start this process automatically. Do
not start a separate server for every shell command: the ephbuf CLI sends
captures to the running server over its local Unix socket.
The private CLI socket uses versioned length-prefixed request and response
frames, so fragmented reads do not depend on half-closing the connection.
Start an isolated Codex session
When using the global Codex MCP configuration, start Codex through the
installed codex-ephemeral launcher. From a source checkout, use
./codex-ephemeral. The launcher creates a unique
EPHEMERAL_SESSION_ID and exports it to Codex, the MCP server, and ephbuf.
It also passes the ID explicitly through Codex's MCP configuration so it is
available even when Codex sanitizes the MCP child environment.
The global configuration requires this identity, so starting Codex directly
will fail closed instead of attaching to another session's socket.
The launcher also enables EPHEMERAL_ALLOW_STDIO_WITHOUT_SOCKET=1 because some
Codex execution environments deny Unix-socket creation. In that case MCP over
stdio remains available and runtime diagnostics report the socket failure;
ephbuf CLI support remains available when the environment permits socket
creation.
Configure other coding agents
The server is not Codex-specific. Any MCP client that launches a local stdio server can use the same command and environment settings:
{
"mcpServers": {
"ephemeral-buffer": {
"command": "/absolute/path/to/ephemeral-buffer-mcp/run.sh",
"args": [],
"env": {
"EPHEMERAL_REQUIRE_ISOLATION": "1",
"EPHEMERAL_SESSION_ID": "agent-session-unique-value",
"EPHEMERAL_ALLOW_STDIO_WITHOUT_SOCKET": "1"
}
}
}
}This shape applies to clients such as Claude-style .mcp.json and
Gemini/Antigravity-style mcp_config.json. Use a different
EPHEMERAL_SESSION_ID for every concurrent agent session. If the client
supports environment interpolation, use its per-session identifier; otherwise
generate an ID when starting the agent and place that same value in the
agent's shell environment:
export EPHEMERAL_SESSION_ID="agent-$(date +%s)-$$"
export EPHEMERAL_REQUIRE_ISOLATION=1
export EPHEMERAL_ALLOW_STDIO_WITHOUT_SOCKET=1The MCP server and ephbuf CLI must inherit the same ID. An MCP client that
does not pass environment variables to child processes can still use the MCP
tools, but its separate ephbuf shell commands will need an equivalent
session environment configured independently.
For other shell-launched agents, use the installed generic launcher. From a
source checkout, use ./ephemeral-agent:
ephemeral-agent claude
ephemeral-agent geminiOr source the environment into an existing shell before launching the agent:
source ephemeral-session-env
claude # or another coding-agent commandGUI-launched agents still need their MCP configuration to provide a unique session ID per conversation; these scripts cannot modify an already-running GUI process.
Configure an MCP client
MCP clients generally need the command, arguments, and environment used to start a stdio server. A portable configuration looks like this:
{
"mcpServers": {
"ephemeral-buffer": {
"command": "/absolute/path/to/ephemeral-buffer-mcp/.venv/bin/python",
"args": ["-m", "server"]
}
}
}Replace the command with the absolute path to the virtual-environment Python
interpreter. Using an absolute path avoids differences between GUI-launched
clients and interactive shells. On Windows, use a path such as
C:\\path\\to\\ephemeral-buffer-mcp\\.venv\\Scripts\\python.exe.
For clients that provide a command-line registration command, register the same executable and arguments conceptually as:
command: /absolute/path/to/.venv/bin/python
arguments: -m serverAfter saving the configuration, restart or reload the MCP client and confirm
that the ephemeral-buffer tools appear. The server exposes capture, search,
summary, slice, consolidation, diagnostics, and cleanup tools; the ephbuf
CLI is a separate convenience client for shell output.
Isolate concurrent agent sessions
For a coding agent that may run alongside another agent, configure the same
session identity for the MCP server and the ephbuf CLI:
"env": {
"EPHEMERAL_REQUIRE_ISOLATION": "1",
"EPHEMERAL_SESSION_ID": "agent-session-1"
}The server and CLI then derive the same session-specific socket, while a
missing identity fails closed instead of falling back to the shared legacy
socket. EPHEMERAL_SOCKET_PATH may be used instead when the launcher assigns
the socket path directly. The MCP initialization instructions describe this
policy to the client, but the environment checks enforce it independently.
The CLI bounds each socket connect, send, and receive operation to 10 seconds
by default. Set EPHEMERAL_SOCKET_TIMEOUT_SECONDS to a positive number of
seconds when a different limit is appropriate; timeout failures return a
nonzero CLI result.
Background model warm-up
After socket startup succeeds, the server loads FastEmbed and runs a small deterministic embedding in a background thread. MCP startup and BM25 search do not wait for this work. A semantic request arriving during warm-up waits on the same model lock instead of starting a duplicate load. Subsequent operations use the local model cache. To disable warm-up for lexical-only or memory-constrained deployments, or to select a compatible model and cache location, set:
export EPHEMERAL_EMBEDDING_WARMUP=0
export EPHEMERAL_EMBEDDING_MODEL="BAAI/bge-small-en-v1.5-fp32"
export EPHEMERAL_FASTEMBED_CACHE_DIR="$HOME/.cache/ephemeral-buffer"The default model is BAAI/bge-small-en-v1.5-fp32, the upstream fp32 ONNX
export of bge-small-en-v1.5 (about 130 MB), which the server registers with
FastEmbed itself. FastEmbed's own catalogue entry, selectable as
BAAI/bge-small-en-v1.5, is a smaller reduced-precision export that produces
identical vectors but whose matrix kernels do not parallelize on common CPU
hosts. In a release-preparation comparison on a 16-vCPU Linux x86_64 host,
the fp32 export reached 69.1 semantic chunks per second with 1.85 seconds
median indexing at 1,024 lines, versus 3.1 chunks per second and 41.15 seconds
for the catalogue file. That roughly 22x difference is host-specific evidence,
not a universal performance guarantee. Embedding inference uses ONNX Runtime's
default thread count; bound it with
EPHEMERAL_EMBEDDING_THREADS when the server shares a host with an
interactive coding agent, and check both settings on the deployment host with
benchmark_semantic_index.py. get_buffer_stats reports the active thread
setting.
export EPHEMERAL_EMBEDDING_THREADS=4Warm-up failures do not stop the server. BM25 remains available, and hybrid
search returns lexical results with a semantic_fallback error-class field
when semantic initialization fails. get_buffer_stats and
get_runtime_diagnostics report warm-up as not-started, loading, ready,
failed, or disabled; failures expose only the exception class.
Lexical and semantic search index different chunk grids. BM25 keeps four-line
sliding windows with two-line overlap so exact line ranges stay tight. Semantic
embeddings use separate windows packed from consecutive lines, closed at eight
lines or 1,024 UTF-8 bytes, whichever comes first, with no overlap. That keeps
every window inside the model's token limit and, because embedding cost tracks
total tokens, roughly halves the work by not embedding the overlap twice. Hybrid ranking fuses the
two grids in line space: a semantic window boosts the lexical hits it overlaps
and appears on its own only when nothing lexical matched inside it. Each match
reports chunk_index as lexical or semantic alongside its line range. Tune
the windows when output has very long or very short lines:
export EPHEMERAL_SEMANTIC_CHUNK_LINES=8
export EPHEMERAL_SEMANTIC_CHUNK_BYTES=1024
export EPHEMERAL_SEMANTIC_CHUNK_OVERLAP=0Larger windows embed fewer chunks but dilute single-line signals and cost more
per token; overlap improves recall across window boundaries at proportional
embedding cost. Compare strategies on the deployment host with
benchmark_semantic_index.py --semantic-chunk-lines ... --semantic-chunk-overlap ....
Semantic indexing is prefetched after ingestion by default, so a search that arrives after the background job finishes pays no indexing cost. Disable it for lexical-only or CPU-constrained hosts, or bound the worker pool:
export EPHEMERAL_SEMANTIC_PREFETCH=0
export EPHEMERAL_SEMANTIC_PREFETCH_WORKERS=1Every eligible capture is queued at ingestion and a bounded worker pool drains
the queue newest-first, since the latest capture is the most likely search
target; a burst of captures is never silently skipped. A semantic or hybrid
search waits for a job that is already running, and pulls a still-queued
capture out of the queue to index it on a separate on-demand pool so it does
not wait behind older work. That pool is bounded by the same worker count, so
searches that give up waiting on captures that are then evicted cannot
accumulate indexing threads. Failed jobs retry through the normal lazy path,
and evicted or cleared captures drop their queued prefetch and on-demand work.
Embedding inference is serialized by one model lock, so extra workers only
overlap bookkeeping; tune EPHEMERAL_EMBEDDING_THREADS instead of the worker
count for throughput. get_buffer_stats and get_runtime_diagnostics expose
only aggregate pending, queued, running, and failed counts.
Indexing cost grows linearly with capture size, so a hybrid search that arrives before a large capture's index is ready waits at most a configurable budget:
export EPHEMERAL_SEMANTIC_WAIT_SECONDS=10When the budget expires, hybrid search returns the BM25 results immediately
with semantic_coverage set to pending (the tool response says
semantic pending (lexical only)), and indexing continues in the background
so repeating the search returns full hybrid ranking. Every other hybrid
response reports semantic_coverage as complete, or unavailable when the
semantic backend failed and semantic_fallback names the exception class;
BM25 results and exact line ranges are identical either way. The default of
10 seconds kept a 2,048-line capture fully hybrid in the
release-preparation Linux run (about 4.0 seconds to index), while 8,192- and
16,384-line captures took about 17.0 and 32.9 seconds to index and therefore
answered lexical-first within the budget. Measured first-search p95 was about
4.0 seconds at 2,048 lines (complete) and 10.002 seconds at the larger sizes
(pending); every needle in the benchmark fixture still ranked first. These
figures are host-specific: Apple silicon and other Linux hosts can differ
materially, so run benchmark_semantic_index.py on the deployment host before
choosing a wait budget.
Set 0 to always answer lexical-first while the index builds, or inf to
wait for the index unconditionally. Semantic mode has no lexical result to
fall back on, so it always waits for the index. An empty capture has nothing
to index, so it reports complete coverage for semantic and hybrid searches.
get_buffer_stats reports the budget and the number of on-demand index jobs
running and queued.
The exact model and cache location can also be supplied in the MCP client's
env configuration. Keep the model cache writable by the user running the
MCP client.
Installation choices at a glance
Use case | Recommended installation |
Normal user | PyPI install in a virtual environment |
MCP host | PyPI install, then configure the installed server command |
Shell/CLI use | PyPI install, then run |
CLI coding agent | PyPI install, then run |
Contributor | Source checkout with |
Release validation | Follow the procedures in OPERATIONS.md |
If the MCP client cannot find the server, check the absolute interpreter path, the selected Python environment, and the client's server logs. For socket, capture-limit, logging, and deployment troubleshooting, see OPERATIONS.md.
🏗 Architecture & Flow
flowchart TD
subgraph Ingestion["1. Ingestion & Diagnostics"]
A["CLI Pipe: command 2>&1 | ephbuf"] --> D["Unix Socket (platform temp dir)"]
B["Agent Tool: execute_and_capture(cmd)"] --> E["Ephemeral Ring Buffer Engine"]
C["Agent Tool: capture_text / capture_file"] --> E
D --> E
P["Agent Tool: preflight_command(cmd, cwd)"] --> Q["Path, executable & repository diagnostics"]
end
subgraph Execution["2. Durable Phase Execution"]
X["Agent Tools: start_execution / resume_execution"] --> Y["Phase Execution Manager"]
Y --> Z["Persistent Execution State & Bounded Phase Output"]
Y --> E
Z --> AA["get_execution / get_execution_output / list_executions"]
end
subgraph Indexing["3. Classification & Search Indexing"]
E --> F["SQLite FTS5 (BM25 Lexical) or Python lexical fallback"]
E --> G["Optional/background FastEmbed ONNX (Dense Vectors)"]
E --> K["Diff & Signal Parser (File Maps & Conflict Detection)"]
E --> M["consolidate_captures: bounded source-aware JSON"]
M --> E
end
subgraph Querying["4. Agent Query & Retrieval"]
F & G --> H["Reciprocal Rank Fusion (RRF)"]
H --> I["search_capture(query, mode='hybrid')"]
K --> L["get_capture_summary: diff stats & bounded file map"]
L --> N["get_capture_slice: exact lines"]
I --> J["Precise Context Chunk + Line Numbers"]
end🚀 How to Use It
1. From the Terminal (CLI Pipe via ephbuf)
You can pipe command output directly into the running MCP server:
# Pipe any command output into the buffer
pytest -v 2>&1 | ephbuf --label "pytest run"
# Pipe git diffs directly
git diff HEAD~3 | ephbuf --label "feature diff" --type diff
# Or wrap command execution
ephbuf --label "backend build" -- cargo build --verboseThe optional --type/-t hint accepts auto (the default), diff, log, or
text. Use diff for unified patches when automatic detection is ambiguous;
otherwise auto classifies diffs, build/test logs, and plain text from the
content and label.
ephbuf also bounds wrapped-command and piped-stdin capture with
--max-output-bytes; it defaults to EPHEMERAL_MAX_BUFFER_BYTES or 50 MiB and
retains the beginning and end of oversized output.
Use --timeout-seconds to stop a wrapped command after a bounded runtime; timed
out commands retain the output collected so far and exit with status 124.
Requested max_output_bytes and capture_file max_bytes values may not
exceed the configured buffer byte limit; the tools return a validation error
instead of silently clamping them.
2. From the AI Agent via MCP Tools
The agent has access to the following tools:
Tool | Purpose |
| Executes a shell command with bounded capture and returns a compact versioned JSON summary containing status, duration, sizes, approximate token counts, truncation, warnings/errors, and optional structured metrics. |
| Performs content-free path, symlink, local Git-root, and executable-resolution diagnostics without executing the requested command. |
| Runs a sequential, durably checkpointed set of command phases and returns phase statuses, metrics, and a partial/completed marker. |
| Resumes from the first incomplete phase, skipping completed phases; retries and unsafe side effects require explicit controls. |
| Retrieves persisted phase metadata, event history, retry requirements, and human/machine-readable completion status. |
| Retrieves a bounded output chunk persisted for all phases or one phase, including after a server restart; use |
| Lists a bounded page of durable executions and their partial/completed summaries; oversized pages return compact IDs with pagination metadata. |
| Ingests text directly into the buffer and returns the same compact summary schema. |
| Ingests a bounded log/output file from disk and returns the same compact summary schema. |
| Creates one bounded, searchable JSON capture from multiple captures while preserving source IDs and source line numbers. |
| Hybrid/BM25/Semantic search over the captured output. BM25 splits underscores and punctuation—including regex-like characters—into alphanumeric terms, then combines those terms with OR. For example, |
| Retrieves exact line ranges to inspect full stack traces, logs, or specific diff files. |
| Returns the compact JSON summary; opt into bounded head/tail previews only when needed. |
| Reports aggregate capture count, content bytes, lines, chunks, embedding model readiness, embedding bytes, accounted bytes, and process RSS. When local metrics are enabled, it also includes the content-free aggregate metrics snapshot. |
| Opt-in, content-free report of runtime version, platform, uptime, socket mode, buffer limits, embedding readiness, and process memory. |
| Adjusts the session's semantic-index chunk budget when |
| Lists active captures in the ring buffer. |
| Clears buffer. |
Capture tools return a compact JSON summary so an agent can decide whether it
needs the full output before spending context on retrieval. The summary uses
schema_version: 1 and includes status (captured, success, failed, or
timed_out), duration_ms, retained and original byte sizes, approximate
token counts, truncation and partial-execution flags, typed warning/error
signals, and bounded caller-provided structured_metrics. The token values
are deterministic planning estimates based on four UTF-8 bytes per token;
they are not provider billing counts. Use get_capture_summary for the
compact form, set include_previews=True only when a head/tail sample is
useful, and use get_capture_slice or search_capture for complete or
targeted content. Diff file maps are also bounded and report omitted entries;
use get_capture_slice for the complete diff. Raw retained captures are
unchanged by summary generation.
The deterministic summary benchmark measures the initial agent-prompt
reduction for representative successful, failed, noisy, truncated, and
timed-out captures. It exercises the public capture API, compares a
parent-contract formatted-text response with the current compact
summary-first decision prompt, and verifies through the public slice API that
retained output can still be retrieved unchanged. The parent response is
reconstructed from the prior execute_and_capture contract; the current path
uses the public compact response. The proxy divides UTF-8 prompt bytes by four
and is intended for regression comparison, not provider billing or exact
token accounting. Execution summaries also bound command and label metadata
so unusually long shell commands cannot re-expand the initial response.
To generate the machine-readable benchmark record:
.venv/bin/python benchmark_effectiveness.py --summary --output /tmp/capture-summary.jsonChoose the execution path based on the output and inspection goal:
Use direct command execution for a small, targeted inspection where the output is already bounded and immediate terminal feedback is sufficient.
Use
execute_and_captureonce output may be noisy, large, or uncertain—such as tests, builds, and logs—because it bounds context and makes later search and exact retrieval available. This is an advisory heuristic, not a hard line-count policy.Use
capture_textwhen output is already in hand, orcapture_filefor a file that has been checked and intentionally selected for ingestion.
Use preflight_command when repository identity or path resolution is
uncertain before a sensitive command. It reports resolved facts and explicit
unavailable states without running the requested command or exposing command
output. It cannot predict shell expansion, aliases, pipelines, redirections,
environment changes, or arbitrary shell logic, so normal command validation
and user intent checks remain necessary.
Resumable phase execution
Durable phase execution and its process-group recovery currently require Linux
with file-locking support and /proc process identities. The package's
Windows installations remain usable for MCP stdio and text/file capture.
Bounded subprocess capture requires POSIX pipe and process-group support, and
start_execution additionally requires Linux leases, /proc process
identities, pidfd signaling, and selector support; startup rejects the request
with a clear platform error when those recovery backends are unavailable.
Use start_execution when a long-running workflow has meaningful checkpoints:
start_execution(
execution_id="release-checks",
phases=[
{"name": "tests", "command": "python -m unittest", "timeout_seconds": 900},
{"name": "publish", "command": "./publish.sh", "side_effects": "unsafe"},
],
)Each phase is persisted as pending, started, completed, failed,
interrupted, or timed_out. Output, exit status, duration, truncation, and
caller metrics are written after every finished phase. If the server restarts
while a phase is started, the next inspection records it as interrupted.
resume_execution skips every completed phase and continues at the first
incomplete phase. Failed and timed-out phases require retry_failed=True;
safe phases recovered as interrupted resume automatically. A timed-out phase
whose process-group cleanup is not confirmed remains fence-pending and blocks
retry. An interrupted
phase marked side_effects: "unsafe" additionally requires
confirm_unsafe=True unless the execution was created with the explicit
resume_policy="allow-unsafe". The persisted idempotency_key is
an audit boundary for an external operation; it does not replace confirmation
or provide an external deduplication guarantee. The compatibility alias
unsafe_side_effects: true is normalized to side_effects: "unsafe"; if both
fields are supplied, they must agree.
The command is run beneath a Linux subreaper supervisor that adopts and
terminates descendants which escape the original process group. The supervisor
identity is checkpointed while a phase runs and is signalled through a pidfd
before restart recovery permits that phase to resume. Linux process start and
boot identities are revalidated while the pidfd is pinned, protecting recovery
from signalling a reused process ID; resume stays blocked if supervisor
termination or group absence cannot be confirmed. A phase marks its launch
fence before spawning the command, so a crash before process identity is
persisted also fails closed. Older in-progress records without these identity
fields are recovered as fence-pending and must be inspected or retired rather
than being retried automatically.
Execution responses include a human-readable summary, machine-readable
execution_status and partial fields, per-phase event history, and the
next resumable phase. If detailed metadata would exceed the 64 KiB tool
response budget, the server returns a compact response with the durable
execution_id and response_truncated: true; call get_execution or the
bounded output tool to retrieve details. Durable JSON state defaults to a temporary local
process-local directory created securely with owner-only permissions; set
EPHEMERAL_SESSION_ID, EPHEMERAL_SOCKET_PATH, or
EPHEMERAL_EXECUTION_STATE_DIR to persist and share state across server
restarts. State can otherwise be placed elsewhere with
EPHEMERAL_EXECUTION_STATE_DIR. State contains the commands and bounded
outputs, so keep any explicitly configured directory protected when commands
or results are sensitive.
Execution metadata is bounded to 64 MiB per record, 64 phases, 32 attempts per phase, 16 KiB of structured metrics, and 1,000 records per state directory; list results are paginated with a maximum page size of 100. There is no automatic expiry: when the record cap is reached, stop the server and archive or rotate the state directory, or remove completed records together with their matching summary files before restarting. State and execution leases are isolated by the explicit execution-state directory, session ID, or socket path; without one, each server process receives a fresh private state directory that is removed during normal shutdown on POSIX platforms. Windows may retain that temporary directory because secure owner-identity cleanup is not available there.
Before any repository-sensitive command or file capture, verify the intended
working directory and target path. Prefer an explicit cwd, confirm the
repository identity, and resolve symlinks when path identity matters. Shell
expansion, inherited working directories, and symlinks can target a different
location than the spelling suggests. Capture limits protect context size; they
do not validate command intent, path identity, or filesystem safety.
For diff captures, get_capture_summary reports the detected file map,
addition/deletion statistics, line ranges, and merge-conflict signals. Use
get_capture_slice with those ranges to retrieve the complete file context.
Consolidating multi-result workflows
When a workflow produces several captures—for example, one command per
repository—use consolidate_captures to give the agent one bounded overview:
consolidate_captures(
capture_ids=["cap_1", "cap_2", "cap_3"],
label="organization activity",
max_captures=25,
max_bytes=20000
)The resulting capture is JSON with source metadata and records containing the
original capture_id and source_line. It can be searched normally with
search_capture, and exact consolidated context can be retrieved with
get_capture_slice. The response reports omitted records, missing IDs, and
the original source IDs; use those original IDs to retrieve complete detail
when the consolidated byte budget is reached. Calling the tool without
capture_ids consolidates the currently active captures, up to
max_captures.
This workflow keeps the server responsible for bounded execution, storage, and retrieval while leaving prioritization and interpretation to the coding agent.
3. Capture Hygiene
Keep captures focused so search results remain useful and the agent receives only the context it needs:
Capture one command or related output stream at a time, using a descriptive label.
Start with
get_capture_summary, then usesearch_captureorget_capture_slicefor targeted retrieval instead of repeatedly recapturing the same output.Use
clear_captures(capture_id)when a capture is no longer needed; useclear_captures("all")between unrelated investigations.
The buffer is intentionally transient and bounded by the LRU capture limit, but explicit cleanup prevents recent investigations from obscuring the active one before automatic eviction occurs. Its memory metrics separate captured content and embedding bytes from process RSS; the unaccounted RSS value includes model, index, and Python object overhead and is approximate.
The server defaults can be overridden with EPHEMERAL_MAX_CAPTURES and
EPHEMERAL_MAX_BUFFER_BYTES. Session-aware launchers can set
EPHEMERAL_SESSION_ID so each server/CLI pair automatically derives a unique
socket path; EPHEMERAL_SOCKET_PATH remains an explicit override. The byte
limit accounts for captured UTF-8 content plus its label; a capture is rejected
when their combined size exceeds the limit. get_buffer_stats also reports
embedding model readiness, embedding/cache settings, and process memory
separately.
Indexed chunks are bounded separately by EPHEMERAL_MAX_INDEXED_CHUNKS, which
defaults to 32,768 total chunks across retained captures. LRU eviction makes
room for a new capture when possible. A capture that exceeds the entire index
budget is rejected rather than partially indexed, so accepted captures remain
fully searchable and cannot produce silent semantic false negatives. The
optional set_semantic_index_budget tool changes this limit for the current
session only and is disabled unless EPHEMERAL_ALLOW_RUNTIME_INDEX_BUDGET=1 is
set at startup. Decreases use the same deterministic LRU order and may evict
multiple captures; deployment defaults are not changed or persisted.
execute_and_capture retains the beginning and end of oversized command
output and marks the capture with its original byte count. Each returned head
or tail preview is independently capped at 4 KiB of UTF-8 data; a truncation
marker directs the agent to get_capture_slice for the complete content.
Call get_runtime_diagnostics() when reporting a field observation. It is
explicitly opt-in and returns operational metadata only; captured content,
labels, command arguments, and session ID values are excluded. Sanitize any
additional output before sharing it.
Operational events are written as privacy-safe JSON lines to stderr. Warnings
and errors are enabled by default; set EPHEMERAL_LOG_LEVEL=INFO to include
normal readiness, eviction, process lifecycle, and MCP tool start/completion
events. Tool lifecycle events contain only a local call ID, tool name, duration,
success state, and error class. Logs never include captured content, labels,
query text, or command text. A start event without a matching completion or
failure event identifies a stalled tool/session boundary.
The Codex A/B adapter can persist these events per MCP run with
--diagnostic-log-dir /path/to/logs; keep that directory outside the
repository. The files contain lifecycle metadata only.
Optional local usage metrics
Set EPHEMERAL_METRICS=1 to collect content-free, in-process usage metrics.
The metrics include per-tool call counts, success/failure counts, duration
totals, aggregate capture/search/retrieval, empty-search, eviction, and
cleanup events, plus session-scoped data-path byte counters. The byte counters
cover input, retained, and original capture bytes; tool/search/retrieval
response bytes; and framed socket request/response bytes. They are disabled by
default, are never sent anywhere, and do
not retain captured content, labels, commands, or query text. When enabled,
both get_runtime_diagnostics() and get_buffer_stats() include the same
aggregate metrics snapshot. The event keys are stable and zero-filled when no
event has occurred, as are the byte-counter keys. Wire counts include framing
headers and payload bytes actually consumed, including partial malformed
requests; payload bytes rejected from an oversized frame before reading are
not counted. MCP tool-response counts measure UTF-8 response content and
exclude transport-envelope overhead. Metrics are process-lifetime
state: restarting the server clears them, while capture-associated correlation
state is released when a capture is evicted or explicitly cleared.
Effectiveness metrics and privacy
The built-in metrics are local, opt-in operational telemetry. Set
EPHEMERAL_METRICS=1 only when you want measurements for the current server
process; nothing is uploaded or shared by the server. The metrics contain
counts, durations, byte sizes, and bounded lifecycle outcomes, but do not
retain captured content, labels, command arguments, or query text. Runtime
logs follow the same privacy model. Treat any captured output or diagnostic
excerpt as potentially sensitive and sanitize it before sharing.
Interpret the measurements in two separate layers:
Layer | What it answers | What it cannot establish |
Operational health | Did the server accept, store, search, retrieve, evict, and clean up requests? Were calls successful and how much local time or memory did they use? | That a search result was relevant, that the agent saw the right context, or that the user's task was completed. |
Task-level effectiveness | Did a representative agent workflow find the needed signal, retrieve the right context, and complete its task? | A universal result from synthetic fixtures or a server-only benchmark. |
The effectiveness harness measures server-side behavior with deterministic fixtures and does not invoke a coding-agent model. A successful targeted retrieval means only that the fixture's expected marker was found. It is not a measure of answer quality, search relevance in a real repository, token cost, or end-to-end task completion. Use representative, privacy-reviewed tasks for those questions and report the fixture, seed, repetition count, success rate, useful-search rate, byte measurements, and local timing separately.
For a reproducible local diagnostic, start the server with
EPHEMERAL_METRICS=1, exercise the workflow, then request
get_runtime_diagnostics() and get_buffer_stats(). A safe bug report
includes the version/commit, Python/platform, configuration limits, operation
name, reproduction steps, and sanitized metric output; it excludes captures,
credentials, tokens, private paths, source code, user data, and raw queries.
See OPERATIONS.md for deployment settings, troubleshooting, release verification, and repository maintenance procedures.
🛠 Testing the Server
Set up a local development environment from a fresh checkout:
python3.12 -m venv .venv
.venv/bin/python -m pip install --require-hashes -r requirements-dev-lock-py312.txtThe committed requirements-dev-lock-py312.txt file is the reproducible
Python 3.12 development and release environment. Python 3.10 remains
supported through the direct requirements and tested constraints.txt file;
the CI matrix exercises both paths. Keep requirements.txt and
requirements-dev.txt as the reviewable dependency inputs, and regenerate the
Python 3.12 locks with pip-tools after an intentional dependency update:
.venv/bin/python -m pip install pip-tools
.venv/bin/pip-compile --generate-hashes --output-file=requirements-lock-py312.txt requirements.txt
.venv/bin/pip-compile --generate-hashes --output-file=requirements-dev-lock-py312.txt requirements-dev.txtReview the resulting changes, run the full test matrix, and run pip-audit
before merging. Downstream users install the package normally; its compatible
dependency ranges in pyproject.toml are intentionally not replaced by the
development locks.
Run the test suite:
.venv/bin/python -m unittest test_benchmark_warmup.py test_engine.py test_capture_utils.py test_config.py test_cli.py test_server.py test_execution.py test_execution_server.py
.venv/bin/python -m unittest test_e2e_pipe.pyMeasure focused-test coverage locally:
.venv/bin/python -m coverage run --source=. --omit='test_*.py,setup.py,benchmark_concurrency.py,benchmark_effectiveness.py,benchmark_latency.py,benchmark_warmup.py,benchmark_agent_ab_repository_fixture.py,release_checks.py' -m unittest test_benchmark_concurrency.py test_benchmark_effectiveness.py test_benchmark_warmup.py test_release_checks.py test_benchmark_agent_ab_repository_fixture.py test_engine.py test_capture_utils.py test_config.py test_cli.py test_server.py test_execution.py test_execution_server.py
.venv/bin/python -m coverage reportCI requires 100% coverage for application runtime modules and excludes test, benchmark, release-check, and packaging-metadata files from that gate. Coverage reports are uploaded for inspection, and new runtime paths should include targeted tests. The release guardrail utility is measured separately because it is a workflow utility rather than application runtime code:
COVERAGE_FILE=.coverage.release .venv/bin/python -m coverage run --source=. -m unittest test_release_checks.py
COVERAGE_FILE=.coverage.release .venv/bin/python -m coverage report --include='release_checks.py'GitHub Actions runs the compile check, focused tests, and end-to-end test on
Python 3.10 and 3.12 for pushes to main and pull requests. The FastEmbed
model is loaded on the first capture or semantic search rather than during
server import. Set EPHEMERAL_EMBEDDING_MODEL to select a compatible model and
EPHEMERAL_FASTEMBED_CACHE_DIR to control its cache directory. The model cache
is retained between CI runs to reduce startup time. CI unit and end-to-end
tests set the internal EPHEMERAL_TEST_EMBEDDINGS=1 flag, which uses a small
deterministic embedding substitute so test execution does not depend on a
model download; release and benchmark jobs continue to exercise FastEmbed.
It also builds the wheel and verifies the installed ephbuf entry point.
CI audits the declared dependencies with pip-audit and fails if known
vulnerabilities are found.
CI installs the hashed Python 3.12 development/runtime locks and uses the
tested constraints.txt path for Python 3.10. The direct requirements and
constraints are updated only after the full test matrix passes; lock updates
must be reviewed together with their resolver output and audit results.
Pushing a version tag such as v0.1.1 runs the release workflow, which first
verifies that the tag is valid SemVer, points to a commit contained in the
default branch, and starts from a clean checkout. It also requires the tag,
pyproject.toml, and a dated matching CHANGELOG.md section to agree. The
workflow then builds wheel and source distributions, validates their metadata,
verifies the installed package, and uploads the artifacts for review. A failed
guardrail reports the mismatched value or source-state problem before building.
The workflow creates a GitHub Release using the matching changelog section,
attaches the wheel, source distribution, and SHA256SUMS, and links back to
the workflow run containing the build-provenance attestation. Verify a
downloaded artifact with sha256sum --check SHA256SUMS from the directory
containing the files. The same verified distributions are then published to
PyPI through trusted publishing.
After the repository's pypi environment is configured with a PyPI trusted
publisher, the workflow publishes the distributions to PyPI automatically.
Run the concurrency benchmark:
.venv/bin/python benchmark_concurrency.py --captures 32 --workers 8The benchmark accepts --min-ingest-per-second and --min-reads-per-second
thresholds for direct checks. For repeatable regression checks, pass
--baseline benchmark_baseline.json --output benchmark-concurrency.json.
The checked-in baseline uses a 20% tolerance: a run fails only when ingest or
read throughput drops below 80% of its baseline. Each scheduled or manually
dispatched GitHub Actions run records the raw JSON result as an artifact and
adds the measurements and regression status to the workflow summary. This
benchmark remains optional and is not part of the required pull-request checks;
update the baseline deliberately when the runner or benchmark workload changes.
Measure command-capture latency by output size and pipeline phase:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_latency.py \
--samples 5 --output benchmark-latency.jsonThe latency harness reports cold-start time plus warm median and p95 timings for command execution, BM25 capture/indexing, deferred semantic indexing, summary generation, and the combined pipeline. Semantic embeddings are now materialized when semantic or hybrid search first needs them, so the warmup explicitly materializes the warm engine's embeddings before timed samples begin. Use the separate semantic-index phase when evaluating end-to-end costs; cold start includes the first engine's model and embedding setup, while warm samples reuse the configured model cache and engine. The benchmark is diagnostic and optional, not a required pull-request check.
Compare lazy semantic indexing with the default asynchronous prefetch:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_prefetch.py \
--line-count 256 --samples 5 --output benchmark-prefetch.jsonThe prefetch harness reports ingestion, first semantic search, and subsequent semantic search medians for both modes. Prefetch can reduce first-query latency when work completes during ingestion, while adding bounded background resource use. In the release-preparation 256-line Linux run, first-search median changed from 0.435 seconds without prefetch to 0.425 seconds with it, while ingestion changed from 1.19 ms to 1.63 ms; treat this as deployment-specific diagnostic evidence rather than a guaranteed improvement.
Measure semantic indexing cost and first hybrid-search latency by capture size:
.venv/bin/python benchmark_semantic_index.py \
--samples 3 --output benchmark-semantic-index.jsonThe semantic-index harness ingests a fresh deterministic log-like capture per
sample, then reports median and p95 timings for ingestion, lazy embedding
materialization, the first hybrid (or --mode semantic) search that triggers
it, and a subsequent search over the complete index, plus chunk count and
indexing throughput. The first search runs against the semantic wait budget
(--semantic-wait-seconds, default EPHEMERAL_SEMANTIC_WAIT_SECONDS or 10),
so the report shows how often it answered with pending semantic coverage
(first_search_pending_rate) and the needle rank it achieved
(first_search_needle_mrr) next to the rank over the complete index
(needle_mrr); pass --semantic-wait-seconds inf to time the full lazy
indexing cost inside the first search instead. Default sizes are 16, 256,
2,048, and 8,192 lines. Run it without EPHEMERAL_TEST_EMBEDDINGS=1 to measure
the configured FastEmbed model; with deterministic test embeddings it only
validates the harness. Prefetch and startup warm-up are disabled inside the
harness so the lazy cost is visible. Results are host-specific diagnostic
evidence, not a required CI gate.
For a release comparison, record the same workload under each model and compare the selected run with the versioned result tool:
.venv/bin/python benchmark_semantic_index.py \
--embedding-model BAAI/bge-small-en-v1.5-fp32 --line-counts 1024 --samples 3 \
--result results/fp32.result.json --experiment embedding-model \
--metadata variant=fp32 --metadata host_class=linux-x86_64
.venv/bin/python benchmark_semantic_index.py \
--embedding-model BAAI/bge-small-en-v1.5 --line-counts 1024 --samples 3 \
--result results/catalogue.result.json --experiment embedding-model \
--metadata variant=catalogue --metadata host_class=linux-x86_64
.venv/bin/python compare_workload_results.py \
results/fp32.result.json#lines-1024 results/catalogue.result.json#lines-1024 \
--statistic median --metric semantic_index --metric throughput_per_secondKeep result documents together with the release benchmark artifacts. Compare results only within the same host class and record model, thread, chunking, prefetch, warm-up, and wait-budget settings; do not treat a different host as a regression.
Compare lazy model loading with background startup warm-up:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_warmup.py \
--samples 5 --output benchmark-warmup.jsonThe warm-up harness reports engine initialization, time to embedding readiness, first semantic-search latency, and process RSS change for both policies. For the lazy policy, embedding readiness is measured through completion of the first semantic search rather than reported as instantaneous. Run it without deterministic test embeddings to measure the configured FastEmbed model and host cache; each policy is measured in a fresh worker process so model pages retained by the allocator do not contaminate the other policy. In the release-preparation Linux run, first-search median was 0.335 seconds without warm-up versus 0.0122 seconds with warm-up, with approximately 186 MB RSS increase in both modes. Results are deployment-specific and the benchmark is optional.
Measure direct-versus-captured routing tradeoffs with synthetic output profiles:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_routing.py \
--samples 5 --output benchmark-routing.jsonThe routing harness compares direct command completion with bounded capture and
summary generation for targeted (16 lines), test-like (256 lines), and
build/log-like (2048 lines) output. Use the medians and p95 values to keep the
heuristic honest: direct execution generally has lower latency for small,
bounded output, while capture adds searchable context and bounded response
size for noisy or uncertain output. These synthetic measurements are guidance,
not universal thresholds or a required CI gate. Both benchmark summaries use
the nearest-rank p95 convention: for n samples, p95 is the value at sorted
rank ceil(0.95 * n), with ranks starting at one.
Measure command-output handling effectiveness with deterministic synthetic data:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_effectiveness.py \
--mode both --output benchmark-effectiveness.jsonThe effectiveness harness compares a full-output baseline with an engine-backed MCP workflow across large output, failure logs, diffs, and follow-up searches. It reports per-scenario success, search usefulness, retrievals, bytes examined, resolution time, and an aggregate comparison as machine-readable JSON. Token usage is explicitly marked unavailable because this harness does not invoke a model. Fixtures contain no project content and are generated in code, so runs are reproducible. This is a server-side smoke evaluation, not a claim about any particular coding agent or model.
Evaluate search relevance across supported modes with deterministic synthetic fixtures:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_relevance.py \
--top-k 3 --baseline benchmark_relevance_baseline.json \
--output search-relevance.jsonThe relevance benchmark covers exact errors, punctuation-heavy queries,
conceptual semantic queries, and lexical/semantic conflicts. It reports
hit@1, hit@k, and mean reciprocal rank (MRR) for BM25, semantic, and hybrid
search. The fixtures define expected retrieval markers, so this measures
retrieval relevance only—not agent answer quality, token usage, or universal
performance. CI compares the deterministic scores with the checked-in
benchmark_relevance_baseline.json and fails only when a metric drops by more
than the recorded tolerance. Baseline changes must be deliberate, reviewable,
and accompanied by a fixture or intended-behavior explanation. The evaluation
uploads its machine-readable JSON result with the other benchmark artifacts.
The baseline stores only schema and fixture versions, deterministic embedding mode, aggregate per-mode scores, query counts, and explicit tolerances. It does not store captures, raw command output, or user queries. Environment-specific latency and effectiveness results remain CI artifacts and summaries rather than exact cross-run gates; retention follows the workflow artifact policy.
Example benchmark results
The reproducible paired evaluation was run on 2026-09-11 with five
repetitions, seed 20260907, and deterministic test embeddings. Across four
synthetic scenarios, both the direct-output baseline and the MCP workflow
completed all 20 tasks, and every MCP search was useful. The MCP workflow
examined 30–85% fewer bytes than the baseline per scenario (68% on average):
Scenario | Bytes examined reduction | Completion |
Large build output | 85% | 5/5 |
Failure log | 77% | 5/5 |
Review diff | 30% | 5/5 |
Timeout log | 79% | 5/5 |
The consolidation evaluation, using the same seed and five repetitions, reduced the initial multi-result overview from an average of 4,298 bytes to 213 bytes (95% fewer overview bytes), while preserving a 100% targeted retrieval success rate. The consolidated workflow retrieved 3.6% fewer bytes overall and took 2.2 times as long locally as sequential processing in this run. These measurements quantify the MCP data path: fewer bytes need to be returned to the agent before it asks for targeted detail.
They are not universal performance guarantees. The fixtures are synthetic, the harness does not invoke a model, and the byte reduction is not a direct token-savings measurement. In this run, consolidated processing took about 2.2 times longer locally than sequential processing, while retrieving similar detail. The benchmark therefore demonstrates context-size and workflow-shaping benefits, not that every workload will be faster or that search results will be relevant for arbitrary repositories. Re-run the commands below with representative, privacy-reviewed tasks before making project-specific claims.
Run a controlled local A/B evaluation with repeated paired measurements:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_effectiveness.py \
--ab-runs 5 --seed 20260907 --output benchmark-effectiveness-ab.jsonThe A/B report uses the same deterministic fixtures in both modes, seeded task and mode ordering, and local-only measurements. It reports completion rate, mean/min/max time, standard deviation, repeated commands, search usefulness, byte reduction, and local MCP processing overhead for each scenario. The timing ratio covers only local capture, indexing, search, and retrieval; it is not an agent-level performance measurement. Since no model is invoked, token usage is unavailable. Treat the recommendations as synthetic benchmark guidance and repeat the evaluation with representative agent tasks before generalizing the results.
For an end-to-end coding-agent evaluation, generate a counterbalanced, privacy-safe schedule:
.venv/bin/python benchmark_agent_ab.py \
--schedule-output agent-ab-schedule.json --repetitions 5 --seed 20260909Run each scheduled task with MCP disabled (control) and enabled (mcp) using
the same model configuration, repository fixture, environment, and reset policy.
Have an external agent adapter write a records envelope containing only the
schedule, non-secret protocol identifiers, and per-run fields: completion,
signal retrieval, duration, tool calls, repeated commands, context proxy bytes
(total plus prompt/output components), provider usage samples, and peak RSS
bytes sampled from that invocation's process. On hosts without a supported
per-process RSS interface, peak RSS is recorded as zero and should be treated
as unavailable. Summarize it with:
.venv/bin/python benchmark_agent_ab.py \
--records agent-ab-records.json --output agent-ab-summary.jsonThe analyzer validates balanced paired runs, reports per-mode aggregates and MCP-minus-control deltas with uncertainty, and emits recommendations. It does not invoke a model, require credentials, or accept raw prompts, transcripts, commands, captures, or user content. Do not commit agent records or generated captures; share only the aggregate summary after privacy review.
The repository includes a Codex CLI adapter for executing that protocol. It uses the requested model explicitly, creates a fresh fixture copy for every run, isolates control and MCP configuration, and writes metadata-only records. Create a private task manifest (do not commit it) with one prompt and optional signal marker for each scheduled task:
{
"tasks": {
"targeted-inspection": {"prompt": "Inspect the fixture and report the marker.", "signal_marker": "MARKER"},
"noisy-test-failure": {"prompt": "Run the fixture test and report the failure marker.", "signal_marker": "MARKER"},
"build-log-search": {"prompt": "Inspect the build log and report the marker.", "signal_marker": "MARKER"},
"follow-up-context": {"prompt": "Find the earlier marker and report it.", "signal_marker": "MARKER"}
}
}Run the adapter from the repository checkout:
.venv/bin/python run_codex_agent_ab.py \
--schedule agent-ab-schedule.json \
--tasks /path/to/private-agent-tasks.json \
--repository /path/to/privacy-reviewed-fixture \
--model gpt-5.6-luna \
--output /tmp/agent-ab-records.json
.venv/bin/python benchmark_agent_ab.py \
--records /tmp/agent-ab-records.json \
--output /tmp/agent-ab-summary.jsonThe runner requires a locally authenticated codex CLI. It uses
codex exec --json --ephemeral, uses a read-only sandbox by default. context_bytes_proxy is an observable prompt/event-envelope
proxy because the CLI does not expose the model's internal context size.
When the fixture does not contain an importable server module, pass
--mcp-server-script /absolute/path/to/server.py.
For MCP experiments where the client must be allowed to call the configured
server, add --allow-mcp-approvals. This uses Codex automatic review with a
workspace-write sandbox, and should only be used with a disposable,
privacy-reviewed fixture. Control runs continue to use the read-only sandbox
without MCP approval routing; the records protocol identifies the selected
policy. Add --require-mcp-calls when the MCP arm must exercise at least one
MCP tool; runs that bypass MCP are then marked incomplete with reason
mcp_not_used.
Review prompts, fixtures, and generated records for privacy before sharing;
the runner does not persist transcripts in its records output.
Runner records use version 5 and add exit code, failure reason, MCP-specific tool-call count, provider-reported input/output token counts, and every provider usage sample when Codex emits them. They also break the observable context proxy into prompt and output byte components. Version-1 through version-4 records remain readable; missing provider metrics are reported as unavailable rather than zero. Version-5 MCP records additionally include content-free session data-path byte counters for capture input/retention, tool/search/retrieval responses, and framed socket traffic. The adapter enables local metrics for MCP runs and collects the server snapshot after each run; missing snapshots are represented as zero counters and should be treated as unavailable when diagnosing a failed run. Summaries also report usage sample counts, monotonicity observations, and first-to-last deltas. Monotonic samples are explicitly inconclusive: they may be cumulative or per-turn values and require a controlled calibration matrix.
Generate the reviewed synthetic EB-heavy fixture and its task manifest with:
.venv/bin/python benchmark_agent_ab_fixtures.py \
--fixture-output /tmp/agent-ab-fixture \
--manifest-output /tmp/agent-ab-tasks.jsonThe fixture generates large test and build output at runtime, plus a small targeted-output task and a follow-up retrieval task. The manifest includes output-size bands, expected signals, and objective success criteria. It is synthetic and contains no user logs or captured output.
For a repository-shaped evaluation, set AGENT_AB_FIXTURE_PROFILE:
AGENT_AB_FIXTURE_PROFILE=repository-shaped-v1 \
CODEX_HOME=/path/to/writable/authenticated-codex-home \
./run_agent_ab_experiment.shThis profile contains source, tests, configuration, and repository workflow tooling. Its test and build commands inspect that layout while producing deterministic noisy signals. It is still synthetic and privacy-safe; it does not contain a production repository or user data.
Repeat the complete five-repetition Codex A/B run with the repository script.
Set CODEX_HOME to a writable, authenticated Codex home; generated fixtures,
records, and lifecycle logs remain under /tmp by default:
CODEX_HOME=/path/to/writable/authenticated-codex-home \
./run_agent_ab_experiment.shOverride AGENT_AB_RUN_DIR, AGENT_AB_MODEL, AGENT_AB_REPETITIONS,
AGENT_AB_SEED, AGENT_AB_TIMEOUT_SECONDS, or AGENT_AB_TEST_EMBEDDINGS to
repeat a different experiment. The script also writes
records.result.json and summary.result.json in the common workload result
format; set AGENT_AB_EXPERIMENT and AGENT_AB_VARIANT to assign them to an
experiment group (see "Organizing experiments"). The test embedding setting defaults to 1 for
deterministic, offline runs; set it to 0 to exercise the configured FastEmbed
model and measure real model startup and first-query behavior. Keep the model,
embedding cache, and other environment settings identical across paired runs.
The script uses the synthetic fixture by default; set
AGENT_AB_FIXTURE_PROFILE=repository-shaped-v1 for the repository-shaped
synthetic profile. Use the lower-level runner commands above for a
privacy-reviewed production-repository fixture and private task manifest.
Create and compare an aggregate agent A/B baseline after a privacy review:
.venv/bin/python benchmark_agent_ab_baseline.py \
--summary /tmp/agent-ab-summary.json \
--create-baseline \
--output benchmark_agent_ab_baseline.json
.venv/bin/python benchmark_agent_ab_baseline.py \
--summary /tmp/agent-ab-summary.json \
--baseline benchmark_agent_ab_baseline.json \
--fail-on-regression \
--output /tmp/agent-ab-comparison.jsonThe baseline stores agent and embedding model configuration, embedding mode and cache, fixture, seed, repetition, aggregate metrics, and explicit tolerances only. It never stores prompts, transcripts, commands, captures, or user content. This comparison is a documented manual workflow; live model calls are not part of required pull-request CI. Update a checked-in baseline only when fixture or model changes are explained in review.
The current agent-level evaluation supports a provisional routing policy: prefer MCP for large noisy output and follow-up retrieval, and prefer direct execution for small targeted inspections. Do not treat this as a universal default or convert it into hard numeric thresholds yet. The repository-shaped profile is synthetic, so production-repository behavior should be validated separately before generalizing the result. Provider-reported token deltas are diagnostic until a calibration matrix establishes whether usage samples are cumulative or per-turn.
Compare sequential per-capture retrieval with the consolidated workflow:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_effectiveness.py \
--consolidation-runs 5 --seed 20260907 \
--output benchmark-effectiveness-consolidation.jsonThis report measures overview and retrieval response bytes, targeted retrieval success, search/retrieval counts, local processing time, and omitted records. It models each synthetic scenario as a repository result and does not invoke a coding-agent model; response-byte reductions therefore describe the MCP data path, not end-to-end agent performance.
When sharing a result, include the command, seed, repetitions, benchmark evaluation name, success rate, useful-search rate, byte reduction, and timing scope. Do not attach generated captures or paste raw command output. Check any surrounding report or wrapper for repository-specific content before sharing the benchmark JSON.
Machine-readable workload results
Every benchmark, evaluation, and the Codex A/B runner can emit one common,
versioned JSON document in addition to its own report and --output record.
Pass --result PATH to write it to a file, or --result - to print it on
stdout; the human-readable report then moves to stderr so stdout stays valid
JSON:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_latency.py \
--samples 3 --result benchmark-latency.result.json
.venv/bin/python benchmark_semantic_index.py --samples 3 --result - > semantic-index.result.json
.venv/bin/python workload_results.py benchmark-latency.result.json semantic-index.result.jsonThe document is a coding-agent-workload-result (format version 1). It is
tool- and task-agnostic: it records what was measured, never how, so a
consumer does not need to know about embeddings, BM25, or any other producer
mechanism. The reference validator is workload_results.py (also usable as a
CLI, as above) and the same contract is published as JSON Schema in
workload_result.schema.json.
{
"format": "coding-agent-workload-result",
"format_version": 1,
"workload": {"name": "capture-latency", "kind": "benchmark",
"producer": "benchmark_latency.py",
"parameters": {"line_counts": [16, 256, 2048], "samples": 3}},
"environment": {"python_version": "3.12.14", "platform": "...",
"cpu_count": 8, "recorded_at": "2026-09-18T15:00:00+00:00",
"tool": {"name": "ephemeral-buffer-mcp", "version": "0.4.0"},
"source_revision": "..."},
"status": "success",
"errors": [],
"measurements": {},
"runs": [
{"id": "lines-256",
"labels": {"cache_state": "warm", "line_count": 256},
"status": "success",
"measurements": {
"output_bytes": {"unit": "bytes", "value": 3840},
"wall_time_seconds": {"unit": "seconds", "median": 0.012, "p95": 0.015, "samples": 3}},
"phases": [
{"name": "command", "unit": "seconds", "median": 0.004, "p95": 0.005, "samples": 3},
{"name": "ingest", "unit": "seconds", "median": 0.006, "p95": 0.008, "samples": 3}],
"errors": []}
],
"experiment": {"group": "chunk-sweep",
"metadata": {"variant": "chunk-8", "model": "bge-small-fp32"}},
"details": {"...": "the producer's own record, for humans"}
}workload.nameidentifies the measurement andworkload.parametersholds everything needed to repeat it (sizes, seeds, modes, option overrides);environmentexplains why two results may legitimately differ.Each run is one comparable unit of work with a stable
id, descriptivelabels(cache_state,mode,task_id,repetition,line_count,profile, ...), astatusofsuccess,failure,timeout,error, orpartial, and its ownerrors. Failed, timed-out, and partial runs are kept with their status rather than dropped.A measurement has a
unit(seconds,bytes,count,tokens,ratio,per_second, orscore) and one or more statistics (value,sum,mean,median,min,max,p95,stdev), optionally with the number ofsamplesand anoteexplaining a proxy.nullmeans the statistic is unavailable, never zero.phasesis an ordered timeline ofsecondsmeasurements.Canonical names such as
wall_time_seconds,queue_wait_seconds,tool_calls,output_bytes,context_bytes,estimated_tokens,retained_summary_tokens,input_tokens,output_tokens,peak_rss_bytes,rss_delta_bytes,success_rate, andthroughput_per_secondpin their unit so results from different producers line up; producers add their own names beside them. The JSON Schema pins those units too.Run
ids are unique within a document. JSON Schema cannot express that rule (itsuniqueItemsonly rejects fully identical runs), so a consumer that validates with the schema alone must check ids itself or runworkload_results.pyon the document first.detailscarries the producer's native record for people who need it; its shape is producer-specific and versioned separately byworkload.producer_schema_version.The optional experiment block assigns the document to a named
groupof related runs and carries flatmetadata(scalar values only) describing what varied; see "Organizing experiments" below. Every producer accepts--experiment GROUP,--metadata KEY=VALUE(repeatable; values parse as JSON when possible), and--redact KEY.
OPERATIONS.md describes how comparison tooling and regression checks should
consume these documents. The shared format is not a privacy exemption: apply
the same review to a result file as to any other benchmark output before
sharing it.
Comparing workload results
compare_workload_results.py compares two or more result documents without
rerunning anything. The first reference is the baseline and every later one is
compared against it. For each run and measurement the documents share it
prints the absolute delta, the percentage change, and an outcome; runs pair by
id, measurements and phases by name, and every statistic is compared only
with the same statistic (median against median, never against mean).
The example below records a baseline, halves the semantic chunk size, and
compares the two:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_latency.py \
--samples 3 --line-counts 256 2048 --result before.result.json
EPHEMERAL_TEST_EMBEDDINGS=1 EPHEMERAL_SEMANTIC_CHUNK_LINES=2 .venv/bin/python benchmark_latency.py \
--samples 3 --line-counts 256 2048 --result after.result.json
.venv/bin/python compare_workload_results.py before.result.json after.result.json \
--tolerance 5 --statistic median --metric wall_time_seconds --metric ingest --metric semantic_indexworkload: capture-latency
baseline: before.result.json producer=benchmark_latency.py kind=benchmark status=success runs=3 recorded=2026-09-18T18:16:11+00:00 python=3.12.14 tool=ephemeral-buffer-mcp 0.4.0 revision=2b58f2490571
candidate: after.result.json producer=benchmark_latency.py kind=benchmark status=success runs=3 recorded=2026-09-18T18:16:28+00:00 python=3.12.14 tool=ephemeral-buffer-mcp 0.4.0 revision=2b58f2490571
statistics=median tolerance=5% metrics=ingest,semantic_index,wall_time_seconds
before.result.json -> after.result.json
run metric stat baseline candidate delta change outcome
lines-256 wall_time_seconds median 0.009854 s 0.01054 s +0.0006824 s +6.9% regressed
lines-256 phase:ingest median 0.0007052 s 0.0007507 s +4.546e-05 s +6.4% regressed
lines-256 phase:semantic_index median 0.0008512 s 0.002113 s +0.001262 s +148.3% regressed
lines-2048 wall_time_seconds median 0.02084 s 0.02982 s +0.008981 s +43.1% regressed
lines-2048 phase:ingest median 0.002724 s 0.002792 s +6.775e-05 s +2.5% unchanged
lines-2048 phase:semantic_index median 0.006279 s 0.01706 s +0.01078 s +171.6% regressed
summary: 0 improved, 5 regressed, 0 changed, 1 unchanged, 0 missing, 0 incompatible; runs compared=3 missing=0; status success -> successThe phase rows attribute the wall-time regression to semantic indexing rather than ingestion. Outcomes are:
improvedorregressed: the value moved beyond--tolerance PERCENT(default 0) in the metric's better or worse direction. Canonical measurements know their direction (time, bytes, tokens, tool calls, and memory are better lower;success_rateand throughput are better higher); otherseconds,bytes,tokens, andper_secondmetrics follow their unit, and--direction NAME=lower|higherdeclares the rest.changed: the value moved but the metric has no known direction, such as a producer-specificcount,ratio, orscore. A change from a zero baseline has no percentage and counts as beyond any tolerance.unchanged: within the tolerance.missing: the run, measurement, or statistic is absent,null, or hassamples: 0on at least one side. These are listed with the side that lacks them, never silently skipped.incompatible: both sides report the metric with different units.
Documents must describe the same workload.name unless
--allow-workload-mismatch is given, and each comparison lists the
workload.parameters and environment fields that differ (CPU count, tool
version, source revision) so a different setup is not mistaken for a
regression. Non-success runs appear with their status and errors.
PATH#RUN_ID selects one run from a document. When the baseline and a
candidate each select a single run, those two runs pair even though their ids
differ, which compares two configurations recorded in the same document:
# Agent configurations: control versus MCP in one A/B summary, or two
# agent-run documents recorded under different models or policies.
.venv/bin/python benchmark_agent_ab.py --records runs.json --result summary.result.json
.venv/bin/python compare_workload_results.py summary.result.json#control summary.result.json#mcp --statistic mean
.venv/bin/python compare_workload_results.py codex-gpt5.result.json codex-candidate.result.json \
--select mode=mcp --metric input_tokens --metric output_tokens --metric wall_time_seconds --metric tool_calls
# Tool-output policies: the same latency workload under two server settings.
EPHEMERAL_SEMANTIC_PREFETCH=0 .venv/bin/python benchmark_latency.py --result lazy.result.json
.venv/bin/python benchmark_latency.py --result prefetch.result.json
.venv/bin/python compare_workload_results.py lazy.result.json prefetch.result.json --metric wall_time_seconds
# Summarization strategies: retained-summary size and prompt-token proxies per
# task; the reduction ratios need an explicit direction.
.venv/bin/python benchmark_effectiveness.py --summary --result summary-a.result.json
.venv/bin/python compare_workload_results.py summary-a.result.json summary-b.result.json \
--metric retained_summary_tokens --metric estimated_tokens --metric summary_token_reduction \
--direction summary_token_reduction=higher--select KEY=VALUE keeps only runs whose label matches (values parse as JSON
when possible, so line_count=256 compares a number), --metric NAME limits
the report to named measurements or phases, and --statistic NAME chooses the
statistics (default value, median, mean, and p95; all adds sum,
min, max, and stdev; stdev describes spread rather than level, so its
changes are reported as changed and never judged). --format json prints,
and --output PATH writes, a coding-agent-workload-comparison document
(format version 1) with the same entries plus each document's workload and
environment blocks. --check exits with status 2 when any metric regressed or
any document has a non-success status, which OPERATIONS.md uses for
regression checks. A document narrowed with PATH#RUN_ID or --select is
judged by its selected runs, and the report shows the whole file's
document_status beside it when the two differ.
Organizing experiments
A performance or token-efficiency study is rarely one comparison: a chunk-size
sweep, a model change, or a prompt-policy A/B produces several result
documents whose relationship is otherwise only in their file names. Every
producer therefore accepts --experiment GROUP to assign its result document
to an experiment or run group, and --metadata KEY=VALUE to record what
varied. The workflow is: tag each run when it is recorded, list the group to
see what exists and which runs failed, and compare documents by group and
metadata instead of by path.
Record. Give every run of one study the same group and describe the
variable under test in metadata. Conventional keys are task_type,
repository_revision, agent_configuration, model, tool_version,
variant, environment, workload_size, and started_at; any other
snake_case key is allowed. Values are identifiers (at most 256 characters),
never prompts or captured content, and started_at must be an ISO 8601
timestamp with a UTC offset (2026-09-18T10:00:00+00:00 or a trailing Z)
so documents order by instant. A value that breaks these rules is rejected
when the arguments are parsed, before the workload runs:
EPHEMERAL_TEST_EMBEDDINGS=1 .venv/bin/python benchmark_latency.py --samples 3 --line-counts 256 \
--result results/chunk-8.result.json --experiment chunk-sweep \
--metadata variant=chunk-8 --metadata model=bge-small-fp32
EPHEMERAL_TEST_EMBEDDINGS=1 EPHEMERAL_SEMANTIC_CHUNK_LINES=4 .venv/bin/python benchmark_latency.py --samples 3 --line-counts 256 \
--result results/chunk-4.result.json --experiment chunk-sweep \
--metadata variant=chunk-4 --metadata model=bge-small-fp32
EPHEMERAL_TEST_EMBEDDINGS=1 EPHEMERAL_SEMANTIC_CHUNK_LINES=16 .venv/bin/python benchmark_latency.py --samples 3 --line-counts 256 \
--result results/chunk-16.result.json --experiment chunk-sweep \
--metadata variant=chunk-16 --metadata model=bge-small-fp32For coding-agent runs, run_agent_ab_experiment.sh tags both of its result
documents (records.result.json and summary.result.json) with the model,
fixture profile, repetition count, embedding environment, and start time, and
takes the group from AGENT_AB_EXPERIMENT and the variant from
AGENT_AB_VARIANT:
AGENT_AB_EXPERIMENT=policy-ab AGENT_AB_VARIANT=summarize-first \
CODEX_HOME=/path/to/writable/authenticated-codex-home ./run_agent_ab_experiment.shList. list_workload_results.py searches files and directories
(recursively) for result documents, ignores other JSON files such as records
and schedules, and prints one row per document with its group, status, run
count, time, and metadata. --group NAME and --where KEY=VALUE filter by
group and metadata, --workload NAME and --status STATUS narrow further,
--field KEY shows chosen metadata keys as columns, and --runs lists every
run with its labels and status so failed, timed-out, and partial runs inside a
document are visible:
.venv/bin/python list_workload_results.py results --field variant --field modelpath group workload status runs time variant model errors
results/chunk-8.result.json chunk-sweep capture-latency success 2 2026-09-18T18:52:02+00:00 chunk-8 bge-small-fp32
results/chunk-16.result.json chunk-sweep capture-latency success 2 2026-09-18T18:52:03+00:00 chunk-16 bge-small-fp32
results/chunk-4.result.json chunk-sweep capture-latency success 2 2026-09-18T18:52:03+00:00 chunk-4 bge-small-fp32
results/prefetch.result.json - semantic-prefetch success 2 2026-09-18T18:52:04+00:00 - bge-small-fp32Rows are ordered by group, then by started_at metadata (or the recording
time when it is absent, both normalised to UTC), then by path. Documents that do not satisfy the
format are listed as invalid with the reason and make the command exit with
status 1, so a broken file is never mistaken for an absent one. --format json prints a coding-agent-workload-listing document whose entries carry
each document's group, metadata, status, errors, and per-run status, and
--format paths prints only the selected paths for shell substitution.
Compare. compare_workload_results.py accepts DIR@GROUP references
beside file references: the reference expands to every document under the
directory that belongs to the group, in the same order as the listing, and
DIR@GROUP,KEY=VALUE keeps only documents whose metadata matches. A lone
results@chunk-sweep compares every later document of the sweep against the
earliest; naming two selectors picks the baseline explicitly, and #RUN_ID
still selects one run from each document:
.venv/bin/python compare_workload_results.py results@chunk-sweep,variant=chunk-8 results@chunk-sweep,variant=chunk-4 \
--statistic median --metric wall_time_seconds --metric semantic_indexworkload: capture-latency
baseline: results/chunk-8.result.json group=chunk-sweep producer=benchmark_latency.py kind=benchmark status=success runs=2 recorded=2026-09-18T18:52:02+00:00 python=3.12.14 tool=ephemeral-buffer-mcp 0.4.0 revision=0a9e8da36b46
candidate: results/chunk-4.result.json group=chunk-sweep producer=benchmark_latency.py kind=benchmark status=success runs=2 recorded=2026-09-18T18:52:03+00:00 python=3.12.14 tool=ephemeral-buffer-mcp 0.4.0 revision=0a9e8da36b46
statistics=median tolerance=0% metrics=semantic_index,wall_time_seconds
results/chunk-8.result.json -> results/chunk-4.result.json
experiment differences: variant: "chunk-8" -> "chunk-4"
run metric stat baseline candidate delta change outcome
lines-256 wall_time_seconds median 0.0159 s 0.01414 s -0.00176 s -11.1% improved
lines-256 phase:semantic_index median 0.001104 s 0.001814 s +0.0007096 s +64.3% regressed
summary: 1 improved, 1 regressed, 0 changed, 0 unchanged, 0 missing, 0 incompatible; runs compared=2 missing=0; status success -> successThe report and the JSON comparison show the group beside each document and
list the metadata that differs (experiment differences) next to the
parameter and environment differences, so a delta can be read together with
the variable that caused it. Selector values may not contain commas; a value
containing @ is fine because only the first @ separates the directory from
the group. A group reference fails on an invalid document only when that
document claims the requested group; stale or broken files in other groups do
not block the comparison (the listing still reports them). Several group
references into one directory scan it once.
Sensitive metadata. Metadata keys that name credentials (token, key,
password, secret, credentials, authorization, bearer, or any
*_token or *_key) are stored as [redacted] by every producer, the
validator rejects a document that carries a real value under such a key, and
--redact KEY stores [redacted] for any other key whose value should not
leave the machine (the key stays visible so readers know it was set). The
listing tool's --redact KEY masks a value in its output without changing the
file. Metadata that should not be recorded at all is simply not passed; the
result format is still not a privacy exemption, so review documents before
sharing them as with any other benchmark output.
Available Tools
18 toolscapture_fileA
Reads a file or log output from disk and ingests it into the ephemeral
search index. Returns a compact versioned JSON summary and preserves
optional named metrics in structured_metrics.
Validate the intended file path before calling: resolve symlinks when path
identity matters, confirm the file belongs to the expected workspace, and
use an explicit bounded max_bytes for large or untrusted files. Capture
limits control output handling; they do not validate filesystem intent.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | ||
| file_path | Yes | ||
| max_bytes | No | ||
| content_type | No | auto | |
| structured_metrics | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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, and it handles this well: it discloses what the tool does (ingests into ephemeral search index), what it returns (compact versioned JSON summary), what it preserves (named metrics in structured_metrics), and an important nuance about limit semantics not validating filesystem intent. It doesn't describe error behavior or what happens on oversized files, but the provided behaviors are disclosed.
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 focused paragraphs with the primary purpose front-loaded in the first sentence. The second paragraph earns its place by conveying safety-critical file-handling guidance. No filler or repetition of the schema; every sentence contributes new information, though it could be slightly tightened.
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 5 parameters, an output schema (which covers the return format), and no annotations. The description adequately covers purpose, return behavior, and file-path validation, but leaves label and content_type semantics unexplained. For a file-ingestion tool with output schema present, it's close but not fully complete—an agent might misuse label or content_type without schema-level descriptions.
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 explicitly explains max_bytes ('use an explicit bounded max_bytes for large or untrusted files'), file_path (via the validation guidance), and structured_metrics ('preserves optional named metrics'). However, it never addresses label or content_type, leaving two of five parameters undocumented in both schema and description, so compensation is only partial.
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 ('Reads a file or log output from disk and ingests it') with a clear resource, distinguishing itself from siblings like capture_text (which would capture text directly) and execute_and_capture (which captures execution output). It also states the output format ('compact versioned JSON summary') and the optional structured metrics, making the tool's distinct purpose unambiguous.
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 second paragraph gives concrete pre-call guidance: resolve symlinks when path identity matters, confirm workspace membership, and use a bounded max_bytes for large/untrusted files. It also clarifies the boundary condition ('Capture limits control output handling; they do not validate filesystem intent'). It provides clear context for safe usage, though it doesn't explicitly name alternatives or state when NOT to use this tool in favor of a sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_textA
Ingest already-collected text and return capture metadata.
Use this when the caller already has output to index. For a noisy or
potentially long command, use execute_and_capture so output remains
bounded before it reaches the agent context. The return value is a compact
versioned JSON summary; optional named metrics are retained in
structured_metrics.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | ||
| content | Yes | ||
| content_type | No | auto | |
| structured_metrics | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It explains the return value (compact versioned JSON summary) and that structured_metrics are retained, but it never explicitly states the side effect of ingestion: whether the text is persisted to a capture store, becomes searchable, or has limits/idempotency behavior. Adds context but leaves the core storage behavior implied.
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 short sentences with the main purpose front-loaded, followed by usage guidance and return-value note. Slight redundancy between 'return capture metadata' and 'return value is a compact versioned JSON summary,' but the description earns each sentence and remains efficient.
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 4-parameter tool with no annotations and 0% schema coverage, the description covers the primary use case, a key alternative, and the return shape, and an output schema exists. It is incomplete on side effects and two parameters ('label', 'content_type'), which an agent needs to craft correct calls.
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 explain parameter meaning. It clarifies 'content' by referring to already-collected text and hints at 'structured_metrics' as optional named metrics, but 'label' and 'content_type' (including the 'auto' default) are never explained, leaving significant parameter semantics undocumented.
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 sentence states a concrete action ('Ingest already-collected text') and the result (return capture metadata), which distinguishes it from the sibling execute_and_capture. It names what input is expected and what the tool is not for (collecting output from command execution).
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?
Explicitly tells an agent when to use it ('when the caller already has output to index') and when to prefer execute_and_capture for noisy/long commands, with a reason (keeping output bounded before agent context). This routes the agent to the correct sibling without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_capturesA
Clears all or a specific capture from the ephemeral buffer to free memory.
| Name | Required | Description | Default |
|---|---|---|---|
| capture_id | No | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden and does reveal the main side effect ('Clears') and the underlying goal ('free memory'), as well as the ephemeral nature of the buffer. It stops short of stating irreversibility or the consequences of clearing all, though the ephemeral phrasing softens that gap.
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?
A single, front-loaded sentence with no filler. Every word adds meaning: the action, the target, the scope, and the purpose.
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 low-complexity tool with one optional parameter, an output schema, and no annotations, the description covers the action, scope, and purpose sufficiently. A minor gap is not explaining how to identify the specific capture, but the parameter schema and title provide enough context.
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%, so the description must compensate. It partially does by indicating that either 'all' or a specific capture can be cleared, which aligns with the default 'all' and the capture_id parameter name, but it does not explicitly explain how to supply a capture_id.
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 ('Clears') and resource ('capture from the ephemeral buffer') and explicitly covers the all-or-specific scope. It does not name a sibling for contrast, but no sibling appears to perform clearing, so the purpose is readily distinguishable.
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 phrase 'to free memory' gives an implicit usage context: use this tool when captures in the ephemeral buffer should be removed. However, it does not state when not to use it or compare it with related tools such as consolidate_captures or get_buffer_stats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
consolidate_capturesB
Create one bounded, searchable JSON capture from multiple captures.
The consolidated capture keeps source capture IDs and source line numbers. If records do not fit, the complete source captures remain available through their original IDs until normal LRU eviction. The operation fails if the consolidated capture cannot be admitted while retaining those sources.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | consolidated captures | |
| max_bytes | No | ||
| capture_ids | No | ||
| max_captures | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does a good job: it discloses that source capture IDs and line numbers are preserved, that sources remain reachable through their original IDs until LRU eviction, and that the operation fails if the consolidated capture cannot be admitted while retaining sources. What it does not clarify is whether the originals are ever removed by a successful consolidation, leaving a small ambiguity about destructiveness.
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 short sentences, front-loaded with the core action and then the retention and failure behavior. No filler, though the phrasing around admission failure is slightly heavy for the information conveyed.
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?
An output schema exists, so return values need no explanation, and the retention/failure semantics are covered. However, for a tool with four fully undocumented parameters, the description omits any guidance on capture_ids, max_captures, or max_bytes, which leaves a meaningful gap 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% across 4 parameters, so the description must compensate and largely does not. It hints at capture_ids ('from multiple captures') and max_bytes ('bounded', 'If records do not fit'), but never names or explains label, max_captures, or the size constraint semantics, leaving half the parameters undocumented in both places.
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 and resource: 'Create one bounded, searchable JSON capture from multiple captures.' That is clearly distinguishable from siblings like capture_text, capture_file, and search_capture. It stops short of naming a sibling or scoping when this is preferred, so it is clear but not maximally differentiated.
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?
Usage is only implied: the agent can infer this is the tool for merging several existing captures rather than creating one. There is no explicit statement of when to prefer it over capture_text/capture_file, nor any exclusions. Implied-but-unstated context warrants a 3.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_and_captureA
Runs a shell command, captures stdout/stderr, indexes it, and returns a compact versioned JSON summary without flooding the prompt context with thousands of lines. The summary includes status, duration, sizes, approximate token counts, truncation, signals, and optional named metrics.
Use this for noisy tests, builds, logs, and other output that benefits from
bounded capture and later search. Direct command execution is usually
faster for a small, targeted inspection; use capture once output may be
noisy, large, or uncertain. This is an advisory routing heuristic, not an
enforced threshold. Before running, verify the
command, intended repository, and working directory: an omitted cwd
inherits the server process directory, and symlinks or shell expansion can
target a different path than expected. This tool bounds output but does
not validate command intent, path identity, or filesystem safety.
Args: command: Shell command line to execute. cwd: Optional working directory for command execution; pass an explicit validated path for repository-sensitive commands. label: Optional human-readable description/label for this capture. content_type: Content type hint - 'auto' (default, detects diff/log/text), 'diff', 'log', or 'text'. max_output_bytes: Maximum command output retained (default: configured buffer byte limit). timeout_seconds: Optional maximum runtime; timed-out commands return exit code 124.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | ||
| label | No | ||
| command | Yes | ||
| content_type | No | auto | |
| timeout_seconds | No | ||
| max_output_bytes | No | ||
| structured_metrics | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden and succeeds: it warns that an omitted cwd inherits the server process directory, that symlinks/shell expansion can target unexpected paths, that it 'bounds output but does not validate command intent, path identity, or filesystem safety', and that timeouts return exit code 124. This is exemplary safety disclosure for a shell-execution tool.
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?
Purpose is front-loaded and every block earns its place — return contract, routing heuristic, safety warnings, then Args. It is longer than average, but the length is justified for a risky, 7-parameter shell tool; the structured_metrics omission in Args is the only structural blemish.
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 complex tool (7 params, output schema, high-risk shell execution, 17 siblings), the description covers purpose, routing, safety, return contents, and all parameters. An output schema exists so return-value details don't need duplication. The small remaining gaps are the unnamed direct-execution sibling and the unlisted structured_metrics parameter.
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 and largely does: command, cwd (with 'pass an explicit validated path' guidance), label, content_type (with its enum values listed), max_output_bytes, and timeout_seconds (with the 124 exit-code semantic) are all explained. The one gap is structured_metrics, which is only hinted at as 'optional named metrics' in the return summary and never appears in the Args list.
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?
Opens with a specific, multi-verb purpose ('Runs a shell command, captures stdout/stderr, indexes it, and returns a compact versioned JSON summary') tied to a concrete resource and a distinguishing behavior (bounded capture + indexing). The return contract (status, duration, sizes, token counts, truncation, signals) makes it unmistakable against siblings like get_execution_output or capture_text.
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?
Gives explicit when-to-use conditions ('noisy tests, builds, logs... bounded capture and later search') and an explicit when-not ('Direct command execution is usually faster for a small, targeted inspection'). Also frames it as an advisory heuristic rather than an enforced threshold, which prevents the agent from over-trusting the rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_buffer_statsB
Returns aggregate capture, accounting, prefetch, and process RSS metrics.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It implies a non-mutating read by saying 'Returns' and names the metric categories, but it does not mention side effects, freshness, performance cost, or any caveats. For a zero-parameter diagnostic this is adequate but not comprehensive.
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 a single sentence with no filler. It leads with the action and then lists the specific metric areas, making efficient use of every word.
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 simple, no-parameter read with an output schema present, the description is mostly sufficient. However, it leaves unresolved how this tool relates to get_runtime_diagnostics or when one should be preferred, creating mild contextual ambiguity for an agent choosing among sibling tools.
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 100% schema description coverage, so there is no parameter semantics to explain. The description adds nothing parameter-specific, but none is needed; this is the appropriate baseline for a parameterless tool.
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 a read operation ('Returns') and a specific resource: aggregate capture, accounting, prefetch, and process RSS metrics. It is more specific than the tool name alone, though it does not explicitly differentiate itself from the similarly diagnostic sibling get_runtime_diagnostics.
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?
There is no guidance on when to use this tool versus alternatives like get_runtime_diagnostics. No context is provided about typical scenarios, prerequisites, or why an agent would prefer this tool over a sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_capture_sliceA
Fetches an exact range of lines (1-indexed) from a capture to inspect full context around a match.
| Name | Required | Description | Default |
|---|---|---|---|
| end_line | Yes | ||
| capture_id | No | latest | |
| start_line | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavior disclosure burden. It does clarify that this is a non-mutating fetch, that lines are 1-indexed, and that the slice is exact. However, it does not mention the default 'latest' capture_id behavior, invalid-range handling, or what happens when the capture does not exist.
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?
A single sentence with no filler. The core action, resource, key constraint (1-indexed), and purpose are all front-loaded in an efficient way.
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 is adequate for a simple read-only slice operation, and the output schema covers return shape, but it lacks explicit routing among siblings and fails to mention capture_id default behavior or error conditions. It is usable but has clear gaps.
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 adds useful meaning for start_line and end_line by stating they define a 1-indexed exact range, but it never explains capture_id or its 'latest' default, leaving one of the three parameters under-specified.
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 concrete operation ('Fetches... range of lines'), the resource ('from a capture'), and the intended use ('inspect full context around a match'). The verb and scope distinguish it from sibling tools like search_capture, get_capture_summary, and list_captures even without explicitly 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?
The description implies usage after finding a match, so the context is fairly clear, but it does not explicitly state when to use this tool versus search_capture or list_captures, nor does it provide exclusions or alternatives. The guidance is implicit rather than direct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_capture_summaryA
Returns a compact versioned JSON summary. Set include_previews when
head and tail samples are needed; full output remains available through
get_capture_slice.
| Name | Required | Description | Default |
|---|---|---|---|
| capture_id | No | latest | |
| include_previews | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden. It conveys that the call is non-mutating ('Returns'), that output is a 'compact versioned JSON' format, and that the full output is deliberately excluded — useful behavioral context. It does not disclose error behavior for an unknown capture_id or any rate/availability constraints, though these matter less for a simple read.
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 with zero filler: the verb-resource purpose is front-loaded, and the parameter guidance plus sibling pointer follow immediately. Every clause carries information.
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?
An output schema exists, so return values are documented elsewhere and need not be repeated. The main gaps are capture_id, undocumented in both the schema (0% coverage) and the description, and the absence of annotations for safety signals; for a simple two-parameter read tool this is adequate but not thorough.
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 does for include_previews ('head and tail samples') but never mentions capture_id, the parameter that selects which capture is summarized. The meaning of the 'latest' default and the behavior for an invalid id are left entirely to inference from sibling tool names.
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-resource pair — 'Returns a compact versioned JSON summary' — and differentiates the tool from its sibling get_capture_slice by noting that 'full output remains available' there. It falls short of a 5 because it never states what the summary actually contains (which fields or statistics), leaving the agent to infer scope from the output schema.
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 concrete selection guidance: enable include_previews 'when head and tail samples are needed' and use get_capture_slice when full output is required. The compact-versus-full contrast makes the decision rule clear, though it stops short of an explicit 'use this when you only need summary statistics' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_executionB
Return durable phase metadata and event history for one execution.
| Name | Required | Description | Default |
|---|---|---|---|
| execution_id | Yes | ||
| include_output | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. 'Return' clearly signals a read-only operation, and 'durable phase metadata' adds useful context about persistence. However, it does not disclose behaviors such as pagination, error conditions, or the effect of include_output, so transparency is only partially addressed.
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 a single, front-loaded sentence with no redundant words. It is concise and scannable, though the term 'durable' is slightly jargon-heavy and could be clearer.
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 is adequate for identifying the tool's purpose but incomplete for confident invocation: it lacks parameter explanations, usage guidance, and behavioral details beyond 'Return'. The presence of an output schema helps, but it does not cover parameter semantics or alternative routing.
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%, and the description does not compensate by explaining execution_id or include_output. It omits include_output entirely, so an agent gains little parameter-level meaning beyond the schema's names and types.
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 ('Return') and a specific resource ('durable phase metadata and event history for one execution'). It distinguishes this tool from siblings like get_execution_output and list_executions by emphasizing a single execution's metadata/history rather than output or multiple executions.
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?
No guidance is provided about when to use this tool versus alternatives such as get_execution_output or list_executions. The phrase 'for one execution' hints at scope, but there are no explicit conditions, exclusions, or selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_execution_outputA
Retrieve one bounded output chunk for all phases or one named phase.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | ||
| max_bytes | No | ||
| phase_name | No | ||
| execution_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that the operation returns a single bounded chunk rather than full output, and that phase filtering is available. It does not discuss pagination semantics or encoding, but for a read-only retrieval tool this is meaningful behavioral context.
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?
A single front-loaded sentence with no filler; it states the action, resource, chunking behavior, and phase option compactly.
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 simple read-oriented tool with a rich output schema and a single required parameter, the description plus schema is mostly sufficient to invoke correctly. It could better explain paging/offset semantics, but with defaults and constraints in the schema this is a minor gap.
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 clarifies phase_name ('one named phase') and the bounded-chunk nature of max_bytes/offset, but it does not define offset semantics or explicitly connect execution_id to the required parameter. The schema's self-explanatory titles and constraints carry much of the remaining weight.
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 action ('Retrieve') on a specific resource ('execution output') and narrows it to a bounded chunk with optional phase scoping. It is clear enough for selection, though it does not explicitly distinguish itself from sibling tools like get_execution or get_capture_slice.
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 phrase 'for all phases or one named phase' gives context about when phase_name matters, but there is no explicit guidance on when to prefer this tool over alternatives or when not to use it. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_runtime_diagnosticsA
Returns opt-in runtime metadata without exposing captured content.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears the full disclosure burden. It adds useful context by stating the tool is opt-in and avoids exposing captured content, implying a read-only diagnostic operation. However, it does not describe any side effects, permissions, or conditions under which metadata is available.
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 a single sentence that is front-loaded with the core action and followed by an important boundary statement. There is no filler, and every phrase earns its place.
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 has no parameters, an output schema, and a fairly simple diagnostic purpose, the description is mostly complete. It lacks guidance on when or why an agent should invoke it, but the output schema covers return values and the boundary statement clarifies what it does not expose.
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 schema coverage is 100%, so there is no parameter information missing. The baseline for a no-parameter tool is 4, and the description does not need to add parameter-level detail.
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 the tool returns runtime metadata and explicitly distinguishes it from exposing captured content, which separates it from sibling capture tools. The resource 'runtime metadata' is somewhat vague, but combined with the tool name it is understandable.
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?
No guidance is provided about when to use this tool instead of siblings. The phrase 'opt-in runtime metadata' hints at a prerequisite condition but does not explain how or when to opt in, and no alternatives are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_capturesA
Lists all captures currently retained in the ephemeral ring buffer.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It usefully signals that the buffer is ephemeral and that the result reflects whatever is currently retained, implying a read-only listing. However, it does not mention ordering, empty-buffer behavior, or whether the listing affects buffer state.
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 a single, front-loaded sentence with no filler. Every word adds meaning: 'all captures', 'currently retained', and 'ephemeral ring buffer' all contribute to accurate selection and invocation.
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 zero-parameter list operation with an output schema available, the description is complete enough. It tells the agent exactly what the tool returns and the scope of that return, and nothing else is needed 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 schema confirms this, so there is no parameter documentation burden. The description focuses on the operation rather than inputs, which is appropriate for a no-argument tool.
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 ('Lists') and a clear resource ('all captures') with an explicit scope ('currently retained in the ephemeral ring buffer'). This distinguishes it from sibling tools like search_capture and get_capture_slice, which imply filtering or partial access.
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 this tool when you need the complete set of currently retained captures. It does not explicitly name alternatives or exclusion conditions, so it stops short of a 5, but the intent is not left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_executionsA
List durable executions with compact partial/completion summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. It does reveal that results are compact partial/completion summaries rather than full execution records, but it does not mention read-only behavior, pagination semantics, ordering, or what 'durable' means in this context.
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 a single front-loaded sentence with no filler. It communicates the action, the resource, and the nature of the returned summaries efficiently.
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 simple paginated list tool with an output schema, the description covers the core behavior sufficiently. It lacks details like ordering or total count, but those are likely already represented in the output schema, and the parameter surface is minimal.
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%, and the description adds no meaning for the limit and offset parameters. The parameter names and schema constraints are self-explanatory enough for simple pagination, but the description does not compensate for the lack of schema descriptions as required when coverage is low.
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 durable executions'. It also identifies the result shape as 'compact partial/completion summaries', which clearly distinguishes this listing tool from siblings like get_execution or get_execution_output that imply retrieving a single execution or its full output.
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 implies this tool is used when a list of executions with summaries is needed, but it does not provide explicit when-to-use guidance or contrast with alternatives such as get_execution, get_execution_output, or list_captures. The usage context is clear but only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preflight_commandA
Return content-free path and executable diagnostics without running command.
This resolves the working directory, symlink target, detectable Git repository root, and first executable token. Shell expansion, aliases, pipelines, redirections, environment changes, and arbitrary shell logic cannot be verified here. The requested command is never executed.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | ||
| command | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so strongly. It explicitly says the command is never executed, that diagnostics are content-free, and that more advanced shell features cannot be verified. This gives the agent a clear and honest safety profile.
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 concise, front-loaded with the core behavior, and every sentence earns its place. The second sentence adds exactly the necessary detail about what is resolved and what cannot be verified, without bloating.
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 is complete for a preflight diagnostic tool: it states purpose, safety guarantees, scope of resolution, and limitations. Since an output schema exists, it does not need to describe return values. A small gap is that `cwd` is not explicitly tied to the 'working directory' mention, but the overall context is sufficient.
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 has 0% description coverage, so the description must compensate. It clarifies that `command` is the operation to inspect rather than execute, and that working-directory resolution is involved, which indirectly covers `cwd`. However, it never explicitly names or explains the `wd` parameter's meaning or default behavior beyond the schema's `default: null`.
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 action and resource: it returns content-free path and executable diagnostics for a command without running it. This clearly distinguishes it from execution-oriented siblings like execute_and_capture by emphasizing safety and static analysis.
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 makes the use context clear: use this when you need path, symlink, git root, or executable-token diagnostics without side effects. It also explicitly lists what cannot be verified here, such as shell expansion, aliases, pipelines, and redirections, signaling when the tool is not suitable. It does not name an alternative, but the boundary is well implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_executionA
Resume an execution from its first incomplete phase.
Completed phases are skipped. Failed and timed-out phases require
retry_failed=True; a safe phase recovered as interrupted resumes on
the normal call. Retries of unsafe phases additionally need
confirm_unsafe=True unless the execution was created with the explicit
allow-unsafe resume policy.
| Name | Required | Description | Default |
|---|---|---|---|
| execution_id | Yes | ||
| retry_failed | No | ||
| confirm_unsafe | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It transparently discloses that completed phases are skipped, that failed/timed-out phases need retry_failed, and that unsafe retries require confirm_unsafe unless the policy permits. It does not mention potential side effects, error cases, or what happens if no incomplete phases exist, but the disclosed behavior is substantial and goes beyond a generic 'resume' statement.
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 three sentences, front-loaded with the core action and scoping. It efficiently packs behavioral rules without redundancy. The structure is logical: purpose, phase handling, then retry conditions. No wasted words.
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 complexity (multiple phases, retry logic, safety policies) and that an output schema exists (so return format is covered), the description is fairly complete. It covers the key decision points an agent needs: skipping completed phases, requiring retry_failed for failures, and confirm_unsafe for unsafe retries. It does not mention edge cases like no incomplete phases or errors, but the core usage is well specified.
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 the retry_failed and confirm_unsafe parameters by stating when they must be set (retry_failed for failed/timed-out phases, confirm_unsafe for unsafe retries without the allow-unsafe policy). It does not explain execution_id, but that is self-evident as the identifier. The description adds meaningful semantics beyond the schema's bare parameter definitions.
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 ('Resume') and resource ('an execution'), and precisely defines the scope as 'from its first incomplete phase'. It clearly distinguishes itself from siblings like start_execution by focusing on resuming rather than starting, and from get_execution by being an action rather than a read.
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 provides clear context on when to use it (to resume an execution) and specifies conditions for retries (failed/timed-out phases require retry_failed, unsafe retries require confirm_unsafe unless policy allows). However, it does not explicitly state exclusions or alternatives beyond implying that start_execution is for new executions. The usage context is strong but not fully explicit about when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_captureA
Searches the captured command output using BM25, Semantic embedding, or Hybrid (RRF) ranking. Semantic prefetch is on by default. Hybrid search waits at most the configured semantic wait budget for a capture's index; on a very large capture it then returns BM25 results with 'semantic pending' noted, and repeating the search once indexing finishes returns hybrid ranking. Semantic mode waits for the index.
Args: query: Search keywords or natural language question (e.g. 'auth failure', 'ECONNREFUSED', 'why did the build fail?'). mode: Search mode - 'hybrid' (recommended, lexically weighted BM25 + Semantic), 'bm25' (keyword terms), or 'semantic' (vector concepts). capture_id: The capture ID to query (defaults to 'latest'). top_k: Number of matching snippets to return (default: 5). context_lines: Number of surrounding lines of context to include with each match (default: 3; must be non-negative).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | hybrid | |
| query | Yes | ||
| top_k | No | ||
| capture_id | No | latest | |
| context_lines | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: semantic prefetch is on by default, hybrid search may fall back to BM25 with a 'semantic pending' note on large captures, and semantic mode waits for the index. This covers timing and fallback behavior well. It does not explicitly state it's read-only, but given it's a search operation, that's implied.
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 well-structured: a single-sentence purpose, a concise paragraph on behavior, then a clean Args list. Every sentence adds value—no fluff. It front-loads the main purpose and then provides necessary details.
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 complexity (5 params, multiple modes, dynamic behavior), the description covers all needed aspects: modes, defaults, behavior under large captures, and parameter semantics. An output schema exists (signal indicates has output schema), so not describing return values is acceptable.
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 explain each parameter. It does: query gives examples, mode explains each option with recommendation, capture_id notes default, top_k states default and purpose, context_lines explains meaning and constraint. This fully compensates for the missing schema descriptions.
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-resource pair: 'Searches the captured command output,' and immediately specifies the ranking methods (BM25, Semantic, Hybrid RRF). This clearly distinguishes it from sibling tools like get_capture_slice or capture_text, which have different operations.
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 provides clear context on how to use the tool (query a capture, choose mode), but does not explicitly mention when NOT to use it or alternatives. For instance, it doesn't say 'use get_capture_slice for raw slice retrieval.' However, the mode descriptions implicitly guide selection (e.g., 'hybrid recommended').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_semantic_index_budgetC
Adjust this session's semantic-index chunk budget when explicitly enabled.
| Name | Required | Description | Default |
|---|---|---|---|
| max_indexed_chunks | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 of behavioral disclosure. It implies a session-state mutation but does not mention side effects, repeat-call behavior, persistence, error conditions, or what happens when the feature is not enabled.
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 a single, front-loaded sentence with no filler words. However, its brevity comes at the cost of substance, especially for the parameter.
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?
With no annotations, no parameter documentation, and a single untyped-in-practice integer parameter, the description is far from complete. The output schema exists but does not compensate for missing parameter and behavioral semantics.
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 schema has zero description coverage for the only parameter, max_indexed_chunks, and the description does not explain it at all. The meaning, range, units, or effect of this integer are left entirely to the agent to guess.
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 action ('Adjust this session's semantic-index chunk budget') and a precondition ('when explicitly enabled'). It is distinguishable from sibling tools that focus on captures and diagnostics, though 'chunk budget' is not elaborated.
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 only usage signal is the vague phrase 'when explicitly enabled'; there is no guidance on when to invoke this tool versus any alternative, no prerequisites, and no explanation of what 'enabled' means or how to determine it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_executionA
Run a sequential, durably checkpointed set of command phases.
Each phase is an object with name and command plus optional
cwd, timeout_seconds, max_output_bytes, structured_metrics,
and side_effects (none or unsafe). A completed phase is never
rerun by resume_execution. An unsafe phase that must be retried after
failure, timeout, or interruption requires confirm_unsafe=True or the
explicit resume_policy='allow-unsafe'. Outputs and phase event history
are stored under EPHEMERAL_EXECUTION_STATE_DIR.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | ||
| label | No | ||
| phases | Yes | ||
| execution_id | No | ||
| resume_policy | No | safe | |
| timeout_seconds | No | ||
| max_output_bytes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden, and it discloses important traits: phases are durable and sequential, completed phases are never rerun, unsafe retries require explicit approval, and outputs/history are stored under EPHEMERAL_EXECUTION_STATE_DIR. It loses a point for mentioning confirm_unsafe=True, which does not appear in the input schema, but the core behavioral story is strong.
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 sentences with no filler; the purpose is front-loaded and the phase contract is packed into a compact paragraph. The density is high, but each sentence contributes, and the structure makes the core behavior easy to absorb.
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 complex tool with 7 top-level parameters, a nested phase schema, and no annotations, this description provides a solid foundation but leaves gaps. It explains phase shape and retry semantics well but does not cover several top-level parameters and directs the agent to a non-existent confirm_unsafe parameter.
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 partially does by defining the phase object and its optional fields and by referencing resume_policy. However, it omits meaningful parameters like idempotency_key, unsafe_side_effects, execution_id, label, and top-level timeout/max_output_bytes, and it references confirm_unsafe=True, which is not in the schema.
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: 'Run a sequential, durably checkpointed set of command phases.' It also distinguishes this tool from its sibling resume_execution by noting that completed phases are never rerun, which helps an agent tell the starting tool apart from the continuation tool.
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 implies this is the entry point for a checkpointed pipeline and that resume_execution is the continuation path, but it never explicitly says 'use this for a fresh run; use resume_execution to continue.' It gives useful context about retrying unsafe phases, but does not clearly route the agent between alternatives.
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.5.0- Changed
capture_file1 field changed- added
Input schema / properties / structured_metricsAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Structured Metrics" +}
- Changed
capture_text1 field changed- added
Input schema / properties / structured_metricsAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Structured Metrics" +}
- Changed
execute_and_capture1 field changed- added
Input schema / properties / structured_metricsAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Structured Metrics" +}
- Changed
get_capture_summary1 field changed- added
Input schema / properties / include_previewsAdded value: +{ + "default": false, + "title": "Include Previews", + "type": "boolean" +}
- Added
get_execution - Added
get_execution_output - Added
list_executions - Added
resume_execution - Added
start_execution
1 tool update
v0.4.0- Added
set_semantic_index_budget
12 tool updates
v0.2.0- First observed
capture_file - First observed
capture_text - First observed
clear_captures - First observed
consolidate_captures - First observed
execute_and_capture - First observed
get_buffer_stats - First observed
get_capture_slice - First observed
get_capture_summary - First observed
get_runtime_diagnostics - First observed
list_captures - First observed
preflight_command - First observed
search_capture
TDQS
Scored across 18 tools
Tools are largely separated by resource type (capture vs execution) and action, with clear roles for ingest, search, retrieval, and diagnostics. A few pairs like execute_and_capture vs start_execution or get_capture_slice vs get_execution_output are close, but their descriptions define sufficiently distinct use cases.
All tool names follow a consistent lowercase snake_case verb_noun pattern: capture_*, get_*, list_*, clear_*, consolidate_*, start_execution, resume_execution, preflight_command, and set_semantic_index_budget. There are no mixed naming styles or vague generic verbs.
18 tools is on the heavy side for a focused ephemeral-buffer server, especially with two overlapping subsystems: captures and executions. The count is not bloated enough to be chaotic, but it exceeds the comfortable well-scoped range.
Capture workflows are well covered: ingest via text, file, or command; search; slice; consolidate; list; clear; and stats. Execution has start/resume/get/output/list, but there is no cancel or delete operation for executions, which is a notable but not blocking gap.
Maintenance
Related MCP Connectors
Project memory, semantic code search, and grounded agent context.
Shared memory for coding agents. Stop re-explaining your codebase every session.
Search your knowledge bases from any AI assistant using hybrid RAG.
- AmberOAuthcom.ambermem
Long-term memory for AI assistants. Hybrid retrieval, query expansion, auto-topics.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides persistent memory for AI agents using hybrid search (vector embeddings + BM25) with neural reranking, enabling storage and retrieval of insights, debugging solutions, and patterns across coding sessions.8MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI coding assistants to search and retrieve information from a locally ingested knowledge base using hybrid search, grounded in user-curated documentation.17MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI coding agents to retrieve and manage code context with hybrid search, project memory, and observability via MCP tools.29MIT
- AlicenseAqualityBmaintenanceProvides persistent, searchable memory across AI coding agent and chat history (Claude Code, Codex, Gemini CLI, ChatGPT, and more) via retrieval-augmented generation, enabling semantic and hybrid search to retain context across sessions.5MIT