Skip to main content
Glama

Filesystem MCP

Let your AI assistant work with your files, safely.

Read, search, edit, and patch files in the folders you choose. Secret files stay hidden, and risky changes wait for your OK.

npm version CI License: MIT GitHub stars

Install in VS Code Install in VS Code Insiders Install in Visual Studio Install in Cursor Install in Claude Desktop

What is this?

Model Context Protocol (MCP) is how AI apps such as Claude, GitHub Copilot in VS Code, and Cursor connect to tools. Filesystem MCP is an MCP server: a small program that runs on your computer and gives the AI 13 tools for working with files. You choose which folders it can use, and everything outside them is off limits.

Once it is connected, you can ask things like:

  • "Find every TODO in this repo and group them by file."

  • "Rename getUser to fetchUser in all .ts files. Show me the diff first."

  • "What changed between config.dev.json and config.prod.json?"

  • "Read the last 50 lines of server.log and explain the error."

  • "Move the old screenshots into archive/2025/."

Related MCP server: Filesys

Why Filesystem MCP?

  • It is safe by default. The AI can use only the folders you allow, and .env files, private keys, and cloud credentials are blocked. The server asks you before the AI deletes a non-empty folder, opens a folder you did not allow, or writes over a file with create or move. Only create and copies can skip that question, by passing overwrite: true. Edits made with edit, patch, and replace_text apply without asking, but the AI can show you the diff first with dryRun. If the AI should never change anything, --read-only removes every tool that writes.

  • Search and editing are made for code. The AI can search inside files like grep, with a regex engine (RE2) that cannot hang, and by default the server skips .gitignored files and folders like node_modules. Edits are exact-match replacements that return an error when the text does not match, and you can preview them as a diff first.

  • It saves the AI's context. The AI can read many files in one call or only the lines it needs, and it can check a file's size and token estimate before reading it.

  • It works with any MCP client, over stdio or HTTP, on macOS, Linux, and Windows. You can install it with npx, Docker, or a one-click Claude Desktop extension, or build your own client on it.

  • It is private. It runs on your machine, has no telemetry, and makes no network calls.

Compared with the reference server

How this server differs from the official @modelcontextprotocol/server-filesystem, checked against its README on 2026-10-11:

Capability

Filesystem MCP

Reference server

Search inside files

search_text: literal text or RE2 regex

None; search_files matches names only

Secret files

.env, keys, and credentials blocked by default

Not blocked

Overwriting a file

create asks you first (unless overwrite: true)

write_file overwrites without asking

Delete files

delete; asks before deleting a non-empty folder

None

.gitignore

Respected by listing and search tools

Not supported

Read-only mode

--read-only removes every tool that writes

Docker ro mounts only

Apply a unified diff

patch

None

Compare two files

diff

None

Replace across many files

replace_text over a folder or glob

None

Watch files

Subscribe to a file and get change notifications

None

Transport

stdio, or Streamable HTTP with --port

stdio

Quick start

NOTE

You need Node.js 24 or later. Check withnode --version.

  1. Add the server to your AI app. Pick yours below.

  2. Replace /path/to/project with the folder the AI may use. You can list several folders.

  3. Restart the app and ask: "Which folders can you access?"

TIP

VS Code currently shares the folders you have open with the server, so the one-click VS Code install works without a path. In other apps, or over HTTP, put the folder inargs. If the AI says it has no folders, that is the fix.

Click Install in VS Code above, or add this to .vscode/mcp.json:

{
  "servers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
    }
  }
}

Or from a terminal:

code --add-mcp '{"name":"filesystem","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest","/path/to/project"]}'

Click Install in Cursor above, then add your folder to args. Or add this to .cursor/mcp.json in your project, or ~/.cursor/mcp.json for all projects:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
    }
  }
}

For a one-click install, download filesystem-mcp.mcpb, open it with Claude Desktop, and pick the folders to allow. Claude Desktop's built-in Node.js runs it.

To set it up by hand, add this to claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
    }
  }
}
claude mcp add filesystem -- npx -y @j0hanz/filesystem-mcp@latest /path/to/project

Or install the plugin, which points the server at your current project:

/plugin marketplace add j0hanz/j0hanz-marketplace
/plugin install filesystem-mcp@j0hanz-marketplace

Add this to .vs\mcp.json in your solution folder, or %USERPROFILE%\.mcp.json for all solutions:

{
  "servers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@j0hanz/filesystem-mcp@latest", "C:/path/to/project"]
    }
  }
}

The filesystem-mcp plugin sets the server up for your current project:

Client

Install

Copilot CLI

copilot plugin marketplace add j0hanz/j0hanz-marketplace, then copilot plugin install filesystem-mcp@j0hanz-marketplace

Antigravity CLI

git clone https://github.com/j0hanz/j0hanz-marketplace, then agy plugin install ./j0hanz-marketplace/plugins/filesystem-mcp

The container can only see the folders you mount. This setup blocks writes twice, with the :ro mount and with the --read-only flag.

{
  "mcpServers": {
    "filesystem": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "/path/to/project:/workspace:ro",
        "ghcr.io/j0hanz/filesystem-mcp:latest",
        "--read-only",
        "/workspace"
      ]
    }
  }
}

Drop :ro and --read-only to let the AI make changes. VS Code and Visual Studio use "servers" instead of "mcpServers". See Running in Docker for more.

Windsurf, Cline, and most other clients use the same mcpServers JSON as Claude Desktop above. In any client, the server is:

  • command: npx

  • args: -y, @j0hanz/filesystem-mcp@latest, then one or more folders

You can also install it globally and run filesystem-mcp /path/to/project:

npm install -g @j0hanz/filesystem-mcp

Tools

Tool

What it does

list_roots

Shows the folders the server may use.

list

Lists a folder as a tree, like ls or tree.

find_files

