plumb
OfficialPlumb is an MCP server that gives coding agents IDE-grade intelligence (LSP + tree-sitter + project memory) with write-safety guardrails and multi-agent coordination.
Explore code semantically —
workspace_symbols,get_definition,explain_symbol,find_references, call/type hierarchies,file_outline, andread_symbolgive source locations, signatures, docs, and reference sites without dumping whole files.Read and search efficiently —
read_file/read_multiple_files(line ranges, in-file pattern search),search_in_files,find_files,file_diff, plus rankedworkspace_search/topology_searchand structural audits.Edit safely and atomically —
write_file,edit_file,delete_file,rename_file,copy_file, multi-filetransaction_applywith rollback,undo_edit, per-path locks, optimistic-concurrency guards (expected_mtime/expected_sha), and diagnostics-aware writes.Refactor with LSP semantics —
rename_symbol,replace_symbol_body,insert_before/after_symbol,safe_delete_symbol, andmove_symbolunderstand scope and references.Verify and run tasks — real diagnostics, gated
gitoperations,run_task/run_commandsandboxed task execution,mutation_test, andtopology_affectedto scope which tests to run.Coordinate agents —
session_startorientation,workspace_sessionspeer awareness,leave_note/check_messagesmailbox,share_intentadvisories, andshare_findingsknowledge handoff.Persist project memory —
list_memories,read_memory,write_memory,delete_memory,search_memories, andrelevant_memorieskeep durable, searchable context across sessions.Operate the daemon —
daemon_infoandrename_sessionsurface session/daemon state and identify which agent you are.
Overall, it turns an agent into an IDE-backed, crash-resilient, multi-agent-safe coding collaborator rather than a blind file reader.
Click on "Install 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., "@plumbfind all references to the function 'sendMail'"
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.
IDE intelligence for agents — guardrails for unattended work, coordination for fleets.
Plumb is an MCP server that gives a coding agent the intelligence layer of an IDE — LSP-backed semantics, a tree-sitter code index, and project memory — inside guardrails: atomic, lock-serialised writes with transactional rollback, scoped filesystem and git access, and a daemon that survives its own crashes. And because every agent you run shares that one daemon, plumb is also the coordination layer between them: peers see the writes others made, message each other, and hand off work instead of duplicating it. A single binary; nothing else to install.
Why Plumb
LLM agents usually work by reading whole files into the context window — token-heavy, lossy at scale, blind to symbol semantics, and unsafe to let loose on a real repo. Plumb is built on four pillars, in priority order.
1. Reliability & write-safety
Leaving an agent to edit a codebase for an hour is only viable if writes can't corrupt files and a crash can't wedge your session.
Atomic I/O — every write is staged in a temp file and renamed into place. No partial writes, ever. Symlink-aware, CRLF-tolerant.
Per-path locking — the daemon serialises concurrent writes to the same file across every session and chat window. No races.
Multi-file transactions — apply edits across dozens of files with guaranteed atomic rollback if any step fails.
Crash-resilient daemon —
plumb serveis a reconnecting proxy. If the daemon crashes or hangs, it respawns one and replays the handshake; the agent never notices. In-flight writes are never silently re-run.Optimistic concurrency — mtime/sha guards catch stale edits before they clobber newer changes.
See it run: docs/demos/ — two-agents-one-file.sh (a stale write is refused, nothing is lost) and daemon-respawn.sh (below — the daemon is killed mid-session; the agent's next edit still succeeds):

2. Multi-agent coordination
One daemon serves every agent you run — which makes it the natural place for agents to see and talk to each other, not merely avoid each other's writes. Locks stop two agents corrupting a file; coordination stops them duplicating a task, rebasing onto a function signature a peer is mid-rewrite of, or shipping a change a peer's in-flight work is about to invalidate.
Peer awareness (on by default) —
workspace_sessionsnames every active session and the writes it made, as the daemon recorded them. Recorded activity, not another agent's say-so: an agent about to start a task can see that a peer is already in those files. (Read-only operations never appear, and a write that failed or was refused is kept but marked[failed — no change applied]— so "a peer is working here" and "this landed" are distinguishable at a glance.)An agent-to-agent mailbox (on by default, same workspace) —
leave_note/check_messagesgive sessions a threaded channel: hand a change to the peer already rewriting those files, or ask a peer to measure a behaviour instead of assuming it. Messages ride on ordinary tool results, so a working agent receives them without polling.Advisory intents (opt-in:
[collab] intents) —share_intentdeclares what an agent is working on; a peer whose write touches a claimed path gets a hint at the moment of the would-be collision. Intents are deliberately labelled as unverified claims, kept distinct from the daemon-recorded activity feed, and never block anything.Durable findings (opt-in:
[collab] knowledge_handoff) —share_findingsturns what an agent just learned into a searchable, secret-scrubbed project memory immediately, so the knowledge outlives the session that produced it.
Coordination is advisory by design — the write-safety above never depends on agents cooperating. Reference: Cross-agent sharing in the tool docs and the [collab] config section.
3. Semantic intelligence
The same primitives your editor has, exposed as structured tools:
LSP-backed refactors —
rename_symbol,replace_symbol_body,safe_delete_symbolunderstand scope, types, and references.Real diagnostics inline — actual
gopls/pyrightoutput is appended to every write, so the agent learns it broke the build immediately.Symbol search — scoped to your code, no stdlib or dependency noise.
4. Context efficiency & safety controls
Read only what you need — symbols or line ranges, not 2,000-line files.
Scoped access you control — a per-connection path allowlist (read-only vs read-write roots) plus tiered git gating (destructive and network operations are off by default and need explicit confirmation). See SECURITY.md.
One-round-trip bootstrap —
session_startreturns workspace, branch, recent commits, diagnostics, and project memory.
See the measured, reproducible numbers behind this: docs/use-cases.md — reading one function is 2.9×–33.4× less context than the whole file (the ratio is how much of the file you didn't need), and find_references returns the real call sites where a text search is 60% noise. The page publishes the losses too: read_multiple_files costs 1.31× more payload than reading the files natively (down from 1.32×, but still a loss — see Scenario 10 for why it isn't smaller). Every figure is regenerated by scripts/measure-use-cases.py.
Related MCP server: uacos
Get started
Plumb is a single binary — from zero to your first answer:
1. Install
# Homebrew (macOS + Linux) — recommended
brew install plumbkit/plumb/plumb
# or with Go
go install github.com/plumbkit/plumb/cmd/plumb@latest
# or grab a prebuilt binary: https://github.com/plumbkit/plumb/releasesmacOS note: prebuilt binaries are not yet notarised — on first run you may need
xattr -d com.apple.quarantine ./plumb, or right-click → Open. Homebrew installs avoid this.
2. Connect your agent
plumb setup claude-code # also: claude-desktop, codex, gemini, cursor, …plumb setup writes the MCP config for you — no hand-editing JSON.
3. Open your project and try it
Make sure the language server you need is on your $PATH (gopls for Go,
pyright for Python, …), then point your agent at a real question. In Claude
Code:
cd your/project
claude "Use plumb to orient in this repo (session_start), then show me
everywhere <Handler> is called and what would break if I changed its signature."Plumb resolves the workspace and runs session_start for orientation, then
answers with real LSP and topology data — actual call sites and blast radius —
instead of guessing from file dumps. It's read-only; nothing is modified. (Any
connected agent works — just paste the prompt.)
No
go.mod/pyproject.tomland not a git repo? Runplumb initonce to pin the workspace root (it also seeds.plumb/context.mdand project config).
Full walkthrough → docs/getting-started.md.
Language support (honest version)
Plumb negotiates LSP capabilities per language and also ships a built-in tree-sitter index for search and navigation with no language server. Support comes in tiers — we'd rather be precise than claim a big number.
Tier | Languages | What you get |
First-class (CI-tested, real-binary integration) | Go (gopls), Python (pyright) | Full LSP: definitions, references, rename, diagnostics, hierarchies + all write tools |
Validated | Java (jdtls), Rust (rust-analyzer), Swift (sourcekit-lsp), TypeScript/JS (typescript-language-server), Zig (zls), Kotlin (kotlin-lsp), HTML (vscode-html-language-server) | Full LSP; just put the server on |
Search & navigation (tree-sitter, no LSP needed) | 31+ incl. JS/TS/TSX, Ruby, C, C#, Elixir, Scala, PHP, JSON, CSS, SCSS, XML, Lua, C++, Objective-C, Dart, Bash, SQL, HCL, Dockerfile, TOML, YAML, Markdown | Ranked symbol search, outlines, graph exploration via the Topology index |
Real-binary validation has been exercised on macOS and Linux — as of 2026-08-21, all nine adapters pass their integration tests against real server binaries on both. Details, including three toolchain traps that look like adapter bugs, are in docs/adding-an-lsp.md. Windows is tracked but not yet supported — the daemon's Unix-socket architecture needs a port.
How it works
plumb serve is a thin, reconnecting stdio proxy. The real work happens in one shared background daemon, so language servers stay warm across chats.
flowchart TD
A1["Claude"] --> S1["plumb serve *"]
A2["Codex"] --> S2["plumb serve *"]
A3["Gemini"] --> S3["plumb serve *"]
S1 --> K["plumb.sock"]
S2 --> K
S3 --> K
K --> D["plumb daemon **"]
D --> SDB[("stats.db ***<br/>global — all projects")]
D --> G["gopls → /projects/foo"]
D --> P["pyright → /projects/bar"]
G --> F1[("/projects/foo/.plumb/ ***<br/>topology.db · memory.db")]
P --> F2[("/projects/bar/.plumb/ ***<br/>topology.db · memory.db")]* plumb serve is a reconnecting proxy — if the daemon crashes or hangs it respawns one and replays the handshake, so your session survives without the agent noticing.
** one shared process, reused across every conversation.
*** SQLite. One global stats.db (tool stats + episodic summaries); two per-project indexes under each workspace's .plumb/ — topology.db (the code graph) and memory.db (memory search). Schema details → docs/architecture.md.
Servers stay warm across chats, per-path locks are shared across every connection, and symbol indexes update live after each write. Full architecture → docs/architecture.md.
Monitoring (TUI)
Run plumb with no arguments for a live dashboard — see what your agent is doing in real time: every tool call as it happens, daemon health, per-tool stats, and streaming logs you can follow and filter. The fastest way to catch a runaway loop or confirm an edit landed.
Core capabilities
Plumb exposes 58 tools. The ones you'll use constantly:
session_start · workspace_symbols · get_definition · find_references · rename_symbol · edit_file · transaction_apply · diagnostics
The rest cover filesystem reads/writes, LSP hierarchies, tiered git, an optional local Topology index (ranked search + blast-radius/route analysis, no language server needed), durable per-project memory, and cross-agent coordination (peer sessions, an agent mailbox, opt-in intents and knowledge handoff). Full API reference: docs/tools.md.
Configuration
Global or per-project config.toml, or environment variables. Run plumb config show to see the resolved config with provenance.
[edits]
strict = true # require read_file before edit_file
rate_limit_per_minute = 30 # bound runaway agent loops
[git]
allow_destructive = false # reset/checkout/rebase off by default
allow_push = false # push/fetch/pull off by defaultFull settings reference: docs/configuration.md.
The hard part
Agents can already read code well enough; writing it unsupervised — concurrently, transactionally, recoverably — is what's still unsolved. Plumb is the bet that this is the half worth getting right first. It's early, and the language coverage says so: a small validated core, the rest clearly marked experimental.
Roadmap
Plumb is pre-1.0. The core — write-safety, the resilient daemon, the topology index, and project memory — is in daily use. The road to 1.0 is mostly about proving it beyond the validated core and smoothing distribution. Issues and ideas welcome.
Shipped
Concurrency-safe, atomic, transactional writes with rollback
Crash-resilient reconnecting daemon
Tree-sitter topology index + per-project memory
Cross-agent coordination: peer awareness + agent mailbox (default on), intents + knowledge handoff (opt-in)
Go and Python LSP adapters validated (real-binary)
Getting to 1.0. Rather than jump from 0.9 straight to 1.0, Plumb ships a series of focused minor releases — 0.10 through 0.19 — each with one coherent theme. 0.19.x is the last 0.x release; 1.0 follows it as a deliberate stability commitment. Native Windows support is intentionally a post-1.0 (1.1) item, not a 1.0 gate. The themed plan:
0.10 — distribution + honest claims (Homebrew, semantic re-rank → GA)
0.11 — validate the experimental LSP adapters on real binaries (zls ✓ validated; Kotlin ✓ validated on JetBrains' kotlin-lsp)
0.12 — Swift on Xcode via Build Server Protocol guidance
0.13 — daemon robustness (git-write crash safety, liveness probe)
0.14 — agent ergonomics + tool surface
0.15 — honesty + full config surface
0.16 — stabilisation + cross-platform proving
0.17 — distribution + discoverability (registries)
0.18 — proof + docs
0.19 — soak + feedback, the last 0.x (rolling patches, not a formal RC)
1.0 — general availability: the stability + validated-core promise
Full detail, rationale, and the post-1.0 items (Windows, tree-sitter cleanup) are in docs/roadmap.md.
Contributing
See CONTRIBUTING.md and AGENTS.md for architecture and code style. We follow Australian English in all prose. By contributing you agree to the Code of Conduct.
License
MIT — see LICENSE.
Available Tools
58 toolsagent_configA
Read and (when enabled) write a small allowlist of plumb config keys on the user's behalf — task commands ([tasks.]), log level, theme, topology excludes, quality analysers. op=describe lists exactly what you may write (always available); op=set writes a batch to the project's .plumb/config.toml, validated and applied all-or-nothing, tagged provenance=agent and one-step revertible (plumb config unset). Writing is OFF unless the user enabled [agent_config_writes]; safety-critical keys (git tiers, workspace roots, strict mode, API keys, the enable knob itself) are never writable. Use it to set up a repo's build/test commands from what you can read in the project.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | describe: list the config keys you are allowed to write (always available). set: write a batch of key/value pairs (only when the user has enabled [agent_config_writes]). | |
| set | No | For op=set: a map of dotted config key to value, e.g. {"tasks.go.test": "go test ./...", "log_level": "warn"}. Validated and applied atomically (all-or-nothing) to the project config; a key outside the allowlist is refused. | |
| scope | No | Write scope. Only "project" (the workspace's .plumb/config.toml) is supported; global writes are out of scope. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels: it discloses that write access is gated by a user setting, lists safety-critical exclusions, and explains atomicity, provenance tagging, and one-step revertibility. This is rich behavioral context beyond what the schema provides.
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 carries important information about permissions, atomicity, and usage. It is slightly long, but the detail is warranted for a security-sensitive config tool.
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 3-parameter tool with a nested object and no output schema, it covers operation semantics, write gating, allowed keys, and side effects well. The only minor gap is explicit error behavior when set is called while writes are disabled, but this is reasonably implied by 'Writing is OFF unless...'.
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 value by naming allowlisted key categories and giving an example (tasks.go.test). This goes beyond the schema's generic 'map of dotted config key to value' and helps the agent understand what can be set.
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 reads and conditionally writes a small allowlist of plumb config keys, listing specific categories like task commands, log level, and theme. It distinguishes itself by focusing on agent configuration management rather than general 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?
It provides a concrete use case ('set up a repo's build/test commands') and explains the describe/set workflow, indicating when to use describe first. It implicitly excludes general file edits but does not explicitly name alternative tools, which would push it to a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
call_hierarchyA
Show the call hierarchy for a symbol: who calls it (incoming) and what it calls (outgoing). PREFER a name (uri + symbol_name) — plumb resolves the exact identifier position for you, avoiding off-by-one errors; a raw file position (uri + line + character) is the fallback and, when it lands off an identifier, is snapped to the enclosing symbol. Useful for understanding control flow and assessing the impact of changes. When the language server provides no call hierarchy for the file (e.g. zls for Zig), falls back to the topology call graph, annotated source=topology (approximate).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path containing the symbol | |
| line | No | Zero-based line number of the symbol. Required when symbol_name is not provided. | |
| character | No | Zero-based character offset within the line. Required when symbol_name is not provided. | |
| direction | No | Which call direction to return: callers (incoming), callees (outgoing), or both. Defaults to both. | |
| symbol_name | No | Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and does well: it discloses the fallback to topology, marks it as 'approximate', explains the snapping behavior when a raw position lands off an identifier, and warns about off-by-one errors. No contradictions with annotations. Minor gap: no mention of return shape or pagination, but the key behaviors are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet information-dense. It front-loads the core purpose, then layers usage guidance, input preferences, and fallback behavior in a logical order. Every sentence adds value, and there is no fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two input modes, direction enum, fallback path), the description covers the essential aspects: what it does, preferred vs. fallback input, fallback to topology, and a use case. It does not describe the output structure (e.g., tree format), but in the absence of an output schema, this is a minor omission for a hierarchy tool.
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?
Even though schema coverage is 100%, the description adds meaningful semantics: it explains why symbol_name is preferred (avoids off-by-one and 'no identifier found' errors), describes the ReceiverType.MethodName form, and clarifies that line/character are unnecessary when symbol_name is provided. This goes 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 description clearly states 'Show the call hierarchy for a symbol: who calls it (incoming) and what it calls (outgoing)', using a specific verb and resource with scope. It distinguishes from siblings like find_references and type_hierarchy by explicitly naming the call direction and fallback behavior.
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 provides clear context: 'Useful for understanding control flow and assessing the impact of changes.' It also explains when the topology fallback applies (e.g., zls for Zig) and prescribes preferred input over fallback. However, it does not explicitly contrast with alternative tools like find_references, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_messagesA
Read messages other agents have sent you, optionally waiting for one to arrive. Receive half of plumb's mailbox; leave_note is the send half. Full etiquette — addressing, delivery, the exchange cap, cross-project rules: the plumb-chat skill.
Omit wait_seconds (or 0) to return immediately with whatever is waiting. A positive wait_seconds BLOCKS until a message arrives or the wait expires — hand your turn to a peer instead of polling. Capped by [collab] max_wait_seconds, kept below the client's own call timeout.
Each message is delivered exactly ONCE, to whichever path sees it first — this tool, the block appended to any tool result, or session_start. Re-calling will not redeliver it. Every message carries a conversation_id; quote it in leave_note to reply in thread.
Also reports your OWN unread mail — any message you sent that nobody has read yet, with its age, since plumb does not push and cannot otherwise tell "read, no answer yet" from "never read". Listing is a read; it never consumes the message on the recipient's behalf.
Requires [collab] mailbox = true.
Parameters: wait_seconds — block up to this long for a message (default 0, no wait).
| Name | Required | Description | Default |
|---|---|---|---|
| wait_seconds | No | Block up to this many seconds waiting for a message. 0 (default) returns immediately. Capped by [collab] max_wait_seconds. |
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 exceeds it: it discloses once-only delivery across three paths, that re-calling will not redeliver, that listing consumes nothing on the recipient's behalf, the blocking/timeout capping behavior, the [collab] mailbox = true requirement, and that plumb does not push. This is rich behavioral context far beyond what annotations would have supplied.
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 nearly every sentence carries unique behavioral or routing information. The final 'Parameters:' line mildly duplicates the schema's wait_seconds description, a small redundancy, but the density of genuinely new information justifies the length.
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 no output schema and no annotations, the description covers an exceptional amount: delivery paths, once-semantics, threading via conversation_id, own-unread reporting with age, config requirement, and wait capping. The one gap is the exact return shape/fields, which the description only touches via conversation_id and age; with no output schema, that duty falls on the description.
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 schema already fully defines wait_seconds including the cap. The description adds marginal strategic meaning beyond the schema — that a positive wait 'hands your turn to a peer instead of polling' and that the cap is 'kept below the client's own call timeout' — which an agent cannot infer from the bare parameter description.
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-plus-resource statement — 'Read messages other agents have sent you' — then scopes it precisely: 'Receive half of plumb's mailbox; leave_note is the send half.' It also discloses a second purpose (reporting your own unread mail), so an agent knows the full scope without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the sibling alternative (leave_note as the send half) and points to the plumb-chat skill for full etiquette rules. It gives explicit when-to conditions for the wait behavior ('hand your turn to a peer instead of polling') and explains the immediate-return path ('Omit wait_seconds (or 0) to return immediately'). Nothing about selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
copy_fileA
Copy a file to a new path, preserving file permissions. Parent directories of to are created if missing. Refuses to overwrite an existing destination unless overwrite=true. Cross-device copies are supported. Notifies the LSP server with FileCreated so diagnostics update immediately. To move or rename a file, use rename_file instead.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Absolute path, file:// URI, or workspace-relative path of the destination. Parent directories are created automatically. | |
| from | No | Absolute path, file:// URI, or workspace-relative path of the source file. | |
| dirty_ok | No | Allow copying a file that has uncommitted changes. Default false. | |
| overwrite | No | Allow overwriting an existing destination file. Default false. |
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 reveals that permissions are preserved, parent directories are created, overwrite is refused by default, cross-device copies work, and the LSP server is notified (FileCreated) for immediate diagnostics. This is comprehensive and goes well beyond the basic schema.
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 (three sentences) and well-structured: it starts with the primary purpose, then covers behavioral details, and ends with a pointer to an alternative. Every sentence contributes unique value; no fluff 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 file copy tool with four parameters and no output schema, the description provides complete context: purpose, key effects (permissions, parent directories, LSP notification), safety (overwrite refusal), technical capability (cross-device), and differentiation from sibling. The absence of an output schema is acceptable, as the description explains the outcome sufficiently.
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 parameters (to, from, dirty_ok, overwrite) are fully documented in the schema. The description adds slight context by reiterating overwrite behavior and parent directory creation, but these are already present in the parameter descriptions. Thus it meets the baseline without significantly enriching beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact action ('Copy a file to a new path') and explicitly distinguishes from the sibling 'rename_file' by instructing to use it for move/rename. It also names the resource and key behaviors clearly, leaving no ambiguity about the tool's purpose.
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 tells the user when to use an alternative tool ('To move or rename a file, use rename_file instead'), and provides usage context such as automatic parent directory creation, overwrite behavior with the overwrite=true flag, and cross-device support. This is clear guidance on when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
daemon_infoA
Returns metadata about the current MCP session and daemon process: session name (e.g. swift-falcon), session ID, daemon version, the source commit the binary was built from (with a dirty marker, or an explicit unknown), Go runtime, OS/arch, start timestamp, and uptime, plus the MCP protocol revision negotiated with this client (and, on a mismatch, the revision it offered and the capabilities it advertised), plus live config-store state (generation, last reload time, and whether a restart is needed for a pending restart-bound change), and — when available — this connection's workspace-pin provenance (how, when, and from where the pin was last set). It also reports this session's total tool-call count and its slowest calls (per-call durations from recorded stats). Use this to identify which session you are operating in or to verify the daemon state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility for behavioral disclosure. It goes into exceptional detail about what is returned, including conditions like 'when available' for workspace-pin provenance and 'on a mismatch' for protocol revision. It also reveals performance-related data (tool-call count, slowest calls) and config-store state, giving a thorough picture of the tool's observational nature.
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 primary purpose, but it consists of one extremely long, comma-heavy sentence that enumerates many details. While every detail is informative, the lack of sentence breaks makes it harder to parse. A shorter, bulleted or multi-sentence structure would improve readability without losing content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (no output schema, no annotations), the description compensates fully. It covers all return categories, conditional behaviors, and usage context, making it self-sufficient for an AI agent to understand what to expect. The lack of output schema is mitigated by the exhaustive list of returned metadata fields.
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 is empty (100% schema coverage by default). The description need not explain parameter meanings. Baseline for 0 params is 4, and there is no need to compensate further.
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 'Returns metadata about the current MCP session and daemon process' with a specific verb and resource. It enumerates the exact aspects covered (session name, ID, daemon version, etc.), making it easily distinguishable from sibling tools like workspace_symbols or read_file. The closing 'Use this to identify which session you are operating in or to verify the daemon state' reinforces the purpose.
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 guidance on when to use the tool: 'Use this to identify which session you are operating in or to verify the daemon state.' It does not explicitly mention alternatives or when not to use it, but given the uniqueness of the tool among its siblings, the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_fileA
Delete files and empty directories. Pass file_path for one, or paths for several in a single call (max 100). Refuses to delete directories unless allow_dir: true is set — and even then only an EMPTY directory is accepted (non-empty directories are always rejected; there is no recursive delete). To remove a whole tree, list its files with find_files and pass them plus their directories in one paths batch with allow_dir: true — every path is validated before anything is removed, and directories go last, deepest first, so they are empty by the time their turn comes. The LSP server is notified with FileDeleted so symbol indexes and diagnostics update immediately. Per-path locking serialises against any concurrent write_file/edit_file targeting the same path. The response reports the line and byte count removed (bytes only for a binary or oversized file).
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Several files and/or empty directories to delete in one call (max 100). Same per-path rules as file_path — this batches round-trips, it does NOT delete recursively. Every path is validated before any is removed, and directories are removed after files, deepest first, so naming a tree's files and its directories together works in one call. | |
| dirty_ok | No | Allow deleting a file that has uncommitted changes in its git repository. Default false — deletion is refused if the file is dirty. Pass true to proceed anyway. | |
| allow_dir | No | Allow deleting an empty directory. Default false — deletion is refused for any directory. The directory must be empty; non-empty directories are rejected even with allow_dir: true. | |
| file_path | No | Absolute path, file:// URI, or workspace-relative path of the file or empty directory to delete. Use paths instead to delete several in one call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure. It details the non-recursive delete restriction, the refusal of non-empty directories, validation before any removal, the order of directory deletion, LSP notification, per-path locking against concurrent writes, and the response report format. This is exhaustive for a complex mutation 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 long, but every sentence delivers new information—no filler. It front-loads the core action and follows with restrictions, deletion strategy, side effects, and response format. The structure is logical, though slightly dense; a compact breakdown of the tree-deletion workflow would improve scanability.
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 covers all necessary operational aspects: path types, batching limits, rejection rules, tree deletion method, concurrency behavior, side effects, and response contents. An agent has sufficient information to call this tool correctly without further inference.
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%, giving a baseline of 3. The description adds meaningful semantics beyond the schema: it clarifies that paths batches round-trips, enforces a max of 100, explains validation and ordering, and explicitly contrasts file_path with paths ('Use paths instead to delete several in one call'). This extra context moves it above baseline.
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 'Delete files and empty directories,' giving a specific verb, resource, and scope. It clearly distinguishes from siblings like write_file, edit_file, rename_file, and copy_file by focusing purely on deletion and adding the nuance that non-empty directories are rejected.
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 clarifies when to use this tool and how to handle tree deletion: 'To remove a whole tree, list its files with find_files and pass them plus their directories in one paths batch with allow_dir: true.' It also notes the batching alternative to file_path and warns against recursive deletion, giving the agent precise routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_memoryA
Delete a memory by name from a workspace's .plumb/memories/ directory.
Use only when explicitly asked, or when the memory has clearly become obsolete (e.g. it describes code that no longer exists).
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Memory name to delete. | |
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden for behavioral disclosure. It does specify the exact directory being modified and adds a safety condition, but it omits critical details such as permanence/irreversibility of deletion and error behavior. This leaves some ambiguity 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 two sentences long and front-loads the action and target. The second sentence adds a necessary usage boundary. There is no redundancy or filler; every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately explains what the tool does, where it operates, and when it should be used, which is sufficient for a simple delete operation with two well-documented parameters. It lacks explicit mention of irreversible consequences or return values, but those are not required given the absence of an output schema and the straightforward nature of the operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage for both parameters ('name' and 'workspace') with clear descriptions. The tool description does not add parameter-specific semantics, which is acceptable given the high schema coverage, but it also doesn't supplement any missing nuance about parameter usage.
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 action ('Delete a memory by name'), the specific resource (memory in .plumb/memories/ directory), and the workspace scope. This distinguishes it from sibling tools like delete_file and other memory operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence provides explicit usage guidance: 'Use only when explicitly asked, or when the memory has clearly become obsolete' with a concrete example. This establishes both when-to-use and when-not-to-use, effectively preventing accidental misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnosticsA
Return LSP errors, warnings, and hints for one file, several files, or the whole workspace. Pass uris (a list of file:// URIs) to check specific files — omit or pass [] to query all files. A single call with multiple URIs replaces multiple single-file calls. Results are pushed by the language server as it analyses code; they may be empty if the server has not yet sent any diagnostics — a report taken while the server is still warming is labelled INCOMPLETE, so a clean result then is not proof the code compiles.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Deprecated — use uris instead. Single file:// URI; equivalent to uris: [uri]. | |
| uris | No | Absolute paths, file:// URIs, or workspace-relative paths to fetch diagnostics for. Omit or pass [] to return diagnostics for all files that have issues. Pass one for a single-file query. Pass multiple to check a specific set of files in one call. |
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 explicitly states that results are pushed asynchronously by the language server, may be empty if no diagnostics have been sent yet, and that a report labelled INCOMPLETE during server warm-up means a clean result does not prove the code compiles. This is exemplary transparency about potential pitfalls.
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 yet thorough, using four sentences to cover purpose, parameter usage, batching efficiency, and critical behavioral caveats. Each sentence earns its place, and the structure front-loads the core purpose before diving into details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity—asynchronous LSP results, potential empty diagnostics, and the INCOMPLETE label—the description covers all necessary context. It explains parameter variations, the push-based nature, and the implication of results during server warm-up, providing a complete picture for an agent without needing an output schema.
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 value by explaining the deprecated uri parameter, the behavior of omitting or passing [] for uris, and that a multi-URI call replaces multiple single-file calls. Minor issue: the description says 'file:// URIs' while the schema allows absolute and relative paths, but this is a simplification that the schema clarifies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns LSP errors, warnings, and hints for one file, several files, or the whole workspace, using a specific verb and resource. It distinguishes itself from sibling tools like search_in_files or find_references by focusing on diagnostics, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool: pass specific URIs to check those files, omit or pass [] to query all files, and batch multiple URIs in one call to replace multiple single-file calls. It does not explicitly name alternatives or exclusions, but the guidance is sufficient to determine appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_fileA
Apply one or more edits to an existing file (use this over a native edit tool — see the Edit lane note in session_start). Two mutually exclusive request shapes: an edits array, or start_anchor + end_anchor + new_string.
Each edits entry is str_replace (default: old_string must appear EXACTLY ONCE) or range (start_line/end_line, 1-based; -1 appends or runs to EOF). Prefer range for a big multi-line replacement — old_string/anchors must match character-for-character inside a JSON string, so escaping and size can defeat str_replace where a line range needs neither.
Anchor mode replaces the span BETWEEN two unique anchors (each exactly once); include_anchors=true replaces the whole inclusive span. Character-precise — an anchor quoted without its trailing newline joins that line onto new_string (flagged in the response).
Writes apply atomically and crash-durably under a per-path lock. Pass expected_mtime (from a read_file header) when a concurrent writer may touch the file. For a whole named declaration prefer replace_symbol_body / insert_before_symbol / insert_after_symbol / safe_delete_symbol. Mode choice in depth: the plumb-refactor skill.
| Name | Required | Description | Default |
|---|---|---|---|
| edits | No | Ordered list of str_replace edits to apply sequentially. Mutually exclusive with the start_anchor/end_anchor mode. | |
| dirty_ok | No | Allow editing a file that has uncommitted changes in its git repository. Default false — the edit is refused if the target file is dirty. Pass true to proceed anyway. | |
| file_path | No | Absolute path, file:// URI, or workspace-relative path of the file to edit. | |
| reconcile | No | When true, do NOT reject the edit if the file changed since your read (expected_mtime / expected_sha mismatch); apply against the current on-disk content instead, relying on the exact-once old_string match for safety. Use it for the edit→format→edit loop, where a formatter bumped the mtime but your anchors still match. Default false. | |
| end_anchor | No | Anchor-bounded edit mode: a unique substring marking the END of the span to replace. Must appear EXACTLY ONCE and after start_anchor. Combine with start_anchor + new_string. | |
| new_string | No | Anchor-bounded edit mode: the replacement text for the span between (or, with include_anchors, including) the two anchors. Empty string deletes the span. Only used when start_anchor/end_anchor are set. | |
| expected_sha | No | Optional. Hex-encoded SHA-256 previously returned by read_file. If provided, the edit is rejected if the file's current content hash differs — stronger than expected_mtime, survives mtime aliasing. | |
| start_anchor | No | Anchor-bounded edit mode (alternative to edits): a unique substring marking the START of the span to replace. Must appear EXACTLY ONCE. Combine with end_anchor + new_string. Mutually exclusive with edits. CRLF / display-only gutter ("<n>\t") tolerated. | |
| apply_partial | No | When true, apply each edit independently and continue on failure instead of rolling back the entire batch. Returns a per-edit result list showing which edits succeeded and which failed. Incompatible with strict mode — not safe when concurrent agents share the file. | |
| expected_mtime | No | Optional. RFC3339Nano mtime previously returned by read_file. If provided, the edit is rejected if the file's current mtime differs — fast optimistic-concurrency check. | |
| include_anchors | No | Anchor-bounded edit mode: when true the anchors are part of the replaced span; when false (default) only the text strictly between them is replaced and both are preserved. | |
| await_diagnostics | No | When true, block up to a few seconds for the language server to finish re-analysing this file, and append a machine-readable 'diagnostics delta' line (fresh, new_errors, resolved, pre_existing). The block is always labelled — authoritative, pre-write snapshot, unverified, or not-analysed — so a stale result is never dressed as fresh. Default false (fast adaptive window; the result may predate the write). | |
| fail_on_new_errors | No | When true (implies await_diagnostics), roll this edit back if the language server CONFIRMS it introduced new errors here, leaving the file byte-for-byte unchanged and returning the delta as the error. An unconfirmed check never rolls back; nor do warnings, pre-existing errors, or breakage elsewhere. Not with apply_partial, or over 1 MiB. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses atomic crash-durable writes, per-path locking, dirty-file refusal and dirty_ok override, expected_mtime/expected_sha concurrency checks, exact-match rejection, anchor newline behavior, apply_partial failure continuation, diagnostics labeling, and fail_on_new_errors rollback behavior.
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 and front-loaded, with no filler sentences. It is somewhat long, and some details overlap with schema field documentation, but the length is justified by the tool's complexity and the absence of annotations.
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 13-parameter mutation tool with no output schema and no annotations, the description is remarkably complete. It covers modes, concurrency, atomicity, dirty-file handling, failure behavior, diagnostics, and how to select among alternative tools. The only minor omission is a formal return-shape description, but response behavior is alluded to in enough places.
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 baseline is 3, but the description adds substantial semantic value beyond the schema: mutual exclusivity of the two request shapes, when to prefer range mode over str_replace mode, exact-once uniqueness requirements, how anchors interact with spans, and the safety implications of reconcile, apply_partial, and fail_on_new_errors.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action and resource: 'Apply one or more edits to an existing file'. It also explicitly routes the agent away from a native edit tool and toward specialized symbol tools for named declarations, which distinguishes it from relevant 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?
Provides explicit when-to-use guidance: prefer this over a native edit tool, prefer range-based edits for large multi-line replacements, and prefer replace_symbol_body / insert_before_symbol / insert_after_symbol / safe_delete_symbol for whole named declarations. Also references a skill for deeper mode choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_symbolA
Returns DOCUMENTATION and type information (LSP hover content: function signature, doc comment, often in Markdown) for the symbol at the given position or by name. PREFER a name (uri + symbol_name) — plumb resolves the exact identifier position for you, avoiding off-by-one errors; a raw file position (uri + line + character) is the fallback and, when it lands off an identifier, is snapped to the enclosing symbol. Use when you need to understand what a symbol is without navigating to its source. For the file location of where the symbol is defined, use get_definition instead.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path of the document | |
| line | No | Zero-based line number. Required when symbol_name is not provided. | |
| character | No | Zero-based character offset. Required when symbol_name is not provided. | |
| symbol_name | No | Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed. |
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 discloses substantial traits: hover content format (Markdown), positional lookup fallback behavior, off-by-one error avoidance via symbol resolution, and snapping to the enclosing symbol when a position lands off an identifier. It does not state what happens when a symbol is not found, but it covers the major behavioral gotchas.
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?
Roughly four sentences, front-loaded with the primary purpose, followed by the preferred invocation path, the usage condition, and the sibling alternative. Every sentence earns its place, though it is slightly wordier than strictly necessary with some inline parentheticals.
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 moderate-complexity tool with no output schema and no annotations, the description covers the return format, both invocation modes, fallback behavior, and the alternative tool. The main missing piece is failure behavior (e.g., return value or error when the symbol cannot be resolved), which prevents a 5.
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, but the description adds genuine value beyond the schema: it establishes that symbol_name is the preferred invocation form and explains why (plumb resolves the identifier, avoiding off-by-one errors), and it describes how line/character behaves when it misses an identifier (snapped to the enclosing symbol). This preference ordering does not exist in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Returns DOCUMENTATION and type information (LSP hover content: function signature, doc comment, often in Markdown)'. It clearly distinguishes this from get_definition by explicitly naming the sibling, so an agent can tell them apart immediately.
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 an explicit when-to-use statement ('Use when you need to understand what a symbol is without navigating to its source') and names the exact alternative ('For the file location of where the symbol is defined, use get_definition instead'). It also instructs which invocation form to prefer (name over position), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
file_diffA
Returns a unified diff between two arbitrary files. Works outside git — for tracked files use the git tool's diff subcommand instead, which understands refs and the index. Use context_lines to control surrounding context and ignore_whitespace to skip formatting-only changes.
| Name | Required | Description | Default |
|---|---|---|---|
| file_a | Yes | Path to the first file (the 'before' side). Absolute path, file:// URI, or workspace-relative path. | |
| file_b | Yes | Path to the second file (the 'after' side). Absolute path, file:// URI, or workspace-relative path. | |
| context_lines | No | Lines of context shown around each change (default 3) | |
| ignore_whitespace | No | Ignore whitespace-only differences |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It clearly indicates a read-only diff operation, works outside git, and explains the effect of two parameters. It does not explicitly state that files are not modified, but that is implicit in the 'diff' operation. Slightly more detail about potential edge cases could improve it, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, stating the purpose in the first sentence. It contains only 41 words and every sentence carries functional information, such as the git alternative and parameter hints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, with all four parameters documented in the schema. The description clearly states the return format (unified diff), provides usage guidelines, and references relevant parameters. Given no output schema, the description adequately covers what is needed for an agent to invoke this tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all parameters with descriptions (100% coverage), so the baseline is 3. The description adds value by explaining how context_lines and ignore_whitespace affect the output, reinforcing the schema's semantics without merely duplicating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a unified diff between two files, with a specific verb and resource. It also explicitly contrasts with the git tool's diff subcommand, effectively distinguishing it from a sibling tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool instead of the git tool (for non-tracked files) and mentions how to control context and whitespace handling. This directly addresses usage alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
file_outlineA
Return a token-cheap skeleton of a file: every function, type, method, class, and constant as its signature line with the body collapsed, nested by containment, with byte-precise 1-based line ranges. Use it to understand a large file's shape in one call without reading it — a 2000-line file becomes a few hundred tokens. Symbols come from the language server when available, falling back to the tree-sitter topology index when the server is cold or does not cover the file (source is annotated). Set include_docs=false to omit leading doc-comment lines.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path of the file to outline. | |
| include_docs | No | Prepend the first line of each symbol's leading doc comment (// /// /** # styles). Default true. |
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 delivers: it describes the output format (signature lines, nesting, byte-precise line ranges), the fallback mechanism between language server and tree-sitter, the source annotation behavior, and the effect of include_docs=false. This is a rich, transparent account of what the tool actually does.
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 appropriately sized and front-loaded with the core purpose. Each sentence adds distinct information: what it returns, why to use it, the fallback source behavior, and the include_docs flag. No waste; 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 tool with no output schema and no annotations, the description is remarkably complete: it covers the return shape, use case, fallback behavior, and parameter semantics. The token-cheap rationale and the concrete example of a 2000-line file make it self-sufficient for an agent to decide when and how to invoke it.
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 documents both parameters at 100% coverage, so the baseline is 3. The description adds value beyond the schema by clarifying that include_docs controls whether leading doc-comment lines are prepended and that the default is true, which gives the agent meaningful behavioral context for parameter choice.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and resource ('a token-cheap skeleton of a file'), then enumerates exactly what is included: functions, types, methods, classes, constants with signature lines and collapsed bodies. It clearly distinguishes itself from siblings like read_file or read_symbol by emphasizing the high-level structural overview rather than content.
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 says to use this tool 'to understand a large file's shape in one call without reading it,' which gives a clear when-to-use context. It contrasts with reading the file itself by mentioning a 2000-line file becomes a few hundred tokens, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
file_statusA
Lightweight, read-only "did this file change under me?" check. For each path reports, without reading content: git_dirty (uncommitted changes vs git HEAD/index — untracked counts as dirty), changed_since_plumb_wrote (the on-disk mtime advanced since plumb last wrote it this session — a peer or external process edited it), last_writer (plumb = plumb wrote it last this session and it is unchanged; external = plumb wrote it but it has since changed on disk; unknown = plumb has not written it this session), plus mtime and size. Use before re-editing a file you read or wrote earlier to confirm your view is still current, instead of a blind re-read; pair changed_since_plumb_wrote / last_writer with a read_file to refresh when it reports drift. Missing files are reported, not an error. This is a status probe, not a content read — it does not satisfy strict mode's read-before-edit requirement.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Files to report on. Each is an absolute path, file:// URI, or workspace-relative path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses read-only semantics, that it does not read content, how fields like last_writer are determined, and that missing files are reported rather than causing an error. It also flags the strict mode limitation, adding valuable context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but tightly packed. It front-loads the core purpose, then details outputs, then gives usage guidance and exclusions. Every sentence adds necessary information; there is no verbiage 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?
There is no output schema, so the description must explain return semantics, which it does thoroughly by defining each field. It also covers edge cases (missing files), usage context (avoiding blind re-reads, pairing with read_file), and a key limitation (strict mode). Given the tool's complexity, the description is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single 'paths' parameter, so the baseline is 3. The description does not add new parameter-level detail beyond what the schema already states (absolute paths, file:// URIs, or workspace-relative paths), but it does reinforce that the tool reports per path without introducing ambiguity.
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 clear, specific verb and resource: "Lightweight, read-only 'did this file change under me?' check." It enumerates exact outputs (git_dirty, changed_since_plumb_wrote, last_writer, mtime, size) and explicitly notes it does not read content, distinguishing it from read_file and similar 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?
The description gives explicit when-to-use guidance: "Use before re-editing a file you read or wrote earlier to confirm your view is still current, instead of a blind re-read." It also names an alternative (read_file) and states when not to rely on it: "it does not satisfy strict mode's read-before-edit requirement."
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_filesA
Workspace-scoped file/directory finder and directory lister. Unlike shell find/fd/ls, results are confined to the active project (no .git/, node_modules/, build output, or anything else .gitignore excludes), every call is recorded in the project's stats, and the pattern semantics are consistent across hosts. pattern is optional — omit it to list everything. Supports glob and regex patterns, extension and type (file/dir/any) filters, depth limits (max_depth=1 lists one level, like ls), sort_by name/size/modified, and include_details for a per-entry [FILE]/[DIR]/[LINK] marker, size, and modified time.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Directory to search in (absolute path, file:// URI, or workspace-relative path). Defaults to the workspace root. | |
| type | No | Restrict to files, directories, or both. Default: 'file'. | |
| pattern | No | Glob (or regex if use_regex=true) matched against the file/directory name. When the pattern contains '/' it matches the full relative path. OPTIONAL — omit it to list every entry. A literal "." only matches a file named ".". | |
| sort_by | No | Order of the result list: 'name' (directories first, then path), 'size' (largest first), 'modified' (newest first). Default: name. | |
| extension | No | Filter by file extension, e.g. 'go' or '.go'. | |
| max_depth | No | Maximum directory depth to descend. 1 lists one level only, like ls. Default: unlimited. | |
| use_regex | No | Treat pattern as a regular expression instead of a glob. Default false. | |
| max_results | No | Maximum number of results to return. Default 500. | |
| include_hidden | No | Include hidden files and directories (starting with '.'). Default false. | |
| include_details | No | Render each entry with a [FILE]/[DIR]/[LINK] marker, its size and last-modified time (symlinks as 'name -> target') instead of a bare path list. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It reveals workspace scoping, .gitignore exclusion, stats recording, cross-host consistency, and optional pattern behavior. It also clarifies output formats (bare path list or details with markers), making the tool's behavior transparent despite being read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single block of four sentences, front-loaded with the core purpose, then contrasts with shell tools, then explains key behaviors. It is dense but every sentence contributes value; it lacks fluff, though it is longer than necessary compared to highly concise examples.
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 read-only search tool with 10 parameters and no output schema, the description is thorough: it covers purpose, scope, limitations, parameter behavior, and output formats. It is self-contained and leaves little ambiguity for an agent deciding when to invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all 10 parameters at 100% with detailed descriptions, so the schema carries the heavy lifting. The tool description adds a narrative summary (e.g., 'pattern is optional — omit it to list everything' and 'max_depth=1 lists one level, like ls'), but these points already exist in the schema, providing no additional meaning beyond what is already structured.
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 it is a 'Workspace-scoped file/directory finder and directory lister,' identifying the specific action and resource. It additionally distinguishes itself from shell find/fd/ls and sibling tools like search_in_files by clarifying its scope and function.
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 contrasts with shell find/fd/ls, highlighting the workspace confinement and .gitignore exclusions, which guides when to use this tool. It mentions consistent pattern semantics across hosts, but it doesn't explicitly reference sibling tools like search_in_files for content-based searches, leaving those alternatives unmentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesA
Find all references to a symbol across the entire workspace. Returns file path, line number, and the source line at each reference site. PREFER a name (uri + symbol_name) — plumb resolves the exact identifier position for you, avoiding off-by-one errors; a raw file position (uri + line + character) is the fallback and, when it lands off an identifier, is snapped to the enclosing symbol.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path of the document containing the symbol | |
| line | No | Zero-based line number. Required when symbol_name is not provided. | |
| character | No | Zero-based character offset. Required when symbol_name is not provided. | |
| symbol_name | No | Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed. | |
| include_declaration | No | Include the symbol's own declaration in results (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses return values (file path, line number, source line), the snapping behavior when a position lands off an identifier, and the advantage of using a symbol name. This goes beyond a simple statement of purpose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose, return values, and parameter guidance. It is front-loaded with the main function and contains no 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?
Given the tool's simplicity and the absence of an output schema, the description covers the essentials: what it does, what it returns, and how to provide input correctly. It could mention limitations or sorting order, but these are not critical.
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 value by explaining the preferred parameter combination (uri + symbol_name) and why it is preferred (avoiding off-by-one errors), as well as the fallback behavior. This clarifies the relationship between parameters beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Find all references to a symbol across the entire workspace.' This is a specific verb+resource with a clear scope, and the mention of 'across the entire workspace' distinguishes it from narrower symbol 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 clear guidance on how to call the tool (prefer a name over a raw position) but does not explicitly mention when to use this tool versus alternatives like get_definition or call_hierarchy. The use case is implied rather than explicitly contrasted with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_replaceA
Grep-equivalent: find text across files with optional replacement. Search and replace text across files in a directory tree.
Defaults to dry_run=true so you can preview the diff before committing. Set dry_run=false to write changes.
When the [edits].show_write_diff config flag is on (the default), the response appends a per-file unified diff — in both preview and applied modes — for up to the first 20 changed files, with a "+N more file(s)" summary beyond that. Set show_write_diff=false to suppress it.
Skips binary files (detected via null-byte sniff of the first 8 KB). Skips files larger than max_file_bytes (50 MiB default). Honours .gitignore. Use 'glob' to limit which files to touch (e.g. ".go", "**/.md"); a glob with a literal directory prefix (e.g. "src/**/*.go") prunes sibling directories from the walk entirely. Files are processed in parallel; output is sorted by path.
For identifier refactors use rename_symbol (scope- and type-aware); find_replace is for plain-text edits (doc strings, license headers, hostnames, version strings, non-code files).
| Name | Required | Description | Default |
|---|---|---|---|
| glob | No | File glob filter, e.g. '*.go' or '**/*.md'. Empty = all non-binary files. | |
| path | No | Directory to walk, or a single file. Absolute path, file:// URI, or workspace-relative path; defaults relative to the workspace root. | |
| dry_run | No | If true (default), preview only; do not write files. | |
| pattern | No | Search pattern. Plain text by default; regex if use_regex=true. | |
| dirty_ok | No | Allow editing files that have uncommitted changes in their git repository. Default false — the replacement is refused if any target file is dirty. Pass true to proceed anyway. | |
| max_files | No | Cap on number of files modified. | |
| use_regex | No | Treat pattern as a regular expression (Go RE2). Default false — pattern is literal text, so regex syntax such as | or \. matches itself. | |
| replacement | No | Replacement text. With regex, supports $1, $2 backreferences. | |
| format_after | No | After writing changes, run the workspace formatter (gofumpt for Go, ruff format for Python) on each modified file. Formatter errors are reported as warnings and do not fail the call. | |
| case_sensitive | No | Default: smart-case (case-insensitive iff pattern is all lowercase). | |
| max_file_bytes | No | Skip files larger than this many bytes. Default 50 MiB. |
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 delivers richly. It discloses the dry_run safety default, the show_write_diff config and its per-file unified diff output with the 20-file cap and '+N more' summary, the binary-file detection via null-byte sniff of first 8 KB, the max_file_bytes skip, .gitignore honoring, glob pruning behavior, and parallel processing with sorted output. This is comprehensive operational transparency well beyond the schema.
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 in the first sentence, followed by a natural progression: safety default, output format, skipping rules, and routing guidance. The prose is efficient; every sentence adds operational value. The only slight deduction is that a few details (glob pruning, parallel processing) could arguably be tightened, but the content is all high-value and nothing is wasted.
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 11-parameter tool with no annotations and no output schema, the description is unusually complete. It covers the safety default (dry_run), the accepted path formats (absolute, file:// URI, or workspace-relative), the output behavior (unified diff with file cap), skip rules (binary, size, .gitignore), glob semantics, formatting behavior after writes (with failure as warnings), and tool selection. An agent has everything needed to call it correctly and predict its effects.
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 semantic value beyond the schema: it explains the smart-case default behavior for case_sensitive, clarifies that replacement supports $1/$2 backreferences in regex mode, and clarifies the glob directory-prefix pruning optimization. However, it does not explicitly walk through every parameter (e.g., dirty_ok is covered in schema but not in the description prose). Given the high coverage, the added semantics push slightly above baseline but not to the top.
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+resource: 'find text across files with optional replacement' and immediately names the directory-tree scope. It explicitly contrasts itself with rename_symbol (scope/type-aware identifier refactor vs plain-text edits), which distinguishes it from the closest sibling. The title and verb are not merely restated; the description adds operational meaning.
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 is unusually explicit about usage: it states the default dry_run=true preview-first workflow, lists concrete applicability examples (doc strings, license headers, hostnames, version strings, non-code files), and names the alternative tool rename_symbol for identifier refactors. It effectively tells an agent when NOT to use this tool and which sibling to prefer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_definitionA
Returns the SOURCE LOCATION (file path + line number) of where a symbol is defined. PREFER a name (uri + symbol_name) — plumb resolves the exact identifier position for you, avoiding off-by-one errors; a raw file position (uri + line + character) is the fallback and, when it lands off an identifier, is snapped to the enclosing symbol. Use when you need to navigate to the implementation of a symbol. For documentation or type signatures at the same position, use explain_symbol instead.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path of the document | |
| line | No | Zero-based line number. Required when symbol_name is not provided. | |
| character | No | Zero-based character offset. Required when symbol_name is not provided. | |
| symbol_name | No | Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It goes beyond a simple definition lookup by disclosing fallback behavior ('snapped to the enclosing symbol') and the rationale for preferring symbol_name (avoids off-by-one and 'no identifier found' errors). It doesn't mention side effects or error cases, but for a read-only navigation tool, the disclosed behavior is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose, preference/behavior, and when-to-use/alternative. It is front-loaded with the most important information and contains no fluff 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 definition-lookup tool, the description covers purpose, input preferences, fallback behavior, and alternative tool. The absence of an output schema is mitigated by explicitly stating what is returned (file path + line number). All parameters are described in the schema, and the description adds the necessary contextual glue. Nothing critical 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% and each parameter is described, so the baseline is 3. The description adds meaningful semantic guidance by explaining why symbol_name is preferred over line/character and explicitly stating that line and character are not needed when symbol_name is provided. This goes beyond the schema's individual parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Returns the SOURCE LOCATION (file path + line number) of where a symbol is defined,' making the core purpose unmistakable. It also differentiates from the sibling explain_symbol by clarifying that this tool is for implementation navigation, not documentation or type signatures.
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 when you need to navigate to the implementation of a symbol') and names the alternative ('For documentation or type signatures at the same position, use explain_symbol instead'). It also provides a clear preference hierarchy: prefer symbol_name over raw line/character positions, with reasoning about avoiding off-by-one errors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gitA
Run git through one tiered, policy-gated tool (no shell, no agent-supplied command line). Read subcommands (status, log, diff, show, blame, shortlog, branch/tag/stash listing) always run. Write (add, commit, switch, mv, branch/tag create, stash push/pop) needs [git] allow_writes (default on). Destructive (reset, clean, checkout, restore, rebase, revert, cherry-pick, branch/tag delete, stash drop) needs allow_destructive AND confirm:true. Network (push, fetch, pull) needs allow_push AND confirm:true; force-pushing a protected branch or using an ad-hoc URL/remote is always refused.
add and commit are typed: add stages with -A semantics; commit takes message, plus an optional files list for a path-limited commit. Every other subcommand uses args.
Cross-session guard refuses a write/destructive/network op if a DIFFERENT session moved this repo's HEAD/branch since observed (override with confirm:true). expected_head pins the exact HEAD commit those ops must be at.
Full tier table, the cross-session guard, commit attribution, and the narrower plumb tool to prefer over a destructive git call: the plumb-git skill.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Flags and arguments passed directly to git for all subcommands except add and commit. Examples: ["--oneline", "-10"] for log; ["--cached"] or ["--staged"] for diff (shows staged changes ready to commit); ["--staged"] for restore. Ignored when subcommand is "add" (use files) or "commit" (use message). | |
| repo | No | Path to any file or directory inside the repository. Omit to use the attached workspace; if no workspace is attached the call is refused (git never falls back to the daemon's working directory). To operate on a nested git submodule, set this to a path inside the submodule — git resolves to the submodule's own root, so add/commit land there; a command run against the superproject only records the submodule's commit pointer, never its file contents. | |
| files | No | Paths to act on. For subcommand "add": paths to stage (-A semantics — new, modified, and deleted entries all staged). For subcommand "commit": optional path-limited commit — commits ONLY these tracked paths (git commit -m <message> -- <files>), ignoring any unrelated staged changes already in the index; omit to commit the whole index. No glob expansion. Ignored by other subcommands. | |
| confirm | No | Required (true) for destructive and network subcommands. Also required to override the cross-session ref-movement guard: when a DIFFERENT plumb session moved this repo's HEAD/branch since this session last observed it, a write/destructive/network op is refused until re-run with confirm:true. | |
| message | No | Commit message — only used for subcommand "commit". Maps to -m; pre-commit hooks always run. Combine with files to commit only specific paths. Not used by any other subcommand. | |
| subcommand | No | Git subcommand to run. Read (always): diff, log, show, blame, status, shortlog, check-ignore, plus branch/tag/stash listing. Write (needs allow_writes, default on): add, commit, switch, mv, branch/tag create, stash push/pop. Destructive (needs allow_destructive + confirm): reset, clean, checkout, restore, rebase, revert, cherry-pick, branch/tag delete, stash drop. Network (needs allow_push + confirm): push, fetch, pull. | |
| expected_head | No | Optimistic-concurrency guard for write, destructive, and network subcommands (mirrors edit_file's expected_mtime): any git revision (full/short SHA, branch, tag) naming the commit HEAD must be at. When supplied and HEAD resolves elsewhere — or resolves to nothing — the operation is refused before running, regardless of which session (or external tool) moved it. Ignored by read subcommands only. Omit for no check. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description thoroughly discloses behavioral nuances: cross-session guard, submodule resolution, fallback refusal, hook execution, and the exact effects of parameters like files and expected_head. No annotations are present, so the description carries the full burden and meets it comprehensively.
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 well-structured with clear sections, and every sentence carries meaningful information. Some redundancy exists (e.g., cross-session guard mentioned in both the main text and in confirm/expected_head), but overall it is efficiently organized and not overly verbose.
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 complexity of git, the description covers all relevant aspects: subcommand categorization, safety guards, file handling, repo resolution, submodule behavior, and hook execution. It leaves no significant ambiguity about how the tool behaves in various scenarios, making it sufficient for correct agent usage.
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?
Each of the 7 parameters has a detailed description covering usage, examples, side effects, and ignored contexts. For instance, args explains its role for non-add/commit subcommands, files clarifies staged vs path-limited commit semantics, and expected_head details optimistic concurrency behavior. Schema coverage is 100% and enriched with practical examples.
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 runs git subcommands, categorizes them into read/write/destructive/network, and lists exact subcommands for each, making the purpose unambiguous. It stands apart from sibling tools like git_init which initializes a repo.
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 explains when to use the tool (for git operations) and provides detailed conditions for confirm, expected_head, and repo usage. It implicitly distinguishes from other file-based tools by focusing exclusively on git operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
git_initA
Initialise a new git repository at the given path (git init). The directory is created if it does not exist. Set init_plumb: true to also create a .plumb/ workspace marker with a blank context.md, so plumb attaches to the project automatically on the next session.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Absolute path, file:// URI, or workspace-relative path of the directory to initialise as a git repository. Created if it does not exist. | |
| init_plumb | No | Also create a .plumb/ workspace marker with a blank context.md so plumb attaches to the project on the next session. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses a key side effect: 'The directory is created if it does not exist', and explains the init_plumb behavior. However, it does not mention whether re-initializing an existing repository is safe, what happens on failure (e.g., invalid path), or any output/return value. This is partial 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?
The description is two sentences, front-loaded with the core purpose, and every clause adds value. No wasted words or redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with two fully documented parameters and no output schema, the description covers the essential context: what it does, side effects, and the optional flag. It does not mention return values or prerequisites (e.g., git must be installed), but those are minor gaps for a common operation. The description is complete enough for an agent to invoke correctly in most cases.
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 both parameters have detailed descriptions. The description largely repeats the schema: 'path' is the directory to initialize, and 'init_plumb' is explained in the schema and again in the description. The description adds no new semantic information beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Initialise a new git repository') and the resource ('at the given path'), with the parenthetical '(git init)' reinforcing the exact command. This distinguishes it from sibling tools like the generic 'git' tool or file-write operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when initializing a repository) but provides no explicit guidance on when not to use it or alternatives, such as the sibling 'git' tool. It does not mention exclusions like 'use this only for new repositories' or 'for other git operations use git'. Context is clear but not formally differentiated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
insert_after_symbolA
Insert text immediately after a symbol's declaration.
Useful for adding a new method to a struct (insert after an existing one), or appending a related helper. Provide the full text to insert in 'content' — include leading newline if appropriate.
The response includes a unified diff of the change — a preview in dry-run, the applied change otherwise — unless show_write_diff is disabled.
Works even when the language server is cold or cannot parse the file: it then locates the symbol via a fresh tree-sitter parse (line-granular range, annotated in the output).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path. | |
| content | No | Text to insert after the symbol. | |
| dry_run | No | If true (default), preview only; do not write. | |
| dirty_ok | No | Allow editing a file with uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| name_path | Yes | Slash-separated symbol path within the file (e.g. "ClassName/methodName", or just "funcName" for top-level). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it explains the diff response, preview vs. applied change, and the tree-sitter fallback for cold/unparseable files. This goes well beyond the basic write semantics implied by the tool name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly-written paragraphs; each sentence conveys a distinct, useful point (use case, content formatting, response behavior, fallback). No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Explains the response (unified diff) and edge-case behavior, but does not cover symbol-not-found errors or the dirty_ok workflow beyond the schema, and references an out-of-schema parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all 5 parameters, so the baseline is 3; the description adds value by advising to include a leading newline in 'content' and mentioning a 'show_write_diff' option, though the latter is not in the schema (additionalProperties true).
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?
Clearly states the action ('Insert text immediately after a symbol's declaration'), specifies the resource (symbol), and differentiates from siblings like insert_before_symbol and replace_symbol_body by the positional scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use cases ('adding a new method to a struct', 'appending a related helper') that indicate when to apply it. Does not mention alternatives or exclusions, but the positional 'after' and sibling tools imply the boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
insert_before_symbolA
Insert text immediately before a symbol's declaration.
Useful for adding a new function/method before an existing one, or prepending a doc comment. Locates the symbol via the LSP document symbol tree (no manual line counting). Provide the full text to insert in 'content' — include trailing newline if appropriate.
Set include_doc_comment=true to insert before any existing leading doc comment instead of between the comment and the symbol — useful when adding a new function (with its own doc comment) above a function that already has one.
The response includes a unified diff of the change — a preview in dry-run, the applied change otherwise — unless show_write_diff is disabled.
Works even when the language server is cold or cannot parse the file: it then locates the symbol via a fresh tree-sitter parse (line-granular range, annotated in the output).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path. | |
| content | No | Text to insert before the symbol. | |
| dry_run | No | If true (default), preview only; do not write. | |
| dirty_ok | No | Allow editing a file with uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| name_path | Yes | Slash-separated symbol path within the file (e.g. "ClassName/methodName", or just "funcName" for top-level). | |
| include_doc_comment | No | If true, extend the operation to cover any contiguous comment lines (//, #, /*, *) directly above the symbol declaration. Lets you replace/delete a function together with its doc comment, or insert a new block above an existing doc comment instead of between the comment and its symbol. A WRAPPED declaration (an exported ES declaration under its export statement, a decorated Python def under its @decorator) keeps its doc comment above the wrapper, so WHEN SUCH A COMMENT EXISTS insert_before_symbol and replace_symbol_body extend past the wrapper — replacement content must then reproduce the export keyword or the decorator, or it is dropped. With no doc comment above the wrapper the range starts at the declaration and the wrapper is untouched; safe_delete_symbol never extends past the declaration at all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden of behavioral disclosure. It covers how symbol location works (LSP document symbol tree), the fallback to tree-sitter when the language server is cold or cannot parse, the response format (unified diff, preview vs. applied), and the effect of include_doc_comment on comment ranges and wrappers. This is rich, actionable 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?
The description is a moderately long paragraph, but each sentence contributes distinct, useful information: purpose, use cases, parameter guidance, output behavior, and graceful fallback. It is not as minimal as a two-sentence description, but given the tool's complexity, the length is justified and there is no obvious filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description is remarkably complete. It explains the operation, the location mechanism, the output (unified diff), the dry-run behavior, and the fallback path. It covers the nuanced doc-comment and wrapper behavior, and it even warns about trailing newlines. An agent can select and invoke this tool correctly with high confidence.
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 practical meaning beyond the schema by specifying that 'content' should be the full text with an appropriate trailing newline, that dry_run produces a diff preview, and by elaborating on include_doc_comment behavior (inserting before a doc comment, wrapper handling). It does not add much for uri, dirty_ok, or name_path, but those are already well described in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Insert text immediately before a symbol's declaration.' This clearly distinguishes it from siblings like insert_after_symbol, replace_symbol_body, and safe_delete_symbol, and the use cases ('adding a new function/method... or prepending a doc comment') reinforce the tool's specific purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool ('Useful for adding a new function/method before an existing one, or prepending a doc comment') and explains how include_doc_comment changes the operation. However, it does not explicitly name alternatives or state when not to use this tool versus siblings, so it stops short of a perfect 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
leave_noteA
Send a message to another agent — a named peer session, or "next" (whoever attaches to this workspace next). Send half of plumb's mailbox; check_messages is the receive half. Full etiquette — addressing, delivery, the exchange cap, cross-project rules: the plumb-chat skill.
Every message belongs to a thread: omit conversation_id to start one (the reply carries its id), or quote an id you were given to reply into that thread (to may then be omitted). A thread is capped at [collab] max_exchanges messages; once spent, replies are refused.
Delivery is by polling only, exactly once — via the next tool call, check_messages, or session_start. A peer idle on its human has not seen the message; silence is not refusal, so do not re-send.
Messages are bound to the exact SESSION when it is connected; a disconnected peer, or "next", is delivered by name instead. Cross-project sends need the recipient project's opt-in. Requires [collab] mailbox = true; the body is secret-scrubbed.
Parameters: body (required); to (peer session name or "next" — omitted means "next" on a new thread, the other participant on a reply); conversation_id (reply into an existing thread).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | A peer session name, or "next" for whoever attaches to this workspace next. Omitting it defaults to "next" when you are starting a thread; when you pass a conversation_id it instead resolves to that thread's other participant, and the send is refused if the thread has no other participant or more than one. A name belonging to a session in another workspace is refused up front unless that project has already opted in to cross-project messages. | |
| body | Yes | The message to send (free text). | |
| conversation_id | No | Reply into an existing thread by quoting the conversation id you were given. Omit to start a new thread. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It richly discloses delivery semantics (polling, exactly once, via next tool call/check_messages/session_start), session binding, 'silence is not refusal', the thread cap, and the secret-scrubbing requirement. This goes far beyond what the schema reveals.
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 sentence serves a purpose, covering addressing, threads, delivery, permissions, and configuration. The final 'Parameters:' paragraph is partially redundant with the schema, but it also provides a quick-reference summary without bloating the overall structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers nearly all practical invocation details: how to start or reply to a thread, what 'next' means, when re-sending is prohibited, what happens when the thread cap is reached, and the permission/config prerequisites. It even hints at the relevant return payload by saying the reply carries the conversation id, compensating for the absence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all three parameters at 100% coverage, so the description's parameter summary adds little new information. It does reinforce the 'reply carries its id' behavior and the omitted-default of 'next', but the schema contains these same nuances. A baseline 3 is appropriate given the high schema coverage.
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 action — 'Send a message to another agent' — and clearly distinguishes it from check_messages, the receive half. It also names the two addressing modes, 'named peer session' and 'next', so an agent immediately knows what the tool is for.
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 identifies check_messages as the counterpart for receiving, and specifies when to use 'to', when to omit it, and how conversation_id starts or continues a thread. It also covers prerequisites such as cross-project opt-in and the mailbox requirement, leaving little ambiguity about when the tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_memoriesA
List memories saved for a workspace.
Memories are markdown notes stored in /.plumb/memories/.md. They persist project-specific context — conventions, architectural decisions, gotchas — across MCP conversations. Each memory may have YAML frontmatter (name, description) used as a one-line summary in the listing.
If 'workspace' is omitted, the daemon's currently-resolved workspace is used.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the transparency burden. It discloses meaningful behavioral traits: memories are markdown notes at a specific path, persist across MCP conversations, may have YAML frontmatter used as a one-line summary in the listing, and fall back to the daemon's resolved workspace when 'workspace' is omitted. This goes beyond a basic one-liner, though it stops short of detailing output format or error behavior.
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: the primary action appears first, followed by necessary context in short sentences. Every sentence contributes meaning—storage location, persistence purpose, frontmatter behavior, and the default workspace fallback. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, single-parameter listing tool without an output schema, the description provides the essential context: what is listed, where memories live, how frontmatter influences the listing, and how the workspace default works. It does not describe sorting, error handling, or the exact return structure, but it is sufficiently informative for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the only parameter ('workspace') with 'Absolute workspace path. Defaults to the daemon's resolved workspace.' The description repeats this same information without adding examples, format details, or edge-case guidance. With 100% schema coverage, the description adds no extra value, so the 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 opens with a specific verb+resource: 'List memories saved for a workspace.' It clearly distinguishes the listing action from sibling tools like read_memory, search_memories, and delete_memory by focusing on the enumeration of all stored memories. Additional detail about markdown location and frontmatter summaries reinforces the purpose.
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 explains the memory concept and the default workspace behavior, which implies when to use this tool (e.g., when you need an overview of saved memories). However, it does not explicitly mention alternatives or state when not to use it, such as 'use search_memories to find by content' or 'use read_memory for a single memory.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
minimal_diff_reviewA
Reviews a diff for signs of over-building — findings NEVER block a write, they are hints. Deterministic, no LLM: it flags a single-use abstraction, a thin forwarding wrapper, a new dependency with a well-known stdlib equivalent, a possible duplicate helper, and a logic change with no accompanying test change. Evidence is asymmetric: a check stays silent unless it can point at concrete evidence and (where defensible) a smaller alternative, so silence is NOT proof a change is minimal. Findings are labelled by confidence: high = proven from the diff text; low = leans on the topology index, which is approximate (its call graph is intra-file — unlike find_references' exact cross-file lookup) and may be a few edits stale. Reviews the working-tree diff vs base_ref (default HEAD); pass files to scope it to your change in a shared worktree. Degrades cleanly outside a git repository.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | changed (default) reviews the working tree vs base_ref (all uncommitted changes); staged reviews only the index vs base_ref. | |
| files | No | Restrict the review to these paths (workspace-relative or absolute). Strongly recommended in a shared worktree so unrelated peer-agent edits are excluded. | |
| base_ref | No | Git ref to diff against (default HEAD, i.e. review uncommitted changes). | |
| max_findings | No | Cap on findings returned (default 20, max 100). | |
| include_suggestions | No | Include a concrete smaller-alternative line per finding (default true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: findings are never blocking, evidence is asymmetric (silence is not proof), confidence is labelled with specific limitations of the topology index (approximate, intra-file, possibly stale), and it degrades cleanly outside git. This exceptional transparency goes beyond typical tool descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph, front-loaded with purpose. Every sentence earns its place, but the length and run-on structure make it slightly harder to scan quickly. It could benefit from shorter sentences or bullet-like separation, yet it remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of explaining what to expect. It lists specific finding types, confidence levels, and the meaning of silence, which is substantial. It stops short of describing the exact return structure, but the behavior is well-covered for a review tool.
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 baseline is 3. The description adds practical meaning beyond the schema by explaining `files` scoping in shared worktrees and reinforcing the default behavior of base_ref. This added context elevates the score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Reviews a diff for signs of over-building'. It clearly distinguishes itself from siblings by contrasting its deterministic, no-LLM approach with find_references' exact cross-file lookup. The tool's unique role as a non-blocking minimality review is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context: reviews working-tree diff vs base_ref, recommends passing `files` in shared worktrees, and notes graceful degradation outside git. However, it does not explicitly name when not to use it or name alternative tools for raw diffs or cross-file reference checking, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_symbolA
Move a top-level declaration (function, method, type, const, or var) from one file to another within the SAME directory/package, atomically. The symbol's full source — declaration plus, by default, its leading doc comment (include_doc_comment) — moves from source_uri to destination_uri in one all-or-nothing operation: if the destination write fails the source is rolled back. Locates the symbol via the LSP document-symbol tree, falling back to tree-sitter when the language server is cold.
Scope (v1, conservative): source and destination must be in the SAME directory — plumb does not rewrite references or imports, so a move that would change a symbol's package or import path is REFUSED. destination_uri must already exist unless create_destination=true. Also refuses an ambiguous symbol (disambiguate with name_path), a path outside the workspace, or (Go) mismatched build constraints between source and destination.
Dry-run by default (dry_run=true): previews the unified diff without writing; set dry_run=false to apply. Undo is per-file — reverting a move takes two undo_edit calls. Scope rationale: the plumb-refactor skill.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | If true (default), preview the diff of both files only; do not write. | |
| dirty_ok | No | Allow moving when either file has uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| name_path | Yes | Slash-separated symbol path within the source file (e.g. "ClassName/methodName", or just "funcName" for a top-level declaration). | |
| source_uri | Yes | Absolute path, file:// URI, or workspace-relative path of the file currently holding the symbol. | |
| destination_uri | Yes | Absolute path, file:// URI, or workspace-relative path of the file to move the declaration into. Must be in the SAME directory (package) as source_uri. | |
| create_destination | No | Create destination_uri if it does not exist. Default false (the destination must already exist). A newly created Go file is seeded with the source file's package clause. | |
| include_doc_comment | No | Move the symbol's contiguous leading doc comment along with it. Default true — a relocated declaration should keep its documentation. Where the declaration is WRAPPED (an exported ES declaration under its export statement, a decorated Python def under its @decorator) its doc comment sits above the wrapper, so the moved range covers the wrapper too — which is what keeps @property with the method it decorates. |
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 does this thoroughly: atomicity (all-or-nothing with rollback), dry-run default, undo semantics (per-file, two undo_edit calls), refusal conditions (ambiguous symbol, path outside workspace, Go build-constraint mismatch), and the doc-comment wrapping behavior (ES export wrapper, Python decorator). It even explains the fallback from LSP to tree-sitter. This is exemplary transparency for a mutation tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured: a clear first sentence stating the core operation, then a 'Scope (v1, conservative)' section for constraints, then a 'Dry-run by default' section for behavior. Every sentence earns its place — the atomicity, rollback, refusal conditions, and undo semantics are all critical for correct invocation. The front-loading of the core operation and the scoped constraints makes it easy for an agent to quickly determine applicability. No fluff 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 complex mutation tool with 7 parameters, no annotations, and no output schema, the description is remarkably complete. It covers the operation's semantics (atomic move), constraints (same-directory, refusal conditions), defaults (dry_run, include_doc_comment), edge cases (wrapped declarations, Go package seeding), and post-conditions (undo requires two calls). The only minor gap is the exact return format of the dry-run diff, but the description says 'previews the unified diff' which is sufficient for an agent to know what to expect. Nothing critical 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 all 7 parameters. The description adds value beyond the schema by explaining the atomicity of the operation, the doc-comment wrapping edge cases (which clarify include_doc_comment), the rollback behavior, and the refusal conditions that affect how parameters like name_path and destination_uri are used. It doesn't add syntax details for the URI formats (the schema already covers those), but it enriches the semantics of the move operation itself. A 4 is appropriate because the description complements the schema without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Move'), a specific resource ('a top-level declaration... from one file to another'), and precise scope constraints (SAME directory/package, atomic). It clearly distinguishes this from siblings like rename_symbol, insert_before_symbol, replace_symbol_body, and safe_delete_symbol by describing the atomic move semantics and the refusal conditions. The purpose is unambiguous and actionable.
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 the tool (moving a top-level declaration between files in the same directory) and when NOT to use it (cross-directory moves that would change package/import paths are refused; ambiguous symbols are refused; Go build-constraint mismatches are refused). It also names the alternative for disambiguation (name_path) and the dry-run default, giving the agent clear decision criteria. The scope rationale ('plumb-refactor skill') further anchors usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutation_testA
Mutation-test your own assertions: apply an explicit mutant, prove it still COMPILES, run a scoped test set, classify the result, and restore the file — the check that tells a real assertion from a vacuous one. Takes explicit mutants only (file_path + exact-once old_string/new_string, like edit_file); it does not generate them. Three outcomes: KILLED (mutant compiled and a test failed — the assertion is real), SURVIVED (mutant compiled and every test still passed — the assertion is VACUOUS, the finding that matters), and INVALID (the mutant did not apply, did not compile, could not be started, or timed out — it proves nothing and is NEVER reported as a kill; that false kill is why the compile gate exists). Scope the run with test_target, which fills the stored test command's {target} placeholder (topology_affected says which tests to name) — the shipped go/python/rust test defaults carry one, so scoping works out of the box. Commands are the stored, trust-gated [tasks.] slots run_task uses; you cannot pass a command line. Restoration is guaranteed on every exit path (pass, fail, compile error, timeout, panic, cancellation): the pre-mutation bytes are snapshotted in memory, rewritten under the same per-path lock, and SHA-256-verified before the run is reported clean. It REFUSES to touch a file with uncommitted changes (untracked included), no override — a clean file means git checkout recovers it if the daemon dies mid-run; that is the recovery story. It also refuses to start unless the workspace BUILDS and its tests PASS unmutated: a kill means "green before, red after", so against an already-red suite every mutant reads as killed for a reason unrelated to it. The refusal says which happened — suite red, command timed out, or could not start — because only the first is about your code. One mutation run at a time per daemon; a second call is refused rather than queued.
| Name | Required | Description | Default |
|---|---|---|---|
| mutants | No | The mutants to test, applied and restored ONE AT A TIME. Each is an exact-once str_replace in the style of edit_file. | |
| test_task | No | Which stored [tasks.<lang>] slot runs the tests. Default "test". The built-ins are build, lint, test, e2e and verify; a project-defined slot works here too. | |
| test_target | No | Optional value for the test command's {target} placeholder — THE way to scope the run to the affected package or test instead of the whole suite (ask topology_affected which). The shipped go/python/rust test defaults carry a defaulted placeholder, so this works with no config edit; a hand-written test command needs a {target} token of its own or the target is refused. Scoping matters: each mutant costs a full compile+test cycle, so the whole suite per mutant is the difference between minutes and tens of minutes. One shell-safe argument ([A-Za-z0-9._/:@-]). | |
| compile_task | No | Which stored slot proves the mutant COMPILES before its tests are trusted. Default "build". It always runs unscoped (no {target}) — a whole-module compile catches breakage a scoped test never reaches. Cannot be disabled: without it a non-compiling mutant looks exactly like a kill. The built-ins are build, lint, test, e2e and verify; a project-defined slot works here too. | |
| timeout_seconds | No | Per-step timeout for the compile and test commands. Default 600. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure. It reveals the compile gate, the restoration guarantee on every exit path with SHA-256 verification, refusals on uncommitted changes and non-green suites, and the meaning of each outcome (KILLED/SURVIVED/INVALID). Nothing is left opaque.
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 long, every sentence adds essential information. The structure is logical: purpose → process → outcomes → scoping → commands → safety → constraints. It is front-loaded with the purpose and each segment earns its place; there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex, but the description covers all critical aspects: the exact process, the three outcome meanings, scoping via test_target and topology_affected, the stored command source, restoration guarantees, refusal conditions, and concurrency. It references sibling tools for supplementary info and fully explains the expected behavior even without an output schema.
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 schema already documents all 5 parameters. The description adds significant semantic value beyond the schema: exact-once requirement for old_string, empty-string deletion semantics, the {target} placeholder mechanics for test_target, the unscoped compile_task, and default timeout. This goes well past the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Mutation-test your own assertions') and outlines the full process (apply mutant, compile, run tests, classify, restore). It explicitly distinguishes itself from mutant-generating tools and references edit_file for exact-once str_replace semantics, making it clearly distinct 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 when-to-use (explicit mutants only, not generated) and when-not-to-use (uncommitted changes, non-green baseline, concurrent runs). It names sibling tools for supplementary decisions (topology_affected for scoping, run_task for stored commands) and states the single-run concurrency constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fileA
Read the text contents of a file (absolute path, file:// URI, or workspace-relative path). Use start_line/end_line to stream a slice of a large file. Each line is prefixed with a 1-based line number + tab (cat -n style) for exact range math; this gutter is display-only — strip the leading '\t' before reusing a line as an edit_file/find_replace old_string. Binary files are rejected; output is capped at 200 KiB (use line ranges on large files). The header carries the file's mtime (RFC3339Nano) and SHA-256 — pass them back as expected_mtime/expected_sha on edit_file for optimistic-concurrency checks. Pass pattern to search WITHIN the file instead of windowing: it returns each matching line with its 1-based line number (and optional context_lines), so an over-cap file stays searchable in one tool — literal text by default (smart-case: case-insensitive when all lowercase), Go RE2 regex when use_regex; output is bounded by max_matches (default 200) and labelled when truncated. Combine pattern with start_line/end_line to restrict the search to a line window; pattern with limit is rejected.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of lines to return starting at the first line (Claude Code-style window; first line defaults to 1). Mutually exclusive with end_line. Not usable together with pattern (search mode) — use max_matches instead. | |
| offset | No | First line to read, 1-based (Claude Code-style alias for start_line; start_line wins if both are given). | |
| pattern | No | Search the file for this pattern instead of returning a window: returns each matching line with its 1-based line number (and optional context), bounded output. Literal text by default; a regular expression when use_regex is true. The whole file is scanned line-by-line regardless of size, so an over-cap file stays searchable. Combine with start_line/end_line to restrict the search to that line window; not usable with limit. | |
| end_line | No | Last line to return (1-based, inclusive). Omit to read to the end of the file. | |
| file_path | No | Absolute path, file:// URI, or workspace-relative path of the file to read. | |
| use_regex | No | Treat pattern as a Go RE2 regular expression. Default false — pattern is literal text. Only consulted when pattern is set. | |
| start_line | No | First line to return (1-based, inclusive). Omit to start from the beginning. | |
| max_matches | No | Maximum number of matching lines to return in search mode. Default 200. Output is truncated (and labelled) beyond this. Only consulted when pattern is set. | |
| context_lines | No | Lines of context to show before and after each match (like rg -C). Default 0. Only consulted when pattern is set. | |
| case_sensitive | No | Force case-sensitive matching for pattern. Default (omitted): smart-case — case-insensitive when pattern is all lowercase, case-sensitive otherwise. Pass false to force case-INSENSITIVE matching even for an uppercase pattern. Only consulted when pattern is set. |
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 excels: it discloses the cat -n style line-number gutter and warns that it is display-only and must be stripped before reusing as an edit_file old_string. It reveals binary-file rejection, the 200 KiB cap, the header with mtime and SHA-256 for optimistic concurrency, smart-case matching, Go RE2 regex semantics, max_matches default and truncation labeling, and that pattern+limit is rejected. This is exemplary transparency beyond the schema.
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 sentence earns its place, with the core purpose front-loaded. It covers reading, windowing, formatting, output limits, header metadata, search mode, and option interactions in a logical progression. It loses one point for being a dense single wall of text; bullet points or short sections would improve scannability without sacrificing 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?
Given 10 parameters, no annotations, and no output schema, the description is remarkably complete. It explains the return format (line-number-prefixed lines, header with mtime and SHA-256), output limits, binary rejection, search-mode results with context, truncation labeling, and constraint combinations. There is no output schema to lean on, so this description fully compensates; an agent has everything needed to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description substantially enriches every parameter. It explains the meaning of the line-number prefix, the search-mode behavior of pattern (literal vs regex, smart-case, case_sensitive semantics), the default and effect of max_matches, context_lines analogized to rg -C, and the mutual-exclusion rules among limit, end_line, start_line, and pattern. This goes well beyond the baseline 3 for high schema coverage.
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 clear, specific verb and resource: 'Read the text contents of a file' with accepted path forms (absolute, file:// URI, workspace-relative). It also distinguishes the search-within-file mode from the plain windowing mode, so an agent can tell this tool apart from siblings like read_multiple_files or search_in_files without opening their 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 provides clear context for when to use different options: use start_line/end_line to stream slices of large files, use pattern to search within the file instead of windowing, and use line ranges to avoid the 200 KiB output cap. It explains when pattern and limit are mutually exclusive. However, it does not explicitly name sibling alternatives or state when NOT to use this tool in favor of another (e.g., search_in_files or read_multiple_files), so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_memoryA
Read a saved memory by name from a workspace's .plumb/memories/ directory.
Returns the full markdown content (including any frontmatter). Use list_memories first to discover what memories exist.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Memory name (alphanumeric, _, - only). | |
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well by revealing it returns the full markdown content including frontmatter, and names the specific directory. It does not cover error behavior or permissions, but for a read operation this is adequate.
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 two sentences long, front-loaded with the primary action, and every word earns its place. It is concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with two well-documented parameters and no output schema, the description is complete. It explains what is returned and provides a usage hint (list_memories first), making the tool fully understandable.
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% and the description adds no additional meaning over the schema. The description only repeats 'by name' and 'workspace' without adding constraints or clarifications beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a saved memory by name from a specific directory (.plumb/memories/). It uses a specific verb ('read') and resource (memory), and differentiates from siblings by focusing on the 'by name' access pattern.
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 advises using list_memories first to discover available memories, which provides context on when to use this tool. However, it does not mention alternatives like search_memories or read_file, so it lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_multiple_filesA
Read up to 20 files in a single call. Each file's content is returned under a '### ' heading, followed by that file's own read_file header (mtime, sha256, line and byte counts) so it can be edited without re-reading — reads ARE recorded per file, exactly like read_file, so edit_file works under [edits] strict mode with no re-read. Errors for individual files are reported inline — one unreadable file doesn't block the others. Accepts absolute paths, file:// URIs, or workspace-relative paths. Binary files are detected and skipped. Each file is subject to the same 200 KiB cap as read_file. Pass start_line/end_line or pattern (with use_regex/context_lines/max_matches) to slice or search EVERY path in the call uniformly — same semantics as read_file's own parameters, applied per file; there is no per-path override, so a windowed batch read still records EACH file's full mtime/sha in the read tracker (identical to read_file's own ranged-read behaviour — strict mode is mtime-based, not range-based, so a later edit anywhere in the file is still covered). The 20-path cap is unchanged by slicing.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Absolute paths, file:// URIs, or workspace-relative paths of files to read. | |
| pattern | No | Search EVERY path in this call for this pattern instead of returning a window — same semantics as read_file's pattern (literal by default, smart-case, Go RE2 regex when use_regex). Combine with start_line/end_line to restrict the search to that line window in every file. | |
| end_line | No | Last line to return (1-based, inclusive) from EVERY path in this call. Omit to read to the end of each file. | |
| use_regex | No | Treat pattern as a Go RE2 regular expression. Only consulted when pattern is set. | |
| start_line | No | First line to return (1-based, inclusive) from EVERY path in this call — same semantics as read_file's start_line, applied uniformly. Omit to start from the beginning of each file. | |
| max_matches | No | Maximum matching lines to return per file in search mode. Default 200. Only consulted when pattern is set. | |
| context_lines | No | Lines of context around each match (like rg -C), applied to every path. Default 0. Only consulted when pattern is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It thoroughly discloses important behaviors: reads per file are recorded, individual file errors do not block others, binary files are skipped, the 200 KiB cap applies, paths can be absolute/relative/URI, and strict mode coverage is based on mtime rather than ranges. This is exemplary for a tool missing structural annotations.
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 content is highly relevant and information-dense, but it is delivered as one large continuous block. Some important strict-mode concepts are explained more than once, which adds length without adding new value. The structure would be improved with bullets or labeled paragraphs for read behavior, search/slice behavior, and limitations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and lack of an output schema, the description covers all relevant dimensions: path input forms, limits, error isolation, file header output, binary skipping, search syntax, defaults, and strict-mode compatibility. An agent has enough information to invoke and interpret the tool safely.
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%, giving a strong baseline. The description adds meaningful semantic nuance beyond the schema by clarifying uniform application, no per-path overrides, how slicing interacts with read tracking, and how pattern plus start_line/end_line interact. This is valuable but somewhat narrative, so a 4 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 opens with a specific verb–resource statement: 'Read up to 20 files in a single call.' It also distinguishes itself from read_file by emphasizing batched reads, per-file headers, and cross-file parameter application, making its scope immediately identifiable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use this tool — multiple files, edit_file under strict mode, and avoiding re-reads. It doesn't explicitly name alternatives such as search_in_files for broader search or read_file for single-file reads, but the intended use case is strongly implied and anchored to read_file semantics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_symbolA
Read the source body of a named symbol (function, method, type) in one call. Accepts plain name or dotted ReceiverType.MethodName form. Returns all matches when the name is ambiguous. Each body line carries a display-only 1-based file line-number gutter ('\t', cat -n style) — strip it before reusing a line as an edit_file old_string. Falls back to a tree-sitter parse when the language server is cold or absent.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Alias for path (absolute path, file:// URI, or workspace-relative path). Used only when path is omitted. | |
| name | No | Exact symbol name. Accepts plain name (e.g. "handleConn") or dotted ReceiverType.MethodName form (e.g. "Model.renderDashboard"). | |
| path | No | Absolute path, file:// URI, or workspace-relative path of the file containing the symbol |
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 discloses ambiguity handling ('Returns all matches when the name is ambiguous'), the line-number gutter caveat with specific stripping instruction for edit_file reuse, and the tree-sitter fallback when the language server is cold or absent. This goes well beyond basic read semantics, though error cases like symbol-not-found are not explicitly mentioned.
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 four sentences long and front-loaded with the core action. Each sentence adds distinct value: the action, accepted input forms, ambiguity behavior, output format caveat, and fallback mechanism. There is no fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with no annotations or output schema, the description sufficiently covers return behavior (all matches), ambiguity handling, output line-number gutter instructions, and language-server fallback. The only minor gap is the absence of a symbol-not-found behavior note, but overall it is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage for all three parameters, so the baseline is 3. The description echoes the dotted-name form present in the schema but adds no new parameter-level nuance; it focuses on output formatting and fallback behavior rather than parameter meanings.
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 action: 'Read the source body of a named symbol (function, method, type) in one call,' clearly identifying the resource and scope. It distinguishes itself from siblings like get_definition and read_file by focusing on the symbol body retrieval rather than definition location or whole-file content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through phrases like 'in one call' and accepts plain or dotted forms, but it does not explicitly state when to prefer this tool over alternatives such as get_definition or search_in_files. No exclusions or direct comparison to siblings are provided, leaving the agent to infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relevant_memoriesA
Return memories whose frontmatter 'paths:' globs match the given file.
Memories can be auto-attached to specific parts of a project by adding a 'paths:' field to their frontmatter (e.g. 'paths: internal/auth/**, cmd/server/*.go'). This tool surfaces only the memories relevant to a given file — much smaller than list_memories when many memories exist.
Call this when starting work on a file to discover context the LLM should load before editing.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | File path. Either absolute or relative to the workspace. | |
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It explains the matching mechanism (frontmatter 'paths:' globs), gives concrete examples of glob patterns, and states the behavioral outcome: 'surfaces only the memories relevant to a given file.' It does not detail return format or edge cases, but given the simplicity of the tool, this is adequate 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?
The description is concise and well-structured: first sentence states the core function, second provides context and an example, third gives usage guidance. Every sentence contributes value with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description sufficiently explains the matching logic, the use case, and how it relates to list_memories. It does not verbosely describe return format, but given the memory tools family this is acceptable. The description is complete enough for an agent to know when to use it and what to 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?
Schema coverage is 100% (both parameters have descriptions). The description adds no parameter-level information beyond what the schema already states; the example glob patterns apply to memory frontmatter, not the tool's parameters. Per calibration, baseline 3 is appropriate when schema covers all parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: 'Return memories whose frontmatter 'paths:' globs match the given file.' It uses a specific verb and resource, and explicitly distinguishes itself from sibling tools like list_memories by emphasizing it returns a much smaller set. This makes the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: 'Call this when starting work on a file to discover context the LLM should load before editing.' It also contrasts with list_memories ('much smaller than list_memories when many memories exist'), implicitly indicating when this tool is preferable and hinting at an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_fileA
Move (rename) a file. Parent directories of to are created if missing. Refuses to overwrite an existing destination unless overwrite=true. The LSP server is notified with FileDeleted (source) and FileCreated (destination) so symbol indexes and diagnostics update immediately. To duplicate a file without removing the source, use copy_file instead. For LSP-semantic identifier renames across files, use rename_symbol instead.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Absolute path, file:// URI, or workspace-relative path of the destination file. Parent directories are created automatically. | |
| from | No | Absolute path, file:// URI, or workspace-relative path of the source file. | |
| dirty_ok | No | Allow moving a file that has uncommitted changes in its git repository. Default false — the move is refused if the source file is dirty. Pass true to proceed anyway. | |
| overwrite | No | Allow overwriting an existing destination file. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it delivers: it discloses parent directory creation, overwrite refusal unless overwrite=true, and the LSP FileDeleted/FileCreated side effects that update symbol indexes and diagnostics. The dirty_ok behavior is left to the schema, which is acceptable because the schema describes it fully. It does not mention the return value, but that is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: purpose, parent-directory behavior, overwrite policy plus LSP side effects, and alternative tools. It is front-loaded and free of fluff — a model of concise, high-signal documentation.
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 mutation tool with LSP side effects, the description adequately covers the core behavioral expectations, notes the overwrite safety, and points to alternatives. The schema fills in parameter details (e.g., dirty_ok, from/to formats). It lacks an explicit statement about return value or error behavior, but no output schema exists and the description is still sufficient for safe use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all 4 parameters with detailed descriptions, so the baseline is 3. The description adds minimal extra meaning: it restates that parent directories are created and that overwrite is refused unless overwrite=true, both already in the schema. No unique parameter semantics beyond the schema are provided.
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 'Move (rename) a file' — a clear verb+resource pair that states exactly what the tool does. It explicitly distinguishes itself from copy_file (duplicates) and rename_symbol (LSP-semantic identifier renames), so the agent knows its unique scope.
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 when-not-to-use guidance: 'To duplicate a file without removing the source, use copy_file instead' and 'For LSP-semantic identifier renames across files, use rename_symbol instead.' This gives clear alternatives and helps the agent select the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_sessionA
Renames the current MCP session. Pass the new name as the name parameter — letters (any case), digits, and hyphens, capped at 25 characters, with no leading/trailing or consecutive hyphens. User-provided case is preserved; auto-generated names are lowercase. The name must be free: a session name is the address the mailbox delivers to, so a name another LIVE session already answers to is refused (compared case-insensitively) and "next" is reserved for the next-arrival address. Renaming to the name you already hold is fine.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New session name. Letters, digits, and hyphens only; max 25 characters. Cannot start/end with hyphen or contain consecutive hyphens. Case is preserved as entered. Must not be a name a live session already uses, and must not be 'next'. |
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 an excellent job by covering case preservation, case-insensitive uniqueness checks, reservation of 'next', and the allowance of renaming to the current name. It does not mention side effects like return values or persistence, but the naming-related behavior is thoroughly explained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph of four sentences, all of which contribute useful information. It front-loads the core purpose and then details constraints. It does repeat some schema information, but the added context justifies the length. It is appropriately concise given the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete regarding naming rules and rejection criteria, but it does not mention what happens on success (e.g., return value or confirmation). Since there is no output schema, the description should ideally provide some hint about the result. It also does not state whether the rename affects existing messages or other sessions. This gap prevents a higher score.
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 context beyond the schema by explaining the mailbox analogy, case-insensitivity, and the fact that renaming to the same name is allowed. This enriches the parameter semantics without contradicting the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Renames the current MCP session', which is a specific verb+resource that clearly distinguishes it from sibling tools like rename_file and rename_symbol. It also includes sufficient detail about naming rules to eliminate ambiguity.
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 explains the operation and its constraints, but it does not explicitly state when to use this tool versus alternatives, nor does it mention any exclusions or situations where other tools would be preferred. The context implies usage (when you need to rename the current session) but lacks explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_symbolA
Rename a symbol throughout the workspace using LSP semantic refactoring.
The language server identifies every reference across all files and applies a precise edit set atomically. Safer than text find-and-replace: it understands scope, shadowing, and types, so it won't rename unrelated identifiers that share the name.
Prefer symbol_name to identify the symbol; plumb resolves it through the document-symbol tree and queries the language server at the exact identifier position. Raw line/character remains supported and recovers from narrow "no identifier" misses by snapping once to the enclosing symbol. Runs in dry_run mode by default; set dry_run=false to apply. The response appends a per-file unified diff (a preview in dry-run, the applied change otherwise), capped at 20 files, unless show_write_diff is disabled.
If the language server cannot compute the rename (an error, or an empty edit set — common with sourcekit-lsp before the build graph resolves), pass structural_fallback=true to attempt a best-effort identifier-boundary text rename via find_replace (still dry_run by default). The fallback is NOT scope-aware — it renames every whole-word occurrence in same-extension files — so review the preview before applying.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path. | |
| line | No | Zero-based line of the identifier. Required when symbol_name is not provided. | |
| dry_run | No | If true (default), preview changes only. | |
| dirty_ok | No | Allow editing target files with uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| new_name | Yes | Replacement identifier name. | |
| character | No | Zero-based character offset within the line. Required when symbol_name is not provided. | |
| symbol_name | No | Symbol name to rename instead of a raw position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. When provided, line and character are not needed. | |
| structural_fallback | No | If true, and the language server cannot compute the rename, attempt a best-effort, identifier-boundary text rename via find_replace (NOT scope-aware; honours dry_run). Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries full burden. It discloses atomic edits, dry_run default, response diff preview capped at 20 files, fallback not being scope-aware ('renames every whole-word occurrence'), and dirty_ok behavior. These are concrete behavioral traits beyond the schema's parameter descriptions.
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?
Every sentence earns its place. The description is organized into three focused paragraphs: core semantics, parameter guidance, and fallback behavior. No fluff; even the repeated dry_run reminder reinforces safety-critical 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?
Given that there is no output schema and no annotations, the description fully compensates: it explains the tool's purpose, identification methods, default behavior, response format (per-file unified diff capped at 20 files), fallback conditions, and limitations. For a complex LSP-dependent tool, this is complete enough for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning beyond the schema: it specifies symbol_name is preferred over line/character, explains how plumb resolves it through the document-symbol tree, and describes snapping recovery for raw positions. It also clarifies when structural_fallback should be used relative to language server failures.
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?
Description opens with 'Rename a symbol throughout the workspace using LSP semantic refactoring' – a specific verb, resource, and mechanism. It explicitly distinguishes itself from text find-and-replace by mentioning scope/shadowing/type awareness, which differentiates it from sibling find_replace and rename_file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: 'Prefer symbol_name to identify the symbol', explains when fallback is appropriate ('If the language server cannot compute the rename... pass structural_fallback=true'), and contrasts with find-and-replace ('Safer than text find-and-replace') to aid tool selection. It also notes dry_run default and review-before-apply for the fallback.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replace_symbol_bodyA
Replace the entire declaration of a symbol with new content.
The replacement spans the symbol's full Range as reported by the LSP — for a function, this is from 'func' keyword through the closing '}'. Provide the complete new declaration (signature + body) in 'content'.
Set include_doc_comment=true to also cover any contiguous doc comment above the symbol — gopls and most LSP servers report the symbol range starting at the declaration keyword, so without this flag the old doc comment is left orphaned. With it on, your 'content' must include the new doc comment too (or the symbol will have none).
Use rename_symbol if you only want to change the symbol's name. Use this tool when changing logic, signature, or both — addressed by name_path, no line/character coordinates to compute like edit_file's range mode.
The response includes a unified diff of the change — a preview in dry-run, the applied change otherwise — unless show_write_diff is disabled.
Works even when the language server is cold or cannot parse the file: it then locates the symbol via a fresh tree-sitter parse (line-granular range, annotated in the output).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path. | |
| content | No | The full replacement declaration. | |
| dry_run | No | If true (default), preview only; do not write. | |
| dirty_ok | No | Allow editing a file with uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| name_path | Yes | Slash-separated symbol path within the file (e.g. "ClassName/methodName", or just "funcName" for top-level). | |
| include_doc_comment | No | If true, extend the operation to cover any contiguous comment lines (//, #, /*, *) directly above the symbol declaration. Lets you replace/delete a function together with its doc comment, or insert a new block above an existing doc comment instead of between the comment and its symbol. A WRAPPED declaration (an exported ES declaration under its export statement, a decorated Python def under its @decorator) keeps its doc comment above the wrapper, so WHEN SUCH A COMMENT EXISTS insert_before_symbol and replace_symbol_body extend past the wrapper — replacement content must then reproduce the export keyword or the decorator, or it is dropped. With no doc comment above the wrapper the range starts at the declaration and the wrapper is untouched; safe_delete_symbol never extends past the declaration at all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the transparency burden. It discloses the LSP range semantics (from 'func' keyword through closing '}'), the orphaned doc comment behavior when include_doc_comment is false, the tree-sitter fallback when LSP is cold, and the unified diff/dry-run response behavior. This is rich, actionable behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although long, the description is appropriately sized for the tool's complexity. It is front-loaded with the core purpose, then systematically covers usage alternatives, response behavior, fallback modes, and edge cases. Every sentence earns its place; there is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a complex mutation tool. It covers the diff response and dry-run behavior, the cold-LSP fallback with annotated output, doc comment edge cases including wrappers, and distinguishes itself from related siblings. No output schema exists, but the described return value (unified diff) suffices.
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%, giving a baseline of 3, but the description adds substantial meaning beyond the schema: what 'entire declaration' means, the need to include full signature and body, the doc comment flag's wrapper/export/decorator implications, and the name_path addressing model compared to edit_file. This goes well beyond the individual parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+scope: 'Replace the entire declaration of a symbol with new content.' It clearly distinguishes itself from rename_symbol ('Use rename_symbol if you only want to change the symbol's name') and positions itself for logic/signature changes, making the purpose unmistakable.
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 names alternatives and gives when-to-use guidance: use rename_symbol for name-only changes, use this for logic/signature changes, and contrasts with edit_file's coordinate-based range mode. Also explains when to set include_doc_comment and the wrapper/decorator caveat, providing clear context for decision-making.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_commandA
Run a named command from the workspace's [[command]] allow-list (build/test/lint/scripts) without leaving plumb. It runs only the exact fixed argv the user configured (no shell, no agent-supplied command line); the optional target fills a single {target} placeholder with one shell-safe argument. A command from a project's .plumb/config.toml must be trusted first (run plumb trust); a command from your global config always runs. The command runs under an OS sandbox (a write jail) when one is available. Output and runtime are bounded. For an ordinary build/lint/test, prefer run_task and its [tasks.] slots — those ship with defaults.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The name of an entry in the [[command]] allow-list (in global or project .plumb/config.toml). You cannot pass an arbitrary command line — only a configured name. | |
| target | No | Optional value substituted for the single {target} token in the command's fixed argv (e.g. a test name or package). Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the command has no {target}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full weight and does so thoroughly. It discloses no shell interpolation, no agent-supplied command line, an OS write-jail sandbox when available, and bounded output/runtime. It also warns about the trust step, which is exactly the kind of behavioral context an agent needs before invoking a command executor.
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 first sentence states the primary purpose immediately, and every subsequent sentence adds a distinct constraint: fixed argv, target placeholder, trust, sandbox, bounded resources, and the run_task alternative. There is no filler or redundancy; the length is justified by the tool's power and risk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no output schema and no annotations, the description still tells an agent everything essential to invoke it correctly: what names are valid, how target is constrained, when trust is needed, what sandboxing applies, and when to use a sibling instead. The only omitted detail, exact output formatting, is not needed for correct selection and invocation of a command-runner.
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 fully documents both name and target. The description mostly restates schema facts (allow-list entry, one shell-safe argument, {target} placeholder) rather than adding new parameter-level meaning. It adds useful surrounding context about trust and global config, but that is behavioral context, not new parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: run a named command from the workspace's [[command]] allow-list. It differentiates itself from siblings by stressing the fixed argv model and explicitly pointing to run_task for ordinary build/lint/test work. An agent can distinguish this from write_file, git, or run_task without opening 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?
It gives crisp selection guidance: prefer run_task for routine build/lint/test tasks, and use run_command when a configured allow-list command is needed. It also states the trust prerequisite for project-local commands and notes that global-config commands always run. This tells the agent both when to use the tool and when to pick a sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_taskA
Run a stored per-language task command — build, lint, test, e2e, verify, or a project-defined slot — configured in [tasks.]. It executes only the command the user saved for this workspace's language (no shell, no agent-supplied command line); the optional target fills a {target} placeholder with one shell-safe argument, and the shipped test defaults carry one so scoping needs no config edit. Commands run from the workspace root, or from [tasks.] working_dir when the module lives in a subdirectory. A project-supplied (.plumb/config.toml) command must be trusted first (run plumb trust); the shipped defaults and global-config commands always run. Output and runtime are bounded. Pairs with topology_affected (which says WHICH tests to run; this runs them).
| Name | Required | Description | Default |
|---|---|---|---|
| slot | No | Which stored task command to run: build, lint, test, e2e, verify, or a project-defined slot under [tasks.<lang>]. session_start lists what's configured; an unconfigured slot is refused with that list. | |
| target | No | Optional target substituted for a {target} token in the stored command (e.g. a single test name or package). The shipped go/python/rust test defaults carry a defaulted placeholder ({target:./...}), so scoping works with no config edit and omitting the target still runs everything. Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the command has no {target} slot. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and is unusually transparent: it discloses trust requirements for project configs, cwd behavior, command provenance, target restrictions, and bounded output/runtime. This gives the agent accurate call-time expectations.
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?
Every sentence adds a distinct non-obvious fact: what is run, trust requirements, cwd, target semantics, and pairing with topology_affected. The core purpose is front-loaded, and the density is justified by the tool's complexity.
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 side-effecting task runner with no annotations or output schema, the description covers the critical prerequisites: trust, working directory, no arbitrary shell, bounded execution, and relationship to topology_affected. The only notable omission is a precise statement of what the tool returns on success/failure, though 'output and runtime are bounded' gestures at it.
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 both slot and target already have detailed descriptions including allowed values, placeholder semantics, regex restriction, and refusal behavior. The prose description restates this information without adding materially new parameter meaning, so the baseline 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 first sentence identifies a specific action ('Run a stored per-language task command') and a concrete resource ([tasks.<lang>] slots), enumerating build/lint/test/e2e/verify. The explicit contrast 'no shell, no agent-supplied command line' separates it from arbitrary command runners like run_command without ambiguity.
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 run_task applies (stored, per-language task slots; paired with topology_affected for which tests to run) and when it does not (no agent-supplied shell command, project configs must be trusted first). It stops short of naming run_command as the alternative for arbitrary commands, but the exclusion is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
safe_delete_symbolA
Delete a symbol's declaration only if it has no remaining references.
Calls LSP textDocument/references first. If any reference outside the declaration itself is found, the deletion is rejected with the list of referencing locations so the caller can decide what to do. This prevents accidental deletion of code that's still in use.
Set include_doc_comment=true to also delete any contiguous doc comment above the symbol — otherwise the comment is left orphaned, pointing at whatever ends up next in the file.
The response includes a unified diff of the deletion — a preview in dry-run, the applied change otherwise — unless show_write_diff is disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path. | |
| dry_run | No | If true (default), preview only; do not write. | |
| dirty_ok | No | Allow editing a file with uncommitted changes. Default false — review/commit first, or pass true to proceed. | |
| name_path | Yes | Slash-separated symbol path within the file (e.g. "ClassName/methodName", or just "funcName" for top-level). | |
| include_doc_comment | No | If true, extend the operation to cover any contiguous comment lines (//, #, /*, *) directly above the symbol declaration. Lets you replace/delete a function together with its doc comment, or insert a new block above an existing doc comment instead of between the comment and its symbol. A WRAPPED declaration (an exported ES declaration under its export statement, a decorated Python def under its @decorator) keeps its doc comment above the wrapper, so WHEN SUCH A COMMENT EXISTS insert_before_symbol and replace_symbol_body extend past the wrapper — replacement content must then reproduce the export keyword or the decorator, or it is dropped. With no doc comment above the wrapper the range starts at the declaration and the wrapper is untouched; safe_delete_symbol never extends past the declaration at all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses important behaviors: it calls LSP references, rejects with referencing locations, handles orphaned doc comments, offers dry-run preview, and respects dirty_ok. This gives the agent a complete picture of side effects and safety guarantees.
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 but comprehensive, using four focused paragraphs to cover core behavior, reference check, doc comment handling, and diff response. It is well-structured and avoids unnecessary fluff, though slightly longer than minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 params, no output schema, no annotations), the description covers the essential contextual aspects: safety mechanism, dry-run, dirty_ok, doc comment behavior, and response content. It is thorough enough for reliable invocation, with minor gaps like exact formatting of reference locations.
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 baseline is 3. The description adds value by explaining include_doc_comment semantics (orphaned comments) and the diff response tied to show_write_diff, enriching beyond the schema's parameter descriptions without repeating them.
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 function: 'Delete a symbol's declaration only if it has no remaining references.' This is a specific verb+resource+condition that immediately distinguishes it from sibling tools like rename_symbol or move_symbol.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it checks references first and rejects deletion if any exist, preventing accidental removal of used code. It does not explicitly name alternatives, but the behavior is clearly scoped to safe deletion, which is enough to guide appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_in_filesA
Exact scan of current file contents — literal text by default, regex when use_regex=true. Use search_in_files when you need every occurrence, exact verification, audits, or safe replacement prep. Unlike shell grep/rg, results are confined to the active project (no .git/, node_modules/, build artefacts, or anything else .gitignore excludes), binary files are skipped (null-byte sniff of the first 8 KB), files larger than max_file_bytes (50 MiB default) are skipped before opening, globs with a literal directory prefix (e.g. "src/**/*.go") prune sibling directories from the walk. Smart-case (case-insensitive when the pattern is all lowercase), supports context lines and glob file filters.
| Name | Required | Description | Default |
|---|---|---|---|
| glob | No | Glob to restrict which files are searched, e.g. '*.go' or '**/*_test.go' | |
| path | No | Directory to search in (absolute path, file:// URI, or workspace-relative path). Defaults to the workspace root. | |
| exclude | No | Glob patterns for paths to exclude, e.g. ["vendor", "*.pb.go", "testdata/**"]. Matched against the entry's base name and relative path. Matching directories are pruned from the walk; matching files are skipped. | |
| pattern | No | Plain text to search for by default; regular expression when use_regex is true. | |
| use_regex | No | Treat pattern as a regular expression (Go RE2). Default false — pattern is literal text. | |
| max_results | No | Maximum number of matching lines to return. Default 200. | |
| context_lines | No | Number of lines of context to show before and after each match (like rg -C). Default 0. Total output is capped at 200 KiB regardless, and truncation is labelled. | |
| case_sensitive | No | Force case-sensitive matching. Default (omitted): smart-case — case-insensitive when pattern is all lowercase, case-sensitive otherwise. Pass false to force case-INSENSITIVE matching even for an uppercase pattern. | |
| include_hidden | No | Include hidden files and directories (starting with '.'). Default false. | |
| max_file_bytes | No | Skip files larger than this many bytes. Default 52428800 (50 MiB). | |
| include_enclosing_symbol | No | When true and an LSP is available, annotate each match with the deepest enclosing symbol (function, method, type, etc.) from the language server. One LSP query per distinct matched file; results cached within the call. Silently omitted when the LSP is unavailable. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses numerous behavioral traits: binary file skipping via null-byte sniff, file size limits, glob pruning of sibling directories, smart-case behavior, context lines, output caps, and LSP-based symbol annotation with silent omission. This is exceptionally transparent 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 dense but well-structured, front-loading the core purpose and mode, then layering exclusions and behaviors. Every sentence adds information, though it is long. It earns a 4 for efficiency despite the length; a 5 would require even tighter phrasing without losing the valuable details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 11 parameters and no output schema, the description covers all critical behaviors: exclusions, binary handling, size limits, smart-case, context lines, output caps, and LSP integration. It also explains defaults and edge cases. Nothing an agent needs to call it correctly is missing, making it complete for its complexity.
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 value beyond the schema by explaining smart-case behavior, the default max_file_bytes value, the 200 KiB output cap, and the LSP caching behavior. It doesn't restate schema descriptions but enriches them with defaults and edge-case behavior, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('scan'), resource ('current file contents'), and mode ('literal text by default, regex when use_regex=true'). It clearly distinguishes from shell grep/rg and other search tools by emphasizing project confinement and exclusions. The purpose is unambiguous and differentiates from siblings like workspace_search and find_files.
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 states when to use this tool ('when you need every occurrence, exact verification, audits, or safe replacement prep') and contrasts with shell grep/rg, noting the confinement to the active project. It also details exclusions (no .git/, node_modules/, build artefacts) and behavior like binary file skipping, which guides selection. This is strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_memoriesA
Search saved memories for a workspace.
When the FTS5 memory index is available and fresh, returns ranked hits (by relevance, with a bonus for user-authored memories) annotated source=memory-fts. Otherwise falls back to a deterministic grep over the markdown files, returning each match with the memory name and line. Smart-case (case-insensitive if 'pattern' is all lowercase) unless 'case_sensitive' is set; 'use_regex' forces the grep path. 'mode' (auto|fts|grep) overrides the choice; default auto.
Memory-only corpus with a deterministic grep fallback — for ranked discovery across code, docs, AND memories in one call, use workspace_search instead. Useful when you don't know which memory contains a piece of context — much faster than reading every memory.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Search strategy. auto (default): ranked FTS when the index is fresh, falling back to grep when the index is stale OR FTS finds no hits (FTS matches whole tokens, grep matches substrings). fts: force ranked FTS (reindex if stale; keeps an empty result). grep: force literal/regex grep. | |
| pattern | No | Text or regex pattern to search for. | |
| use_regex | No | Treat pattern as a regex. Forces the grep path (FTS is not regex). | |
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. | |
| case_sensitive | No | Default: smart-case. Setting this forces the grep path (FTS is case-insensitive). |
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 thoroughly explains the FTS5 vs. grep fallback logic, the ranking bonus for user-authored memories, the 'source=memory-fts' annotation, smart-case behavior, and the effect of 'use_regex' and 'case_sensitive' forcing the grep path. It also reveals the output format for grep ('memory name and line'), making behavior highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than a simple one-liner but every sentence adds value, covering the main purpose, fallback mechanics, parameter nuances, and alternative tool guidance. There is minor redundancy (e.g., mentioning 'deterministic grep fallback' twice) and the final 'use workspace_search' sentence could be viewed as slightly repetitive, but overall it is well-structured and information-dense without being overly verbose.
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 an output schema, the description adequately covers return values: ranked hits with source annotation for FTS, and memory name+line for grep. It also explains the behavioral nuances of each mode, the conditions for fallback, and the difference from the broader workspace_search tool. For a search tool of this complexity, the description is remarkably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameters with detailed descriptions, so the baseline is 3. The description adds extra context beyond the schema by explaining how 'mode' overrides the default choice, why 'use_regex' and 'case_sensitive' force grep, and what the FTS vs. grep distinction means for results. It also clarifies that FTS matches whole tokens while grep matches substrings, which enriches parameter understanding.
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 clearly states the tool's function: 'Search saved memories for a workspace.' It distinguishes itself from sibling tools like workspace_search by emphasizing that it targets the memory-only corpus, and it also differentiates the FTS vs. grep fallback behavior, making its scope explicit.
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 tells the agent when to use this tool vs. alternatives: 'for ranked discovery across code, docs, AND memories in one call, use workspace_search instead.' It also notes that this tool is 'useful when you don't know which memory contains a piece of context' and is 'much faster than reading every memory.' This provides clear 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.
session_startA
Bootstrap tool — call this first at the start of every session. Returns one-shot orientation: workspace path, language, current git branch, first 200 lines of .plumb/context.md, all saved memory names/descriptions, top-5 most-used tools, 5 most recently-modified files, 3 most recent commits, the live git tool policy (whether commits/destructive/push are enabled), and any active LSP errors/warnings. If no workspace is resolved yet, pass an absolute workspace to pin it — clients like Claude Desktop do not report the folder automatically. A subagent that just needs cheap re-orientation should pass detail: "brief" for a ≤1.5 KB summary instead of the full packet. Idempotent — safe to call multiple times.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Override the sticky-pin guard: when this connection is already pinned to a different project by an explicit session_start call, a re-pin is refused unless force is true. Use it only when you are deliberately switching THIS connection to another project — e.g. a new conversation on a connection reused across conversations. On a connection shared by several agents (Cowork, Claude Desktop local-agent-mode), prefer a dedicated plumb serve process per agent over forcing. | |
| detail | No | Orientation packet size. 'brief' (≤1.5 KB) returns workspace path, language, branch, a one-line git policy, diagnostics and active-peer COUNTS, memory NAMES only (no descriptions/sizes), and the edit-lane rule where it applies — cheap re-orientation for a subagent that does not need the full packet. 'full' returns the complete packet documented above. Defaults to 'full', except this default flips to 'brief' automatically when the supplied session_id was already seen by this daemon within the last 24h (a resumed conversation); an explicit value always wins over the automatic default. | |
| purpose | No | Optional human-readable tag describing what this session is for (e.g. 'deploy-fix', 'feature-auth'). Surfaced in the TUI session list, daemon_info, and workspace_sessions so an operator can tell concurrent sessions apart. Allowed characters: letters, digits, and hyphens; max 32 characters. An invalid value is rejected with a clear error. | |
| language | No | Optional override for the workspace's primary language when automatic detection cannot infer it — e.g. an Xcode app that has .swift sources but no SwiftPM Package.swift, so no root marker resolves. Pass the [lsp.<lang>] key (e.g. 'swift', 'typescript', 'rust') to force that language server as the primary, so workspace_symbols and the call/type hierarchies work. The server must be installed and enabled; an unknown, uninstalled, or disabled language is ignored and normal detection applies. Honoured on the connection's current workspace, or alongside an explicit 'workspace' arg. | |
| workspace | No | Absolute workspace path. Use this to pin the project for clients that do not report a folder (e.g. Claude Desktop). If this connection is already pinned to a different project, passing a workspace here re-pins it to the new project — this is how you switch projects on a connection reused across conversations. When the current pin was itself set by an explicit session_start, the re-pin is refused unless you also pass force: true — a guard against a peer agent silently stealing the pin on a shared connection (issue #182). Defaults to the daemon's already-resolved workspace. | |
| session_id | No | Optional opaque identifier linking this plumb session to the caller's own session (e.g. a Claude Code conversation ID). When provided, plumb persists the ID and, if a recent session with the same ID ended within the last 24 h, inherits its name — so a resumed conversation keeps its session name in the TUI. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full behavioral burden, and it succeeds. It discloses idempotency ('safe to call multiple times'), the sticky-pin guard and force override, the automatic default flip for resumed sessions, and what the returned packet contains. This gives an agent a faithful model of the tool's side effects and safety characteristics.
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 it is dense and each sentence carries real content: returned fields, workspace pinning, brief mode, idempotency, and the guard behavior. It is front-loaded with the most important instruction ('call this first'). Slight structure improvements (e.g., bullets) would help, but the length is justified for a complex bootstrap tool.
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?
This is a six-parameter tool with no annotations and no output schema, so the description must compensate — and it does. It covers output contents, default behaviors, parameter interactions, edge cases (resumed sessions, no resolved workspace, shared connections), and safety. An agent has enough to invoke it correctly and interpret its results.
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 schema already documents all six parameters in detail. The description reinforces the purpose of workspace and detail, and adds context about the sticky-pin guard, but it does not meaningfully add new parameter semantics beyond the rich schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Bootstrap tool — call this first at the start of every session' and then enumerates exactly what it returns (workspace path, language, git branch, context file excerpt, memory names, git policy, diagnostics, etc.). This is a specific verb plus resource with a clear one-shot orientation purpose that separates it from all sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'call this first at the start of every session.' It also instructs when to pass workspace ('If no workspace is resolved yet'), when to use detail:'brief' ('A subagent that just needs cheap re-orientation'), and when to use force ('deliberately switching THIS connection to another project'). This is unusually actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
structural_queryA
Run a curated structural check over the topology index — find symbols by SHAPE, not name. Complements topology_search (find by name) and search_in_files (find by text) with audits useful for review and refactor prep. Named queries (no raw tree-sitter queries are exposed): "undocumented-exports" (exported functions/methods/types/constants with no doc comment), "long-functions" (functions over min_lines, default 80), "unused-context" (Go functions taking context.Context whose body never references it). Results are approximate (source=topology) and confidence-labelled where the check is heuristic. Returns a clear message when the index is disabled or empty.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of findings to return. Default 50. | |
| query | No | Which structural check to run: "undocumented-exports", "long-functions", or "unused-context". | |
| language | No | Optional filter by language (e.g. 'go', 'python'). unused-context is Go-only regardless. | |
| min_lines | No | For long-functions: minimum line span to flag. Default 80. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that results are approximate (source=topology), confidence-labelled for heuristics, that no raw tree-sitter queries are exposed, and that a clear message appears when the index is disabled or empty. This is comprehensive behavioral disclosure.
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 a clear purpose, uses a single well-structured paragraph, and every sentence adds value—from sibling differentiation to query examples to behavioral caveats. No redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no annotations or output schema, the description covers purpose, usage, alternatives, behaviors, parameter details, and an edge case (disabled/empty index). Missing are the general return format and permission requirements, but these are less critical for a read-style query tool.
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 baseline is 3, but the description adds significant meaning beyond schema fields: it explains the named query options with concrete definitions (undocumented-exports, long-functions, unused-context), notes that unused-context is Go-only, and clarifies the default for min_lines. This extra context elevates the score.
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+resource combination ('Run a curated structural check over the topology index') and explicitly contrasts with sibling tools ('Complements topology_search (find by name) and search_in_files (find by text)'). It clearly distinguishes the tool's shape-based search purpose from name- or text-based 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 names the primary alternatives and explains the tool complements them by providing structural audits useful for review and refactor prep. While it doesn't exhaustively list every possible 'when not to use' scenario, the contrast with topology_search and search_in_files gives clear contextual guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
topology_affectedA
After you change code, ask this which tests to run instead of running the whole suite. Given changed files or symbols, it answers with PACKAGES to run — one row each with the test count and why the package is implicated, plus the individual test names in the package the change landed in. Where the workspace's test runner takes a positional path (go, python), each row leads with a ready target to hand straight to run_task(slot:"test"), expressed relative to [tasks.].working_dir so it works from the directory that command runs in. Where the runner scopes by name or by a project-specific flag (rust, typescript, swift, zig), the directory is named and no command is guessed. A package is reached either by containing the change, or by importing a package that does (cross-package import edges). Within a reached package every test is counted, because co-location cannot tell which of them exercise the change: that is the recall bias, and it is deliberate — a missed test is worse than an extra. Results are heuristic; verify before relying. max_results bounds the number of PACKAGES, and the changed package is always listed first so a cap cannot drop it. Returns a clear message when topology is disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | Workspace-relative file paths to treat as change roots. | |
| symbols | No | Symbol names to treat as change roots. | |
| max_results | No | Maximum PACKAGES to return. Default 50, which is well above a normal answer — raise it only for a change that fans out very widely. Tests are counted per package rather than listed individually, so this no longer caps test rows; the changed package always sorts first, so a cap cannot drop the package the edit landed in. |
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 succeeds: it discloses the heuristic nature of results, the deliberate recall bias (counting every test in a reached package), the cross-package import edge rule, language-dependent command formatting, and the behavior when topology is disabled. This is exemplary transparency for a complex 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 long, but it is front-loaded with the core purpose and every subsequent sentence adds necessary operational detail (output shape, path handling, reachability rules, cap behavior). It could be tightened with bullet points, but it avoids fluff and each clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of an output schema, and the absence of annotations, the description is remarkably complete. It covers input expectations, output structure, per-language command behavior, recall bias, heuristics, max_results semantics, ordering guarantees, and failure mode when topology is disabled. An agent has enough information to invoke and interpret the result 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 3, but the description adds meaningful semantics beyond the schema: files and symbols are "change roots," max_results bounds PACKAGES rather than test rows, and the changed package is always sorted first so a cap cannot drop it. This goes beyond what the schema descriptions already state.
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 concrete use case: "After you change code, ask this which tests to run instead of running the whole suite." It names a specific resource (affected PACKAGES) and a specific output (packages with test counts, reasons, and individual test names), which clearly distinguishes it from siblings like topology_status, topology_search, and topology_impact.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use this tool — after code changes, to select tests rather than run everything. It implies the alternative (running the full suite) but does not explicitly name other topology or test-selection tools or state when not to use it, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
topology_exploreA
Bounded BFS neighbourhood around a named symbol in the topology index. NARROW IT FIRST on a large file or an unfamiliar language: include_source="none" returns names only (the default, "signatures", is several times larger), and depth=1 with max_nodes=15 answers "what touches this?" in a fraction of the default budget (depth 2, 50 nodes, 30000 bytes) — raise them once you know what you are looking for. Returns the centre node, neighbour nodes, and connecting edges up to depth/max_nodes/max_bytes. Reports truncation when limits are hit. Source is 'topology' (approximate — use LSP semantic tools for authoritative reference and definition lookups). Returns an error when topology is disabled or the symbol is not in the index.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Optional node kind to disambiguate a shared name: function, method, type, class, constant, variable, field, … | |
| name | No | Symbol name or qualified name to explore. Must exist in the topology index. | |
| path | No | Optional file-path substring to disambiguate when several indexed symbols share this name (case-insensitive). | |
| depth | No | BFS depth from the centre node. Default 2, max 4. | |
| max_bytes | No | Approximate byte budget for neighbour data. Default 30000, max 100000. | |
| max_nodes | No | Maximum number of neighbour nodes to return. Default 50, max 200. | |
| edge_kinds | No | Optional filter on edge kinds: calls, imports, contains, defines, inherits, implements. | |
| include_source | No | How much source detail to include per symbol: none (name only), signatures (default), or snippets/full (signature plus docstring). Symbols are always returned whole — max_bytes truncates on symbol boundaries, never mid-function. | signatures |
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 does well. It discloses that source is approximate, returns an error when topology is disabled or symbol missing, reports truncation when limits hit, and explains how max_bytes truncates on symbol boundaries. It doesn't mention rate limits or performance, but for a read-only exploration tool, it covers the key behavioral aspects.
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 and informative, but moderately long. It front-loads the purpose and immediately provides usage maxims, followed by behavioral notes. Some redundancy with the schema (like repeating default values) adds length but not much cost. It earns its place overall, though a tighter version could trim the default value 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 complex tool with 8 parameters and no output schema or annotations, the description is remarkably complete. It covers the return content (centre node, neighbour nodes, edges), truncation behavior, error conditions, approximation caveat, and parameter tuning guidance. The output schema would further help, but given the constraints, an agent has enough to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description goes beyond the schema by explaining the relative cost of include_source options (signatures is 'several times larger' than none) and providing example combinations (depth=1 with max_nodes=15), which helps agents choose values strategically. It does not describe relationship between edge_kinds and output, but the schema already lists valid kinds.
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 it performs a bounded BFS neighbourhood exploration around a named symbol in the topology index, with a specific resource and operation. It is distinguished from siblings like topology_search or find_references by the explicit neighbourhood/BFS focus, though it doesn't name a direct sibling for contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'NARROW IT FIRST on a large file or an unfamiliar language', recommends specific parameter values (include_source='none', depth=1, max_nodes=15) for quick 'what touches this?' queries, and advises raising limits 'once you know what you are looking for'. Also notes caveats such as topology being approximate and recommending LSP semantic tools for authoritative lookups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
topology_impactA
Bidirectional BFS blast-radius analysis around a named symbol. Returns two sections: 'depends on' (outward — what the symbol depends on) and 'depended on by' (inward — what depends on this symbol). Primary use: assess blast radius before a refactor. Source is 'topology' (approximate); the topology call graph is intra-file, so for a function/method the inward section is augmented with a 'cross-file callers' block resolved via the language server (source=lsp) when one is available. mode="reachability" switches to entry-point reachability. The default package granularity follows production import edges from package-main roots plus candidate-seeded topology_routes roots; Go _test.go importers are excluded, and unsupported/polyglot workspaces are refused rather than reported as falsely unreachable. Set granularity="function" for the additive Go-only admitted partial static call graph: it uses exact callable roots, production callers, durable derived cross-file edges, and the full reachable closure. Unresolved receiver/dynamic calls, test callers, unsupported languages, and unindexed roots remain outside that lower-bound answer. Each granularity supports the default summary, path_to (one shortest root-to-target chain), and layers (SCC condensation; import cycles for package or recursion cycles for function). All outputs disclose their scope and known limitations, and responses are byte-capped. Returns a clear message when topology is disabled or the symbol is not in the index.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Optional node kind to disambiguate a shared name: function, method, type, class, constant, variable, field, … | |
| mode | No | Optional. "reachability" switches from the default single-symbol blast-radius analysis to entry-point reachability. Go-only for now; roots/path_to/layers require this mode. | |
| name | No | Symbol name or qualified name to analyse. Must exist in the topology index. Required unless mode="reachability". | |
| path | No | Optional file-path substring to disambiguate when several indexed symbols share this name (case-insensitive). | |
| depth | No | BFS depth for both traversals. Default 3, max 4. | |
| roots | No | Requires mode="reachability". package granularity accepts package directories or "main". function granularity accepts exact file.go#Symbol selectors or "main"; omit for defaults (package main roots plus candidate-seeded topology_routes roots). | |
| layers | No | Requires mode="reachability". When true, the response is an SCC condensation of the reachable subgraph — package import cycles or function recursion depending on granularity — instead of the summary. | |
| path_to | No | Requires mode="reachability". When set, the response is the single shortest root -> target chain; use a package directory for package granularity or file.go#Symbol for function granularity. | |
| max_bytes | No | Approximate byte budget per direction. Default 30000, max 100000. | |
| max_nodes | No | Maximum neighbour nodes per direction. Default 100, max 200. | |
| edge_kinds | No | Optional filter on edge kinds: calls, imports, contains, defines, inherits, implements. Defaults to imports, calls. | |
| granularity | No | Requires mode="reachability". Default package follows production import edges. function follows the admitted Go call graph outward from exact callable roots; test-file callers are excluded and unresolved/dynamic calls are disclosed. | package |
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 it excels: it discloses that the topology source is approximate and intra-file, that cross-file callers come from the language server when available, that unsupported/polyglot workspaces are refused rather than falsely reported, and that every output discloses limitations and is byte-capped. This is unusually rich behavioral disclosure.
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 the tool is complex with 12 parameters and no annotations. Almost every sentence contributes distinct information about modes, sources, limitations, or failure behavior. It would benefit from tighter paragraph separation, but it remains well above a minimal viable description.
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 no output schema and no annotations, the description covers the input modes, granularities, edge kinds, source limitations, cross-file resolution, failure messages, and disclosed scope. An agent has enough context to decide when and how to invoke it and what to expect in return.
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%, but the description goes well beyond the schema by explaining the meaning of granularity, roots, mode, and path_to in operational terms. For example, package granularity is tied to 'production import edges from package-main roots plus candidate-seeded topology_routes roots', and function granularity is tied to an 'admitted Go-only partial static call graph' with exact callable roots.
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 immediately pins down the behavior: 'Bidirectional BFS blast-radius analysis around a named symbol' and explicitly names the two output sections. It is clearly distinct from sibling topology tools like topology_search or topology_explore because it frames itself as blast-radius analysis for refactoring.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives the primary use ('assess blast radius before a refactor') and explains when to switch modes and granularity, including Go-only and reachability constraints. It does not explicitly name sibling tools as alternatives, but the context is clear enough for an agent to choose it over related topology tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
topology_routesA
Pattern-matches entry-point-shaped symbol NAMES and signatures: Go handler funcs (http.HandleFunc, r.GET/POST, mux.Handle), Cobra cmd.Run/RunE, Python decorators (@app.route, @router.get, FastAPI path decorators), and Swift/Vapor idioms (RouteCollection.boot, configure(_:Application), ParsableCommand.run). It does NOT parse route registrations or call sites, so it cannot recover a path-to-handler binding (e.g. "/api/x" -> handlerFn) — it only finds functions whose name or signature looks like a known entry-point idiom. Results are candidates, not confirmed routes: each carries a confidence annotation reflecting the pattern's typical accuracy, not a resolved binding. Returns a clear message when no candidates match or topology is disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of route entries to return. Default 20. | |
| framework | No | Optional framework hint: 'gin', 'chi', 'mux', 'echo', 'cobra', 'fastapi', 'flask', 'vapor', 'argument-parser'. Omit to scan all known patterns. | |
| path_prefix | No | Optional substring filter applied to the candidate symbol's name/signature (e.g. 'api') — NOT a URL path filter; it is not matched against any route path, since none is parsed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full behavioral disclosure burden. It fully meets that burden: it discloses that no route registrations or call sites are parsed, that results are candidates rather than confirmations, that each candidate carries a confidence annotation, and that a clear 'no match'/disabled message will be returned. This is exemplary transparency for a tool with no structured annotations.
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 informative and mostly well-structured, opening with the core function and then bounded by scope limitations and result semantics. Some redundancy exists: the 'no route registration parsing' point is stated multiple times, and 'candidates, not confirmed routes' is also echoed in slightly different wording. Still, the key constraints are front-loaded and readable.
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 parameter-light, no-output-schema tool, the description covers the modeling intent, negative scope, result semantics, confidence annotations, and failure behavior. The main gap is that it does not describe the exact snapshot of the return value beyond candidates and message, which would matter more given that there is no output schema. Overall, though, an agent can call this tool with clear expectations.
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 fully documents `limit`, `framework`, and `path_prefix`. The description mainly restates what the schema provides, including the caveat that `path_prefix` is not a URL path filter. It adds no significant new meaning beyond the schema, so the baseline 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 specifies what the tool does: it pattern-matches entry-point-shaped symbol names and signatures, with concrete examples across Go, Python, and Swift/Vapor. It also draws an explicit boundary by stating what it does NOT do — parse route registrations or resolve path-to-handler bindings. It does not name a sibling tool as a direct alternative, but the scope is concrete enough to be distinguishable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong usage guidance: use this tool to find entry-point-shaped candidate functions, not to recover confirmed route bindings. It clarifies that results are unconfirmed candidates and that path_prefix is not a URL path filter. However, it does not explicitly point to an alternative sibling tool (e.g. a route-resolution or topology-search tool) for cases where the user needs actual parsed route mappings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
topology_searchA
Ranked FTS5 search over the topology index. Narrow a broad query first: kinds, language, limit, include_snippets=false. Finds symbols, functions, types, classes, and other named entities by name, tokenised identifier (camelCase/snake_case), qualified name, signature, or docstring. Results include kind, file path, line range, match field, score, and optional snippet. Source is 'topology' (approximate; use search_in_files for exact filesystem matches). Code-structure corpus only — for ranked discovery that also spans docs and memories, use workspace_search (this tool is one of its backends). Returns a clear message when the index is disabled or empty.
| Name | Required | Description | Default |
|---|---|---|---|
| kinds | No | Optional filter by node kinds: function, method, type, class, constant, variable, import, package, test. | |
| limit | No | Maximum number of results to return. Default 20. | |
| query | No | Search query. Terms are OR-matched against symbol names, tokenised identifiers (camelCase/snake_case split), qualified names, signatures, and docstrings. | |
| rerank | No | Re-rank FTS5 results by semantic similarity to the query (needs [semantics] enabled + an API key). Defaults to the [semantics].enabled config; pass false to force the plain FTS5 ranking, true to force re-rank when configured. | |
| language | No | Optional filter by language (e.g. 'go', 'python'). | |
| include_snippets | No | Include a short snippet showing the matching text. Default true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden of behavioral disclosure. It conveys that the source is approximate ('topology (approximate)'), explains the return fields (kind, file path, line range, match field, score, optional snippet), and mentions a clear message when the index is disabled or empty. It does not mention side effects (none for a search) but adequately covers the operational behavior.
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 reasonably concise, with each sentence delivering distinct value: it states purpose, provides usage guidance, lists result fields, and gives alternative tooling. The key 'Narrow a broad query first' instruction is front-loaded. It's slightly long but not verbose, earning a 4 rather than a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a search tool: it specifies the result structure, explicitly notes the approximate nature of the source, and covers the disabled/empty index behavior. Since there is no output schema, the description properly explains return fields. It also references sibling tools for alternative use cases, making it self-sufficient 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?
Schema coverage is 100%, so the schema already fully documents all parameters. The description adds minor guidance (e.g., suggesting include_snippets=false to narrow) and clarifies the re-rank behavior, but it does not add substantial meaning beyond what the schema provides. A baseline of 3 is appropriate when the schema is the primary source of parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb (search) and resource (topology index), and explicitly distinguishes itself from search_in_files (exact filesystem matches) and workspace_search (broader discovery including docs and memories). It also lists what it finds (symbols, functions, types, classes) and the fields returned.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description opens with 'Narrow a broad query first', gives specific narrowing parameters (kinds, language, limit, include_snippets=false), and explicitly tells the agent when to use alternatives: 'use search_in_files for exact filesystem matches' and 'for ranked discovery that also spans docs and memories, use workspace_search'. This provides clear 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.
topology_statusA
Report the health and statistics of the topology index for this workspace: indexer state, indexed/skipped file counts (with the recorded reason for each skipped file, most recent first), total nodes and edges, database size, last sync time, indexed languages, and the most recent indexing error if any. Returns a clear message when topology indexing is disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | No | Absolute path to the workspace root. Defaults to the session workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool reports information and returns a clear message when indexing is disabled, which is a behavioral trait. It does not mention potential side effects, errors, or performance implications, but the verb 'Report' implies read-only behavior, and the listed outputs are transparent. Some details about failure modes remain unspecified.
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 two sentences, with the main verb 'Report' front-loaded. It lists all relevant output items without fluff or repetition. The conditional 'Returns a clear message when disabled' is a concise, structured addition. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema, so the description must explain the return values. It enumerates the statistics (indexer state, counts, reasons, nodes/edges, db size, sync time, languages, error) and the disabled-case message, which is sufficient for an agent to know what to expect. It does not specify the exact format or types, but that is not strictly required. Minor gap: no mention of error handling in exceptional situations.
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 parameter 'workspace' is fully described in the input schema (absolute path, defaults to session workspace). The tool description does not add any additional meaning or context for this parameter, so it does not go beyond the schema. Since schema coverage is 100%, the baseline score of 3 applies.
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 function: reporting the health and statistics of the topology index. It lists the specific information returned (indexer state, counts, nodes/edges, db size, etc.) and mentions the disabled-indexing case. This distinguishes it from sibling tools like topology_search or topology_explore, which are clearly about querying rather than status reporting.
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 does not explicitly state when to use this tool versus alternatives, such as 'use this to check if the index is up-to-date' or 'use topology_search for querying.' However, the purpose is self-evident from the report content, and the disabled-indexing fallback hints at a diagnostic role. Still, explicit guidance on when to choose this over siblings is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transaction_applyA
Apply str_replace edits across multiple files atomically. Every operation is validated against the on-disk content first; if any old_string is missing or ambiguous, NO files are written. If writes start succeeding but one fails partway, the already-written files are rolled back to their pre-transaction content. Per-path locks prevent interleaving with other write tools. Use for refactors that must land as one unit. Up to 50 operations per call; the response lists each file with a unified diff unless show_write_diff is off.
| Name | Required | Description | Default |
|---|---|---|---|
| dirty_ok | No | Allow editing files that have uncommitted changes in their git repository. Default false — the transaction is refused if any target file is dirty. Pass true to proceed anyway. | |
| operations | No | Ordered list of per-file edit groups. Every file is validated first; only if all validate do any writes happen. | |
| await_diagnostics | No | When true, wait for the language server to re-analyse each written file and append a labelled per-file diagnostics block with a machine-readable 'diagnostics delta' line. Default false. | |
| fail_on_new_errors | No | When true (implies await_diagnostics), roll the WHOLE transaction back if any written file is CONFIRMED to have gained new errors — all-or-nothing. An unconfirmed check never rolls back; nor do warnings or pre-existing errors. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description thoroughly explains the behavior: validation against on-disk content, all-or-nothing write semantics, rollback on partial failure, and locking. Since no annotations are provided, the description carries full responsibility for transparency, and it does so completely without contradictions.
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, using three sentences to convey purpose, behavior, and usage context. It is well-structured and free of redundancy, with each sentence contributing essential 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?
The description covers the core aspects: what the tool does, how it ensures atomicity, the locking mechanism, and the intended use case. It also mentions the 50-operation limit. Since no output schema is present, explaining return values is not required, and the description is complete for an agent to decide and invoke 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 provides 100% coverage of parameter descriptions, so the baseline is 3. The description does not add further semantic meaning to the parameters; it mentions atomicity and locking but does not elaborate on await_diagnostics or fail_on_new_errors beyond what the schema states. Thus no extra value is added.
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 action (apply str_replace edits), the resource (multiple files), and the key property (atomically). It also distinguishes this tool from others by mentioning per-path locks and the use case for refactors that must land as one unit, making it easy to tell apart from sibling tools like edit_file or write_file.
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 this tool: 'Use for refactors that must land as one unit.' It also contrasts with other write tools by noting per-path locks prevent interleaving, implying it is preferred for multi-file atomic operations. This gives clear guidance on selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
type_hierarchyA
Show the type hierarchy for a type: its supertypes (interfaces it implements, embedded types) and subtypes (types that implement or embed it). PREFER a name (uri + symbol_name) — plumb resolves the exact identifier position for you, avoiding off-by-one errors; a raw file position (uri + line + character) is the fallback and, when it lands off an identifier, is snapped to the enclosing symbol. Useful for understanding inheritance and polymorphism.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Absolute path, file:// URI, or workspace-relative path containing the type | |
| line | No | Zero-based line number of the type. Required when symbol_name is not provided. | |
| character | No | Zero-based character offset within the line. Required when symbol_name is not provided. | |
| direction | No | Which direction to traverse: parent types (supertypes), child types (subtypes), or both. Defaults to both. | |
| symbol_name | No | Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses important behaviors: identifier positions are resolved by plumb to avoid off-by-one errors, and positions off an identifier are snapped to the enclosing symbol. It does not mention read-only status or potential errors, but the transparency provided is meaningful.
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: first sentence defines what it does, second explains parameter preference, and third gives the use case. Every sentence contributes necessary information with no 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?
The description covers core purpose, parameter selection, and use case, while the schema fully documents all parameters. The main gap is the lack of output format (e.g., whether it returns a tree or list), which is somewhat important given there is no output schema, but the description is still adequate for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining why symbol_name is preferred over line/character, describing off-by-one risks, and the snapping fallback. This enriches the parameter semantics beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Show the type hierarchy for a type' and elaborates with concrete definitions of supertypes and subtypes. It implicitly distinguishes from siblings like call_hierarchy by focusing on inheritance/embedding relationships rather than call relationships.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool ('Useful for understanding inheritance and polymorphism') and provides usage guidance on preferring symbol_name over line/character to avoid off-by-one errors. However, it does not explicitly name alternative sibling tools or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_editA
Revert plumb's most recent write to a file — the safe alternative to git checkout <file>, which discards EVERY uncommitted change in the file. undo_edit restores only what plumb's last edit_file/write_file changed, and refuses by default if the file was modified since (an external or peer edit), so it never silently clobbers someone else's work (pass force:true to override). If the last write created the file, undo removes it. Single-level per file: it undoes the last write; a fresh write re-arms it. Undo history is per session and cleared on a workspace switch. Very large files (pre-write content over 1 MiB) are not snapshotted, so undo is unavailable for them.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Revert even if the file changed since plumb's last write to it (an external or peer edit). Default false — the undo is refused in that case so it cannot silently discard someone else's change. | |
| file_path | No | Absolute path, file:// URI, or workspace-relative path of the file to revert. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden and excels: it discloses the refusal default, force override, file-creation removal, single-level undo behavior, per-session history clearing, and the 1 MiB snapshot limit. This gives the agent a complete mental model of side effects and constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph, but every sentence earns its place: main purpose, safety comparison, refusal behavior, force override, creation removal, re-arm behavior, session scope, and size limit. It is front-loaded with the primary action and logically organized from common to 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?
This is a moderately complex tool with no output schema and no annotations, yet the description covers all essential behavioral aspects: what it undoes, safety guards, force semantics, file lifecycle, undo depth, session lifetime, and availability limitations. It is complete enough for an agent to correctly decide when to call it and predict outcomes.
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, but the description adds meaningful context for `force` by elaborating when and why to use it (to override refusal after external edits) and warns about the 1 MiB limit affecting undo availability. It does not add much for `file_path` beyond the schema, but the added force context justifies a 4.
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 action and resource: 'Revert plumb's most recent write to a file.' It clearly distinguishes itself from `git checkout <file>` by framing it as the safe alternative, and the detail about restoring only plumb's last edit removes ambiguity about scope.
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 names `git checkout <file>` as an alternative and explains the safety tradeoff, giving clear context for when this tool is appropriate. It also describes refusal conditions (file modified since, no snapshot over 1 MiB), but does not explicitly state 'use this instead of X when...' or cover scenarios like undoing multiple edits, so it stops short of full usage-exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
workspace_searchA
Ranked discovery across the workspace's indexed corpora: code symbols, doc sections (Markdown/HTML), and project memories. Use workspace_search when you have a conceptual question ("where is daemon locking handled?") and want likely starting points. Approximate by design and never a proof of absence — the exact lane is search_in_files (literal or regex over current file contents). Results are FTS5-ranked within each corpus and interleaved; every hit is labelled with corpus, source, field, score, and why it matched, and the header reports per-corpus index freshness (exact_match=false always).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of merged results to return. Default 20. | |
| query | No | Free-text discovery query, e.g. "daemon locking" or "workspace pool". Token-aware and ranked; not a regex and not an exact scan. | |
| corpora | No | Restrict the search to these corpora. Omit to search all three: code (indexed symbols), docs (indexed Markdown/HTML sections), memory (project memories). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses approximate ranking, non-exhaustiveness, result labelling (corpus, source, field, score, why matched), per-corpus freshness headers, and that exact_match is always false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, purpose-first, no wasted words. Each sentence adds distinct value: scope, usage guidance, and result behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description explains return structure and freshness reporting. It also covers limitations (approximate, no proof of absence) which is important for a search tool.
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 covers all three parameters with helpful descriptions. The description adds context about FTS5 ranking and interleaving, clarifying how query and corpora behave 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?
Description opens with 'Ranked discovery across the workspace's indexed corpora: code symbols, doc sections (Markdown/HTML), and project memories' – a specific verb and resource scope. It also names the sibling tool search_in_files as the alternative, establishing clear differentiation from other search 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?
Explicitly states when to use: 'Use workspace_search when you have a conceptual question...' and when not to use: 'Approximate by design and never a proof of absence — the exact lane is search_in_files.' Names the alternative tool and gives an example query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
workspace_sessionsA
Returns same-workspace session awareness: who else is actively connected to this project and what files they recently edited.
you — this session's name.
active_sessions — sessions on this workspace right now (name, client, how long since their last tool call). A single entry whose is_self field is true means you are the only active session — your view of the workspace is authoritative. Multiple entries mean concurrent agents are working here; treat any file a peer recently touched as potentially changed.
recent_writes — the last N write operations (write_file, edit_file, rename_file, git commit, …) by all sessions on this workspace. The file path (when available), session name, operation, and age are shown. Only operations that could modify the workspace are listed: read-only git subcommands (status, log, diff, …) and dry-run previews never appear. A call that failed or was refused is kept but marked '[failed — no change applied]' — evidence the peer is working in that file even though nothing landed on disk. A successful git commit is attributed in full: its line carries the session name, the commit's short SHA and subject, and the repository, so a peer's commit is traceable to the session that authored it. When [collab] peer_awareness is on and the topology index has the file, each entry is annotated with its enclosing package/symbol (best-effort, source=topology).
Use this before editing a file that another session may have recently modified: if it appears in recent_writes, re-read it first.
Parameters: recent_limit — max recent-write entries to return (default 10, max 50).
Workspace boundary: workspace_sessions is scoped to the caller's pinned workspace; it never reveals sessions from a different project.
| Name | Required | Description | Default |
|---|---|---|---|
| recent_limit | No | Maximum recent-write entries to return (1–50; default 10). |
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 succeeds admirably. It explains complex behaviors in depth: the distinction between the caller's session and others, that only write operations appear while read-only git subcommands are excluded, that failed operations are kept but marked, and that git commits are attributed in full with SHA and repo. This far exceeds what structured data could convey.
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 thorough, using clear markdown headers to organize information about the workspace boundary, the output fields, and usage guidance. The critical usage instruction is front-loaded before the parameter details, and while detailed, every sentence earns its place by explaining behavior that couldn't be inferred from 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 tool with no output schema and no annotations, this description is remarkably complete. It fully explains the response structure, the semantics of the 'self' session versus peers, the scope of recent_writes, and even the edge case of failed operations. The agent has all the information needed to call this tool correctly and interpret its results, from concurrency semantics to what the boundary of 'workspace' means.
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's recent_limit parameter has 100% schema description coverage, so the baseline is 3. The description adds one meaningful piece of behavioral detail about the parameter — indicating it specifically limits 'recent-write entries' — which is a slight clarification, but doesn't add entirely new semantic information beyond the schema's well-documented parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Returns'), a specific resource ('same-workspace session awareness'), and the key differentiators: who else is connected and what files they recently edited. It provides a clear, non-tautological definition that goes beyond the tool name and effectively distinguishes it from sibling tools like file_status or git.
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, most notably: 'Use this before editing a file that another session may have recently modified: if it appears in recent_writes, re-read it first.' It also clearly explains the semantics of multiple active sessions versus a single self-session, effectively telling the agent when this tool is the right choice over alternatives for concurrency checks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
workspace_symbolsA
Search for symbols (functions, types, variables, constants) by name or substring across the entire workspace — instant, uses the LSP index. Pass uri to restrict the search to that one document instead. Returns names, kinds, and source locations.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | Optional: restrict the search to this ONE document (absolute path, file:// URI, or workspace-relative path). Omit it to search the whole workspace. | |
| query | No | Symbol name or substring to search for (case-insensitive) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavioral disclosure. It adds meaningful context beyond the schema: 'instant, uses the LSP index' reveals the underlying mechanism and performance expectations, and 'Returns names, kinds, and source locations' clarifies the output shape. While it doesn't explicitly say 'read-only,' the word 'Search' strongly implies a non-destructive operation, and no contradiction exists.
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 two sentences, tightly written, and front-loaded with the core action ('Search for symbols'). Every clause earns its place: the symbol types, workspace scope, LSP mechanism, uri restriction, and return content. No redundant or filler language.
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 two-parameter search tool with no output schema, the description is complete: it states what is searched, how to narrow the search, what the result includes, and the performance characteristic. It also covers parameter usage (uri optional vs. default workspace-wide) and return shape, which is sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the query semantics ('by name or substring') and the uri restriction, but it does not add significant new meaning beyond what the schema already documents — the schema already describes uri as 'restrict the search to this ONE document' and query as 'Symbol name or substring... case-insensitive.' Thus the description adds only marginal value on top of the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the verb ('Search'), the resource ('symbols across the entire workspace'), and the scope ('by name or substring'). It names symbol types (functions, types, variables, constants) and includes a distinguishing trait ('uses the LSP index'), which separates it from text-search siblings like search_in_files and workspace_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 provides clear context for when to use the tool (searching symbols workspace-wide) and explains how to narrow scope with the uri parameter ('Pass uri to restrict the search to that one document instead'). However, it does not explicitly state when not to use it or mention alternatives, so it stops short of full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_fileA
Create or overwrite a file with the given content. The write is atomic and crash-durable (temp file fsynced, renamed, parent directory fsynced before the call returns — never partially written); parent directories are created automatically and the LSP server is notified so diagnostics and symbols update immediately. Pass expected_mtime or expected_sha (from a read_file header) to reject the write if the file changed since you read it, so a full-content overwrite never silently clobbers a concurrent change. If the call fails with a transport/connection error, the atomic temp+rename guarantees the file is either fully written or untouched — never partially written; re-read to confirm which side of the rename it landed on. Use edit_file for targeted edits to an existing file.
| Name | Required | Description | Default |
|---|---|---|---|
| content | No | Full content to write to the file. | |
| dirty_ok | No | Allow writing a file that has uncommitted changes in its git repository. Default false — the write is refused if the target file is dirty. Pass true to overwrite anyway. | |
| file_path | No | Absolute path, file:// URI, or workspace-relative path of the file to write. | |
| create_dirs | No | Create parent directories if they do not exist. Default true. | |
| expected_sha | No | Optional. Hex-encoded SHA-256 previously returned by read_file. If provided, the write is rejected if the file's current content hash differs — stronger than expected_mtime, survives mtime aliasing. | |
| expected_mtime | No | Optional. RFC3339Nano mtime previously returned by read_file. If provided, the write is rejected if the file's current mtime differs — fast optimistic-concurrency check, so a full-content overwrite never silently clobbers a change made since you read it. | |
| await_diagnostics | No | When true, block up to a few seconds for the language server to finish re-analysing this file, and append a machine-readable 'diagnostics delta' line (fresh, new_errors, resolved, pre_existing). The block is always labelled — authoritative, pre-write snapshot, unverified, or not-analysed — so a stale result is never dressed as fresh. Default false (fast adaptive window; the result may predate the write). | |
| overwrite_changed | No | Allow overwriting a file that changed on disk since this session read it (a peer agent or human edited it after your read). Default false — the write is refused so a stale full-content overwrite cannot silently discard that change. Re-read to merge, or pass true to overwrite anyway. Only consulted when neither expected_mtime nor expected_sha is given (those guards take precedence). | |
| fail_on_new_errors | No | When true (implies await_diagnostics), roll this write back if the language server CONFIRMS it introduced new errors here, leaving the file byte-for-byte unchanged and returning the delta as the error. An unconfirmed check never rolls back; nor do warnings, pre-existing errors, or breakage elsewhere. Not over 1 MiB. Default false. |
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 temp-file-plus-rename behavior, fsync guarantees, automatic parent-directory creation, LSP notification, and the no-partial-write outcome even on transport errors. It also explains the conditional rollback-ish protections against stale reads. This significantly exceeds what the raw name and schema alone would convey.
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 organized: primary action first, then safety guarantees, concurrency controls, failure semantics, and an alternative-tool pointer. It front-loads the most important decision-relevant information and avoids irrelevant filler. Any redundancy in reinforcing 'never partially written' is purposeful in the context of failure handling.
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 9-parameter mutation tool with no annotations and no output schema, this description is unusually complete. It explains the critical runtime behaviors an agent must reason about: atomicity, durability, read-check guards, transport failure outcomes, and diagnostic update side effects. An agent can safely invoke this tool with appropriate expectations of behavior and consequences.
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 covers 100% of parameters with descriptive text, so the baseline is 3. The description adds valuable meaning beyond the schema by explaining expected_mtime/expected_sha as concurrency guards tied to a prior read_file, and by framing atomicity, overwrite protection, and directory creation as behaviors. It does not walk through every parameter, but the schema does that job.
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 clear, specific verb and resource: 'Create or overwrite a file with the given content.' It distinguishes write_file from the sibling edit_file by explicitly directing targeted-edits use cases to edit_file, and it establishes full-content write as the core responsibility.
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 last sentence gives an explicit routing rule: use edit_file for targeted edits instead. It also describes exactly when to pass expected_mtime/expected_sha/overwrite_changed, showing when to refuse a write to avoid clobbering concurrent changes. This gives clear selection context among file-related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_memoryA
Write or overwrite a memory in a workspace's .plumb/memories/ directory.
The memory is a markdown file at /.plumb/memories/.md. If 'description' or 'paths' is provided, frontmatter is prepended automatically — list_memories will surface the description, and relevant_memories / hint injection use paths globs to attach the memory to files.
Memory names must match [A-Za-z0-9_-]+. Choose specific names that describe the memory's topic (e.g. 'auth-architecture', 'test-conventions', 'gotchas-cache-invalidation').
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Memory name (alphanumeric, _, - only). | |
| paths | No | Optional workspace-relative file globs this memory applies to, e.g. internal/auth/** or cmd/server/*.go. Stored as frontmatter and used by relevant_memories plus hint injection. | |
| content | No | Markdown body to save. | |
| workspace | No | Absolute workspace path. Defaults to the daemon's resolved workspace. | |
| description | No | One-line summary (optional). Stored as frontmatter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses the exact file path, the fact that it overwrites, automatic frontmatter prepending, and name constraints. It stops short of describing error behavior, return values, or permission requirements, but the key mutating behavior is clearly surfaced.
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: the first sentence states the core action, the second paragraph adds valuable behavioral detail about frontmatter and downstream consumers, and the third gives concise naming rules with concrete examples. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters, no annotations, and no output schema, the description covers the essential operational context: file location, frontmatter behavior, naming rules, and parameter semantics. It lacks explicit return-value or error-case details, but for a memory write tool this is adequate and would not leave an agent confused about invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing a baseline of 3. The description adds meaningful semantics: it explains how paths globs are used by relevant_memories/hint injection, that description is surfaced by list_memories, and provides naming conventions and workspace default. This goes beyond the schema's property 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 line 'Write or overwrite a memory in a workspace's .plumb/memories/ directory' clearly states the operation (write/overwrite), the resource (memory), and the location. It distinguishes itself from sibling memory tools like list_memories, read_memory, and delete_memory by its specific write-oriented action.
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 explains when the tool is relevant by describing how frontmatter is consumed (list_memories surfaces descriptions, relevant_memories/hint injection use paths globs) and provides naming guidance with examples. However, it does not explicitly contrast with alternatives like write_file or state when not to use it, so it lacks explicit exclusions.
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. Dates show when Glama detected each change.
3 tool updates
v0.17.7- Removed
execute_shell_command - Changed
run_task1 field changed- changed
Input schema / properties / target / descriptionPrevious value: -"Optional target substituted for a {target} token in the stored command (e.g. a single test name or package). The shipped go/python/rust test defaults carry a defaulted placeholder ({target:./...}), so scoping works with no config edit and omitting the target still runs everything. Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the stored command has no {target}."New value: +"Optional target substituted for a {target} token in the stored command (e.g. a single test name or package). The shipped go/python/rust test defaults carry a defaulted placeholder ({target:./...}), so scoping works with no config edit and omitting the target still runs everything. Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the command has no {target} slot."
- Changed
topology_impact7 fields changed- added
Input schema / properties / granularityAdded value: +{ + "default": "package", + "description": "Requires mode=\"reachability\". Default package follows production import edges. function follows the admitted Go call graph outward from exact callable roots; test-file callers are excluded and unresolved/dynamic calls are disclosed.", + "enum": [ + "package", + "function" + ], + "type": "string" +} - added
Input schema / properties / layersAdded value: +{ + "description": "Requires mode=\"reachability\". When true, the response is an SCC condensation of the reachable subgraph — package import cycles or function recursion depending on granularity — instead of the summary.", + "type": "boolean" +} - added
Input schema / properties / modeAdded value: +{ + "description": "Optional. \"reachability\" switches from the default single-symbol blast-radius analysis to entry-point reachability. Go-only for now; roots/path_to/layers require this mode.", + "type": "string" +} - changed
Input schema / properties / name / descriptionPrevious value: -"Symbol name or qualified name to analyse. Must exist in the topology index."New value: +"Symbol name or qualified name to analyse. Must exist in the topology index. Required unless mode=\"reachability\"." - added
Input schema / properties / path_toAdded value: +{ + "description": "Requires mode=\"reachability\". When set, the response is the single shortest root -> target chain; use a package directory for package granularity or file.go#Symbol for function granularity.", + "type": "string" +} - added
Input schema / properties / rootsAdded value: +{ + "description": "Requires mode=\"reachability\". package granularity accepts package directories or \"main\". function granularity accepts exact file.go#Symbol selectors or \"main\"; omit for defaults (package main roots plus candidate-seeded topology_routes roots).", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / requiredAdded value: +[]
2 tool updates
v0.17.2- Changed
mutation_test4 fields changed- changed
Input schema / properties / compile_task / descriptionPrevious value: -"Which stored slot proves the mutant COMPILES before its tests are trusted. Default \"build\". It always runs unscoped (no {target}) — a whole-module compile catches breakage a scoped test never reaches. Cannot be disabled: without it a non-compiling mutant looks exactly like a kill."New value: +"Which stored slot proves the mutant COMPILES before its tests are trusted. Default \"build\". It always runs unscoped (no {target}) — a whole-module compile catches breakage a scoped test never reaches. Cannot be disabled: without it a non-compiling mutant looks exactly like a kill. The built-ins are build, lint, test, e2e and verify; a project-defined slot works here too." - removed
Input schema / properties / compile_task / enumRemoved value: -[ - "build", - "lint", - "test", - "e2e", - "verify" -] - changed
Input schema / properties / test_task / descriptionPrevious value: -"Which stored [tasks.<lang>] slot runs the tests. Default \"test\"."New value: +"Which stored [tasks.<lang>] slot runs the tests. Default \"test\". The built-ins are build, lint, test, e2e and verify; a project-defined slot works here too." - removed
Input schema / properties / test_task / enumRemoved value: -[ - "build", - "lint", - "test", - "e2e", - "verify" -]
- Changed
run_task2 fields changed- changed
Input schema / properties / slot / descriptionPrevious value: -"Which stored task command to run: build, lint, test, e2e (integration), or verify (build then test). The command is configured per language in [tasks.<lang>] and resolved for this workspace's language — you cannot pass an arbitrary command."New value: +"Which stored task command to run: build, lint, test, e2e, verify, or a project-defined slot under [tasks.<lang>]. session_start lists what's configured; an unconfigured slot is refused with that list." - removed
Input schema / properties / slot / enumRemoved value: -[ - "build", - "lint", - "test", - "e2e", - "verify" -]
17 tool updates
v0.17.0- Changed
delete_file2 fields changed- changed
Input schema / properties / file_path / descriptionPrevious value: -"Absolute path, file:// URI, or workspace-relative path of the file or empty directory to delete."New value: +"Absolute path, file:// URI, or workspace-relative path of the file or empty directory to delete. Use paths instead to delete several in one call." - added
Input schema / properties / pathsAdded value: +{ + "description": "Several files and/or empty directories to delete in one call (max 100). Same per-path rules as file_path — this batches round-trips, it does NOT delete recursively. Every path is validated before any is removed, and directories are removed after files, deepest first, so naming a tree's files and its directories together works in one call.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
edit_file4 fields changed- changed
Input schema / properties / await_diagnostics / descriptionPrevious value: -"When true, block up to a few seconds for the language server to finish re-analysing this file and report an authoritative post-write result — a clean fresh pass is stated explicitly. Use it for a trustworthy \"did my change compile?\" answer instead of shelling out to a build. Default false (fast adaptive window; the result may predate the write)."New value: +"When true, block up to a few seconds for the language server to finish re-analysing this file, and append a machine-readable 'diagnostics delta' line (fresh, new_errors, resolved, pre_existing). The block is always labelled — authoritative, pre-write snapshot, unverified, or not-analysed — so a stale result is never dressed as fresh. Default false (fast adaptive window; the result may predate the write)." - added
Input schema / properties / fail_on_new_errorsAdded value: +{ + "description": "When true (implies await_diagnostics), roll this edit back if the language server CONFIRMS it introduced new errors here, leaving the file byte-for-byte unchanged and returning the delta as the error. An unconfirmed check never rolls back; nor do warnings, pre-existing errors, or breakage elsewhere. Not with apply_partial, or over 1 MiB. Default false.", + "type": "boolean" +} - changed
Input schema / properties / include_anchors / descriptionPrevious value: -"Anchor-bounded edit mode: when true the anchors themselves are part of the replaced span (the whole inclusive span becomes new_string); when false (default) only the text strictly between the anchors is replaced and the anchors are preserved as boundaries."New value: +"Anchor-bounded edit mode: when true the anchors are part of the replaced span; when false (default) only the text strictly between them is replaced and both are preserved." - changed
Input schema / properties / reconcile / descriptionPrevious value: -"When true, do NOT reject the edit if the file changed since your read (expected_mtime / expected_sha mismatch); apply against the current on-disk content instead, relying on the exact-once old_string match for safety. Use it for the edit→format(gofumpt/golangci-lint --fix)→edit loop, where a formatter bumped the mtime but your anchors still match. Default false (the mtime guard stays strict)."New value: +"When true, do NOT reject the edit if the file changed since your read (expected_mtime / expected_sha mismatch); apply against the current on-disk content instead, relying on the exact-once old_string match for safety. Use it for the edit→format→edit loop, where a formatter bumped the mtime but your anchors still match. Default false."
- Changed
explain_symbol4 fields changed- changed
Input schema / properties / character / descriptionPrevious value: -"Zero-based character offset"New value: +"Zero-based character offset. Required when symbol_name is not provided." - changed
Input schema / properties / line / descriptionPrevious value: -"Zero-based line number"New value: +"Zero-based line number. Required when symbol_name is not provided." - added
Input schema / properties / symbol_nameAdded value: +{ + "description": "Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "line", - "character" -]
- Changed
find_replace1 field changed- added
Input schema / properties / use_regex / descriptionAdded value: +"Treat pattern as a regular expression (Go RE2). Default false — pattern is literal text, so regex syntax such as | or \\. matches itself."
- Changed
git2 fields changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Required (true) for destructive and network subcommands. Also required to override the cross-session ref-movement guard: when a DIFFERENT plumb session moved this repo's HEAD/branch since this session last observed it, a write/destructive op is refused until re-run with confirm:true."New value: +"Required (true) for destructive and network subcommands. Also required to override the cross-session ref-movement guard: when a DIFFERENT plumb session moved this repo's HEAD/branch since this session last observed it, a write/destructive/network op is refused until re-run with confirm:true." - changed
Input schema / properties / expected_head / descriptionPrevious value: -"Optimistic-concurrency guard for write/destructive subcommands (mirrors edit_file's expected_mtime): any git revision (full/short SHA, branch, tag) naming the commit HEAD must be at. When supplied and HEAD resolves elsewhere — or resolves to nothing — the operation is refused before running, regardless of which session (or external tool) moved it. Ignored by read and network subcommands. Omit for no check."New value: +"Optimistic-concurrency guard for write, destructive, and network subcommands (mirrors edit_file's expected_mtime): any git revision (full/short SHA, branch, tag) naming the commit HEAD must be at. When supplied and HEAD resolves elsewhere — or resolves to nothing — the operation is refused before running, regardless of which session (or external tool) moved it. Ignored by read subcommands only. Omit for no check."
- Changed
leave_note1 field changed- changed
Input schema / properties / to / descriptionPrevious value: -"A peer session name, or \"next\" (default) for whoever attaches to this workspace next. A name belonging to a session in another workspace is delivered only if that project allows cross-project messages."New value: +"A peer session name, or \"next\" for whoever attaches to this workspace next. Omitting it defaults to \"next\" when you are starting a thread; when you pass a conversation_id it instead resolves to that thread's other participant, and the send is refused if the thread has no other participant or more than one. A name belonging to a session in another workspace is refused up front unless that project has already opted in to cross-project messages."
- Added
mutation_test - Changed
read_file1 field changed- changed
Input schema / properties / context_lines / maximumPrevious value: -10New value: +50
- Changed
read_multiple_files6 fields changed- added
Input schema / properties / context_linesAdded value: +{ + "description": "Lines of context around each match (like rg -C), applied to every path. Default 0. Only consulted when pattern is set.", + "maximum": 50, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / end_lineAdded value: +{ + "description": "Last line to return (1-based, inclusive) from EVERY path in this call. Omit to read to the end of each file.", + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / max_matchesAdded value: +{ + "description": "Maximum matching lines to return per file in search mode. Default 200. Only consulted when pattern is set.", + "maximum": 2000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / patternAdded value: +{ + "description": "Search EVERY path in this call for this pattern instead of returning a window — same semantics as read_file's pattern (literal by default, smart-case, Go RE2 regex when use_regex). Combine with start_line/end_line to restrict the search to that line window in every file.", + "type": "string" +} - added
Input schema / properties / start_lineAdded value: +{ + "description": "First line to return (1-based, inclusive) from EVERY path in this call — same semantics as read_file's start_line, applied uniformly. Omit to start from the beginning of each file.", + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / use_regexAdded value: +{ + "default": false, + "description": "Treat pattern as a Go RE2 regular expression. Only consulted when pattern is set.", + "type": "boolean" +}
- Changed
run_task1 field changed- changed
Input schema / properties / target / descriptionPrevious value: -"Optional target substituted for a literal {target} token in the stored command (e.g. a single test name or package). Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the stored command has no {target}."New value: +"Optional target substituted for a {target} token in the stored command (e.g. a single test name or package). The shipped go/python/rust test defaults carry a defaulted placeholder ({target:./...}), so scoping works with no config edit and omitting the target still runs everything. Restricted to one shell-safe argument ([A-Za-z0-9._/:@-]); refused if the stored command has no {target}."
- Changed
search_in_files2 fields changed- changed
Input schema / properties / context_lines / descriptionPrevious value: -"Number of lines of context to show before and after each match (like rg -C). Default 0."New value: +"Number of lines of context to show before and after each match (like rg -C). Default 0. Total output is capped at 200 KiB regardless, and truncation is labelled." - changed
Input schema / properties / context_lines / maximumPrevious value: -10New value: +50
- Changed
session_start1 field changed- added
Input schema / properties / detailAdded value: +{ + "description": "Orientation packet size. 'brief' (≤1.5 KB) returns workspace path, language, branch, a one-line git policy, diagnostics and active-peer COUNTS, memory NAMES only (no descriptions/sizes), and the edit-lane rule where it applies — cheap re-orientation for a subagent that does not need the full packet. 'full' returns the complete packet documented above. Defaults to 'full', except this default flips to 'brief' automatically when the supplied session_id was already seen by this daemon within the last 24h (a resumed conversation); an explicit value always wins over the automatic default.", + "enum": [ + "brief", + "full" + ], + "type": "string" +}
- Changed
topology_affected1 field changed- changed
Input schema / properties / max_results / descriptionPrevious value: -"Maximum affected nodes to return. Default 50."New value: +"Maximum PACKAGES to return. Default 50, which is well above a normal answer — raise it only for a change that fans out very widely. Tests are counted per package rather than listed individually, so this no longer caps test rows; the changed package always sorts first, so a cap cannot drop the package the edit landed in."
- Changed
topology_routes1 field changed- changed
Input schema / properties / path_prefix / descriptionPrevious value: -"Optional path prefix filter for route handlers (e.g. '/api/')."New value: +"Optional substring filter applied to the candidate symbol's name/signature (e.g. 'api') — NOT a URL path filter; it is not matched against any route path, since none is parsed."
- Changed
transaction_apply2 fields changed- added
Input schema / properties / await_diagnosticsAdded value: +{ + "description": "When true, wait for the language server to re-analyse each written file and append a labelled per-file diagnostics block with a machine-readable 'diagnostics delta' line. Default false.", + "type": "boolean" +} - added
Input schema / properties / fail_on_new_errorsAdded value: +{ + "description": "When true (implies await_diagnostics), roll the WHOLE transaction back if any written file is CONFIRMED to have gained new errors — all-or-nothing. An unconfirmed check never rolls back; nor do warnings or pre-existing errors. Default false.", + "type": "boolean" +}
- Changed
type_hierarchy4 fields changed- changed
Input schema / properties / character / descriptionPrevious value: -"Zero-based character offset within the line"New value: +"Zero-based character offset within the line. Required when symbol_name is not provided." - changed
Input schema / properties / line / descriptionPrevious value: -"Zero-based line number of the type"New value: +"Zero-based line number of the type. Required when symbol_name is not provided." - added
Input schema / properties / symbol_nameAdded value: +{ + "description": "Symbol name to look up instead of a position — PREFERRED over line/character. Accepts plain name or ReceiverType.MethodName form. plumb resolves it against the file's symbols, avoiding the off-by-one and 'no identifier found' errors of a hand-computed position. When provided, line and character are not needed.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "line", - "character" -]
- Changed
write_file2 fields changed- changed
Input schema / properties / await_diagnostics / descriptionPrevious value: -"When true, block up to a few seconds for the language server to finish re-analysing this file and report an authoritative post-write result — a clean fresh pass is stated explicitly. Use it for a trustworthy \"did my change compile?\" answer instead of shelling out to a build. Default false (fast adaptive window; the result may predate the write)."New value: +"When true, block up to a few seconds for the language server to finish re-analysing this file, and append a machine-readable 'diagnostics delta' line (fresh, new_errors, resolved, pre_existing). The block is always labelled — authoritative, pre-write snapshot, unverified, or not-analysed — so a stale result is never dressed as fresh. Default false (fast adaptive window; the result may predate the write)." - added
Input schema / properties / fail_on_new_errorsAdded value: +{ + "description": "When true (implies await_diagnostics), roll this write back if the language server CONFIRMS it introduced new errors here, leaving the file byte-for-byte unchanged and returning the delta as the error. An unconfirmed check never rolls back; nor do warnings, pre-existing errors, or breakage elsewhere. Not over 1 MiB. Default false.", + "type": "boolean" +}
58 tool updates
v0.16.6- First observed
agent_config - First observed
call_hierarchy - First observed
check_messages - First observed
copy_file - First observed
daemon_info - First observed
delete_file - First observed
delete_memory - First observed
diagnostics - First observed
edit_file - First observed
execute_shell_command - First observed
explain_symbol - First observed
file_diff - First observed
file_outline - First observed
file_status - First observed
find_files - First observed
find_references - First observed
find_replace - First observed
get_definition - First observed
git - First observed
git_init - First observed
insert_after_symbol - First observed
insert_before_symbol - First observed
leave_note - First observed
list_memories - First observed
minimal_diff_review - First observed
move_symbol - First observed
read_file - First observed
read_memory - First observed
read_multiple_files - First observed
read_symbol - First observed
relevant_memories - First observed
rename_file - First observed
rename_session - First observed
rename_symbol - First observed
replace_symbol_body - First observed
run_command - First observed
run_task - First observed
safe_delete_symbol - First observed
search_in_files - First observed
search_memories - First observed
session_start - First observed
share_findings - First observed
share_intent - First observed
structural_query - First observed
topology_affected - First observed
topology_explore - First observed
topology_impact - First observed
topology_routes - First observed
topology_search - First observed
topology_status - First observed
transaction_apply - First observed
type_hierarchy - First observed
undo_edit - First observed
workspace_search - First observed
workspace_sessions - First observed
workspace_symbols - First observed
write_file - First observed
write_memory
TDQS
Most tools have clearly distinct purposes, but a few overlapping search/analysis tools exist (workspace_symbols vs topology_search vs search_in_files, and find_references vs topology_impact) that could cause misselection. Descriptions are detailed enough to disambiguate in most cases.
There is a mix of conventions: many tools use verb_noun (read_file, write_file, get_definition), but others use noun_verb (file_outline, file_status, topology_search) or plain nouns (daemon_info). Naming is readable but not consistently patterned.
58 tools is substantially more than needed for the server's scope, exceeding the 25+ threshold for 'too many'. While each tool has a niche, many could be consolidated (e.g., topology_* cluster, collaborative messaging cluster), making the surface feel bloated.
The tool set provides comprehensive coverage of code editing, symbol manipulation, searching, git operations, memory management, and collaboration. Lifecycle operations for files and symbols are fully covered, with multiple fallback strategies and safety mechanisms, leaving no obvious dead ends.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Lean 4 MCP server: compile, prove theorems, and formalize math with Mathlib.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
An MCP server that gives your AI access to the source code and docs of all public github repos
Related MCP Servers
- FlicenseCqualityCmaintenanceA security-first MCP server that provides LLMs with structured tools for filesystem, process, search, build/test/lint, IDE integration, and more.402-
- AlicenseNot gradedqualityBmaintenanceLocal-first code intelligence and safety layer for AI coding agents. MCP server exposes dependency graph, impact analysis, and AST-compressed repo context, backed by typed local memory, patch-scope safety gates, and git-independent transaction rollback.1MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that exposes LSP-backed code navigation and editing tools to LLM agents using a single global config file to route file extensions to language servers.MIT
- AlicenseNot gradedqualityAmaintenanceLocal-first MCP server that provides project context, verification gates, and structured tools for coding agents to discover knowledge, run diagnostics, and execute allowlisted commands within a repository.35MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/plumbkit/plumb'
If you have feedback or need assistance with the MCP directory API, please join our Discord server