workspace-mcp
Provides read-only Git repository integration with git_status and git_diff tools, allowing agents to inspect branch status, working tree changes, and diffs within the workspace.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@workspace-mcpshow me the current git status and recent work log for my project"
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.
workspace-mcp
A Model Context Protocol (MCP) server that gives an agent in any MCP-capable chat client a small, safe filesystem toolkit scoped to one or more named project workspaces: read, write, edit, patch, grep and list. The point is to remove copy-paste: instead of asking the user to paste file contents into the chat, the agent reads, searches and edits files directly through typed tools with a containment boundary that rejects everything outside the selected workspace root. Since v1.5.0 one server process can serve several projects at once, and every path or state tool takes an optional workspace argument.
The tool set is modelled after opencode's built-in tools (read, write, edit, patch, grep, glob), plus an opt-in run_command tool for tests, linters and builds. Command execution is off by default and only registers when you ask for it with --shell (allowlist) or --shell-any (unrestricted).
On top of that, the server keeps a small workspace-local memory: an automatic activity journal plus persistent notes (work_log, remember, recall), and read-only git_status / git_diff tools that work without the shell, so a new chat can recover context on its own.
Runtime: Node.js >= 22, ESM only
Transports: stdio (default) and Streamable HTTP at
/mcpZero runtime dependencies beyond
@modelcontextprotocol/sdkandzod
Documentation
docs/ARCHITECTURE.md - module map, request flow, state model and design decisions.
docs/SECURITY.md - trust model, path containment, command execution and HTTP exposure.
CHANGELOG.md - release history.
Related MCP server: Abbie MCP Server
Requirements
Node.js 22 or newer
pnpm (or npm) for building from source
Install, build, run
pnpm install
pnpm build
# stdio (default) - what MCP clients launch
node dist/index.js --root /absolute/path/to/project
# Streamable HTTP with bearer token
node dist/index.js --root /absolute/path/to/project --http --port 3333 --token "$MCP_TOKEN"CLI reference
Option | Default | Description |
|
| Primary workspace root, registered as the workspace named |
| Register an additional named workspace. Repeatable. Names match | |
| off | Serve Streamable HTTP at |
|
| HTTP bind host. |
|
| HTTP bind port. |
|
| When set, every HTTP request must send |
| off | Enable |
| off | Enable the same tools in unrestricted mode (any executable). Implies |
| Add executables to the allowlist. Comma-separated ( | |
| Print usage. | |
| Print the version. |
Shell environment fallbacks (CLI flags take precedence): WORKSPACE_MCP_SHELL=1 enables allowlist mode, WORKSPACE_MCP_SHELL_MODE=allowlist|any sets the mode (setting it also enables the tool), WORKSPACE_MCP_SHELL_ALLOW=git,docker extends the allowlist.
Notes:
In stdio mode the server never writes to stdout (that is the protocol stream). All diagnostics go to stderr.
SIGINT/SIGTERMtrigger a graceful shutdown (transports and HTTP server are closed).If
--httpis used without a token on a non-loopback host, the server prints a loud security warning to stderr.
Tools
Every tool that takes a path/cwd or reads or writes workspace state also accepts an optional workspace argument (see Multiple workspaces); it defaults to the primary workspace.
Tool | Arguments | Behavior |
|
| Returns text with 1-based line numbers as |
|
| Creates parent directories, overwrites existing files. Returns |
|
| Exact string replacement. Empty |
|
| All-or-nothing: validates every edit against the current (in-memory) file contents first. If any edit fails, no file is written and the failing index is reported as |
|
| Read-only. Newest-first automatic journal of the mutating operations ( |
| none | Read-only. Lists the configured workspaces: name, absolute root path, |
|
| Appends a persistent note under |
|
| Read-only. Newest-first notes rendered as |
|
| Returns |
|
| Sorted workspace-relative entries; directories carry a trailing |
|
| Opt-in. Runs |
|
| Opt-in. Starts the command detached and returns immediately with a |
|
| Read-only. With |
|
| Sends |
|
| Read-only, no shell required. Runs |
|
| Read-only, no shell required. Runs |
|
| Creates a tracked change: JSON record plus documents directory, id = kebab-case slug of the title (deduped with |
|
| Makes an existing change active. While active, every journal entry is tagged with its id and the other change tools default to it. Unknown id is a clear error. |
|
| Writes |
|
| Read-only. The single re-orientation call: full view of one change (docs present/missing with byte sizes, tasks grouped by status, constraints, the last 10 tagged journal entries, and a derived suggested next action) or, with |
|
| Appends a task with a sequential id ( |
|
| All-or-nothing: every task id and status is validated before anything is written; one bad entry changes nothing on disk and the error lists the bad ids. A |
|
| Appends a constraint to the change and returns the count plus the full list. Constraints are shown by |
All tools:
accept workspace-relative paths (absolute paths inside the root also work) and reject anything that resolves outside the root;
return workspace-relative paths;
fail with
{ isError: true }and exactly one short, actionable message - never a stack trace or rawENOENTdump;annotate themselves for clients:
readOnlyHint: trueforread_file,grep,list_files,work_log,recall,git_status,git_diffandchange_status;destructiveHint: trueforwrite_file,edit_file,patch;readOnlyHint: false, destructiveHint: true, openWorldHint: truefor the opt-inrun_command,start_jobandjob_kill;readOnlyHint: true, openWorldHint: falseforjob_status; andreadOnlyHint: falseforrememberand the six mutating change tools (change_create,change_activate,change_doc,task_add,task_update,constraint_add) - they append to state under.workspace-mcp/and change no workspace data.
Glob syntax (used by grep.include and list_files.pattern): **, *, ?, {a,b} and [abc] character classes (including [!abc]). Patterns without a / match the file name at any depth, so *.ts matches src/index.ts.
Client configuration
Claude Desktop (Linux)
Config file: ~/.config/Claude/claude_desktop_config.json (macOS and Windows use their own platform paths). Restart Claude Desktop after editing.
{
"mcpServers": {
"workspace-mcp": {
"command": "node",
"args": ["/path/to/workspace-mcp/dist/index.js", "--root", "/path/to/project"]
}
}
}Cursor
Config file: ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project).
{
"mcpServers": {
"workspace-mcp": {
"command": "node",
"args": ["/path/to/workspace-mcp/dist/index.js", "--root", "${workspaceFolder}"]
}
}
}opencode
opencode.json (or global ~/.config/opencode/opencode.json) - local servers use the mcp key with type: "local":
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"workspace-mcp": {
"type": "local",
"command": ["node", "/path/to/workspace-mcp/dist/index.js", "--root", "/path/to/project"],
"enabled": true
}
}
}For the HTTP transport, use a remote entry with a header:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"workspace-mcp": {
"type": "remote",
"url": "http://127.0.0.1:3333/mcp",
"oauth": false,
"headers": { "Authorization": "Bearer ${MCP_TOKEN}" }
}
}
}ChatGPT desktop app
Settings -> MCP servers -> Add server -> choose STDIO, then provide the name plus the command and arguments (node /path/to/workspace-mcp/dist/index.js --root /path/to/project), save and restart. The desktop app (and Codex CLI / IDE extension, which share the config in ~/.codex/config.toml) also supports Streamable HTTP servers and bearer token authentication.
Remote HTTP clients that support custom headers
Any client that can set headers may connect to the HTTP transport with Authorization: Bearer <token>:
node dist/index.js --root /srv/project --http --host 127.0.0.1 --port 3333 --token "$MCP_TOKEN"
curl -s -X POST http://127.0.0.1:3333/mcp \
-H "Authorization: Bearer $MCP_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'The endpoint is stateless: every POST creates a fresh server instance, so no session headers are needed. GET/DELETE /mcp return 405, and a missing or wrong token returns 401 with WWW-Authenticate: Bearer.
ChatGPT web and other hosted web clients - read this
Hosted web clients (ChatGPT web, claude.ai connectors, and similar) are a different story:
They require a publicly reachable HTTPS Streamable HTTP endpoint.
localhostis not reachable from them.ChatGPT custom connectors authenticate through OAuth 2.1 (plus its own connector review flow). A static
Authorization: Bearerheader - which is all this server implements in v1 - is not an option there.Therefore v1 HTTP mode targets local testing and clients that accept custom headers (Cursor remote entries, opencode remote entries, Claude Code via
claude mcp add --transport http ... --header "Authorization: Bearer ...", API playgrounds, scripts). For ChatGPT web you would need to add an OAuth 2.1 layer around this server, which is out of scope for v1.
If you want to test with a public URL anyway, a tunnel works:
# WARNING: this publishes full read/write access to the --root directory on the
# public internet. The bearer token is the only thing protecting it. Use a long
# random token, a throwaway root, and shut the tunnel down when you are done.
cloudflared tunnel --url http://127.0.0.1:3333Then point the client at https://<random>.trycloudflare.com/mcp with the bearer header.
Multiple workspaces
Since v1.5.0 one server process can serve several projects at once. Each workspace is a named root with its own state under <root>/.workspace-mcp/:
node dist/index.js --root /path/to/project --workspace api=/path/to/other-project--root <dir>registers the primary workspace nameddefault.--rootalone behaves exactly as before (fully backward compatible).--workspace <name>=<path>is repeatable and registers another workspace. Names must match^[a-z0-9][a-z0-9_-]*$. A missing=, an invalid name, a duplicate name (including--workspace default=...next to--root) or a non-existent path aborts startup with a clear message.With only
--workspaceflags, the first one is primary unless one is literally nameddefault. With no flags at all, the current working directory is the single primary workspace nameddefault.Every path or state tool accepts an optional
workspaceargument, for exampleread_file { "path": "src/index.ts", "workspace": "api" }. Omitting it targets the primary workspace. An unknown name fails withunknown workspace "X". Available: ....workspace_list(read-only) shows every workspace: name, absolute path,(primary)marker, whether<root>/.workspace-mcpexists, and the active change id whenstate.jsonexists.Isolation is per root. Paths are confined to the selected root, and the journal, notes and change tracking live under the selected root's
.workspace-mcp/. A../escape is rejected relative to the selected workspace even when the same path would be valid in another one.Shell tools follow the selection.
run_commandandstart_jobresolvecwdagainst the selected workspace, andgit_status/git_diffrungit -C <selected root>.
ChatGPT tunnel and Codex examples
Secure MCP Tunnel: scripts/tunnel.sh supports --workspace <name>=<path> (repeatable); the script regenerates the profile automatically when the configuration changes (reusing the stored tunnel_id):
scripts/tunnel.sh --shell \
--root /path/to/project \
--workspace api=/path/to/other-projectIf --root is omitted, the first --workspace becomes the primary. The profile's mcp-command is passed straight to the server, so you can also extend it by hand:
# ~/.config/tunnel-client/workspace-mcp.yaml
mcp-command: "node /path/to/workspace-mcp/dist/index.js --root /path/to/project --workspace api=/path/to/other-project"~/.codex/config.toml (shared by the ChatGPT desktop app, Codex CLI and IDE extension):
[mcp_servers.workspace-mcp]
command = "node"
args = [
"/path/to/workspace-mcp/dist/index.js",
"--root", "/path/to/project",
"--workspace", "api=/path/to/other-project",
"--shell"
]Security model
Trust model. The server runs as a normal child process with your OS user's permissions; it is not a sandbox. --root is the intended boundary: everything inside it is fair game (including deletion of content through overwrites and edits), everything outside is not reachable through these tools. Run it with an account that has no more filesystem access than you want the agent to have. A malicious or confused model with write access to a workspace can still destroy that workspace - version control and backups remain your safety net.
Containment. Every path argument goes through one implementation:
Absolute paths outside the root are rejected; relative paths resolve against the root.
Both the root and the target are canonicalized with
fs.realpath. For a target that does not exist yet (a new file), the nearest existing ancestor is realpath-ed and the remaining segments are appended - so a symlinked ancestor that escapes is caught.The final real path must equal the root or start with
root + path.sep, otherwise the tool fails withpath outside workspace root: <input>.
This blocks ../../etc/passwd, absolute paths such as /etc/passwd, and symlinks inside the workspace that point outside it (for reads and writes).
Other deliberate restrictions:
No command execution unless you opt in. With no
--shell/--shell-anyflag and no shell env vars,run_commandis not registered andtools/listexposes exactly nineteen tools: the six filesystem tools plusworkspace_list,work_log,remember,recall,git_status,git_diffand the seven change tools. When enabled, read the dedicated subsection below.Binary files (NUL byte within the first 8 KiB) cannot be read or searched;
list_filesomits them..git,node_modules,.cacheand.workspace-mcpdirectories are skipped bygrepandlist_files.Symbolic links are never followed during directory traversal (prevents loops and escape).
Tool errors are sanitized: one short sentence, no stack traces, no raw filesystem errors. Full details are logged to stderr only.
HTTP mode: the bearer token is compared in constant time, and requests without it get
401. The token never appears in logs.Known limitations: path checks and the subsequent file operation are not a single atomic operation (TOCTOU);
patchwrites files one by one after validating all edits, so a disk error mid-write can leave some files updated; there is no rate limiting, audit log or per-tool allowlist; the HTTP transport trusts the network beyond the token (put a TLS-terminating reverse proxy in front for anything non-local).
Command execution (opt-in)
run_command exists so an agent can run tests, linters, builds and commands such as git status in the workspace. Be honest about what it is: an allowlist is a guardrail against casual or accidental execution, NOT a sandbox.
Off by default. Without
--shell,--shell-anyor theWORKSPACE_MCP_SHELLenv vars, the tool is not registered at all.No shell parsing. The command is an argv array executed with
spawn(..., { shell: false }). Pipes (|),&&, redirection (>),$VARexpansion and globs are passed as literal arguments and are never interpreted - that is the whole point.The allowlist is not containment. In allowlist mode the executable name (
path.basename(command[0])) must be in the allowlist (pnpm,npm,npx,nodeby default; extend with--shell-alloworWORKSPACE_MCP_SHELL_ALLOW). Butnode -e,npxand package scripts can execute arbitrary code, so every allowlisted entry already implies arbitrary-code execution.--shell-anyskips the check entirely and prints a loud warning to stderr.Same OS permissions. The child runs with your OS user's permissions.
cwdis confined to the workspace root, but the process itself can reach anything your user can.Environment scrubbing.
CONTROL_PLANE_API_KEY,OPENAI_API_KEY,OPENAI_ADMIN_KEYandMCP_TOKENare removed from the child environment;NO_COLOR=1andFORCE_COLOR=0are set.Timeouts kill the process group. Default 120 s, max 600 s. On timeout the whole group receives
SIGTERM, thenSIGKILLafter a 3 s grace period.Output is bounded. stdout and stderr are merged (best effort, arrival order), ANSI escape codes are stripped, and above 256 KiB only the first 32 KiB and the last 32 KiB are kept - the tail is where test failures print.
ChatGPT asks for confirmation per call. The tool is annotated
readOnlyHint: false,destructiveHint: true,openWorldHint: true, so ChatGPT requests approval for every invocation; it cannot be made read-only because it is not.
How to enable:
Local / ChatGPT desktop (Work) / Codex config (
~/.codex/config.toml): append--shell(allowlist) or--shell-any(unrestricted) to the server args, e.g.args = ["/path/to/workspace-mcp/dist/index.js", "--root", "/path/to/project", "--shell"].ChatGPT chat through Secure MCP Tunnel:
scripts/tunnel.sh --root /path --shellor--shell-any. The script exportsWORKSPACE_MCP_SHELL=1/WORKSPACE_MCP_SHELL_MODE=anybeforeexec tunnel-client run, and the daemon child inherits them.
Long-running commands (jobs)
run_command is synchronous: the client waits for the result. Test suites with testcontainers, docker pulls or server boots can outlive that wait - ChatGPT closes the call on timeout, the result never reaches the conversation, and the work done so far is unreachable even if the OS process is still running. start_job exists for exactly that case.
The workflow:
start_jobwith the same argv array,cwdand allowlist rules asrun_command, plus an optionalnamelabel. It returns in milliseconds with ajobId,pid,startedAtand the log file path - it never waits for output.Poll
job_statuswith thejobId. It is read-only (readOnlyHint: true), so ChatGPT does not ask for confirmation and polling is cheap. It reportsrunning/exited/killed/timed-out/failed-to-start, the exit code, duration, log size and the lasttailBytesof output (ANSI-stripped; default 8 KiB, cap 256 KiB).Call
job_killif the job must stop.SIGTERMgoes to the whole process group,SIGKILLfollows after 3 seconds. Killing an already finished job is not an error.
Details worth knowing:
Jobs survive client disconnects. The process is spawned detached and the registry is process-global, so a timed-out call, a dropped transport or a fresh server instance in stateless HTTP mode can still read the job with
job_status. This is the point of the feature.Logs live outside the workspace, at
$TMPDIR/workspace-mcp-jobs/<jobId>.log(normally/tmp/workspace-mcp-jobs/), or under$WORKSPACE_MCP_JOB_DIRwhen that variable is set. stdout and stderr append there, so they never show up inlist_filesorgrep.The log is capped at 64 MiB per job. Past the cap output is discarded;
job_statusthen showslog capped at 64 MiB.maxRuntimeMsbounds the job: default 30 minutes, minimum 1 second, cap 2 hours. On expiry the process group is killed and the status becomestimed-out.Restarting the daemon kills running jobs. Jobs live in the server process;
SIGINT/SIGTERM(or a stdio stdin close) terminates every running job's process group before exiting, so no orphans are left behind. There is no durable queue.Same guardrails as
run_command. Allowlist mode applies before spawning (validation failures are synchronous errors and create no job), the environment is scrubbed,cwdis confined to the workspace root, and there is no shell. The child still runs with your OS user's permissions.
Memory and tracking
The server keeps a small, workspace-local memory so a new chat can recover context without the user re-explaining anything. Every workspace has its own state, and everything lives under the selected workspace's <workspace-root>/.workspace-mcp/:
.workspace-mcp/
.gitignore # contains "*", so the directory stays invisible to git
journal.jsonl # automatic activity journal (mutating operations)
journal.1.jsonl # rotated previous journal, created when the size limit is exceeded
notes.jsonl # deliberate notes saved with remember
notes.1.jsonl # rotated previous notes
state.json # { "activeChange": "<id>" | null }
changes/
<id>.json # change record: title, goal, constraints, tasks
<id>/ # stage documents written on demand
proposal.md
spec.md
design.md
notes.mdThe directory is created lazily on the first write, contains its own .gitignore with * (the repository's own .gitignore is never touched), and is part of the traversal ignore list, so grep and list_files never see it.
What is journaled automatically
Every mutating tool appends one JSON line ({ ts, tool, paths?, detail?, result? }) after it completes, whether it succeeded or failed:
Tool |
|
|
|
|
|
|
|
|
|
|
|
| the joined argv |
|
| the joined argv |
|
| the job id | final status / |
What is NOT journaled: every read-only tool (read_file, grep, list_files, work_log, recall, git_status, git_diff) and job_status. Journaling is best-effort: a state write failure is logged to stderr and never changes the tool's own result. Appends are serialized per file and written with fs.appendFile, which is atomic for small lines, so concurrent tools cannot interleave.
Session-start and session-end convention
At the start of a session, call work_log (what happened recently) and recall (notes saved deliberately) to recover context. After finishing a chunk of work, call remember with what changed and what should happen next — for example:
{
"text": "Refactored auth middleware; next: add refresh-token rotation",
"tags": ["auth", "todo"]
}The server instructions sent to MCP clients carry this convention, so a cooperating model follows it without user prompting.
work_logreturns lines like2026-09-18T07:50:12.000Z edit_file src/x.ts — 2 replacements [ok], newest first, with optionalsince(ISO 8601),path(substring on any recorded path) andlimit(default 50, cap 500) filters. An empty result isno activity recorded yet.recallreturns lines like2026-09-18 [#auth] Refactored auth middleware..., newest first, filterable byquery(case-insensitive substring on the text) andtag(case-insensitive exact). No matches reportsno notes match.
Rotation and size bounds
Both streams rotate at WORKSPACE_MCP_JOURNAL_MAX_BYTES (default 5 MiB): when the current file exceeds the limit it is renamed to <name>.1.jsonl (replacing any older .1) and a fresh file is started. Reads are bounded too: at most the last 1 MiB of the current file, then the last 1 MiB of the rotated file when more entries are needed; malformed lines are skipped. detail and result are truncated to 300 characters.
Read-only git tools
git_status and git_diff are always registered — they do not need --shell. They spawn git argv-style (shell: false) with LC_ALL=C and a scrubbed environment, are annotated readOnlyHint: true, and only read the repository (nothing is fetched or written). git_status runs git status --porcelain=v1 -b with a 10 s timeout; git_diff runs git diff with a 30 s timeout, optional --cached/--stat, and a workspace-relative path resolved through the containment check and passed after --. git_diff output is capped at 64 KiB (first 32 KiB + last 32 KiB).
Changes and tasks (SDD-lite)
A change is the unit of work. It is a JSON record at .workspace-mcp/changes/<id>.json plus a sibling directory .workspace-mcp/changes/<id>/ holding stage documents written on demand (proposal.md, spec.md, design.md, notes.md). The record shape is:
{
"id": "my-change",
"title": "My change",
"goal": "optional outcome statement",
"constraints": ["no new runtime dependencies"],
"tasks": [
{ "id": "T1", "text": "wire the schema", "status": "pending", "notes": [], "createdAt": "...", "updatedAt": "..." }
],
"createdAt": "...",
"updatedAt": "..."
}.workspace-mcp/state.json stores { "activeChange": "<id>" | null }. Change JSON and state.json are written atomically (<file>.tmp + rename), so readers never observe a partial file and no .tmp remains after a successful write. Mutating change tools (change_create, change_activate, change_doc, task_add, task_update, constraint_add) are additionally serialized by an in-process mutex, so parallel tool calls from one client cannot interleave a read-modify-write and lose updates.
Workflow: change_create (creates the record and documents directory, becomes active) → change_doc for the proposal/spec/design documents, in any order and on demand → task_add to break the work down → task_update to move tasks (pending → in_progress → done, or blocked) with optional notes → constraint_add for rules the work must respect.
Re-orient in one call: change_status is read-only, needs no confirmation and never writes state. Without arguments it renders the active change in full; with all: true (or when no change is active) it lists every change newest-first with done/total task counts and an (active) marker. The only read-only change tool is change_status; all other change tools are marked readOnlyHint: false because they write state under .workspace-mcp/.
While a change is active, every journal entry written by a mutating operation is tagged with its id, and work_log accepts a change filter to scope the log to one change. The full view ends with a derived suggested next action, in priority order:
Situation | Suggestion |
no tasks and no proposal | write the proposal with |
all tasks done | run the tests and save a summary with |
any task | unblock |
any task | continue |
any task | start |
no tasks (but a proposal exists) | break the work into tasks with |
The full view also shows each stage document present or missing with its byte size, all tasks grouped by status as T1 [pending] text, every constraint, and the last 10 journal entries tagged with the change.
Limits
Limit | Value |
| 2000 (hard cap; |
| ~1 MiB |
| 2000, with |
File size that can be read or edited | 16 MiB |
| default 100, cap 1000 |
| first 1 MiB |
| default 500, cap 5000 |
| default 6, cap 12 |
Binary detection window | first 8 KiB |
Ignored directories |
|
| default 120000 ms, min 1000 ms, max 600000 ms |
| 256 KiB before collapsing to first 32 KiB + last 32 KiB |
| 3 s between |
| default 1800000 ms, min 1000 ms, max 7200000 ms |
| 64 MiB hard cap, then output is discarded and flagged |
| default 8192 bytes, cap 262144 bytes |
| 20 most recent jobs |
job kill grace | 3 s between |
State rotation |
|
State read bound | last 1 MiB of the current file, then last 1 MiB of |
| default 50, cap 500 |
| default 20, cap 100 |
| max 20 tags, 50 characters each |
Journal | truncated to 300 characters |
| 10 s |
| 30 s |
| 64 KiB (first 32 KiB + last 32 KiB) |
Development
pnpm build # tsc -> dist/
pnpm typecheck # strict typecheck of src and test
pnpm test # vitest (unit + end-to-end over InMemoryTransport)
pnpm dev # tsc --watchThe test suite uses a real temporary workspace (fs.mkdtemp) and a real MCP Client over the SDK's InMemoryTransport; nothing about the filesystem is mocked. Coverage includes the handshake and tool listing, read/write/edit/patch semantics, all-or-nothing patching, path traversal and symlink escapes, grep include/ignore rules, listing depth and patterns, the glob matcher, opt-in command execution (registration on/off, allowlist rejection and extension, unrestricted mode, non-zero exits, timeouts, cwd confinement, env scrubbing, head+tail truncation and ANSI stripping), background jobs (immediate return, survival across client disconnects, allowlist/cwd rejection without job creation, tailBytes, job_kill with a dead-pid check, maxRuntimeMs, env scrubbing, ANSI stripping and shutdown hygiene), the activity journal and notes (instrumentation for every mutating tool, error entries, filters, persistence across server instances, lazy state creation, self-ignoring git directory, size rotation), the read-only git tools (porcelain status, staged/unstaged/stat/filtered diffs, non-repository and missing-git errors) and change tracking (slug ids and dedupe, atomic records, activation, document replace/append, sequential task ids, all-or-nothing task updates with notes, constraints, the derived suggestions across the lifecycle, journal tagging and the change filter, cross-instance persistence, registration counts and no leftover .tmp files), plus multi-workspace support (flag parsing, named roots, default resolution, per-workspace isolation and confinement, workspace_list, and per-workspace git/run_command).
License
Available Tools
19 toolschange_activateActivate changeA
Make an existing change the active one. While a change is active, every journal entry written by mutating operations is tagged with its id, and the change tools default to it. Returns a short summary of the change.
| Name | Required | Description | Default |
|---|---|---|---|
| changeId | Yes | Id of the change to activate, as returned by change_create. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate that the operation is not read-only and not destructive. The description adds valuable behavioral context: activating a change tags journal entries from mutating operations and makes the change the default for change tools. It also mentions the return value, going beyond the 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?
Three short sentences deliver purpose, side effects, and return value with no filler. The key action is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is sufficient for a simple two-parameter tool: it explains the operation, its consequences, and the return value. It does not elaborate on error cases or the fate of a previously active change, but those are not essential for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both changeId and workspace clearly documented. The description does not add parameter-level details beyond the schema, so the baseline 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 begins with a specific verb and resource: 'Make an existing change the active one.' It clearly distinguishes this from sibling tools like change_create (creation) and change_status (status reporting) by focusing on setting the active/default change, and it adds concrete behavioral effects.
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: when an existing change should become the active context for journal tagging and for change tools' default behavior. It does not explicitly name alternatives or exclusion conditions, 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.
change_createCreate changeA
Create a tracked change (the unit of work) and make it the active change. A change is a JSON record plus a directory that holds its stage documents (proposal.md, spec.md, design.md, notes.md) written on demand with change_doc. Use it to track multi-step work so any future chat can re-orient with a single change_status call. The id is a kebab-case slug of the title, deduplicated with -2, -3, ... on collision. Next step: write the proposal with change_doc, then break the work into tasks with task_add.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | Optional one-sentence goal or outcome statement. | |
| title | Yes | Short human-readable title of the change; it becomes the kebab-case id. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnly=false, openWorld=false, destructive=false. The description adds substantial behavioral detail: making the new change active, creating a JSON record plus a stage-document directory, writing documents on demand, and deriving a deduplicated kebab-case id. This gives the agent a concrete model of side effects beyond what annotations provide.
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?
Front-loaded with the core action in the first sentence; each following sentence adds a distinct fact (concept, use case, id rule, workflow next steps). It is slightly longer than the bare minimum, but 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?
The description covers creation semantics, id generation, and the surrounding workflow. However, with no output schema, it does not say what the call returns (e.g., the generated id or change object), and it leaves the effect on any previously active change implicit.
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 meaningful semantics beyond the schema by explaining that the title becomes the kebab-case id with -2, -3 collision deduplication, which directly affects how an agent should choose a title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Create a tracked change ... and make it the active change.' This clearly distinguishes creation from sibling change_activate and positions the tool within the change lifecycle, so an agent can tell it apart without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly identifies the intended use ('track multi-step work so any future chat can re-orient with a single change_status call') and gives explicit next steps with change_doc and task_add. It does not explicitly say when not to use it or name alternatives for existing changes, 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.
change_docWrite change documentA
Write one stage document of a change: proposal, spec, design or notes. By default the document is replaced; with append: true the new content is appended after a blank line. Documents live under /.workspace-mcp/changes//.md and can be written in any order, on demand. Returns the workspace-relative path and which stage documents exist.
| Name | Required | Description | Default |
|---|---|---|---|
| stage | Yes | Document stage: proposal (why/scope), spec (requirements), design (how), or notes (scratchpad). | |
| append | No | Append after a blank line instead of replacing the document. Defaults to false. | |
| content | Yes | Markdown content to store. | |
| changeId | No | Change id. Defaults to the active change; an unknown id is a clean error. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint false, destructiveHint false), the description discloses the default replace behavior, the append option, the exact file path pattern, and the return value (workspace-relative path and existing stage documents). This adds meaningful behavioral context that annotations do not provide, such as the overwrite semantics and the location convention. It does not contradict any annotation.
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 with no filler. The first sentence states the core purpose, the second explains the append/replace behavior, and the third gives the location and return value. Each sentence earns its place and information is front-loaded.
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 moderate complexity (5 params, no output schema) and available annotations, the description covers the key operational details: purpose, overwrite semantics, file path, and return value. It does not explicitly mention the active change default or the clean error for unknown changeId, but those are documented in the input schema, so the description is adequately complete 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?
With 100% schema description coverage, the baseline is 3. The description adds value by showing how parameters map to the file path (<workspace>/.workspace-mcp/changes/<id>/<stage>.md) and reinforcing the append behavior. This goes beyond the schema's per-property descriptions by illustrating the relationships between workspace, changeId, and stage.
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: 'Write one stage document of a change: proposal, spec, design or notes.' It names the four stage types and clarifies this is for change documents, distinguishing it from generic file tools like write_file or edit_file. The first sentence alone fully conveys the tool's unique 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 gives clear context for when to use the tool: it writes change stage documents, can be written in any order, and on demand. It explains the replace/append options but does not explicitly name alternative tools or state when not to use it. The purpose is narrow enough that usage is clear, but explicit sibling differentiation would push this to 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
change_statusChange statusARead-only
Read-only orientation call: the single way to re-orient on tracked work at the start of any chat. Without arguments it renders the active change in full: title, goal, stage documents present or missing, tasks grouped by status, constraints, the last ten journal entries tagged with the change, and a derived suggested next action. With all: true (or with no active change) it lists every change newest-first with done/total task counts. Never writes state and is never journaled.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | List every change instead of rendering one in full. Defaults to false. | |
| changeId | No | Change id. Defaults to the active change; an unknown id is a clean error. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this with 'Never writes state and is never journaled,' adding the journaling detail beyond the annotations. It also discloses fallback behavior ('with no active change'), the full list of rendered content, and the meaning of all: true. No contradiction with annotations 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 dense but well structured: it front-loads the read-only orientation purpose, then details the two modes and the safety guarantee. It is slightly longer than strictly necessary because the final 'Never writes state' partially repeats the opening 'Read-only' framing, but every sentence otherwise adds useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with three optional parameters and no output schema, the description thoroughly covers invocation modes, output contents, default behavior, fallback when no active change exists, and side-effect guarantees. An agent has everything needed to call it correctly without inferring missing behavior.
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 three parameters. The description adds behavioral nuance around all: true and the no-argument default, but it does not substantially extend the meaning of changeId or workspace beyond what the schema states. This matches the baseline for fully self-documenting schemas.
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 names a specific verb and resource: a read-only orientation call that renders the active change in full or lists all changes. It clearly distinguishes itself from sibling mutation tools like change_create and task_add by emphasizing it never writes state. The phrase 'the single way to re-orient on tracked work' makes its role 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 gives explicit usage context: use it at the start of any chat to re-orient on tracked work. It also explains the two call modes (no arguments vs all: true) and the no-active-change fallback. It does not name sibling alternatives explicitly, but the read-only framing plus sibling names like change_create and task_add make the boundary clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
constraint_addAdd constraintA
Append one constraint to a change: a rule, limit or requirement that the work must respect (for example 'no new runtime dependencies'). Constraints are shown by change_status so later chats do not have to re-ask.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The constraint, phrased as a short rule. | |
| changeId | No | Change id. Defaults to the active change; an unknown id is a clean error. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate this is a mutating operation (readOnlyHint=false), and the description confirms and elaborates by saying the tool appends rather than replaces. It adds meaningful behavior beyond annotations: constraints persist and are surfaced by change_status in later chats. No contradiction with annotations was found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the core action and an illustrative example are front-loaded, and the persistence rationale is stated in one concise second sentence. Every part adds value.
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 small append-only tool, the description plus fully documented schema covers how to use it, what the constraint is for, and how it will be visible afterward. With no output schema, it does not describe the return value, but that is low-stakes for this operation and does not impede correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the text parameter's intended form with an example and explains persistence, but it does not add new details about changeId or workspace beyond what the schema already provides. The example is helpful but not essential given the schema already says 'phrased as a short rule.'
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-resource pair, 'Append one constraint to a change,' and clarifies what a constraint is with an example ('no new runtime dependencies'). It clearly distinguishes this from siblings like task_add and change_doc by focusing on constraint semantics and their persistence through change_status.
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: when the work needs a rule, limit, or requirement to be remembered and respected. It also explains why this tool is useful rather than just re-asking later. It does not explicitly name alternatives or exclusions, but the context is strong enough for an agent to infer appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_fileEdit fileADestructive
Replace an exact string in an existing text file. The oldString must match the file content exactly, including whitespace and indentation. If oldString appears more than once, either add more surrounding context to make it unique or set replaceAll=true. Read the file first with read_file. The change is written to disk immediately and is not reversible. For several files or several changes at once, prefer patch so all edits succeed or none are applied.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Workspace-relative path of the file to edit. Absolute paths inside the workspace are also accepted. | |
| newString | Yes | Replacement text. Use an empty string to delete the matched text. | |
| oldString | Yes | Exact text to replace. Must not be empty. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. | |
| replaceAll | No | Replace every occurrence instead of requiring a unique match. Defaults to false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, but the description adds meaningful context: 'The change is written to disk immediately and is not reversible.' This goes beyond the structured hint by disclosing immediacy and irreversibility, which materially affect how an agent should invoke the 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?
Four sentences, each earning its place: purpose, matching constraint, ambiguity handling, and atomicity guidance via patch. The core behavior is front-loaded and no words are 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 destructive mutation tool, the description covers the prerequisite (read_file first), the matching pitfalls, the multi-occurrence handling, and the reversible-vs-atomic tradeoff with an alternative tool. No output schema exists, but return values are secondary for a tool whose effects are the point; the description is complete enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real value: it explains that oldString must match the file content exactly including whitespace and indentation, explains the ambiguity condition ('If oldString appears more than once'), and prescribes the remedy (more context or replaceAll=true). These semantics are not present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Replace an exact string in an existing text file'), and the exact-match semantics distinguish it from siblings like write_file and patch. An agent can immediately tell what this tool does and how it differs from nearby 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?
It explicitly instructs the agent to read the file first with read_file and names patch as the preferred alternative when multiple changes must be atomic ('so all edits succeed or none are applied'). This gives clear when-to-use and when-not-to-use guidance without leaving it to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
git_diffGit diffARead-only
Read-only git diff of the workspace: runs 'git diff' without a shell (LC_ALL=C, 30 s timeout) and returns the patch text. Use staged=true for the index (--cached), stat=true for a diffstat (--stat), and path to limit the diff to one workspace-relative file (passed after '--'). Reports '(no changes)' when the diff is empty. Output longer than 64 KiB keeps the first 32 KiB and the last 32 KiB. No --shell flag is needed for this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Workspace-relative file or directory to limit the diff to. Absolute paths inside the workspace are also accepted. | |
| stat | No | Return a diffstat (git diff --stat) instead of the full patch. Defaults to false. | |
| staged | No | Diff the staged changes (git diff --cached) instead of the working tree. Defaults to false. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses execution details (LC_ALL=C, 30 s timeout, no shell), return shape (patch text, '(no changes)' on empty), and truncation behavior at 64 KiB. These add real behavioral context beyond the readOnlyHint/openWorldHint annotations; no contradiction.
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 with no filler; the core purpose is front-loaded, and implementation details and edge cases are compactly packed. Every sentence carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with full schema parameter documentation, the description is complete: it covers command execution, output format, empty-diff behavior, output size handling, and the workspace parameter. Since no output schema exists, the explicit return explanation is valuable.
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 met and schema descriptions already document each parameter. The description adds flag-level mapping (staged=true for --cached, stat=true for --stat, path passed after '--'), which helps agents use parameters correctly.
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 'Read-only git diff of the workspace' — a specific verb, resource, and scope, and clarifies it runs without a shell, distinguishing it from mutating or shell-based siblings. It could go further by explicitly naming alternatives like git_status or patch, so it stops short of full sibling differentiation.
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 for when to use the tool (any need for a git diff of the workspace) and covers the main option flags (staged, stat, path), but it does not explicitly contrast it with sibling tools. The guidance is adequate but largely implied rather than stated as selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
git_statusGit statusARead-only
Read-only git status of the workspace: runs 'git status --porcelain=v1 -b' without a shell (LC_ALL=C, 10 s timeout) and returns a 'branch: ...' header followed by the porcelain lines exactly as git prints them. A clean tree reports 'working tree clean'. A directory that is not a git repository or a missing git binary is reported as a clear error. No --shell flag is needed for this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint annotation by disclosing the exact command, environment settings (LC_ALL=C), timeout (10 s), output format ('branch: ...' header plus porcelain lines), clean-tree behavior, and error handling for non-repository directories or missing git binaries. This is rich behavioral context that helps an agent anticipate results and failure modes.
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 information-dense but every sentence contributes: command specification, environment and timeout, output format, clean-tree behavior, error handling, and a usage note. Key details are front-loaded with 'Read-only git status' and the command, followed by supporting behavior details. No filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one optional parameter and no output schema, the description covers everything an agent needs: input, command behavior, output format, edge cases, and error reporting. There are no significant gaps in context for correct invocation and interpretation.
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 single parameter 'workspace' is fully described in the input schema, including its default behavior, so schema coverage is 100%. The tool description itself does not need to add parameter semantics. Baseline 3 is appropriate because the schema already carries the necessary meaning.
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 ('git status'), the exact command form ('git status --porcelain=v1 -b'), and explicitly marks it as read-only, distinguishing it from mutation tools in the sibling list. It also clarifies what the tool does not do (no shell, no --shell flag). This makes the tool's identity unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes when to use the tool: to obtain the git status of a workspace. It also provides practical usage context such as not needing a --shell flag and how clean trees and error cases are reported. It does not explicitly contrast with siblings like git_diff, but the scoped purpose is strong enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grepSearch file contentsARead-only
Search file contents in the workspace with a JavaScript regular expression and return matches as 'relative/path:LINE: '. Use this to find where a symbol, string or pattern appears. Narrow the search with path and include. Skips binary files and the .git, node_modules and .cache directories. Do not use it to list files (use list_files) or to read a known file (use read_file).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | File or directory to search, workspace-relative. Defaults to the workspace root. | |
| include | No | Glob filter for file paths, e.g. '*.ts' or 'src/**/*.ts'. Patterns without a slash match the file name at any depth. | |
| pattern | Yes | JavaScript regular expression source, e.g. 'function\s+main' or 'TODO:'. Not a shell glob. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. | |
| ignoreCase | No | Case-insensitive matching. Defaults to false. | |
| maxResults | No | Maximum number of matching lines to return. Defaults to 100 and is capped at 1000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safe-read nature is covered without redundancy. The description adds genuinely useful behavior beyond annotations: it skips binary files and the .git, node_modules, and .cache directories, and it defines the exact match output shape. Minor gap: it does not spell out that matching is line-oriented rather than context/block based, though the output format implies it.
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: core purpose and output format, usage trigger, narrowing strategy, behavioral caveat, and exclusions. The most decision-relevant fact is front-loaded, and no sentence is redundant with the annotations or 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?
The definition is complete for a 6-parameter read-only search tool with no output schema. It covers what is searched, how matches are formatted, which directories are excluded, how to narrow the search, and which siblings to use instead. Parameter defaults live in the schema (maxResults cap, workspace default), and the read-only guarantee lives in the annotations.
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 all 6 parameters are already documented at the schema level; the baseline of 3 applies. The description adds only marginal strategic value by saying 'Narrow the search with path and include', which groups parameters into a usage pattern but does not add per-parameter detail beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Search file contents in the workspace') plus the mechanism (JavaScript regular expression) and an explicit output format ('relative/path:LINE: <line text>'). It clearly differentiates from siblings by stating this finds where a symbol, string, or pattern appears, and names list_files/read_file as the tools for adjacent tasks.
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 an explicit use case ('find where a symbol, string or pattern appears'), notes how to narrow results ('Narrow the search with path and include'), and names the two alternatives with the conditions that route to them ('Do not use it to list files (use list_files) or to read a known file (use read_file)'). An agent needs no inference to pick the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_filesList filesARead-only
List files and directories inside the workspace, sorted by workspace-relative path. Directories are marked with a trailing '/'. Use this to discover what exists before reading or editing, optionally filtered with a glob pattern. Skips the .git, node_modules and .cache directories and does not follow symbolic links. Do not use it to read content (use read_file) or to search text (use grep).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Directory to list, workspace-relative. Defaults to the workspace root. | |
| limit | No | Maximum number of entries to return. Defaults to 500 and is capped at 5000. | |
| pattern | No | Glob filter such as '*.ts', 'src/**' or '**/*.{js,json}'. Patterns without a slash match the name at any depth. Defaults to all entries. | |
| maxDepth | No | Maximum directory depth to descend. Defaults to 6 and is capped at 12. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond that: it skips .git, node_modules, and .cache, does not follow symbolic links, and sorts by workspace-relative path. It does not detail the exact output format beyond the trailing slash marker, but that is a minor gap given the 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 three sentences with zero waste. The core behavior and output format are front-loaded, followed by usage guidance and exclusions. 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 read-only listing tool with 100% schema coverage and no output schema, the description is nearly complete. It covers purpose, exclusions, symlink behavior, and routing to siblings. The only minor gap is that it doesn't describe the exact return structure beyond the trailing slash marker, but that is not essential for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description adds a little extra meaning by explaining the glob pattern semantics ('Patterns without a slash match the name at any depth') and the default/cap behavior, but most parameter meaning is already in the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a resource ('files and directories inside the workspace'), and a distinguishing behavior (sorted by workspace-relative path, directories marked with trailing '/'). It also explicitly contrasts with siblings read_file and grep, so an agent can tell it apart 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?
The description explicitly says when to use this tool ('to discover what exists before reading or editing') and when not to use it ('Do not use it to read content (use read_file) or to search text (use grep)'). It also mentions optional glob filtering, giving clear context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
patchPatch filesADestructive
Apply several exact-string edits across one or more files in a single all-or-nothing operation. Every edit is validated against the current file contents first; if any edit fails, NO file is modified and the failing edit index is reported. Use this instead of several edit_file calls when changes belong together. Read the affected files first with read_file. Changes are written to disk immediately when all edits are valid.
| Name | Required | Description | Default |
|---|---|---|---|
| edits | Yes | Edits to apply. All must be valid against the current file contents, otherwise nothing is written. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the destructiveHint and readOnlyHint annotations: describes validation against current file contents, atomic all-or-nothing failure behavior with failing edit index reporting, and immediate disk writes when all edits are valid. This is exactly the kind of behavioral detail an agent needs.
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?
Five sentences, each carrying distinct information: function, atomicity/failure behavior, usage guidance, prerequisite, and write timing. Front-loaded with the core capability and 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?
The description covers what the tool does, when to use it, prerequisites, failure semantics, and persistence behavior. Given the moderate complexity, the complete schema coverage, and the existing annotations, nothing material is missing for an agent to invoke this 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 documents all parameters with 100% coverage, including exact-match semantics for oldString and replaceAll behavior. The description adds context about 'exact-string' edits and atomic validation, but does not add significant per-parameter meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action: apply several exact-string edits across files as one all-or-nothing operation. Clearly differentiates from sibling edit_file by naming it and explaining when patch should be preferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this instead of several edit_file calls when changes belong together' and instructs to read files first with read_file. This gives an agent clear selection criteria and prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fileRead fileARead-only
Read a UTF-8 text file from the workspace and return its content with 1-based line numbers in the form 'N: '. Use this before editing a file, or to inspect specific line ranges with offset/limit. Do not use it for binary files (they are rejected), to search file contents (use grep), or to discover files (use list_files).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Workspace-relative path of the file to read. Absolute paths inside the workspace are also accepted. | |
| limit | No | Maximum number of lines to return. Defaults to 2000 and is capped at 2000. | |
| offset | No | 1-based line number to start reading from. Defaults to 1. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, covering the safety profile. The description adds valuable behavioral context beyond that: UTF-8-only support, rejection of binary files, and the exact line-numbered output shape. It stops short of describing error behavior, but the disclosed traits are sufficient for a read 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?
Two sentences with no wasted words. The purpose and output format are front-loaded, followed by compact usage guidance and exclusions. Every 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?
For a read-only file tool, the description covers what it reads, how output is formatted, when to use it, and which tools should be used instead. With no output schema present, the explicit line-number format is especially valuable and makes the tool effectively self-contained.
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 every parameter already has a clear description. The description adds only light semantic color by mentioning offset/limit for line ranges, but it does not meaningfully extend what the schema already provides. This matches the baseline 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 names a specific verb ('Read'), a specific resource ('UTF-8 text file from the workspace'), and the output format ('1-based line numbers'). It also distinguishes itself from siblings by explicitly excluding search (grep) and discovery (list_files), so an agent can select it correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete when-to-use guidance: before editing a file and for inspecting line ranges via offset/limit. It also gives explicit when-not-to-use guidance for binary files, content search (grep), and file discovery (list_files), naming the exact alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallRecall notesARead-only
Read the persistent notes saved with remember for this workspace, newest first. Call it at the start of a session together with work_log to recover context from previous chats. Filter by free-text query (case-insensitive substring) and/or tag. This tool is read-only; use work_log for the automatic activity journal instead.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Tag to filter by (case-insensitive, exact match). | |
| limit | No | Maximum notes to return, newest first. Defaults to 20 and is capped at 100. | |
| query | No | Case-insensitive substring matched against the note text. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only and not open-world, and the description reinforces this. It adds behavioral context beyond annotations: notes are persistent, ordered newest-first, scoped to the workspace, and intended for recovering prior session context. This is useful but not exhaustive; it does not describe edge-case behavior such as empty results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The main action and scope are front-loaded, followed by usage timing, filtering capability, and a clear pointer to the sibling alternative.
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 retrieval tool with four optional parameters, the description plus schema covers what the tool does, when to call it, how to filter, and which sibling to use instead. The absence of an output schema is not a serious gap here since the tool's purpose as a note reader is clear.
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 that query and tag filtering can be combined ('and/or tag') and clarifying that query is free-text, which is a useful semantic nuance beyond the individual schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Read the persistent notes saved with remember for this workspace, newest first.' It clearly differentiates from siblings like work_log and remember by naming them and defining the read/retrieval role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use it: 'Call it at the start of a session together with work_log to recover context from previous chats.' It also identifies the alternative, work_log, for the automatic activity journal, giving the agent both positive and negative usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberRemember noteA
Save a short persistent note for this workspace so any future chat can recover it with recall. Use it after finishing a chunk of work: record what changed, what should happen next, or a decision that must survive the conversation. Notes are append-only JSONL stored under /.workspace-mcp/ and are never edited or deleted by this tool. Keep each note short and self-contained; use tags for later filtering.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Optional short tags for recall filtering, for example ["todo", "phase-2"]. | |
| text | Yes | Note text. One short, self-contained sentence or paragraph. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond annotations: notes are 'append-only JSONL' stored under a specific path, and 'never edited or deleted by this tool'. This fully discloses persistence and mutation semantics, which is exactly the kind of context an agent needs.
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: purpose, use-case timing, persistence model, and authoring guidance. The most important information is front-loaded, and there is no 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 create-note tool with rich annotations and full schema coverage, the description is complete: it explains why to call it, what to write, how data is stored, and how it will be retrieved later. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3. The description adds meaningful usage semantics for text and tags ('short and self-contained', 'use tags for later filtering'), and clarifies the workspace-contextual nature of the note. It does not add detail about the workspace parameter, but the schema already covers that.
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 with a resource: 'Save a short persistent note for this workspace' and immediately ties it to recovery via 'recall', which distinguishes it from sibling tools like work_log or write_file. The purpose is unmistakable even before looking at the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when to use this tool: 'after finishing a chunk of work', and what to record (changes, next steps, decisions). It names recall as the recovery mechanism, but does not explicitly state when not to use it or how it differs from work_log, so it falls just 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.
task_addAdd taskA
Append one task to a change. Task ids are sequential (T1, T2, ...). The task starts as pending unless another status is given. Use task_update to move a task between statuses.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | What the task is; one imperative sentence. | |
| status | No | Initial status. Defaults to pending. | |
| changeId | No | Change id. Defaults to the active change; an unknown id is a clean error. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only convey that this is a non-read-only, closed-world, non-destructive operation. The description adds real behavioral facts annotations cannot express: task IDs are sequential (T1, T2, ...) and the task starts as pending unless another status is given.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences each earn their place: the core action, the ID sequencing behavior, and the default status plus sibling routing. The main purpose is front-loaded and there is zero 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 append tool whose schema documents every parameter, the description covers all distinctive behaviors an agent needs. The one gap: with no output schema present, it never states what the call returns (e.g., the newly assigned T-id), which the agent must infer from the sequential-ID note.
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 all four parameters (text, status, changeId, workspace) already carry defaults, formats, and enum values. The description's "starts as pending unless another status is given" largely restates what the schema's "Defaults to pending" already says, adding little beyond 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?
"Append one task to a change" names a specific verb, resource, and target scope, going well beyond the tautological title "Add task." It also differentiates from the most confusable sibling by noting task_update moves tasks between statuses.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The final sentence gives an explicit when-not: "Use task_update to move a task between statuses," routing agents away from this tool for status transitions. Situating the operation "to a change" also orients it within the change lifecycle alongside siblings like change_create and change_activate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
task_updateUpdate tasksA
Update the status of one or more tasks in a single all-or-nothing write: every taskId is validated before anything is stored, so one unknown id leaves the change untouched and the error lists the bad entries. An optional note is appended to the task's notes. One aggregate journal entry is written.
| Name | Required | Description | Default |
|---|---|---|---|
| updates | Yes | Task updates to apply together; all are validated before any write. | |
| changeId | No | Change id. Defaults to the active change; an unknown id is a clean error. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing the all-or-nothing write behavior, pre-validation of every taskId, error behavior listing bad entries, optional note appending, and the single aggregate journal entry. This gives an agent a precise model of what will happen, including side effects.
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: three sentences, each adding distinct value. The main purpose is front-loaded, followed by behavioral guarantees and side effects. No filler or redundant restatement of 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?
Given the annotations, full schema descriptions, and lack of an output schema, the description covers everything an agent needs to invoke the tool correctly: atomicity, validation, error shape, note behavior, and journal side effect. 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 updates, changeId, and workspace. The description adds useful context around updates (atomic validation, error listing) but does not add per-parameter meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Update the status of one or more tasks'. It makes the atomic all-or-nothing nature explicit, which clearly differentiates this from task_add and other task tools. The scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies use when updating task statuses in bulk, which is evident from the opening sentenceabc and the schema. It does not explicitly name alternatives like task_add or state when not to use it, so it misses the highest bar, but the context is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
work_logWork logARead-only
Read the automatic activity journal of this workspace: a newest-first list of the mutating operations this server performed (write_file, edit_file, patch, run_command, start_job, job_kill) plus the change-tracking operations (change_create, change_activate, change_doc, task_add, task_update, constraint_add), each with timestamp, paths, a short detail and the outcome. Entries made while a change was active carry a change tag, so the log can be scoped to one change. Call it at the start of a session to recover what happened in previous chats. Read-only operations (read_file, grep, list_files, work_log itself, recall, git tools, change_status) are never journaled. Filter with since, path and change; use recall to read the deliberate notes saved with remember.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Substring filter applied to the workspace-relative paths recorded in each entry. | |
| limit | No | Maximum entries to return, newest first. Defaults to 50 and is capped at 500. | |
| since | No | ISO 8601 timestamp (for example 2026-09-18T00:00:00Z). Only entries at or after this time are returned. | |
| change | No | Exact change id filter: only entries tagged with that change are returned (for example the id from change_create). | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this by listing which operations are journaled and stating read-only operations are never journaled. It adds useful behavioral context: entries are newest-first, carry change tags when a change is active, and can be scoped to one change. It does not detail pagination or exact outcome fields, but the annotations cover the safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: it front-loads the core purpose, then lists journaled operations, then gives usage guidance and filter hints. Every sentence earns its place, and the sibling distinction is included without padding.
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 log tool with no output schema, the description covers what is logged, the ordering, the change-tag behavior, and when to use it. It does not describe the exact output shape or pagination behavior, but the limit parameter and the list of fields (timestamp, paths, detail, outcome) give an agent enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description adds a little context by mentioning filters (since, path, change) and explaining the change tag scoping, but it does not add substantial meaning beyond the schema's own 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 states a specific verb ('Read') and resource ('automatic activity journal'), enumerates exactly which operations are journaled, and distinguishes itself from recall by noting the log is automatic while recall reads deliberate notes. This clearly differentiates it from sibling tools like recall and change_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to call it at the start of a session to recover what happened in previous chats, and explicitly names recall as the alternative for deliberate notes. It also clarifies that read-only operations are never journaled, which helps an agent decide 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.
workspace_listList workspacesARead-only
Read-only list of the named project workspaces served by this process: name, absolute root path, which one is primary, whether it already has workspace state under .workspace-mcp/, and the id of its active change when state.json exists. Every path or state tool accepts an optional workspace argument (defaults to the primary workspace), so call this first to discover the available names.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, and the description reinforces it while adding substantial behavioral detail: it reports the primary workspace, presence of .workspace-mcp/ state, and active change id when state.json exists. This goes beyond annotation information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences; the first front-loads the operation and return fields, the second gives the usage context. No filler or repetition of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only enumeration tool with no output schema, the description fully specifies the output fields and the important primary-workspace/default behavior. Nothing critical is missing for correct invocation and interpretation.
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?
There are zero parameters, so the baseline is 4 and the schema leaves nothing undocumented. The description still adds useful context by noting that other tools default to the primary workspace and that this listing is the discovery mechanism.
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 read-only list operation with the resource ('named project workspaces served by this process') and enumerates the returned fields. It is unambiguous and clearly distinct from the file/state mutation 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?
Explicitly instructs the agent to call this tool first to discover workspace names and explains that every path or state tool accepts an optional workspace argument defaulting to primary. This gives direct when-to-use guidance for the surrounding toolset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_fileWrite fileADestructive
Create a file (parent directories are created automatically) or overwrite an existing file with exactly the given content. Use this for new files or full rewrites. Prefer edit_file or patch for targeted changes to existing files, because this tool replaces the whole file and is not reversible. The file is written to disk immediately.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Workspace-relative path of the file to write. Absolute paths inside the workspace are also accepted. | |
| content | Yes | Exact file content to write, as a UTF-8 string. | |
| workspace | No | Workspace name (see workspace_list). Defaults to the primary workspace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond destructiveHint=true and readOnlyHint=false, the description reveals that parent directories are auto-created, writes are immediate, the whole file is replaced, and the operation is not reversible. These are behavioral facts an agent needs and would not know from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, no filler, with the core action and key auto-directory behavior front-loaded, followed by usage routing and a caution about irreversibility. 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 3-parameter write tool with fully documented parameters and annotations, the description completes the picture: it covers side effects, timing, irreversibility, and sibling routing. No necessary information is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds a new parameter-level behavior for path ('parent directories are created automatically') and emphasizes exact-content semantics for content, taking it just 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 a specific verb and resource ('Create a file ... or overwrite an existing file') and explicitly scopes it to 'new files or full rewrites.' It names edit_file and patch as distinct alternatives, so an agent can immediately tell this tool apart 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?
It gives explicit when-to-use ('new files or full rewrites') and when-not-to-use ('Prefer edit_file or patch for targeted changes'), with the reason being that this tool replaces the whole file. This is textbook usage routing.
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.
19 tool updates
v1.5.0- First observed
change_activate - First observed
change_create - First observed
change_doc - First observed
change_status - First observed
constraint_add - First observed
edit_file - First observed
git_diff - First observed
git_status - First observed
grep - First observed
list_files - First observed
patch - First observed
read_file - First observed
recall - First observed
remember - First observed
task_add - First observed
task_update - First observed
work_log - First observed
workspace_list - First observed
write_file
TDQS
Scored across 19 tools
Every tool targets a distinct operation: file read/write/edit/patch/list/grep are clearly separated, work_log is distinguished from remember/recall, and each change/task tool has a unique role. The closest pair is edit_file vs patch, but their single-edit vs atomic-multi-edit scopes are explicitly documented.
Most file tools use verb_noun style (read_file, write_file, edit_file, list_files), while change and task tools reverse it (change_create, task_add, constraint_add), and standalone names appear (patch, grep, git_status). The naming is readable and grouped by domain, but the mixed verb placement makes the pattern less predictable.
19 tools is on the upper end, but the server spans four distinct subdomains—file editing, persistent memory, git inspection, and change/task tracking—and each tool has a separate responsibility. The count feels slightly heavy rather than bloated, with no true redundancy.
The file surface covers list/read/write/edit/patch/grep but lacks a delete or rename operation, leaving cleanup workflows with a dead end. Change tracking supports create/status/document/task updates but has no way to remove a change or constraint. These are notable, work-around-able gaps rather than a total lack of coverage.
Maintenance
Related MCP Connectors
Read and write shared BitsWeave context, projects, tasks, and work sessions through MCP.
1A MCP server built for developers enabling Git based project management with project and personal…
Project management MCP for AI agents with safe task reads and writes.
MCP server for generating rough-draft project plans from natural-language prompts.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA desktop launcher and local MCP workspace server that enables ChatGPT and other MCP clients to securely read, edit, search, run commands, and show changes in selected local project folders.1MIT
- AlicenseNot gradedqualityBmaintenanceProvides tools for governed project work, including project setup, workspace management, and task execution, with credential-safe MCP wiring.MIT
- FlicenseNot gradedqualityAmaintenanceTurns local project directories into persistent MCP workspaces, allowing AI agents to read files, modify code, run commands, manage Git, and save session progress across conversations.-
- FlicenseNot gradedqualityCmaintenanceExposes a secure, path-confined bridge to a local workspace and git remotes, enabling MCP clients to search, read, write, reset files, and perform git operations.-