Finds files by name or glob, such as **/*.test.ts.

search_text

Searches inside files for text or a regex, like grep, with optional context lines.

stat

Gets size, dates, type, permissions, and a token estimate without reading the file.

read

Reads one or many text files, whole or by line range, head, or tail. Images and audio come back as media.

diff

Compares two files and returns a unified diff.

create ✎

Writes new files, or appends to them. Asks before replacing an existing file, unless overwrite: true.

edit ✎

Replaces exact text in files. All edits to a file apply, or none do. dryRun shows the diff first.

patch ✎

Applies a unified diff to a file. All hunks apply, or none do.

replace_text ✎

Finds and replaces text or a regex across many files. dryRun shows what would change.

move ✎

Moves, renames, or copies files and folders. Asks before overwriting, unless a copy passes overwrite: true.

delete ✎

Deletes files and folders. Asks before deleting a non-empty folder.

✎ changes files. --read-only removes these tools.

Search and listing tools skip hidden files, .gitignored files, and folders like node_modules, dist, and .git unless the AI asks for them.

Configuration

Most people only need the folder argument. These options cover the common cases:

Option

What it does

--read-only

Removes every tool that changes files.

--deny '<pattern>'

Blocks more files, for example --deny 'private/**' or --deny '*.sqlite'.

--allow '<pattern>'

Unblocks one built-in secret pattern, for example --allow '.env.example'.

--allow-cwd

Also allows the folder the server was started from.

--max-file-size <n>

Largest file read will load, in bytes. Default 10 MiB.

--port <n>

Serves over HTTP at http://127.0.0.1:<n>/mcp instead of stdio.

--print-config

Prints the settings the server would use, then exits.

Flags go in args after the package name, for example ["-y", "@j0hanz/filesystem-mcp@latest", "--read-only", "/path/to/project"].

The full configuration reference covers every flag and environment variable, the complete secret-file list, limits, HTTP setup with API keys, Docker, and troubleshooting.

Security

Protection

How it works

Folder sandbox

The server resolves every path, including symlinks, and the resolved path must stay inside an allowed folder.

Secret files

.env, *.pem, *.key, SSH keys, .npmrc, cloud credentials, and more are blocked and hidden from listings.

You stay in charge

The server asks you before the AI deletes a non-empty folder, gets access to a new folder, or writes over a file with create or move. Only create and copies skip that question, when the AI passes overwrite: true. In-place edits (edit, patch, replace_text) do not ask, but dryRun previews them. A client that cannot ask gets an error instead.

Off-limits folders

Neither the AI nor the client can ever add your home folder itself, system folders, or ~/.ssh, ~/.aws, and similar folders.

Safe writes

New content goes to a temporary file that is then renamed into place, so a crash never leaves a half-written file. Writes keep the file's permissions.

No regex hangs

RE2 runs in linear time, so no search pattern can freeze the server.

HTTP

The server listens only on localhost by default. Any other address requires an API key.

Container

The Docker image runs as a non-root user.

If you find a vulnerability, please report it privately. SECURITY.md explains how.

Build your own client

You can also call Filesystem MCP from your own code: an agent, an editor plugin, a web app, a CI job, or a script. The same rules apply as for an AI app, so your code cannot reach outside the allowed folders or read secret files.

import { Client } from '@modelcontextprotocol/client';
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';

const dir = '/path/to/project';
const client = new Client(
  { name: 'my-app', version: '1.0.0' },
  { capabilities: { elicitation: { form: {} } }, versionNegotiation: { mode: 'auto' } },
);
client.setRequestHandler('elicitation/create', async () => ({ action: 'decline' }));
await client.connect(
  new StdioClientTransport({
    command: 'npx',
    args: ['-y', '@j0hanz/filesystem-mcp', dir],
    cwd: dir,
  }),
);

const result = await client.callTool({ name: 'search_text', arguments: { searchPattern: 'TODO' } });
const { matches } = (result.structuredContent ?? result._meta) as { matches: unknown[] };
console.log(matches);
await client.close(); // stops the server process; without it the script never exits

The basics:

  • Where the data is. The text block is written for a model. The same data as JSON is in _meta for tools that write their own text (list, search_text, edit, ...) and in structuredContent for stat, create, and list_roots. read is the exception: the file's text is only in the text block, and _meta holds metadata about it.

  • Paths. A relative path resolves against the server's working directory when that is inside a root, and against the root otherwise. With several roots, it must exist under exactly one of them. Absolute paths are never ambiguous. Search results are printed relative to the root, so a result can be passed straight back.

  • Confirmations. Overwrites, recursive deletes, and paths outside the roots are questions for the user. Declare the elicitation capability and answer them in a handler, or, on the 2026-07-28 protocol, take them as data (input_required) and answer later.

  • Protocol versions. The server speaks the 2025 protocol and 2026-07-28, over stdio and Streamable HTTP. Over HTTP, 2025-era clients get no confirmations or change notifications.

  • Resources. Read and subscribe to any file as filesystem-mcp://file/{+path}; internal://instructions and the get-help prompt hold the server's guide for models.

The client guide has the details, tested with the TypeScript and Python SDKs, and examples/ has six runnable clients:

Example

What it is

fsq

Any tool from your shell, over stdio or HTTP; --json for scripts

browser

A local web UI where the server's questions appear in the page

tail

tail -f through file subscriptions, locally or on a remote server

gatekeeper

A coding agent that shows each change's diff and waits for your y/N

hooks

Runs a task through a model whenever the workspace changes

python

A TODO report for a workspace, with the Python SDK

Privacy policy

Filesystem MCP runs entirely on your machine. This policy covers the npm package, the Docker image, and the .mcpb desktop extension.

  • Data collection: none. The server has no telemetry, analytics, or crash reporting, and makes no outbound network requests.

  • Use and storage: the server reads and writes files only inside the folders you allow, and only when your MCP client calls a tool. Tool results go to that client and nowhere else. Short-lived result caches live in memory and disappear when the server exits.

  • Third-party sharing: none by this server. Your MCP client may send tool results to its model provider under that client's own privacy policy.

  • Retention: the server keeps nothing after the process exits. Diagnostic logs go to stderr on your machine; your MCP client may save them in its own log files.

  • Contact: open an issue at https://github.com/j0hanz/filesystem-mcp/issues, or report security problems privately through GitHub Security Advisories.

Contributing

Bug reports, ideas, and pull requests are welcome. Start with CONTRIBUTING.md. It covers setup, running the server from source, and the checks a pull request needs.

If Filesystem MCP is useful to you, a star on GitHub helps other people find it.

Contributors

License

MIT

Available Tools

13 tools
createCreate FilesA
Destructive

Write whole text files: create new ones, overwrite, or append. Missing parent directories are created. edit or patch changes part of an existing file.

ParametersJSON Schema
NameRequiredDescriptionDefault
filesYesList of files to create (max 100); each entry requires path and content; combined content is capped at the file-size limit

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and readOnlyHint=false; the description adds real value beyond them by disclosing that missing parent directories are created and by flagging the whole-file overwrite/append semantics. It does not cover the return value or the confirmation prompt behavior (that lives in the schema), keeping it below 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, with the core verb-and-resource statement front-loaded and the sibling disambiguation immediately after. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write tool with no output schema, the description covers modes, side effects, and sibling routing adequately. It omits batching behavior and what the call returns (paths, confirmation results), which are minor but real gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents path, content, append, and overwrite thoroughly, so the baseline is 3. The description echoes the create/overwrite/append modes but adds no syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Write whole text files') and enumerates the modes (create, overwrite, append). It explicitly distinguishes itself from the edit and patch siblings, so an agent can route 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternatives (edit, patch) and the boundary condition that selects them: those change part of an existing file, whereas this writes whole files. There is no explicit when-not guidance (e.g. for binary files or very large files), so it falls just short of 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteDelete FileA
Destructive

Permanently delete files, directories, or symlinks, like rm or rm -r. Paths are exact; globs are not expanded.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathsYesPaths to delete (max 1000); accepts files, directories, or symlinks
recursiveNoDelete directory contents recursively (required for non-empty directories)
ignoreIfNotExistsNoSilently succeed if a path does not exist instead of returning an error

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and readOnlyHint=false. The description adds meaningful behavior beyond that: deletion is permanent, applies to files/directories/symlinks, and uses exact path matching. This enriches rather than contradicts the annotation profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with no filler. The core purpose is front-loaded, and the glob caveat is a single high-value clarification that prevents misuse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool, the description covers permanence, target types, recursion analogy, and path-matching behavior. Parameters and destructive nature are already handled by the schema and annotations, so nothing critical is missing 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all three parameters in detail. The description adds only a high-level rm/rm -r analogy and an exact-paths caveat, which is marginal but not required for parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource set: 'Permanently delete files, directories, or symlinks.' The rm/rm -r analogy clarifies expected semantics and distinguishes this destructive tool from sibling read/write/edit/move operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when to use—permanent deletion of paths—and adds a useful constraint: paths are exact and globs are not expanded. It does not name explicit alternatives, but no sibling provides a delete operation, so the usage context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diffDiffA
Read-only

Compare two text files and return a unified diff from a to b, like diff -u.

ParametersJSON Schema
NameRequiredDescriptionDefault
aYesFirst file to compare
bYesSecond file to compare
contextNoNumber of context lines surrounding each change (default: 3)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only behavior, so the description need not repeat that. It adds the important ordering behavior (from a to b) and the output format ('unified diff, like diff -u'), which are not in annotations or schema. It does not discuss edge cases such as identical files or how the context parameter is applied, so the disclosure is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that states action, input, and output with no filler. Every phrase ('Compare', 'two text files', 'unified diff', 'from a to b', 'like diff -u') carries semantic weight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only comparison tool with a self-describing schema, the description covers the key agent-facing facts: inputs, direction, and output format. It leaves edge-case behavior to implementation, but no output schema exists and the phrase 'like diff -u' provides a known format. This is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema descriptions already cover all three parameters at 100%, so the default baseline is 3. The description adds meaning by clarifying that a is the source/original and b is the target ('from a to b'), which removes ambiguity in how arguments should be passed. It does not comment on the context parameter, but the schema already defines its default, minimum, and maximum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Compare') and names the resource ('two text files') plus the exact output form ('unified diff'), so the tool's core purpose is unmistakable. It does not explicitly name a sibling alternative, but 'compare' is distinct from the create/edit/delete/search siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use case: whenever two text files need to be diffed, rather than edited or searched. It gives no explicit 'when not to use' guidance or sibling routing, so an agent must infer the context from tool name and purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

editEdit Files
Destructive

Edit text files in place by replacing exact oldText with newText, like str_replace. Each oldText must match exactly once, and a file is written only if all its edits match. replace_text replaces every occurrence across files.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoSingle file path; mutually exclusive with files
editsNoReplacements applied to path; not allowed when using files
filesNoPer-file entries (batch mode)
dryRunNoPreview diffs without writing to disk (default: false = apply edits)
ignoreWhitespaceNoIgnore leading/trailing whitespace differences when matching oldText
find_filesFind Files
Read-only

Find files by name or glob pattern; returns file paths relative to the root, ready to pass to read or edit. A pattern without / matches file names at any depth. search_text searches contents.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoBase directory to search under (default: first allowed root)
cursorNoOpaque pagination cursor; pass unchanged for the next page. Pages slice one snapshot taken on the first call; it expires after ~60s — re-request without a cursor if rejected.
sortByNoSort order: path = full path (default), name = basename onlypath
patternYesGlob pattern to match file paths (e.g. **/*.ts, src/**/*.js)
maxDepthNoMax directory depth to scan; 0 = base directory only, omit for unlimited
maxResultsNoMaximum number of matching files to return per page
includeHiddenNoInclude hidden items (starting with .)
includeIgnoredNoInclude ignored items (node_modules, .git, etc).
listListA
Read-only

