Semantic Cache MCP
Semantic Cache MCP is a Model Context Protocol server that reduces AI model token usage by 80%+ through intelligent file caching, semantic search, and efficient file operations.
Token-Efficient File Reading:
read— Automatic three-state responses: full content (first read), unchanged marker (~0 tokens on cache hit), or unified diff (modified, 80-95% savings)batch_read— Read multiple files under a token budget with glob expansion, priority ordering, unchanged suppression, and batch embedding
File Modifications:
write— Create or replace files with cache refresh, overwrite diffs, append support, and optional auto-formattingedit— Targeted edits via three modes: find/replace, scoped (line-range bounded), or line-range replacementbatch_edit— Apply multiple edits to a single file in one call with partial success reportingdelete— Delete a file/symlink with cache eviction and dry-run preview
Search & Discovery:
search— Semantic (meaning-based) hybrid BM25 + HNSW vector search across cached files (no API keys, works offline)similar— Find semantically related files via nearest-neighbor lookupgrep— Exact regex or literal string search with line numbers and contextglob— Discover files by pattern with cache coverage indicatorsdiff— Compare two files with a unified diff and semantic similarity score
Cache Management & Diagnostics:
stats— View token savings, hit rates, tool call counts, embedding model performance, and memory usageclear— Reset all cache entries to force cold re-seeding
Key Technical Features:
BLAKE3 content hashing detects unchanged files even when timestamps change
Local ONNX embeddings (default: BAAI/bge-small-en-v1.5); supports custom HuggingFace models
LRU-K cache eviction with up to 10,000 entries
Optional GPU acceleration (NVIDIA CUDA)
DoS protection via configurable write/edit size limits and match count caps
Can block native file tools to force all I/O through semantic-cache for maximum savings
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., "@Semantic Cache MCPSearch for code semantically related to the user authentication flow"
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.
Cut your MCP client's token usage by ~98% on cached reads, with millisecond responses.
Semantic Cache MCP is a Model Context Protocol server that puts every file operation behind one cache. Re-reading a file you already hold costs a few tokens instead of the whole file, and search and grep run over that same corpus rather than the disk.
Fourteen tools share the layer: read, read_image, batch_read, warm, write, edit, edit_preview, batch_edit, search, grep, glob, delete, clear, stats.
Why this exists
Reads stop costing tokens. The first read hands back a content_hash. Send it back — known_hash on read, a known_hashes entry on batch_read — and the server replies unchanged without resending. A modified file returns a diff with changed line numbers; an oversized one collapses to a structure-preserving summary rather than a blind cut at a byte offset.
Hashes travel as their first 16 hex characters — a claim is only ever checked against the entry for the path it names, so 64 bits separates two versions of one file with room to spare, and the full digest is still accepted. A shorter prefix is not: that would match every version at once.
That echoed hash is the whole contract, and it is the only evidence the server has that a file is still in your context. A warm cache proves the server holds the file, never that you do — the store is on disk and outlives the process, the session, and your context window. A read without a matching hash always sends the file, so forgetting is safe: after a compaction, omit the hashes and get your files back in full.
Search and grep run on the cache, not the disk. BM25 keyword search, glob, and grep all read the corpus that read, batch_read and warm populate — and warm fills it without returning a byte of content, so a whole tree becomes searchable for a few dozen tokens. An in-session result LRU collapses repeated queries to sub-millisecond hits.
Mutations are bounded by default. write, edit, and batch_edit enforce size and match limits, can run formatters, and refresh the cache atomically. A dry_run writes nothing and says so — the status becomes would_create / would_update / would_edit — so a preview is never mistaken for a completed write.
Related MCP server: Ambiance MCP Server
Installation
Add to Claude Code settings (~/.claude.json).
Option 1: uvx, always runs the latest version:
{
"mcpServers": {
"semantic-cache": {
"command": "uvx",
"args": ["semantic-cache-mcp"]
}
}
}Option 2: uv tool install:
uv tool install semantic-cache-mcp{
"mcpServers": {
"semantic-cache": {
"command": "semantic-cache-mcp"
}
}
}Restart Claude Code.
Block Native File Tools (Recommended)
Disable the client's built-in file tools so all file I/O routes through semantic-cache.
Claude Code — ~/.claude/settings.json:
{
"permissions": {
"deny": ["Read", "Edit", "Write"]
}
}OpenCode — ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"read": "deny",
"edit": "deny",
"write": "deny"
}
}CLAUDE.md Configuration
Add to ~/.claude/CLAUDE.md to enforce semantic-cache globally:
## Tools
- MUST use `semantic-cache-mcp` instead of native I/O tools (98% token savings on cached reads)Tools
Core
Tool | Description |
| Cache-aware single-file read: full content plus a |
| Image pass-through. Returns an MCP image content block (base64 + mime) so vision models see the pixels; sidecar metadata carries size and mime. Format verified by magic bytes (PNG, JPEG, GIF, TIFF, BMP, WebP), not extension. Bypasses the cache. Capped at 5 MiB ( |
| Full-file create or replace with cache refresh. Returns creation status or an overwrite diff; supports |
| Exact edit against cached content, with scoped and line-range modes plus |
| Many exact edits to one file, applied atomically, with per-edit success reporting. Takes |
| Read-only probe returning match count, line numbers, and context snippets for a candidate |
| Single-path delete for a file or symlink, with cache eviction and |
Discovery
Tool | Description |
| Index files into the cache so |
| Multi-file cache-aware read. Handles globs, priorities, token budgets, and diff/full routing. Returns each file's |
| Cache-only BM25 ranking of cached files. Terms join with |
| Cache-only exact search — regex or literal. Best for symbols and exact strings. Hits come back as |
| File discovery plus cache coverage. Find candidates, then pass the paths to |
Management
Tool | Description |
| Cache metrics, session usage (tokens saved, tool calls), and lifetime aggregates. |
| Reset all cache entries. |
Tool Reference
The table above is the authoritative map; these are the common call shapes.
read path="/src/app.py" # automatic: full, unchanged, or diff
read path="/src/app.py" offset=120 limit=80 # lines 120 to 199 onlyState | Response | Token cost |
First read | Full content plus a | Normal |
Unchanged |
| A few tokens |
Modified | Unified diff only | 5 to 20% of original |
write path="/src/new.py" content="..."
write path="/src/new.py" content="..." auto_format=true
write path="/src/large.py" content="...chunk1..." append=false # first chunk
write path="/src/large.py" content="...chunk2..." append=true # subsequent chunks# Mode A: find/replace, searches the entire file
edit path="/src/app.py" old_string="def foo():" new_string="def foo(x: int):"
edit path="/src/app.py" old_string="..." new_string="..." replace_all=true auto_format=true
# Mode B: scoped find/replace, searches only within the line range (a shorter old_string works)
edit path="/src/app.py" old_string="pass" new_string="return x" start_line=42 end_line=42
# Mode C: line replace, swaps the whole range with no old_string needed (most token savings)
edit path="/src/app.py" new_string=" return result\n" start_line=80 end_line=83Mode | Parameters | Best for |
Find/replace |
| Unique strings, no line numbers known |
Scoped |
| Shorter context when |
Line replace |
| Maximum token savings when line numbers are known |
# Mode A: find/replace, [old, new]
batch_edit path="/src/app.py" edits='[["old1","new1"],["old2","new2"]]'
# Mode B: scoped, [old, new, start_line, end_line]
batch_edit path="/src/app.py" edits='[["pass","return x",42,42]]'
# Mode C: line replace, [null, new, start_line, end_line]
batch_edit path="/src/app.py" edits='[[null," return result\n",80,83]]'
# Mixed modes in one call (object syntax also supported)
batch_edit path="/src/app.py" edits='[
["old1", "new1"],
{"old": "pass", "new": "return x", "start_line": 42, "end_line": 42},
{"old": null, "new": " return result\n", "start_line": 80, "end_line": 83}
]' auto_format=truebatch_read paths="/src/a.py,/src/b.py" max_total_tokens=50000
batch_read paths='["/src/a.py","/src/b.py"]' priority="/src/main.py"
batch_read paths="/src/*.py" max_total_tokens=30000
batch_read paths="/src/a.py,/src/b.py" known_hashes='{"/src/a.py":"8f3c..."}'Expands simple globs, honors priority, enforces max_total_tokens, and reports skipped paths with recovery hints. Every file is returned in full unless you prove you still hold it: echo the delivered content_hash values back as known_hashes and the ones you hold collapse into an unchanged count.
warm paths="src/**/*.py"
warm paths="src/a.py,src/b.py"
warm paths="src/**/*" max_files=500Indexes the files into the cache and returns counts — warmed, already_current, skipped, tokens_indexed — with no content, no previews, and no per-file paths for the ones that worked. Anything skipped comes back under failures with a reason, and a cap that stops the walk sets truncated or incomplete.
The usual opening move on an unfamiliar tree: warm, then grep for the exact string or search for the concept, then read only what those name.
search query="authentication middleware logic" k=5
glob pattern="**/*.py" directory="./src" cached_only=true
grep pattern="class Cache" path="src/**/*.py"
grep pattern="content_hash" output="paths"
grep pattern="TODO" output="count"A grep response names the shared directory once as root and reports each file's hits as "<line>:<text>" strings — measured at 37% fewer tokens than the per-match objects it replaced, and glob at 50%. output="count" turns a 2.6k-token answer into 77.
Configuration
Environment Variables
Variable | Default | Description |
|
| Logging verbosity ( |
|
| Response detail ( |
|
| Global response token cap ( |
|
| Seconds before a tool call times out (auto-resets executor) |
|
| Max bytes returned by read operations |
|
| Max cache entries before W-TinyLFU eviction |
| (platform) | Override cache/database directory path |
|
| Also send each result as MCP |
|
| Advertise per-tool output schemas in |
A malformed value falls back to the default and logs a warning naming the variable. See docs/env_variables.md for detail.
Safety Limits
Limit | Value | Protects against |
| 10 MB | Memory exhaustion via large writes |
| 10 MB | Memory exhaustion via large file edits, in |
| 10,000 | CPU exhaustion via unbounded |
| 1,000 chars | Oversized |
Regex shape check | — | Catastrophic backtracking (details) |
MCP Server Config
{
"mcpServers": {
"semantic-cache": {
"command": "uvx",
"args": ["semantic-cache-mcp"],
"env": {
"LOG_LEVEL": "INFO",
"TOOL_OUTPUT_MODE": "compact",
"MAX_CONTENT_SIZE": "100000"
}
}
}
}Cache location: ~/.cache/semantic-cache-mcp/ (Linux), ~/Library/Caches/semantic-cache-mcp/ (macOS), %LOCALAPPDATA%\semantic-cache-mcp\ (Windows). Override with SEMANTIC_CACHE_DIR.
How It Works
┌──────────┐ ┌────────────┐ ┌──────────────────────────┐
│ Claude │────▶│ smart_read │────▶│ stat() + cache lookup │
│ Code │ │ │ │ (BEFORE any disk read) │
└──────────┘ └────────────┘ └──────────────────────────┘
│
┌────────────────┼─────────────────┬──────────────────┐
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐
│ mtime │ │ mtime │ │ Changed │ │ New / │
│ match │ │ drift, │ │ content │ │ Large │
│ FAST │ │ hash │ │ → diff │ │ → summary │
│ PATH │ │ match │ │ (80-95%) │ │ or full │
│ ~5 tok │ │ ~5 tok │ └──────────┘ └────────────┘
│ (99%) │ │ (99%) │
│ ~1 ms │ │ ~1 ms │
│ no I/O │ │ +update │
└──────────┘ └──────────┘search is cached on the same principle. An in-session LRU keyed on (query, k, directory) returns warm hits in ~10 µs, and misses fall through to BM25. Every cache mutation (put, clear, delete_path, update_mtime) bumps the LRU, so callers never see a result that predates a write.
Performance
Measured on this project's 41 source files (212,499 tokens), i9-13900K, ext4 on NVMe, corpus held fixed across phases. Every phase models a caller that keeps its hashes and echoes them back — that is what earns the savings.
Token savings: 98.9% overall (phases 2 to 6)
Phase | Scenario | Savings |
Overall (cached, phases 2 to 6) | Aggregate token reduction | 98.9% |
Unchanged re-read | mtime match, fast path skips disk I/O | 99.3% |
Content hash | mtime drifted, BLAKE3 still matches | 99.3% |
Batch read | All files via | 99.3% |
Search previews | 5 queries × k=5, previews vs full reads | 98.6% |
Small edits | Real ~5% line changes in 30% of files | 98.1% |
Cold read | First read, no cache; one file exceeds | 5.9% |
Latency: unchanged reads ~1 ms; repeat searches < 0.01 ms
Operation | p50 | Notes |
Single unchanged read (fast path) | 1.1 ms | mtime + cache hit, no disk I/O |
Single diff read (changed file) | 0.7 ms | hash check + unified diff |
Search k=5 (cache hit) | < 0.01 ms | in-session LRU |
Search k=5 (cache miss) | 1.4 ms | BM25 keyword search |
Edit (scoped find/replace) | 3.1 ms | cached content, plus the atomic write's fsync |
Grep (literal | 1.5 ms | FTS5 over cached corpus |
Grep (regex) | 3.4 ms | compiled once |
Batch read (41 files, diff mode) | 45.6 ms | chunk + tokenize changed files; one summarises each full pass |
Unchanged re-read (41 files) | 19.5 ms | whole-corpus pass |
Cold read (41 files, total) | 100 ms | single unrepeated pass: I/O, tokenisation, one summarisation |
Write (200-line file) | 2.7 ms | creates + caches, durable before it returns |
Run them yourself. Pin TMPDIR to a real disk — the default /tmp is usually tmpfs, which discards fsync and reports write latency ~40% low:
TMPDIR="$HOME/.cache/scmcp-bench" \
uv run python benchmarks/benchmark_performance.py # operation latency
uv run python benchmarks/benchmark_token_savings.py # token savingsSee docs/performance.md for full methodology.
Documentation
Guide | Description |
Component design, algorithms, data flow | |
Benchmarks, methodology, cache footprint | |
Threat model, input validation, size limits | |
Programmatic API, custom storage backends | |
Common issues, debug logging | |
All env vars with defaults and examples |
Contributing
git clone https://github.com/CoderDayton/semantic-cache-mcp.git
cd semantic-cache-mcp
uv sync
uv run pytestSee CONTRIBUTING.md for commit conventions, pre-commit hooks, and code standards.
License
MIT License. Use it freely in personal and commercial projects.
Credits
Built with FastMCP 4.0+ and:
SQLite with FTS5 for keyword (BM25) full-text search, vendored as a small built-in store
Semantic summarization based on TCRA-LLM (arXiv:2310.15556)
BLAKE3 cryptographic hashing for content freshness
W-TinyLFU frequency-aware cache eviction
Available Tools
14 toolsbatch_editBatch EditA
Apply many exact edits to one file in a single atomic call.
Preferred over repeated edit calls on the same file: one response,
applied atomically, faster on large files. Partial success is allowed —
any failed edits are returned with their reason so you can retry just the
misses (status is edited when all apply, partial when some fail,
no_changes when none do). A dry_run writes nothing and says so: the
status becomes would_edit/would_partial and dry_run: true comes back
with it. For edits across different files, call the tool once per file.
edits is a JSON array; each entry is one of:
[old, new]— exact find/replace.[old, new, start_line, end_line]— find/replace confined to a range.[null, new, start_line, end_line]— replace that line range wholesale.{"old": ..., "new": ..., "start_line": ..., "end_line": ...}— object form.
Prefer line-range entries when you already have line numbers from read.
Pass known_hash and the response carries a claimable content_hash, so
no read is needed afterwards; without it, or with auto_format, you get
file_hash instead.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to modify (absolute, or relative to root). | |
| edits | Yes | JSON array of edit entries, in any of the forms above. | |
| dry_run | No | Preview without writing. | |
| show_diff | No | Return the full diff even on a deterministic all-success batch. | |
| known_hash | No | The `content_hash` from your last read of this file. Proves you hold the text being edited, so the result can be handed back as a claimable `content_hash`. | |
| auto_format | No | Run the formatter after all edits. |
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 thoroughly. It discloses atomic application semantics, partial success behavior, status values (`edited`, `partial`, `no_changes`), dry-run behavior (`would_edit`/`would_partial` and `dry_run: true`), and hash-handling behavior (`content_hash` vs `file_hash`).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core purpose and usage preference, then covers edit formats, status outcomes, dry-run behavior, and hash semantics without redundant fluff.
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 6 parameters, no annotations, and no output schema, the description is remarkably complete. It covers invocation context, input formats, failure behavior, return-status semantics, and post-call hash handling, leaving little ambiguity for an agent.
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?
Although the input schema already covers 100% of parameters, the description adds meaningful semantics beyond the schema: it documents the JSON array forms for `edits`, explains the line-range variants, and clarifies how `known_hash`, `content_hash`, and `file_hash` interact. This significantly helps an agent construct valid calls.
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: 'Apply many exact edits to one file in a single atomic call.' It also distinguishes the tool from repeated `edit` calls, making its purpose and scope immediately clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to prefer this tool over repeated `edit` calls, when to use it once per file for cross-file edits, and when to prefer line-range entries based on existing `read` data. This gives the agent actionable routing criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_readBatch ReadA
Read several files at once under a shared token budget.
Cheaper than many single read calls. To make files searchable without
reading them at all, use warm instead — this tool returns their text.
Pass known_hashes and each file you still hold collapses to an
unchanged count, or to a diff when it moved on disk; the rest come back
in full with their content_hash. A file large enough to come back
summarized carries none: a summary is not the file. Smallest files are read
first, and a file too big for the remaining budget is listed under
skipped while smaller ones keep being read. Recover anything skipped with
read using offset/limit. Paths are relative to the root the
response names, when there is one worth naming.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | The files to read — a comma-separated list, a JSON array, or glob patterns (expanded for you). | |
| priority | No | Optional paths to read first, ahead of the remaining files. Ordering only — a priority file still has to fit the budget, and is skipped like any other when it does not. | |
| known_hashes | No | JSON object mapping a path to the `content_hash` you still hold for it, e.g. `{"src/a.py": "8f3c..."}`. Any file you cannot vouch for this way is sent in full. | |
| max_total_tokens | No | Total token budget shared across the whole batch. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and meets it: it discloses hash-based deduplication (files collapse to an `unchanged` count or a diff), summarization of large files with no `content_hash`, smallest-first read order, `skipped` behavior under budget pressure, and root-relative path resolution. An agent can predict edge-case behavior it has never seen.
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?
Eight sentences, but each carries a distinct behavioral fact (budget sharing, sibling routing, hash dedup, summaries, ordering, skipping, recovery, root path) with no repetition. Longer than minimal, but the density is justified by the tool's complexity and every sentence 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?
For a complex tool with 4 parameters, budget dynamics, and no output schema, the description is complete: it explains what comes back in each case (full text with `content_hash`, `unchanged` counts, diffs, summaries, `skipped`, `root`) and how to recover skipped files. Nothing an agent needs to invoke it correctly or interpret its response is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description enriches parameter meaning: it explains that `known_hashes` changes the response shape (collapse to `unchanged`/diff) and that `max_total_tokens` drives the smallest-first ordering and `skipped` behavior. This goes beyond the schema's per-parameter descriptions without restating syntax already covered there.
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 verb+resource+constraint — 'Read several files at once under a shared token budget' — which immediately distinguishes it from single-file `read` and names `warm` as the alternative for searchability. The scope is unambiguous and the tool is clearly differentiated from siblings.
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 routing guidance: 'To make files searchable without reading them at all, use `warm` instead' names the alternative and the condition that selects it, and 'Recover anything skipped with `read` using `offset`/`limit`' provides the fallback path. The cost comparison to single `read` calls clarifies when batching is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clearClearA
Empty the cache. Does not touch any project file.
Removes every cached file entry and returns how many were dropped; the
next read/batch_read re-seeds from disk. Use rarely — only to recover
from stale cache state or force a cold re-seed. Normal reads already
refresh changed files on their own, so this is seldom needed. Takes no
arguments.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses side effects: does not touch project files, removes every cached file entry, returns count dropped, and that next read/batch_read re-seeds from disk. With no annotations, this provides full behavioral transparency.
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?
Description is concise, front-loaded with the core action, and every sentence adds useful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, it covers the action, side effects, return value, and appropriate usage context. No output schema exists, but the description adequately explains what the caller can expect.
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 no parameters and the description explicitly states 'Takes no arguments,' so no additional parameter meaning is needed beyond the empty input 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?
States a specific verb and resource ('Empty the cache') and clearly distinguishes from sibling tools like read and batch_read by focusing on cache clearing rather than file 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?
Explicitly says when to use ('only to recover from stale cache state or force a cold re-seed') and when not to use it, noting normal reads already refresh changed files and this is seldom needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteDeleteA
Delete one file or symlink and evict its cache entries.
Use this for explicit single-path removal instead of shelling out. A
missing path is reported as status not_found, not an error.
Statuses: deleted (removed), would_delete (dry-run preview only, and
dry_run: true comes back with it), not_found (nothing was there).
Constraints: one path only — no globs, no recursion, no real-directory
deletes. A symlink path deletes the link itself, never its target.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File or symlink path (absolute, or relative to the project root). | |
| dry_run | No | Preview the outcome without deleting or evicting the cache. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavior disclosure burden. It explains status outcomes (`deleted`, `would_delete`, `not_found`), dry-run behavior, cache eviction, missing-path handling (not an error), and symlink-link vs. target behavior. This is exceptionally transparent for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: core action first, usage guidance second, statuses third, and constraints last. Every sentence carries useful information and none are redundant or filler. The density is justified given the tool's destructive nature and complex edge cases.
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?
Despite lacking annotations and an output schema, the description covers the essential operational context: what the tool deletes, how it handles edge cases (missing path, symlinks, directories, dry-run), and what statuses to expect. Nothing critical that an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description adds meaningful extra semantics beyond the schema, such as the `dry_run` status `would_delete` and path constraints (one path only, no globs, no recursion). This goes beyond the baseline but is primarily behavioral rather than deeply expanding parameter format details.
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: 'Delete one file or symlink and evict its cache entries.' This clearly distinguishes it from sibling tools like read, write, edit, and clear, none of which perform single-path deletion. The scope is 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?
It explicitly states when to use the tool: 'Use this for explicit single-path removal instead of shelling out.' It also provides clear when-not constraints: one path only, no globs, no recursion, no real-directory deletes, and symlink-link-only semantics. These conditions enable an agent to select this tool correctly and avoid misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
editEditA
Edit one file by exact text replacement.
Three modes:
find/replace:
old_string+new_string(the default).scoped: add
start_line/end_lineto confine the search to a range.line-range: omit
old_stringand give both lines to replace them wholesale.
old_string must match exactly — whitespace and indentation included —
and, unless replace_all=true, must be unique, or the edit fails. Use
edit_preview first if you're unsure an anchor is unique. Returns the
replacement count and the affected line numbers, and refreshes the cache.
The diff itself is omitted unless you ask for it with show_diff;
diff_state always tells you which you got. A dry_run writes nothing
and says so: the status is would_edit and dry_run: true comes back
with it. For several edits to
one file use batch_edit; for a full rewrite use write.
Pass known_hash and the response carries a claimable content_hash, so
no read is needed afterwards. Without it, or with auto_format, you get
file_hash instead — editing a file is not the same as having read it.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to modify (absolute, or relative to root). | |
| dry_run | No | Preview without writing. | |
| end_line | No | 1-based inclusive end line for a scoped or line-range edit. | |
| show_diff | No | Return the diff even on a deterministic edit. | |
| known_hash | No | The `content_hash` from your last read of this file. Proves you hold the text being edited, so the result can be handed back as a claimable `content_hash`. | |
| new_string | No | Replacement text (an empty string deletes the match). | |
| old_string | No | Exact text to find. Omit only for a line-range replacement. | |
| start_line | No | 1-based inclusive start line for a scoped or line-range edit. | |
| auto_format | No | Run the formatter after editing. | |
| replace_all | No | Replace every occurrence instead of requiring a unique match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It states exact-match requirements, uniqueness rules, return values (replacement count and line numbers), cache refresh behavior, diff omission unless show_diff is set, dry_run semantics, and hash implications. This covers both success paths and caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with the core purpose and mode summary. It is organized in scannable chunks, and every sentence contributes functional value: constraints, return behavior, hash semantics, and tool routing. Given the complexity of a 10-parameter editing tool, this length is earned rather than bloated.
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 file-editing tool with no annotations and no output schema, this description is remarkably complete. It explains all three invocation modes, uniqueness constraints, preview fallback, dry-run behavior, return values, diff control, and hash semantics. An agent has enough context to invoke the tool correctly without additional probing.
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 100%, so a baseline of 3 applies. The description adds meaningful semantic context beyond the schema by explaining how old_string, new_string, start_line, end_line, replace_all, dry_run, known_hash, and auto_format interact across the three modes. It does not merely repeat schema descriptions but frames them behaviorally.
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 crisp statement: 'Edit one file by exact text replacement.' It immediately names the resource ('one file'), the action ('exact text replacement'), and goes on to distinguish itself from sibling tools like batch_edit and write. An agent can tell exactly what this tool does and what it does not do.
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 explicit usage guidance: three modes are spelled out, when uniqueness is required, when to use edit_preview, and when to prefer batch_edit or write. It also explains when known_hash is beneficial and what happens without it. This is exemplary 'when to use vs. alternatives' content.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_previewEdit PreviewA
Show where old_string would match in a file, without editing it.
Returns the match count, 1-based line numbers, and short snippets so you
can confirm an anchor is unique before calling edit. Read-only and cheap
(kept under ~200 tokens), so use it freely as a probe. Raises an error on
a binary file or an empty old_string.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to search (absolute, or relative to root). | |
| old_string | Yes | Anchor text to locate. Must match exactly, including whitespace and indentation. Cannot be empty. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral transparency. It clearly states that the tool is read-only, returns match count, line numbers, and snippets, and raises errors on binary files or empty `old_string`.
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 and well-structured, covering purpose, behavior, usage guidance, and error conditions in just a few sentences. Every sentence adds useful information without redundancy or fluff.
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?
Although there is no output schema, the description adequately explains the return content (match count, 1-based line numbers, snippets). It also covers error cases and usage context, making the tool's behavior sufficiently complete for an agent to use 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 schema already describes both parameters with 100% coverage, including path absoluteness and exact matching rules for `old_string`. The tool description adds no additional parameter-level detail beyond what the schema provides, so a baseline score of 3 is appropriate.
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's purpose: showing where `old_string` would match in a file without editing it. It also distinguishes itself from the sibling `edit` tool by explicitly noting it is a preview step before calling `edit`.
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 explains when to use the tool: to confirm an anchor is unique before calling `edit`. It also provides practical guidance by noting the operation is read-only, cheap, and kept under ~200 tokens, and it specifies error conditions for binary files and empty `old_string`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
globGlobA
List files matching a glob and show which are already cached.
Use it to discover files and see what search/grep can already access
before you spend reads. Each match carries a cached flag; set
cached_only=true to list only files already in the cache. Pair it with
batch_read to pull in whatever isn't cached yet.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Glob pattern to match (e.g. `src/**/*.py`). | |
| directory | No | Base directory the pattern is evaluated from. | . |
| cached_only | No | Return only files that are already cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It reveals that results include a cached flag, that cached_only restricts results, and that no content reads are performed before a batch_read step. It does not explicitly state it is read-only/safe, but the listing language makes that clear.
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?
Four short sentences, with the core action front-loaded and each subsequent sentence adding a distinct piece of useful context (cache flag, filter, batch_read pairing). No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 3-parameter listing tool with no output schema, the description fully covers what the tool returns (matches with cached flags), when to use it, and how to pair it with batch_read. Nothing critical for a correct first call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters are already described with examples and defaults. The description adds modest value by highlighting cached_only usage, but does not add new meaning beyond the schema; baseline 3 is appropriate.
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 begins with a specific verb and resource: 'List files matching a glob and show which are already cached.' It clearly distinguishes itself from sibling tools like search/grep by focusing on filesystem discovery and cache status, so an agent can tell what this tool does without opening the 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?
Explicitly tells when to use it: before spending reads, to see what search/grep can already access. It names batch_read as the partner for uncached files, and identifies cached_only as a filter. This is clear guidance with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grepGrepA
Search cached file contents for an exact string or regex.
Fast, exact, line-numbered matching over files already in the cache — it
does NOT touch disk, so index files first with warm, which costs a few
dozen tokens however many files it covers (empty results usually mean the
files aren't cached). A pattern that is not a
valid regex is an error, never an empty result, so zero matches always
means zero matches. For concept-level questions where you don't know the
exact term, use search instead.
Counts are complete unless the response says otherwise: if a cap stops the
scan, complete comes back false with limit_reached naming which one, so
total_matches is never mistaken for the total that exists.
Each file's hits come back as "<line>:<text>" strings under lines, with
context lines using - instead of :. Paths are relative to the root
the response names, when there is one worth naming. The cache is shared
across projects, so a relative path — or none — searches only the
current project; an absolute path reaches files anywhere.
A repeated group wrapping an unbounded quantifier ((a+)+) is rejected
rather than run — it can take exponential time and cannot be interrupted
once started. Drop the redundant repeat, or pass fixed_string=true.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Optional filter — an exact path, a path suffix, a directory (matching every cached file beneath it), or a glob. | |
| output | No | How much to return — `matches` (default), `paths` for the matching files without their lines, or `count` for the totals alone. | matches |
| pattern | Yes | A regular expression, or a literal string when `fixed_string=true`. | |
| max_files | No | Cap on the number of files returned. | |
| max_matches | No | Cap on total matches returned across all files. | |
| fixed_string | No | Match `pattern` literally instead of as a regex. | |
| context_lines | No | Lines of surrounding context to include around each match. Overlapping windows are merged, so no line is sent twice. | |
| case_sensitive | No | Match case-sensitively. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that the tool does not touch disk, that invalid regexes are errors rather than empty results, that capped results are reported via `complete` and `limit_reached`, and that catastrophic regex patterns are rejected to avoid hangs. This is exceptionally thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every paragraph earns its place: cache behavior, error semantics, alternative tool routing, output format, path scoping, and security-related regex rejection are all covered without redundancy. The first sentence immediately states the primary purpose, and subsequent paragraphs are logically organized.
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 that there is no output schema and no annotations, the description compensates fully by explaining the response structure (`lines`, `"<line>:<text>"`, context lines using `-`), completeness guarantees, error behavior, path semantics, and the need for pre-warming. An agent has everything necessary to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is already strong, but the description adds substantial meaning: the line-numbered output format, the distinction between relative and absolute `path` with respect to the shared cache, the semantics of `fixed_string`, and the behavior of caps. It goes well beyond simply restating schema fields.
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: 'Search cached file contents for an exact string or regex.' It then reinforces the tool's identity with 'Fast, exact, line-numbered matching over files already in the cache' and explicitly contrasts itself with the sibling `search`, so an agent can distinguish grep from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage conditions: it only works over cached files, so it directs the agent to first index with `warm`; it advises using `search` for concept-level questions where the exact term is unknown; and it even explains path-scoping behavior for current vs. other projects. This is explicit when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
readReadA
Read a file, returning as few tokens as possible. For 2+ files, use batch_read.
The first read returns the file's full content plus a content_hash. Echo
it back as known_hash on every later read: an unchanged file then answers
"unchanged": true with no body, a changed one returns a unified diff, and
without it the file is always sent in full. Reading also caches the file so
grep, search, and batch_read can see it.
Use offset/limit to read an exact line range, for example after a large
file was summarized. A read that returns only part of a file — a line
range, or a summary — reports file_hash (prefixed partial:) rather than
content_hash, and it cannot be redeemed as known_hash. A ranged read
also returns a coverage_token: pass it back as known_hash on your next
ranged read and a window you already hold answers unchanged; once the
windows cover the whole file you get a claimable content_hash.
For a large or unfamiliar file, outline=true is the cheap first read: one
line per class/function as <line>: <signature>, and every number is an
offset you can read next. An outline is a map, not the file, so it comes
back as file_hash.
is_diff marks a unified diff and truncated marks a summary. A binary
file returns metadata instead of content; for images use read_image.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path (absolute, or relative to the project root). Use an absolute path for files outside the project root. | |
| limit | No | Number of lines to return starting at `offset`. | |
| offset | No | 1-based first line for a ranged read; omit or pass 0 to start from the first line. | |
| outline | No | Return the file's definitions and their line numbers instead of its text. Cannot be combined with `offset`/`limit`. | |
| max_size | No | Byte threshold above which the file is semantically summarized; recover exact lines afterward with `offset`/`limit`. | |
| known_hash | No | The `content_hash` from your last read of this file — or the `coverage_token` from your last ranged read of it — passed back to get `"unchanged"` instead of the content re-sent. Omit only on a first read, or when you no longer hold what it vouches for. | |
| line_numbers | No | Prefix each line of a ranged read with its number. Costs about 17% more tokens; the range is in `lines` either way. Requires `offset` or `limit`. |
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 does so thoroughly. It discloses the caching side effect ('Reading also caches the file so grep, search, and batch_read can see it'), the content_hash/known_hash protocol, the partial file_hash behavior, the coverage_token mechanism, and the binary-file metadata fallback.
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 lengthy but every paragraph earns its place given the tool's complex caching and hashing behavior. It is front-loaded with the core purpose, then progresses logically from hash protocol to ranged reads, outlines, and output flags, with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has seven parameters, no annotations, and no output schema, so the description must explain behavior and return values on its own. It covers the full content_hash lifecycle, unchanged/diff responses, partial hashes, coverage tokens, outline format, summary truncation, and binary metadata, leaving no material gap for an agent to call 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?
Although the schema already has 100% description coverage, the tool description adds substantial meaning beyond the schema. It explains how known_hash redeems content, why partial file_hash cannot be redeemed, how coverage_token extends ranged reads, what outline returns, and the max_size summarization threshold — all semantics an agent would not infer from parameter names alone.
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: 'Read a file, returning as few tokens as possible.' It also differentiates itself from siblings by explicitly directing multi-file reads to batch_read and images to read_image, so an agent can distinguish it without inspecting other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when alternatives should be used: 'For 2+ files, use batch_read' and 'for images use read_image.' It also advises outline=true as the cheap first read for large or unfamiliar files, and offset/limit for exact line ranges, giving clear contextual guidance and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_imageRead ImageA
Read an image file so the model can see it.
Returns an MCP image block (base64 data + mime type) plus a small JSON
metadata sidecar (size, mime). Use this only when the model needs to
view the image; for text or any other file type use read.
The format is detected from the file's magic bytes, not its extension, so
a mis-named image still works and a non-image (e.g. text saved as .png)
is rejected. Supports PNG, JPEG, GIF, TIFF, BMP, and WebP. Images are
never cached — every call re-reads from disk. Oversized images are
rejected before encoding; the cap is SCMCP_MAX_IMAGE_BYTES (default
5 MiB), bounded by Anthropic's ~5 MB upload limit.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Image file path (absolute, or relative to the project root). |
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 reveals the return shape, magic-byte detection, rejection of non-images, supported formats, no-caching behavior, and the size cap. These traits are not inferable from the schema or title, making this strong transparency.
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?
Four short paragraphs each earn their place: purpose, return value, usage routing, and behavioral caveats. Key information is front-loaded and there is no filler or tautology.
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 one-parameter tool with no annotations and no output schema, the description supplies the output format, error behavior, supported formats, cache policy, and size bound. An agent has everything needed to decide whether and how to call 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?
Schema coverage is 100% for the single parameter, including absolute/relative path semantics. The description doesn't add parameter-level detail, but none is needed given the schema already fully documents `path`. Baseline 3 is appropriate.
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 ('read'), resource ('image file'), and purpose ('so the model can see it'). It clearly separates itself from sibling `read` by restricting to images. This is 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?
Explicitly says 'Use this only when the model needs to view the image; for text or any other file type use `read`.' This gives both a clear condition and an alternative tool. Additional format and size notes reinforce correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearchA
Find cached files by keyword relevance (BM25 ranking).
Searches only files already in the cache — index them first with warm,
which returns counts rather than content (thin results usually mean too
few files are cached).
Ranks by BM25 term relevance, so multi-word and keyword queries work
well; matching is lexical, not embedding-based, so synonyms won't match a
word that isn't present. Terms are OR'd — a word the corpus happens not to
contain costs you ranking, not the whole result set. For an exact string or
regex use grep; to pull more of the repo into the cache use batch_read.
Returns matches with a normalized 0–1 relevance score (best match = 1.0)
and a short preview. The cache is shared across projects, so a search with
no directory ranks the current project only; name one to look elsewhere.
| Name | Required | Description | Default |
|---|---|---|---|
| k | No | Maximum number of matches to return. | |
| query | Yes | Keywords to rank by. Natural-language phrasing is fine, but ranking is on the individual words. | |
| directory | No | Restrict matches to files under this directory. Defaults to the project root. | |
| show_preview | No | Include a short preview line for each match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: it states cache-only search, BM25 lexical ranking, OR semantics, synonyms not matching, normalized 0–1 scores, previews, and cross-project cache behavior. This is unusually rich behavioral disclosure for a search 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?
The description is front-loaded with the core purpose and each subsequent sentence earns its place: prerequisites, ranking behavior, OR semantics, alternatives, return format, and scope. It is longer than average but dense with non-redundant 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?
For a tool with no annotations and no output schema, the description explains the return format (matches with normalized score and preview), the prerequisite indexing step, and when to choose sibling tools. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema: query terms are OR'd and ranked by individual words, and directory's scope is tied to the shared-cache project behavior. Most parameter details, however, are already present 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 opening sentence states a specific verb and resource: 'Find cached files by keyword relevance (BM25 ranking).' This clearly distinguishes it from sibling tools like grep and batch_read, which are explicitly named later as alternatives.
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 concrete when-to-use guidance: use warm first to index files, use grep for exact strings/regex, and use batch_read to pull more repo into cache. It also explains the directory default behavior across projects, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statsStatsA
Report cache health, token savings, and runtime diagnostics.
Returns storage occupancy (files, tokens, documents, DB size), session and lifetime token savings and cache hit rates, per-tool call counts, and process memory. Use it to measure or debug — not as a routine step in read/edit loops. Takes no arguments.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It conveys a read-only, observational character through 'Report' and 'diagnostics,' and lists what the caller should expect. It does not explicitly state 'does not modify state,' but the reporting/diagnostic framing makes mutation unlikely.
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 compact and front-loaded with the core purpose, followed by a useful enumerative detail list and a clear usage boundary. Every sentence earns its place, and no filler or redundancy is present.
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 diagnostic tool with no output schema, the description is complete: it names the full return categories, explains the tool's purpose, and gives usage boundaries. An agent has enough information to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema already reflects this with an empty properties object. The description reinforces this with 'Takes no arguments,' which is sufficient; there are no parameter semantics needing explanation.
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: 'Report cache health, token savings, and runtime diagnostics.' It then enumerates the exact outputs, making the tool's purpose concrete and distinguishably diagnostic relative to siblings like read, edit, and search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it: 'Use it to measure or debug' and equally explicitly when not to use it: 'not as a routine step in read/edit loops.' This gives clear, actionable usage guidance without requiring inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
warmWarmA
Index files into the cache so grep and search can see them, returning counts only.
Costs a few dozen tokens however many files it indexes: no content, no previews, no paths for the files that succeeded — just how many were indexed, how many were already current, and how many were not.
Anything not indexed is counted in skipped, and the first few come back
under failures with a reason (not_found, not_a_file, binary,
too_large, unreadable, timeout). If a cap stopped the walk early you
get truncated or incomplete rather than a short count that looks
complete.
Use it before searching an unfamiliar tree, then grep for the exact
string or search for the concept, and read only what those name.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Files to index — a comma-separated list, a JSON array, or glob patterns (expanded for you, e.g. `src/**/*.py`). | |
| max_files | No | Cap on files indexed in this call. Matches beyond it are left out and flagged with `truncated`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does this thoroughly: no content/previews/paths returned, counts-only output, token cost, failure reason categories, and truncated/incomplete behavior when a cap stops the walk. This is unusually transparent about side effects and edge cases.
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?
Though longer than average, every sentence earns its place: core purpose, cost, output restrictions, failure semantics, and usage workflow. The structure is front-loaded with the essential definition and uses clear paragraphing and lists of error reasons, making it scannable for an agent.
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?
Despite having no output schema, the description fully compensates by explaining what the agent will get back: counts of indexed/current/not-indexed files, skipped counts, failure reasons, and truncated/incomplete flags. Combined with the complete input schema and usage guidance, nothing necessary for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining the significance of max_files behavior ('If a cap stopped the walk early you get `truncated` or `incomplete`') and listing concrete failure reasons such as `not_found`, `not_a_file`, `binary`, and `too_large` that map to path-related outcomes. This enriches the parameter semantics beyond the schema's basic 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 first sentence states a specific verb and resource: 'Index files into the cache so `grep` and `search` can see them, returning counts only.' This clearly distinguishes warm from read, search, grep, and other siblings by positioning it as a cache-warming pre-step rather than a retrieval or content 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 final paragraph explicitly tells the agent when and how to use the tool: 'Use it before searching an unfamiliar tree, then `grep` for the exact string or `search` for the concept, and `read` only what those name.' This gives concrete workflow context and names the related sibling tools, satisfying the when-to-use and alternatives requirement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
writeWriteA
Create a file or replace its entire contents.
Use this for new files or full rewrites; for localized changes prefer
edit or batch_edit. Status is created for a new path or updated
for an existing one; an update reports diff_state, and includes the diff
against the previous content only when you ask with show_diff. A
dry_run writes nothing and says so: the status is
would_create/would_update and dry_run: true comes back with it.
Writing refreshes the cache so later reads, grep, and search see the
new text.
A full write supplies the whole file, so the content_hash it returns is
claimable. An append only adds a tail: pass known_hash to show you held
the rest, or you get file_hash instead. auto_format reports file_hash
too — the formatter's output is not what you sent.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to create or replace (absolute, or relative to root). | |
| append | No | Append `content` to the end of the file instead of overwriting. | |
| content | Yes | Full file content, or the text to append when `append=true`. | |
| dry_run | No | Preview the result without writing. | |
| show_diff | No | Return the unified diff even on a deterministic write. | |
| known_hash | No | The `content_hash` you hold for this file. Only needed for `append`, to prove you hold the part you are not resending. | |
| auto_format | No | Run the formatter after writing. | |
| create_parents | No | Create any missing parent directories. |
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 fully delivers. It discloses returned status values (`created`, `updated`, `would_create`, `would_update`), the `dry_run: true` signal, cache-refresh side effects, and the different hash-return behavior for full writes, appends, and `auto_format`. This is far more than a generic mutation description.
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 front-loaded with the core purpose and usage rule, then organized into hash and side-effect semantics. Despite its length, every sentence adds operational detail that an agent needs, and none merely repeats the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 8 parameters, no output schema, and no annotations, the description is exceptionally complete. It explains the outcome variants, return-value semantics for diff, dry-run, append, and auto_format, and side effects on the cache. No critical behavioral dimension is left for the agent to infer.
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 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema by explaining how `known_hash`, `show_diff`, `dry_run`, `append`, and `auto_format` affect the response and the claimability of hashes. It earns a 4, though a full parameter-by-parameter walkthrough is not needed given the schema already documents each field.
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 precise verb and resource: 'Create a file or replace its entire contents.' It explicitly distinguishes this tool from siblings by saying localized changes should use `edit` or `batch_edit`, so an agent can immediately tell which tool fits.
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 clearly states when to use `write` ('new files or full rewrites') and when not to use it ('for localized changes prefer `edit` or `batch_edit`'). It also explains the append path and dry-run behavior, giving the agent actionable routing and usage context beyond the schema.
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.
14 tool updates
v0.6.0- Changed
batch_edit2 fields changed- added
Input schema / properties / known_hashAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The `content_hash` from your last read of this file. Proves\nyou hold the text being edited, so the result can be handed back as\na claimable `content_hash`." +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "content_hash": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content Hash" - }, - "diff": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff" - }, - "diff_omitted": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Omitted" - }, - "diff_state": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff State" - }, - "diff_stats": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Stats" - }, - "failed": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Failed" - }, - "failures": { - "anyOf": [ - { - "items": { - "properties": { - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Error" - }, - "old": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Old" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchEditFailure", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Failures" - }, - "from_cache": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "From Cache" - }, - "outcomes": { - "anyOf": [ - { - "items": { - "properties": { - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Error" - }, - "line_number": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line Number" - }, - "new": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "New" - }, - "old": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Old" - }, - "success": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Success" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchEditOutcome", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Outcomes" - }, - "params": { - "anyOf": [ - { - "properties": { - "auto_format": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Auto Format" - }, - "dry_run": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Dry Run" - }, - "show_diff": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Show Diff" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchEditParams", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "succeeded": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Succeeded" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchEditResponse", - "type": "object" -}New value: +null
- Changed
batch_read3 fields changed- added
Input schema / properties / known_hashesAdded value: +{ + "default": "", + "description": "JSON object mapping a path to the `content_hash` you\nstill hold for it, e.g. `{\"src/a.py\": \"8f3c...\"}`. Any file you\ncannot vouch for this way is sent in full.", + "type": "string" +} - changed
Input schema / properties / priority / descriptionPrevious value: -"Optional paths to read first, ahead of the remaining files."New value: +"Optional paths to read first, ahead of the remaining files.\nOrdering only — a priority file still has to fit the budget, and is\nskipped like any other when it does not." - changed
Output schema / (root)Previous value: -{ - "properties": { - "files": { - "anyOf": [ - { - "items": { - "properties": { - "content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content" - }, - "from_cache": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "From Cache" - }, - "hint": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hint" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchReadFile", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files" - }, - "skipped": { - "anyOf": [ - { - "items": { - "properties": { - "est_tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Est Tokens" - }, - "hint": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hint" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchReadSkipped", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Skipped" - }, - "summary": { - "anyOf": [ - { - "properties": { - "files_read": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Read" - }, - "files_skipped": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Skipped" - }, - "hint": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hint" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "total_tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Tokens" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - }, - "unchanged": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Unchanged" - }, - "unchanged_count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Unchanged Count" - } - }, - "title": "BatchReadSummary", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "BatchReadResponse", - "type": "object" -}New value: +null
- Changed
clear1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Count" - }, - "output_mode": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Output Mode" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "ClearResponse", - "type": "object" -}New value: +null
- Changed
delete1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "cache_removed": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cache Removed" - }, - "deleted": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Deleted" - }, - "dry_run": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Dry Run" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "symlink": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Symlink" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "DeleteResponse", - "type": "object" -}New value: +null
- Changed
edit2 fields changed- added
Input schema / properties / known_hashAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The `content_hash` from your last read of this file. Proves\nyou hold the text being edited, so the result can be handed back as\na claimable `content_hash`." +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "content_hash": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content Hash" - }, - "diff": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff" - }, - "diff_omitted": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Omitted" - }, - "diff_state": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff State" - }, - "diff_stats": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Stats" - }, - "from_cache": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "From Cache" - }, - "line_numbers": { - "anyOf": [ - { - "items": { - "type": "integer" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line Numbers" - }, - "params": { - "anyOf": [ - { - "properties": { - "auto_format": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Auto Format" - }, - "dry_run": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Dry Run" - }, - "replace_all": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Replace All" - }, - "show_diff": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Show Diff" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "EditParams", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "replaced": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Replaced" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "EditResponse", - "type": "object" -}New value: +null
- Changed
edit_preview1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "context": { - "anyOf": [ - { - "items": { - "properties": { - "line": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line" - }, - "snippet": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Snippet" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "EditPreviewMatch", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Context" - }, - "found": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Found" - }, - "line_numbers": { - "anyOf": [ - { - "items": { - "type": "integer" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line Numbers" - }, - "match_count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Match Count" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "EditPreviewResponse", - "type": "object" -}New value: +null
- Changed
glob1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "cached_count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cached Count" - }, - "directory": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Directory" - }, - "matches": { - "anyOf": [ - { - "items": { - "properties": { - "cached": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cached" - }, - "mtime": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Mtime" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "GlobMatch", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Matches" - }, - "pattern": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Pattern" - }, - "total_cached_tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Cached Tokens" - }, - "total_matches": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Matches" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "GlobResponse", - "type": "object" -}New value: +null
- Changed
grep4 fields changed- changed
Input schema / properties / context_lines / descriptionPrevious value: -"Lines of surrounding context to include per match."New value: +"Lines of surrounding context to include around each\nmatch. Overlapping windows are merged, so no line is sent twice." - added
Input schema / properties / outputAdded value: +{ + "default": "matches", + "description": "How much to return — `matches` (default), `paths` for the\nmatching files without their lines, or `count` for the totals\nalone.", + "type": "string" +} - changed
Input schema / properties / path / descriptionPrevious value: -"Optional filter — an exact path, a path suffix, or a glob."New value: +"Optional filter — an exact path, a path suffix, a directory\n(matching every cached file beneath it), or a glob." - changed
Output schema / (root)Previous value: -{ - "properties": { - "case_sensitive": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Case Sensitive" - }, - "context_lines": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Context Lines" - }, - "files": { - "anyOf": [ - { - "items": { - "properties": { - "count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Count" - }, - "matches": { - "anyOf": [ - { - "items": { - "properties": { - "after": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "After" - }, - "before": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Before" - }, - "line": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line" - }, - "line_number": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Line Number" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "GrepMatch", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Matches" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "GrepFile", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files" - }, - "files_matched": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Matched" - }, - "fixed_string": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Fixed String" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "pattern": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Pattern" - }, - "total_matches": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Matches" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - }, - "truncated_files": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated Files" - }, - "truncated_matches": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated Matches" - } - }, - "title": "GrepResponse", - "type": "object" -}New value: +null
- Changed
read4 fields changed- changed
Input schema / properties / known_hash / descriptionPrevious value: -"The `content_hash` from your last read of this file; pass it\nback to get `\"unchanged\"` instead of the content re-sent. Omit only\non a first read or when you no longer hold the hash."New value: +"The `content_hash` from your last read of this file — or the\n`coverage_token` from your last ranged read of it — passed back to\nget `\"unchanged\"` instead of the content re-sent. Omit only on a\nfirst read, or when you no longer hold what it vouches for." - added
Input schema / properties / line_numbersAdded value: +{ + "default": false, + "description": "Prefix each line of a ranged read with its number. Costs\nabout 17% more tokens; the range is in `lines` either way. Requires\n`offset` or `limit`.", + "type": "boolean" +} - added
Input schema / properties / outlineAdded value: +{ + "default": false, + "description": "Return the file's definitions and their line numbers instead\nof its text. Cannot be combined with `offset`/`limit`.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content" - }, - "content_hash": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content Hash" - }, - "from_cache": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "From Cache" - }, - "hint": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hint" - }, - "is_binary": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Is Binary" - }, - "is_diff": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Is Diff" - }, - "lines": { - "anyOf": [ - { - "properties": { - "end": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "End" - }, - "start": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Start" - }, - "total": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "ReadLineRange", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "mime": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Mime" - }, - "params": { - "anyOf": [ - { - "properties": { - "diff_mode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Mode" - }, - "limit": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Limit" - }, - "max_size": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Max Size" - }, - "offset": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Offset" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "ReadParams", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "size": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Size" - }, - "tokens_original": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Original" - }, - "tokens_returned": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Returned" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "total_lines": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Lines" - }, - "total_tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Tokens" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - }, - "unchanged": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Unchanged" - } - }, - "title": "ReadResponse", - "type": "object" -}New value: +null
- Changed
read_image1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "mime": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Mime" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "size": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Size" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "ReadImageResponse", - "type": "object" -}New value: +null
- Changed
search2 fields changed- changed
Input schema / properties / directory / descriptionPrevious value: -"Restrict matches to files under this directory."New value: +"Restrict matches to files under this directory. Defaults to\nthe project root." - changed
Output schema / (root)Previous value: -{ - "properties": { - "cached_files": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cached Files" - }, - "count": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Count" - }, - "directory": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Directory" - }, - "files_searched": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Searched" - }, - "k": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "K" - }, - "matches": { - "anyOf": [ - { - "items": { - "properties": { - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "preview": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Preview" - }, - "similarity": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Similarity" - }, - "tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "SearchMatch", - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Matches" - }, - "query": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Query" - }, - "show_preview": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Show Preview" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "SearchResponse", - "type": "object" -}New value: +null
- Changed
stats1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "lifetime": { - "anyOf": [ - { - "properties": { - "cache_hits": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cache Hits" - }, - "cache_misses": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cache Misses" - }, - "files_edited": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Edited" - }, - "files_read": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Read" - }, - "files_written": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Written" - }, - "hit_rate_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hit Rate Pct" - }, - "tokens_original": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Original" - }, - "tokens_returned": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Returned" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "total_sessions": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Sessions" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "StatsLifetime", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "mode": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Mode" - }, - "process_rss_mb": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Process Rss Mb" - }, - "session": { - "anyOf": [ - { - "properties": { - "cache_hits": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cache Hits" - }, - "cache_misses": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Cache Misses" - }, - "diffs_served": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diffs Served" - }, - "files_edited": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Edited" - }, - "files_read": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Read" - }, - "files_written": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Written" - }, - "hit_rate_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Hit Rate Pct" - }, - "tokens_original": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Original" - }, - "tokens_returned": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Returned" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "tool_calls": { - "anyOf": [ - { - "additionalProperties": { - "type": "integer" - }, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tool Calls" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - }, - "uptime_s": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Uptime S" - } - }, - "title": "StatsSession", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "storage": { - "anyOf": [ - { - "properties": { - "db_size_mb": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Db Size Mb" - }, - "files_cached": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Files Cached" - }, - "total_documents": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Documents" - }, - "total_tokens_cached": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Tokens Cached" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "StatsStorage", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "StatsResponse", - "type": "object" -}New value: +null
- Added
warm - Changed
write2 fields changed- added
Input schema / properties / known_hashAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The `content_hash` you hold for this file. Only needed for\n`append`, to prove you hold the part you are not resending." +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "bytes_written": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Bytes Written" - }, - "content_hash": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Content Hash" - }, - "created": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Created" - }, - "diff": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff" - }, - "diff_omitted": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Omitted" - }, - "diff_state": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff State" - }, - "diff_stats": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Diff Stats" - }, - "dry_run": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Dry Run" - }, - "from_cache": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "From Cache" - }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Path" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Status" - }, - "tokens_saved": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Saved" - }, - "tokens_written": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tokens Written" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "WriteResponse", - "type": "object" -}New value: +null
12 tool updates
v0.5.1- Changed
batch_edit5 fields changed- added
Input schema / properties / auto_format / descriptionAdded value: +"Run the formatter after all edits." - added
Input schema / properties / dry_run / descriptionAdded value: +"Preview without writing." - added
Input schema / properties / edits / descriptionAdded value: +"JSON array of edit entries, in any of the forms above." - added
Input schema / properties / path / descriptionAdded value: +"File path to modify (absolute, or relative to root)." - added
Input schema / properties / show_diff / descriptionAdded value: +"Return the full diff even on a deterministic all-success batch."
- Changed
batch_read3 fields changed- added
Input schema / properties / max_total_tokens / descriptionAdded value: +"Total token budget shared across the whole batch." - added
Input schema / properties / paths / descriptionAdded value: +"The files to read — a comma-separated list, a JSON array, or\nglob patterns (expanded for you)." - added
Input schema / properties / priority / descriptionAdded value: +"Optional paths to read first, ahead of the remaining files."
- Changed
delete2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"Preview the outcome without deleting or evicting the cache." - added
Input schema / properties / path / descriptionAdded value: +"File or symlink path (absolute, or relative to the project root)."
- Changed
edit9 fields changed- added
Input schema / properties / auto_format / descriptionAdded value: +"Run the formatter after editing." - added
Input schema / properties / dry_run / descriptionAdded value: +"Preview without writing." - added
Input schema / properties / end_line / descriptionAdded value: +"1-based inclusive end line for a scoped or line-range edit." - added
Input schema / properties / new_string / descriptionAdded value: +"Replacement text (an empty string deletes the match)." - added
Input schema / properties / old_string / descriptionAdded value: +"Exact text to find. Omit only for a line-range replacement." - added
Input schema / properties / path / descriptionAdded value: +"File path to modify (absolute, or relative to root)." - added
Input schema / properties / replace_all / descriptionAdded value: +"Replace every occurrence instead of requiring a unique match." - added
Input schema / properties / show_diff / descriptionAdded value: +"Return the diff even on a deterministic edit." - added
Input schema / properties / start_line / descriptionAdded value: +"1-based inclusive start line for a scoped or line-range edit."
- Changed
edit_preview2 fields changed- added
Input schema / properties / old_string / descriptionAdded value: +"Anchor text to locate. Must match exactly, including\nwhitespace and indentation. Cannot be empty." - added
Input schema / properties / path / descriptionAdded value: +"File path to search (absolute, or relative to root)."
- Changed
glob3 fields changed- added
Input schema / properties / cached_only / descriptionAdded value: +"Return only files that are already cached." - added
Input schema / properties / directory / descriptionAdded value: +"Base directory the pattern is evaluated from." - added
Input schema / properties / pattern / descriptionAdded value: +"Glob pattern to match (e.g. `src/**/*.py`)."
- Changed
grep7 fields changed- added
Input schema / properties / case_sensitive / descriptionAdded value: +"Match case-sensitively." - added
Input schema / properties / context_lines / descriptionAdded value: +"Lines of surrounding context to include per match." - added
Input schema / properties / fixed_string / descriptionAdded value: +"Match `pattern` literally instead of as a regex." - added
Input schema / properties / max_files / descriptionAdded value: +"Cap on the number of files returned." - added
Input schema / properties / max_matches / descriptionAdded value: +"Cap on total matches returned across all files." - added
Input schema / properties / path / descriptionAdded value: +"Optional filter — an exact path, a path suffix, or a glob." - added
Input schema / properties / pattern / descriptionAdded value: +"A regular expression, or a literal string when\n`fixed_string=true`."
- Changed
read6 fields changed- added
Input schema / properties / known_hashAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The `content_hash` from your last read of this file; pass it\nback to get `\"unchanged\"` instead of the content re-sent. Omit only\non a first read or when you no longer hold the hash." +} - added
Input schema / properties / limit / descriptionAdded value: +"Number of lines to return starting at `offset`." - added
Input schema / properties / max_size / descriptionAdded value: +"Byte threshold above which the file is semantically\nsummarized; recover exact lines afterward with `offset`/`limit`." - added
Input schema / properties / offset / descriptionAdded value: +"1-based first line for a ranged read; omit or pass 0 to start\nfrom the first line." - added
Input schema / properties / path / descriptionAdded value: +"File path (absolute, or relative to the project root). Use an\nabsolute path for files outside the project root." - removed
Output schema / properties / semantic_matchRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Semantic Match" -}
- Changed
read_image1 field changed- added
Input schema / properties / path / descriptionAdded value: +"Image file path (absolute, or relative to the project root)."
- Changed
search4 fields changed- added
Input schema / properties / directory / descriptionAdded value: +"Restrict matches to files under this directory." - added
Input schema / properties / k / descriptionAdded value: +"Maximum number of matches to return." - added
Input schema / properties / query / descriptionAdded value: +"Keywords to rank by. Natural-language phrasing is fine, but\nranking is on the individual words." - added
Input schema / properties / show_preview / descriptionAdded value: +"Include a short preview line for each match."
- Changed
stats2 fields changed- removed
Output schema / properties / embeddingRemoved value: -{ - "anyOf": [ - { - "properties": { - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Model" - }, - "process_rss_mb": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Process Rss Mb" - }, - "provider": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Provider" - }, - "ready": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Ready" - }, - "truncated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Truncated" - } - }, - "title": "StatsEmbedding", - "type": "object" - }, - { - "type": "null" - } - ], - "default": null -} - added
Output schema / properties / process_rss_mbAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Process Rss Mb" +}
- Changed
write7 fields changed- added
Input schema / properties / append / descriptionAdded value: +"Append `content` to the end of the file instead of overwriting." - added
Input schema / properties / auto_format / descriptionAdded value: +"Run the formatter after writing." - added
Input schema / properties / content / descriptionAdded value: +"Full file content, or the text to append when `append=true`." - added
Input schema / properties / create_parents / descriptionAdded value: +"Create any missing parent directories." - added
Input schema / properties / dry_run / descriptionAdded value: +"Preview the result without writing." - added
Input schema / properties / path / descriptionAdded value: +"File path to create or replace (absolute, or relative to root)." - added
Input schema / properties / show_diff / descriptionAdded value: +"Return the unified diff even on a deterministic write."
6 tool updates
v0.4.8- Removed
diff - Added
edit_preview - Changed
grep2 fields changed- added
Output schema / properties / truncated_filesAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Truncated Files" +} - added
Output schema / properties / truncated_matchesAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Truncated Matches" +}
- Changed
read5 fields changed- added
Output schema / properties / content_hashAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Content Hash" +} - added
Output schema / properties / is_binaryAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Is Binary" +} - added
Output schema / properties / mimeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Mime" +} - added
Output schema / properties / sizeAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Size" +} - added
Output schema / properties / total_linesAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total Lines" +}
- Added
read_image - Removed
similar
13 tool updates
v0.4.5- Added
batch_edit - Added
batch_read - Added
clear - Added
delete - Added
diff - Added
edit - Added
glob - Added
grep - Added
read - Added
search - Added
similar - Added
stats - Added
write
3 tool updates
v0.4.1- Removed
clear - Removed
read - Removed
stats
3 tool updates
v0.4.1- First observed
clear - First observed
read - First observed
stats
TDQS
Scored across 14 tools
Each tool targets a clearly distinct operation — read/batch_read split single vs. multi-file, edit/batch_edit split single vs. batch edits, search/grep split semantic vs. exact matching, and the descriptions explicitly cross-reference each other (e.g., 'for several edits use batch_edit'). The hash/cache protocol tools (warm, stats, clear, edit_preview) have non-overlapping roles.
Tool names mostly follow a verb or verb_object pattern with consistent snake_case (read_image, batch_read, edit_preview, batch_edit), and the batch_ prefix family is coherent. Minor deviations: 'stats' is a noun rather than verb_noun (e.g., get_stats), 'warm' is a bare verb without an object, and grep/glob are domain jargon rather than descriptive verb phrases.
14 tools sits at the upper edge of a well-scoped set, but the broader domain (file read/write/edit plus cache indexing, search, and administration) justifies the count. Each tool has a distinct job — warm/search/grep form an indexing pipeline, read/batch_read/read_image cover consumption, and stats/clear handle cache lifecycle — so nothing feels redundant.
The cache-aware file lifecycle is fully covered: read, write, edit, batch_edit, delete, plus discovery (glob), search (grep/search), indexing (warm), and diagnostics (stats). The content_hash/known_hash protocol creates a coherent multi-step workflow with no dead ends. Minor gaps: no move/rename and no directory operations beyond glob, though those appear deliberately out of scope for a cache-centric server.
Maintenance
Related MCP Connectors
Provide your AI coding tools with token-efficient access to up-to-date technical documentation for…
SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Codebase intelligence for agents: 152 structured artifacts across 21 programs, one call.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides AI coding assistants with context optimization tools including targeted file analysis, intelligent terminal command execution with LLM-powered output extraction, and web research capabilities. Helps reduce token usage by extracting only relevant information instead of processing entire files and command outputs.539 npm62TypeScriptMIT
- AlicenseAqualityDmaintenanceProvides intelligent code context and analysis through semantic compression, AST parsing, and multi-language support. Offers 60-80% token reduction while enabling AI assistants to understand codebases through local analysis, OpenAI-enhanced insights, and GitHub repository integration.616 npm3MIT
- AlicenseNot gradedqualityDmaintenanceProvides file caching and diff tracking for AI coding agents, reducing token usage by returning changes or confirming no changes instead of full file contents on repeated reads.140 npm217MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI coding agents to query a pre-built semantic knowledge graph of code, reducing token usage and tool calls. Supports 16 tools for code exploration, analysis, and context building.5 npm7MIT