List a directory's files and subdirectories as a tree of names, like ls or tree. stat returns sizes and dates.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoDirectory to list (default: first allowed root)
cursorNoOpaque pagination cursor; pass unchanged for the next page. Pages slice one snapshot taken on the first call; it expires after ~60s — re-request without a cursor if rejected.
maxDepthNoMax directory depth to traverse (default: 1 = top-level only; increase to recurse deeper)
maxEntriesNoPage size (default: 1000). Continue with nextCursor; an incomplete first page also carries resourceUri for the whole list.
includeHiddenNoInclude hidden items (starting with .)
includeIgnoredNoInclude ignored items (node_modules, .git, etc).

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description correctly does not contradict this. However, the description adds no behavioral context beyond what annotations provide—it does not mention pagination, snapshot semantics, or any side effects (which would be none given read-only). The schema itself documents cursor behavior and expiration, but the description itself adds no extra value beyond the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that starts with the core function and ends with a helpful pointer to an alternative. It wastes no words and is appropriately front-loaded, fitting within the ideal length for a tool this simple.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 6 parameters and no output schema. The description is very brief, but the schema carries rich information (pagination, snapshot expiry, defaults, limits). For a listing tool, an agent can likely infer most behavior from the schema. However, the description does not mention that results are paginated or that deeper recursion is possible, which could be useful context. It is adequate but not comprehensive; a 3 reflects that it covers the essentials without being fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 does not elaborate on any parameter (e.g., path, maxDepth, includeHidden), relying entirely on the schema. It adds no additional meaning beyond what the schema already provides, so a 3 is appropriate per the rubric.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('directory's files and subdirectories') and clarifies the output format ('as a tree of names'). It also distinguishes itself from a sibling tool ('stat returns sizes and dates'), making it easy for an agent to know what this tool does and what it does not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an implicit usage guideline by noting that 'stat returns sizes and dates,' implying that stat is the tool for metadata. However, it does not explicitly state when to use this tool versus alternatives like find_files or list_roots, nor does it mention any exclusions or prerequisites. The guidance is minimal and mostly inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rootsWorkspace RootsA
Read-only

List the directories this server can access, as absolute paths, including any the user granted during this session. Other tools can ask the user to grant access to a path outside them.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the read-only nature is covered. The description adds useful context beyond that: results are absolute paths and include any directories granted during the current session. This helps the agent understand what the returned set represents.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core behavior is stated first, and the companion behavior about other tools granting access is a useful one-line addition. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter listing tool, the description fully explains what is returned (absolute paths of accessible directories), the session-grant aspect, and how it relates to other tools. No output schema is present, but the return concept is simple and clearly stated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parametersasi, so the schema cannot provide parameter detail. With no parameters to document, the baseline of 4 applies; the description fully clarifies what the tool returns without needing parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') with a clear resource ('directories this server can access, as absolute paths'). It distinguishes list_roots from the generic sibling 'list' by scoping it to server-accessible workspace roots, including session-granted paths.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes it clear this tool is for discovering accessible directories. It also notes that other tools can request access to paths outside these roots, giving the agent a hint about when this tool is not sufficient. It does not explicitly name alternatives, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

moveMove or Copy FilesA
Destructive

Move, rename, or copy files and directories, like mv or cp -r. Each destination is the full new path, not a folder to move into; missing parent directories are created.

ParametersJSON Schema
NameRequiredDescriptionDefault
copyNoCopy instead of move; sources are left in place
movesYesOperations to perform (max 100)
overwriteNoCopy mode only: overwrite existing destinations without confirmation

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true, and the description adds useful context about path interpretation ('full new path, not a folder') and automatic parent directory creation. However, it does not disclose whether move mode overwrites existing destinations by default, a critical behavioral detail given the destructive hint and the copy-only scope of the overwrite parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundancy. It front-loads the primary purpose, then immediately adds a key behavioral caveat. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, path semantics, and parent creation, which are essential. However, it leaves overwrite behavior in move mode ambiguous—whether move overwrites without confirmation—especially since the schema states overwrite applies only to copy mode. This is a significant gap for a destructive tool and reduces completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are fully documented in the schema. The description adds minor clarification for the destination parameter (full path semantics) but does not add value beyond the schema for copy or overwrite, which are already described in their property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Move, rename, or copy files and directories, like mv or cp -r.' It names specific operations and the resource type, distinguishing it from siblings like create, delete, or edit. The additional note about destination being a full path further clarifies scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for moving, renaming, or copying but does not explicitly state when to use this tool over alternatives like create or delete. It lacks exclusions or conditions that would help an agent choose between tools, leaving the decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

patchPatchA
Destructive

Apply a single-file unified diff to one existing text file, like git apply. Nothing is written unless every hunk applies in file order with exactly matching context; hunks are found by their context, so start line numbers may be off.

ParametersJSON Schema
NameRequiredDescriptionDefault
diffYesSingle-file unified diff to apply (as produced by the diff tool or edit dry-run)
pathYesFile to apply the diff to
dryRunNoPreview the result without writing (default: false)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations (destructiveHint=true) by detailing the atomicity: 'Nothing is written unless every hunk applies in file order with exactly matching context.' It also discloses a critical quirk: hunks are located by context, so line numbers may be off. This is essential behavioral information that the annotations do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose and behavioral nuance. Every clause earns its place; the critical atomicity rule and context-matching caveat are delivered without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three well-documented parameters, no output schema, and annotations covering destructiveness, the description supplies everything an agent needs: the exact operation, the single-file constraint, the atomicity guarantee, and the context-matching behavior. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides complete descriptions for all three parameters (diff, path, dryRun) with 100% coverage. The tool description adds no additional parameter-level detail beyond what the schema states, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb and resource: 'Apply a single-file unified diff to one existing text file.' The analogy 'like git apply' anchors it firmly in a well-known operation, and the distinction of single-file vs. multi-file and the context-matching behavior clearly separate it from sibling tools like edit or replace_text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes it obvious when to use this tool: whenever you have a unified diff for a single file. It does not explicitly enumerate alternatives or exclusions, but the context is clear enough that an agent can infer the correct use case. The mention of 'existing text file' also implicitly signals it is not for new files.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

readRead File
Read-only

Read text files, like cat: whole, or one slice via head, tail, or startLine/endLine. Images and audio return as media; other binary files are rejected.

ParametersJSON Schema
NameRequiredDescriptionDefault
headNoReturn first N lines
pathNoSingle file path; mutually exclusive with paths
tailNoReturn last N lines
pathsNoArray of file paths for batch mode (max 1000); mutually exclusive with path
endLineNoEnd line (1-indexed)
startLineNoStart line (1-indexed)
includeHashNoInclude SHA-256 hash of the returned content in the response
replace_textSearch and Replace
Destructive

Find and replace every occurrence of literal text or an RE2 regex, like sed -i, in one file or all files under a directory, optionally filtered by glob. The pattern runs over the whole file: it can span lines, and ^ and $ anchor to file start and end. edit replaces one unique exact match.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoFile to rewrite, or directory to rewrite under. Omitting it targets the ENTIRE first allowed root — scope it deliberately, and pair a wide scope with dryRun=true first
dryRunNoPreview replacements without writing to disk (default: false = apply changes)
isRegexNoTreat searchPattern as a RE2 regex (default: literal text match)
patternNoGlob to restrict replacements to specific file types (e.g. **/*.ts); default: all text files
maxDepthNoMax directory depth to scan; 0 = base directory only, omit for unlimited
maxFilesNoMaximum number of files to process
wholeWordNoMatch whole words only (word boundary anchoring)
maxResultsNoMaximum total match count across all files before stopping
returnDiffNoInclude a unified diff of all changes in the response
replacementYesReplacement text. Use capture group references ($1, $2, etc.) when isRegex=true. Use an empty string to delete all matches.
caseSensitiveNoEnable case-sensitive matching (default: case-insensitive)
includeHiddenNoInclude hidden items (starting with .)
searchPatternYesExact literal text or RE2 regex pattern to search for. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences are supported). Cannot be empty or whitespace-only.
includeIgnoredNoInclude ignored items (node_modules, .git, etc).
search_textSearch Content
Read-only

Search file contents for literal text or an RE2 regex, like grep; returns matching lines with line numbers and paths relative to the root, ready to pass to read or edit. Patterns match within one line. find_files matches file names.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoFile to search, or directory to search under (default: the whole first allowed root). Naming a file searches that file alone: pattern is ignored and hidden/ignored filtering does not apply.
cursorNoOpaque pagination cursor; pass unchanged for the next page. Pages slice one snapshot taken on the first call; it expires after ~60s — re-request without a cursor if rejected.
contextNoLines of context to return either side of each match, like grep -C (default: 0, max: 10)
isRegexNoTreat searchPattern as a regex (default: literal text match)
patternNoGlob to restrict search to specific file types (e.g. **/*.ts); default: all text files
maxDepthNoMax directory depth to scan; 0 = base directory only, omit for unlimited
maxResultsNoMaximum number of matching lines to return per page
caseSensitiveNoEnable case-sensitive matching (default: case-insensitive)
includeHiddenNoInclude hidden items (starting with .)
searchPatternYesExact literal text or RE2 regex pattern to search for in file contents. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences). Cannot be empty or whitespace-only.
includeIgnoredNoInclude ignored items (node_modules, .git, etc).
statGet File Info
Read-only

Get metadata without reading contents, like ls -ld: type, size (files only; use list for directory contents), tokenEstimate, timestamps, permissions (readOnly on Windows), MIME type guessed from the extension, and symlink target. Also checks whether paths exist.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoSingle file path; mutually exclusive with paths
pathsNoArray of file paths for batch mode (max 1000); mutually exclusive with path

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv2.8.1
    • Changededit11 fields changed
      • removedInput schema / $defs
        Removed value: -{
        -  "EditSpec": {
        -    "additionalProperties": false,
        -    "properties": {
        -      "newText": {
        -        "description": "Replacement text. Use an empty string to delete the matched oldText.",
        -        "examples": [
        -          "const x = 2;",
        -          "function newName(",
        -          ""
        -        ],
        -        "type": "string"
        -      },
        -      "oldText": {
        -        "description": "Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers.",
        -        "examples": [
        -          "const x = 1;",
        -          "function oldName("
        -        ],
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "oldText",
        -      "newText"
        -    ],
        -    "type": "object"
        -  }
        -}
      • removedInput schema / properties / edits / items / $ref
        Removed value: -"#/$defs/EditSpec"
      • addedInput schema / properties / edits / items / additionalProperties
        Added value: +false
      • addedInput schema / properties / edits / items / properties
        Added value: +{
        +  "newText": {
        +    "description": "Replacement text. Use an empty string to delete the matched oldText.",
        +    "examples": [
        +      "const x = 2;",
        +      "function newName(",
        +      ""
        +    ],
        +    "type": "string"
        +  },
        +  "oldText": {
        +    "description": "Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers.",
        +    "examples": [
        +      "const x = 1;",
        +      "function oldName("
        +    ],
        +    "minLength": 1,
        +    "type": "string"
        +  }
        +}
      • addedInput schema / properties / edits / items / required
        Added value: +[
        +  "oldText",
        +  "newText"
        +]
      • addedInput schema / properties / edits / items / type
        Added value: +"object"
      • removedInput schema / properties / files / items / properties / edits / items / $ref
        Removed value: -"#/$defs/EditSpec"
      • addedInput schema / properties / files / items / properties / edits / items / additionalProperties
        Added value: +false
      • addedInput schema / properties / files / items / properties / edits / items / properties
        Added value: +{
        +  "newText": {
        +    "description": "Replacement text. Use an empty string to delete the matched oldText.",
        +    "examples": [
        +      "const x = 2;",
        +      "function newName(",
        +      ""
        +    ],
        +    "type": "string"
        +  },
        +  "oldText": {
        +    "description": "Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers.",
        +    "examples": [
        +      "const x = 1;",
        +      "function oldName("
        +    ],
        +    "minLength": 1,
        +    "type": "string"
        +  }
        +}
      • addedInput schema / properties / files / items / properties / edits / items / required
        Added value: +[
        +  "oldText",
        +  "newText"
        +]
      • addedInput schema / properties / files / items / properties / edits / items / type
        Added value: +"object"
    • Changedread2 fields changed
      • changedInput schema / properties / endLine / maximum
        Previous value: -100000New value: +2147483647
      • changedInput schema / properties / startLine / maximum
        Previous value: -100000New value: +2147483647
    • Changedreplace_text1 field changed
      • removedInput schema / properties / searchPattern / examples
        Removed value: -[
        -  "TODO",
        -  "function\\s+(\\w+)",
        -  "import.*from"
        -]
    • Changedsearch_text1 field changed
      • removedInput schema / properties / searchPattern / examples
        Removed value: -[
        -  "TODO",
        -  "function\\s+(\\w+)",
        -  "import.*from"
        -]
  2. 1 tool updatev2.7.0
    • Changedcreate1 field changed
      • changedInput schema / properties / files / description
        Previous value: -"List of files to create (max 100); each entry requires path and content"New value: +"List of files to create (max 100); each entry requires path and content; combined content is capped at the file-size limit"
  3. 3 tool updatesv2.5.0
    • Changedfind_files1 field changed
      • changedInput schema / properties / pattern / examples
        Previous value: -[
        -  "**/*.ts",
        -  "src/**/*.js",
        -  "*.{ts,tsx}"
        -]New value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "**/*.{ts,tsx}"
        +]
    • Changedreplace_text1 field changed
      • changedInput schema / properties / pattern / examples
        Previous value: -[
        -  "**/*.ts",
        -  "src/**/*.js",
        -  "*.{ts,tsx}"
        -]New value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "**/*.{ts,tsx}"
        +]
    • Changedsearch_text1 field changed
      • changedInput schema / properties / pattern / examples
        Previous value: -[
        -  "**/*.ts",
        -  "src/**/*.js",
        -  "*.{ts,tsx}"
        -]New value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "**/*.{ts,tsx}"
        +]
  4. 13 tool updatesv2.4.1
    • Changedcreate1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddelete1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddiff1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changededit3 fields changed
      • addedInput schema / $defs / EditSpec / properties / newText / examples
        Added value: +[
        +  "const x = 2;",
        +  "function newName(",
        +  ""
        +]
      • addedInput schema / $defs / EditSpec / properties / oldText / examples
        Added value: +[
        +  "const x = 1;",
        +  "function oldName("
        +]
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedfind_files2 fields changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / properties / pattern / examples
        Added value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "*.{ts,tsx}"
        +]
    • Changedlist1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedlist_roots1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedmove1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedpatch1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedread1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedreplace_text4 fields changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / properties / pattern / examples
        Added value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "*.{ts,tsx}"
        +]
      • addedInput schema / properties / replacement / examples
        Added value: +[
        +  "$1_renamed",
        +  "",
        +  "TODO: fix"
        +]
      • addedInput schema / properties / searchPattern / examples
        Added value: +[
        +  "TODO",
        +  "function\\s+(\\w+)",
        +  "import.*from"
        +]
    • Changedsearch_text3 fields changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / properties / pattern / examples
        Added value: +[
        +  "**/*.ts",
        +  "src/**/*.js",
        +  "*.{ts,tsx}"
        +]
      • addedInput schema / properties / searchPattern / examples
        Added value: +[
        +  "TODO",
        +  "function\\s+(\\w+)",
        +  "import.*from"
        +]
    • Changedstat1 field changed
      • addedInput schema / $schema
        Added value: +"https://json-schema.org/draft/2020-12/schema"
  5. 3 tool updatesv2.3.0
    • Changedcreate2 fields changed
      • addedInput schema / properties / files / items / properties / append
        Added value: +{
        +  "description": "Append the content to the end of the file instead of overwriting; creates the file if it does not exist",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / files / items / properties / overwrite
        Added value: +{
        +  "description": "Replace an existing file without asking the user; without it an existing file prompts for confirmation",
        +  "type": "boolean"
        +}
    • Changededit1 field changed
      • changedInput schema / $defs / EditSpec / properties / oldText / description
        Previous value: -"Exact literal text to locate in the file. Must include 3-5 lines of context to ensure uniqueness and avoid matching the wrong block."New value: +"Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers."
    • Changedsearch_text1 field changed
      • addedInput schema / properties / context
        Added value: +{
        +  "default": 0,
        +  "description": "Lines of context to return either side of each match, like grep -C (default: 0, max: 10)",
        +  "maximum": 10,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  6. 5 tool updatesv2.1.5
    • Changeddelete1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "results": {
        -      "description": "Per-path results ordered to match the input paths",
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "error": {
        -            "additionalProperties": false,
        -            "description": "Error details; present on failure",
        -            "properties": {
        -              "code": {
        -                "type": "string"
        -              },
        -              "message": {
        -                "type": "string"
        -              },
        -              "path": {
        -                "type": "string"
        -              },
        -              "suggestion": {
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "code",
        -              "message"
        -            ],
        -            "type": "object"
        -          },
        -          "path": {
        -            "description": "Requested path",
        -            "type": "string"
        -          },
        -          "value": {
        -            "additionalProperties": false,
        -            "description": "Delete outcome; present on success",
        -            "properties": {
        -              "deleted": {
        -                "description": "True when the path was removed; false when the user chose Skip",
        -                "type": "boolean"
        -              }
        -            },
        -            "required": [
        -              "deleted"
        -            ],
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "path"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "summary": {
        -      "additionalProperties": false,
        -      "properties": {
        -        "failed": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "succeeded": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "total": {
        -          "minimum": 0,
        -          "type": "integer"
        -        }
        -      },
        -      "required": [
        -        "total",
        -        "succeeded",
        -        "failed"
        -      ],
        -      "type": "object"
        -    }
        -  },
        -  "required": [
        -    "results",
        -    "summary"
        -  ],
        -  "type": "object"
        -}New value: +null
    • Changededit1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "results": {
        -      "description": "Per-path edit results ordered to match the input paths",
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "error": {
        -            "additionalProperties": false,
        -            "description": "Error details; present on failure",
        -            "properties": {
        -              "code": {
        -                "type": "string"
        -              },
        -              "message": {
        -                "type": "string"
        -              },
        -              "path": {
        -                "type": "string"
        -              },
        -              "suggestion": {
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "code",
        -              "message"
        -            ],
        -            "type": "object"
        -          },
        -          "path": {
        -            "description": "Requested file path",
        -            "type": "string"
        -          },
        -          "value": {
        -            "additionalProperties": false,
        -            "description": "Edit result; present on success",
        -            "properties": {
        -              "appliedEdits": {
        -                "description": "Number of edits successfully applied",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "diff": {
        -                "description": "Unified diff of all changes (present only in dryRun mode)",
        -                "type": "string"
        -              },
        -              "kind": {
        -                "description": "Broad file kind: text, binary, image, audio, or pdf",
        -                "enum": [
        -                  "text",
        -                  "binary",
        -                  "image",
        -                  "audio",
        -                  "pdf"
        -                ],
        -                "type": "string"
        -              },
        -              "lineCount": {
        -                "description": "Number of lines in the file after edits",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "lineRange": {
        -                "description": "Line range [firstLine, lastLine] covering all applied edits",
        -                "prefixItems": [
        -                  {
        -                    "exclusiveMinimum": 0,
        -                    "type": "integer"
        -                  },
        -                  {
        -                    "exclusiveMinimum": 0,
        -                    "type": "integer"
        -                  }
        -                ],
        -                "type": "array"
        -              },
        -              "linesAdded": {
        -                "description": "Net lines added by all applied edits",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "linesRemoved": {
        -                "description": "Net lines removed by all applied edits",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "mimeType": {
        -                "description": "Detected MIME type of the file",
        -                "type": "string"
        -              },
        -              "modified": {
        -                "description": "Last modification timestamp after edits (ISO 8601 UTC)",
        -                "format": "date-time",
        -                "type": "string"
        -              },
        -              "path": {
        -                "description": "Resolved absolute path of the edited file",
        -                "type": "string"
        -              },
        -              "resourceUri": {
        -                "description": "Resource URI pointing to the updated file content; omitted when no edit matched (appliedEdits is 0) and the file was left untouched",
        -                "type": "string"
        -              },
        -              "size": {
        -                "description": "File size in bytes after edits",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "unmatchedEdits": {
        -                "description": "oldText values that did not match any content in the file",
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              }
        -            },
        -            "required": [
        -              "path",
        -              "size",
        -              "lineCount",
        -              "mimeType",
        -              "kind",
        -              "modified",
        -              "appliedEdits"
        -            ],
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "path"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "summary": {
        -      "additionalProperties": false,
        -      "properties": {
        -        "failed": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "succeeded": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "total": {
        -          "minimum": 0,
        -          "type": "integer"
        -        }
        -      },
        -      "required": [
        -        "total",
        -        "succeeded",
        -        "failed"
        -      ],
        -      "type": "object"
        -    }
        -  },
        -  "required": [
        -    "results",
        -    "summary"
        -  ],
        -  "type": "object"
        -}New value: +null
    • Changedlist1 field changed
      • changedInput schema / properties / maxEntries / description
        Previous value: -"Page size (default: 1000). Continue with nextCursor; resourceUri is only for hard-cap overflow."New value: +"Page size (default: 1000). Continue with nextCursor; an incomplete first page also carries resourceUri for the whole list."
    • Changedread1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "results": {
        -      "description": "Per-path results ordered to match the input paths",
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "error": {
        -            "additionalProperties": false,
        -            "description": "Error details; present on failure",
        -            "properties": {
        -              "code": {
        -                "type": "string"
        -              },
        -              "message": {
        -                "type": "string"
        -              },
        -              "path": {
        -                "type": "string"
        -              },
        -              "suggestion": {
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "code",
        -              "message"
        -            ],
        -            "type": "object"
        -          },
        -          "path": {
        -            "description": "Requested file path",
        -            "type": "string"
        -          },
        -          "value": {
        -            "additionalProperties": false,
        -            "description": "Read result; present on success",
        -            "properties": {
        -              "contentHash": {
        -                "description": "SHA-256 hex digest of the returned content (present when includeHash=true)",
        -                "pattern": "^[0-9a-f]{64}$",
        -                "type": "string"
        -              },
        -              "continuation": {
        -                "additionalProperties": false,
        -                "description": "Next-read arguments; present when content was truncated due to size limits",
        -                "properties": {
        -                  "args": {
        -                    "additionalProperties": false,
        -                    "description": "Ready-to-use arguments for the next call; pass verbatim",
        -                    "properties": {
        -                      "endLine": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "integer"
        -                      },
        -                      "path": {
        -                        "type": "string"
        -                      },
        -                      "startLine": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "integer"
        -                      }
        -                    },
        -                    "required": [
        -                      "path",
        -                      "startLine",
        -                      "endLine"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "hint": {
        -                    "description": "One-sentence description of the data still remaining to be read",
        -                    "type": "string"
        -                  },
        -                  "tool": {
        -                    "description": "Tool name to call for the next chunk",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "tool",
        -                  "args",
        -                  "hint"
        -                ],
        -                "type": "object"
        -              },
        -              "endLine": {
        -                "description": "End line",
        -                "exclusiveMinimum": 0,
        -                "type": "integer"
        -              },
        -              "hasMoreLines": {
        -                "description": "True when additional lines remain beyond what was returned",
        -                "type": "boolean"
        -              },
        -              "head": {
        -                "description": "Head lines requested",
        -                "exclusiveMinimum": 0,
        -                "type": "integer"
        -              },
        -              "kind": {
        -                "description": "Broad file kind: text, binary, image, audio, or pdf",
        -                "enum": [
        -                  "text",
        -                  "binary",
        -                  "image",
        -                  "audio",
        -                  "pdf"
        -                ],
        -                "type": "string"
        -              },
        -              "linesRead": {
        -                "description": "Number of lines returned in this response",
        -                "minimum": 0,
        -                "type": "integer"
        -              },
        -              "mimeType": {
        -                "description": "Detected MIME type (e.g. text/typescript)",
        -                "type": "string"
        -              },
        -              "resourceUri": {
        -                "description": "Resource URI for externalized content (present when file is stored in resource store)",
        -                "type": "string"
        -              },
        -              "startLine": {
        -                "description": "Start line",
        -                "exclusiveMinimum": 0,
        -                "type": "integer"
        -              },
        -              "tail": {
        -                "description": "Tail lines requested",
        -                "exclusiveMinimum": 0,
        -                "type": "integer"
        -              },
        -              "totalLines": {
        -                "description": "Total line count in the full file",
        -                "minimum": 0,
        -                "type": "integer"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "path"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "summary": {
        -      "additionalProperties": false,
        -      "properties": {
        -        "failed": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "succeeded": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "total": {
        -          "minimum": 0,
        -          "type": "integer"
        -        }
        -      },
        -      "required": [
        -        "total",
        -        "succeeded",
        -        "failed"
        -      ],
        -      "type": "object"
        -    }
        -  },
        -  "required": [
        -    "results",
        -    "summary"
        -  ],
        -  "type": "object"
        -}New value: +null
    • Changedreplace_text1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "diff": {
        -      "description": "Unified diff of all changes (present when returnDiff=true or dryRun=true)",
        -      "type": "string"
        -    },
        -    "diffTruncated": {
        -      "description": "True when the diff was cut due to the size limit",
        -      "type": "boolean"
        -    },
        -    "filesScanned": {
        -      "description": "Total number of files examined",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "results": {
        -      "description": "Per-file results: modified files, then any that could not be processed",
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "error": {
        -            "additionalProperties": false,
        -            "description": "Error details; present on failure",
        -            "properties": {
        -              "code": {
        -                "type": "string"
        -              },
        -              "message": {
        -                "type": "string"
        -              },
        -              "path": {
        -                "type": "string"
        -              },
        -              "suggestion": {
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "code",
        -              "message"
        -            ],
        -            "type": "object"
        -          },
        -          "path": {
        -            "description": "File path relative to the search root",
        -            "type": "string"
        -          },
        -          "value": {
        -            "additionalProperties": false,
        -            "description": "Replacement outcome; present on success",
        -            "properties": {
        -              "matches": {
        -                "description": "Replacements applied in this file",
        -                "minimum": 0,
        -                "type": "integer"
        -              }
        -            },
        -            "required": [
        -              "matches"
        -            ],
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "path"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "resultsTruncated": {
        -      "description": "True when the results list holds fewer entries than summary.total: the changed-file or failed-file cap was hit. Trust summary over results.length.",
        -      "type": "boolean"
        -    },
        -    "stoppedReason": {
        -      "description": "Why enumeration stopped early: maxResults = match cap reached, maxFiles = file cap reached, timeout = time limit hit or cancelled. Absent when every matching file was enumerated. Marks the sweep incomplete, not the writes; files already dispatched still complete.",
        -      "enum": [
        -        "maxResults",
        -        "maxFiles",
        -        "timeout"
        -      ],
        -      "type": "string"
        -    },
        -    "summary": {
        -      "additionalProperties": false,
        -      "properties": {
        -        "failed": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "succeeded": {
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "total": {
        -          "minimum": 0,
        -          "type": "integer"
        -        }
        -      },
        -      "required": [
        -        "total",
        -        "succeeded",
        -        "failed"
        -      ],
        -      "type": "object"
        -    },
        -    "totalMatches": {
        -      "description": "Total number of replacements made across all files",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "results",
        -    "summary",
        -    "totalMatches",
        -    "filesScanned"
        -  ],
        -  "type": "object"
        -}New value: +null
  7. 28 tool updatesv2.0.0
    • Removedapply_patch
    • Removedcalculate_hash
    • Addedcreate
    • Addeddelete
    • Addeddiff
    • Removeddiff_files
    • Changededit27 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "EditSpec": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "newText": {
        +        "description": "Replacement text. Use an empty string to delete the matched oldText.",
        +        "type": "string"
        +      },
        +      "oldText": {
        +        "description": "Exact literal text to locate in the file. Must include 3-5 lines of context to ensure uniqueness and avoid matching the wrong block.",
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "oldText",
        +      "newText"
        +    ],
        +    "type": "object"
        +  }
        +}
      • removedInput schema / $schema
        Removed value: -"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / oneOf
        Added value: +[
        +  {
        +    "required": [
        +      "path",
        +      "edits"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "files"
        +    ]
        +  }
        +]
      • changedInput schema / properties / dryRun / description
        Previous value: -"Preview edits without writing. Check `unmatchedEdits` in response."New value: +"Preview diffs without writing to disk (default: false = apply edits)"
      • changedInput schema / properties / edits / description
        Previous value: -"List of replacements to apply sequentially. Each edit replaces the first occurrence of oldText."New value: +"Replacements applied to path; not allowed when using files"
      • addedInput schema / properties / edits / items / $ref
        Added value: +"#/$defs/EditSpec"
      • removedInput schema / properties / edits / items / additionalProperties
        Removed value: -false
      • removedInput schema / properties / edits / items / properties
        Removed value: -{
        -  "newText": {
        -    "description": "Replacement string. Preserve surrounding indentation style.",
        -    "type": "string"
        -  },
        -  "oldText": {
        -    "description": "Exact literal string to replace (character-for-character). Include 3–5 lines of context for unique targeting.",
        -    "maxLength": 102400,
        -    "minLength": 1,
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / edits / items / required
        Removed value: -[
        -  "oldText",
        -  "newText"
        -]
      • removedInput schema / properties / edits / items / type
        Removed value: -"object"
      • addedInput schema / properties / edits / maxItems
        Added value: +100
      • addedInput schema / properties / files
        Added value: +{
        +  "description": "Per-file entries (batch mode)",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "edits": {
        +        "description": "Replacements to apply to this specific file",
        +        "items": {
        +          "$ref": "#/$defs/EditSpec"
        +        },
        +        "maxItems": 100,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "path": {
        +        "description": "File or directory path inside an allowed workspace root.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "edits"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 5,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / ignoreWhitespace / description
        Previous value: -"Treat all whitespace sequences as equivalent when matching oldText."New value: +"Ignore leading/trailing whitespace differences when matching oldText"
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to file or directory."New value: +"Single file path; mutually exclusive with files"
      • removedInput schema / required
        Removed value: -[
        -  "path",
        -  "edits"
        -]
      • removedOutput schema / $schema
        Removed value: -"https://json-schema.org/draft/2020-12/schema"
      • removedOutput schema / properties / appliedEdits
        Removed value: -{
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / diff
        Removed value: -{
        -  "description": "Unified diff of changes (dryRun)",
        -  "type": "string"
        -}
      • removedOutput schema / properties / lineRange
        Removed value: -{
        -  "description": "Line range modified [start, end] (1-based)",
        -  "prefixItems": [
        -    {
        -      "maximum": 9007199254740991,
        -      "minimum": 1,
        -      "type": "integer"
        -    },
        -    {
        -      "maximum": 9007199254740991,
        -      "minimum": 1,
        -      "type": "integer"
        -    }
        -  ],
        -  "type": "array"
        -}
      • removedOutput schema / properties / linesAdded
        Removed value: -{
        -  "description": "Lines added",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / linesRemoved
        Removed value: -{
        -  "description": "Lines removed",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / ok
        Removed value: -{
        -  "type": "boolean"
        -}
      • removedOutput schema / properties / path
        Removed value: -{
        -  "type": "string"
        -}
      • addedOutput schema / properties / results
        Added value: +{
        +  "description": "Per-path edit results ordered to match the input paths",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "error": {
        +        "additionalProperties": false,
        +        "description": "Error details; present on failure",
        +        "properties": {
        +          "code": {
        +            "type": "string"
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "path": {
        +            "type": "string"
        +          },
        +          "suggestion": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "code",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "path": {
        +        "description": "Requested file path",
        +        "type": "string"
        +      },
        +      "value": {
        +        "additionalProperties": false,
        +        "description": "Edit result; present on success",
        +        "properties": {
        +          "appliedEdits": {
        +            "description": "Number of edits successfully applied",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "diff": {
        +            "description": "Unified diff of all changes (present only in dryRun mode)",
        +            "type": "string"
        +          },
        +          "kind": {
        +            "description": "Broad file kind: text, binary, image, audio, or pdf",
        +            "enum": [
        +              "text",
        +              "binary",
        +              "image",
        +              "audio",
        +              "pdf"
        +            ],
        +            "type": "string"
        +          },
        +          "lineCount": {
        +            "description": "Number of lines in the file after edits",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "lineRange": {
        +            "description": "Line range [firstLine, lastLine] covering all applied edits",
        +            "prefixItems": [
        +              {
        +                "exclusiveMinimum": 0,
        +                "type": "integer"
        +              },
        +              {
        +                "exclusiveMinimum": 0,
        +                "type": "integer"
        +              }
        +            ],
        +            "type": "array"
        +          },
        +          "linesAdded": {
        +            "description": "Net lines added by all applied edits",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "linesRemoved": {
        +            "description": "Net lines removed by all applied edits",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "mimeType": {
        +            "description": "Detected MIME type of the file",
        +            "type": "string"
        +          },
        +          "modified": {
        +            "description": "Last modification timestamp after edits (ISO 8601 UTC)",
        +            "format": "date-time",
        +            "type": "string"
        +          },
        +          "path": {
        +            "description": "Resolved absolute path of the edited file",
        +            "type": "string"
        +          },
        +          "resourceUri": {
        +            "description": "Resource URI pointing to the updated file content; omitted when no edit matched (appliedEdits is 0) and the file was left untouched",
        +            "type": "string"
        +          },
        +          "size": {
        +            "description": "File size in bytes after edits",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "unmatchedEdits": {
        +            "description": "oldText values that did not match any content in the file",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "path",
        +          "size",
        +          "lineCount",
        +          "mimeType",
        +          "kind",
        +          "modified",
        +          "appliedEdits"
        +        ],
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "path"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / summary
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "failed": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "succeeded": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "total": {
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "succeeded",
        +    "failed"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / properties / unmatchedEdits
        Removed value: -{
        -  "description": "Edits that could not be applied",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "ok"
        -]New value: +[
        +  "results",
        +  "summary"
        +]
    • Removedfind
    • Addedfind_files
    • Removedgrep
    • Addedlist
    • Addedlist_roots
    • Removedls
    • Removedmkdir
    • Addedmove
    • Removedmv
    • Addedpatch
    • Changedread31 fields changed
      • removedInput schema / $schema
        Removed value: -"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / dependentRequired
        Added value: +{
        +  "endLine": [
        +    "startLine"
        +  ]
        +}
      • removedInput schema / description
        Removed value: -"Use one read mode only: 'head', 'tail', or 'startLine'/'endLine'."
      • addedInput schema / oneOf
        Added value: +[
        +  {
        +    "required": [
        +      "path"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "paths"
        +    ]
        +  }
        +]
      • changedInput schema / properties / endLine / description
        Previous value: -"End line (1-based, inclusive). Defaults to last line when startLine is set."New value: +"End line (1-indexed)"
      • changedInput schema / properties / endLine / maximum
        Previous value: -9007199254740991New value: +100000
      • changedInput schema / properties / head / description
        Previous value: -"Read first N lines (preview)"New value: +"Return first N lines"
      • changedInput schema / properties / includeHash / description
        Previous value: -"Include SHA-256 hash of full file content"New value: +"Include SHA-256 hash of the returned content in the response"
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to file or directory."New value: +"Single file path; mutually exclusive with paths"
      • addedInput schema / properties / paths
        Added value: +{
        +  "description": "Array of file paths for batch mode (max 1000); mutually exclusive with path",
        +  "items": {
        +    "description": "File or directory path inside an allowed workspace root.",
        +    "maxLength": 4096,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 1000,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / startLine / description
        Previous value: -"Start line (1-based, inclusive). Defaults to 1 when endLine is set."New value: +"Start line (1-indexed)"
      • changedInput schema / properties / startLine / maximum
        Previous value: -9007199254740991New value: +100000
      • changedInput schema / properties / tail / description
        Previous value: -"Read last N lines"New value: +"Return last N lines"
      • removedInput schema / required
        Removed value: -[
        -  "path"
        -]
      • removedOutput schema / $schema
        Removed value: -"https://json-schema.org/draft/2020-12/schema"
      • removedOutput schema / properties / content
        Removed value: -{
        -  "description": "Content",
        -  "type": "string"
        -}
      • removedOutput schema / properties / contentHash
        Removed value: -{
        -  "description": "SHA-256 of full file content",
        -  "pattern": "^[a-f0-9]{64}$",
        -  "type": "string"
        -}
      • removedOutput schema / properties / endLine
        Removed value: -{
        -  "description": "End line",
        -  "maximum": 9007199254740991,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / hasMoreLines
        Removed value: -{
        -  "description": "More lines?",
        -  "type": "boolean"
        -}
      • removedOutput schema / properties / head
        Removed value: -{
        -  "description": "Head lines",
        -  "maximum": 9007199254740991,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / linesRead
        Removed value: -{
        -  "description": "Lines read",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / ok
        Removed value: -{
        -  "const": true,
        -  "type": "boolean"
        -}
      • removedOutput schema / properties / path
        Removed value: -{
        -  "type": "string"
        -}
      • removedOutput schema / properties / resourceUri
        Removed value: -{
        -  "description": "Full content URI",
        -  "type": "string"
        -}
      • addedOutput schema / properties / results
        Added value: +{
        +  "description": "Per-path results ordered to match the input paths",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "error": {
        +        "additionalProperties": false,
        +        "description": "Error details; present on failure",
        +        "properties": {
        +          "code": {
        +            "type": "string"
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "path": {
        +            "type": "string"
        +          },
        +          "suggestion": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "code",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "path": {
        +        "description": "Requested file path",
        +        "type": "string"
        +      },
        +      "value": {
        +        "additionalProperties": false,
        +        "description": "Read result; present on success",
        +        "properties": {
        +          "contentHash": {
        +            "description": "SHA-256 hex digest of the returned content (present when includeHash=true)",
        +            "pattern": "^[0-9a-f]{64}$",
        +            "type": "string"
        +          },
        +          "continuation": {
        +            "additionalProperties": false,
        +            "description": "Next-read arguments; present when content was truncated due to size limits",
        +            "properties": {
        +              "args": {
        +                "additionalProperties": false,
        +                "description": "Ready-to-use arguments for the next call; pass verbatim",
        +                "properties": {
        +                  "endLine": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "integer"
        +                  },
        +                  "path": {
        +                    "type": "string"
        +                  },
        +                  "startLine": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "integer"
        +                  }
        +                },
        +                "required": [
        +                  "path",
        +                  "startLine",
        +                  "endLine"
        +                ],
        +                "type": "object"
        +              },
        +              "hint": {
        +                "description": "One-sentence description of the data still remaining to be read",
        +                "type": "string"
        +              },
        +              "tool": {
        +                "description": "Tool name to call for the next chunk",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "tool",
        +              "args",
        +              "hint"
        +            ],
        +            "type": "object"
        +          },
        +          "endLine": {
        +            "description": "End line",
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "hasMoreLines": {
        +            "description": "True when additional lines remain beyond what was returned",
        +            "type": "boolean"
        +          },
        +          "head": {
        +            "description": "Head lines requested",
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "kind": {
        +            "description": "Broad file kind: text, binary, image, audio, or pdf",
        +            "enum": [
        +              "text",
        +              "binary",
        +              "image",
        +              "audio",
        +              "pdf"
        +            ],
        +            "type": "string"
        +          },
        +          "linesRead": {
        +            "description": "Number of lines returned in this response",
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          "mimeType": {
        +            "description": "Detected MIME type (e.g. text/typescript)",
        +            "type": "string"
        +          },
        +          "resourceUri": {
        +            "description": "Resource URI for externalized content (present when file is stored in resource store)",
        +            "type": "string"
        +          },
        +          "startLine": {
        +            "description": "Start line",
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "tail": {
        +            "description": "Tail lines requested",
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "totalLines": {
        +            "description": "Total line count in the full file",
        +            "minimum": 0,
        +            "type": "integer"
        +          }
        +        },
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "path"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / properties / startLine
        Removed value: -{
        -  "description": "Start line",
        -  "maximum": 9007199254740991,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • addedOutput schema / properties / summary
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "failed": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "succeeded": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "total": {
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "succeeded",
        +    "failed"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / properties / tail
        Removed value: -{
        -  "description": "Tail lines",
        -  "maximum": 9007199254740991,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / totalLines
        Removed value: -{
        -  "description": "Total lines",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / truncated
        Removed value: -{
        -  "description": "Truncated?",
        -  "type": "boolean"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "ok"
        -]New value: +[
        +  "results",
        +  "summary"
        +]
    • Removedread_many
    • Addedreplace_text
    • Removedrm
    • Removedroots
    • Removedsearch_and_replace
    • Addedsearch_text
    • Changedstat6 fields changed
      • removedInput schema / $schema
        Removed value: -"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / oneOf
        Added value: +[
        +  {
        +    "required": [
        +      "path"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "paths"
        +    ]
        +  }
        +]
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to file or directory."New value: +"Single file path; mutually exclusive with paths"
      • addedInput schema / properties / paths
        Added value: +{
        +  "description": "Array of file paths for batch mode (max 1000); mutually exclusive with path",
        +  "items": {
        +    "description": "File or directory path inside an allowed workspace root.",
        +    "maxLength": 4096,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 1000,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "path"
        -]
      • changedOutput schema / (root)
        Previous value: -{
        -  "$schema": "https://json-schema.org/draft/2020-12/schema",
        -  "additionalProperties": false,
        -  "properties": {
        -    "info": {
        -      "additionalProperties": false,
        -      "properties": {
        -        "accessed": {
        -          "description": "Accessed",
        -          "format": "date-time",
        -          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
        -          "type": "string"
        -        },
        -        "created": {
        -          "description": "Created",
        -          "format": "date-time",
        -          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
        -          "type": "string"
        -        },
        -        "isHidden": {
        -          "description": "Hidden?",
        -          "type": "boolean"
        -        },
        -        "mimeType": {
        -          "description": "MIME type",
        -          "type": "string"
        -        },
        -        "modified": {
        -          "description": "Modified",
        -          "format": "date-time",
        -          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
        -          "type": "string"
        -        },
        -        "name": {
        -          "description": "Name",
        -          "type": "string"
        -        },
        -        "path": {
        -          "description": "Absolute path",
        -          "type": "string"
        -        },
        -        "permissions": {
        -          "description": "Permissions",
        -          "type": "string"
        -        },
        -        "size": {
        -          "description": "Size (bytes)",
        -          "maximum": 9007199254740991,
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "symlinkTarget": {
        -          "description": "Target (symlink)",
        -          "type": "string"
        -        },
        -        "tokenEstimate": {
        -          "description": "Est. tokens (size/4)",
        -          "maximum": 9007199254740991,
        -          "minimum": 0,
        -          "type": "integer"
        -        },
        -        "type": {
        -          "description": "Type",
        -          "enum": [
        -            "file",
        -            "directory",
        -            "symlink",
        -            "other"
        -          ],
        -          "type": "string"
        -        }
        -      },
        -      "required": [
        -        "name",
        -        "path",
        -        "type",
        -        "size",
        -        "created",
        -        "modified",
        -        "accessed",
        -        "permissions",
        -        "isHidden"
        -      ],
        -      "type": "object"
        -    },
        -    "ok": {
        -      "const": true,
        -      "type": "boolean"
        -    }
        -  },
        -  "required": [
        -    "ok"
        -  ],
        -  "type": "object"
        -}New value: +null
    • Removedstat_many
    • Removedtree
    • Removedwrite

TDQS

A4.2/5.0

Scored across 13 tools

Disambiguation5/5

Each tool targets a clearly distinct file operation (read, write, edit, diff, patch, search, metadata) with explicit cross-references in the descriptions. Overlaps like edit vs replace_text are well delineated by exact-match uniqueness vs global replacement.

Naming Consistency5/5

All names use consistent snake_case with imperative verbs (create, delete, list, read, move, stat, etc.). Multi-word names like replace_text, search_text, and find_files follow the same verb_noun pattern.

Tool Count5/5

13 tools is well-scoped for a filesystem server, covering essential operations without redundancy. Each tool earns its place by handling a specific action or resource.

Completeness4/5

Core file lifecycle (create, read, update, delete, move, list, search, diff, stat) is well covered, with parent directory creation handled implicitly. Minor gaps remain for permission changes (chmod/chown) and link creation, but agents can work around most needs.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A Filesystem MCP server that allows an LLM to read and list files from a specified directory on your local machine through the Model Context Protocol.
    2
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server providing filesystem operations, shell execution, and web search capabilities.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Experimental MCP server for local LLM orchestration with filesystem tools (read, write, list, delete files) and a CLI agent that communicates via Ollama.
    6 npm
    ISC