-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Request: Add missing tool annotations — @modelcontextprotocol/server-filesystem v0.2.0
Context
We ran an automated scan of this server via live JSON-RPC handshake. This server is the gold standard for tool annotations in the MCP ecosystem — it's the only official server that provides readOnlyHint, destructiveHint, and idempotentHint on every tool.
This issue is filed to acknowledge that, and to suggest two small additions that would make the coverage complete.
Current Annotation Coverage — 14/14 tools annotated
| # | Tool | readOnlyHint |
destructiveHint |
idempotentHint |
openWorldHint |
|---|---|---|---|---|---|
| 1 | read_file |
true ✅ |
— | — | — |
| 2 | read_text_file |
true ✅ |
— | — | — |
| 3 | read_media_file |
true ✅ |
— | — | — |
| 4 | read_multiple_files |
true ✅ |
— | — | — |
| 5 | write_file |
false ✅ |
true ✅ |
true ✅ |
— |
| 6 | edit_file |
false ✅ |
true ✅ |
false ✅ |
— |
| 7 | create_directory |
false ✅ |
false ✅ |
true ✅ |
— |
| 8 | list_directory |
true ✅ |
— | — | — |
| 9 | list_directory_with_sizes |
true ✅ |
— | — | — |
| 10 | directory_tree |
true ✅ |
— | — | — |
| 11 | move_file |
false ✅ |
false ✅ |
false ✅ |
— |
| 12 | search_files |
true ✅ |
— | — | — |
| 13 | get_file_info |
true ✅ |
— | — | — |
| 14 | list_allowed_directories |
true ✅ |
— | — | — |
Every tool has readOnlyHint. Every write tool has destructiveHint. edit_file correctly reports idempotentHint: false. This is exactly what the MCP spec envisions.
Suggested additions
Two small improvements to reach full annotation coverage:
1. Add idempotentHint to read-only tools
All 10 read-only tools currently omit idempotentHint. Since reads are inherently idempotent, adding idempotentHint: true would let clients safely implement automatic retries on failure.
Affected tools: read_file, read_text_file, read_media_file, read_multiple_files, list_directory, list_directory_with_sizes, directory_tree, search_files, get_file_info, list_allowed_directories
Example — the change for read_text_file:
// Before
server.registerTool(
"read_text_file",
{
description: "Read the complete contents of a file...",
inputSchema: { path: z.string(), head: z.number().optional(), tail: z.number().optional() },
annotations: { readOnlyHint: true },
},
handler
);
// After — add idempotentHint
server.registerTool(
"read_text_file",
{
description: "Read the complete contents of a file...",
inputSchema: { path: z.string(), head: z.number().optional(), tail: z.number().optional() },
annotations: { readOnlyHint: true, idempotentHint: true },
},
handler
);Same one-property addition for all 10 read-only tools.
2. Add openWorldHint: false to all tools
All tools are scoped to allowed directories, making them closed-world by design. Explicitly marking openWorldHint: false communicates that the tool's behavior is fully determined by the configured directories, with no external side effects.
Example — the change for write_file:
// Before
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true }
// After — add openWorldHint
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false }Why annotations matter — chaining risks in multi-server setups
This server is commonly installed alongside other MCP servers (GitHub, memory, email, shell). When agents use multiple servers together, tool annotations become the primary signal for distinguishing safe operations from risky ones:
write_file+ any input server → An agent receiving instructions from email or chat could be directed to overwrite files.destructiveHint: true(already present ✅) enables clients and emerging security tools to gate this regardless of the instruction source.read_media_file+ network server → Large base64-encoded files could be exfiltrated if an agent chains a file read into an outbound HTTP call.readOnlyHint: truehelps distinguish the safe local read from the risky outbound send.
These composition risks are invisible when testing a server in isolation. Annotations are the metadata that makes them visible to downstream tooling as it matures.
This server as the ecosystem example
We're filing similar annotation requests on server-memory (0/9 annotated), server-github (0/26 annotated), server-sequential-thinking (0/1), and server-everything (0/13). In each of those issues, we reference server-filesystem as the example to follow.
Thank you for setting the standard.
Found via automated scan with AgentWard. Enumerated via live JSON-RPC handshake, protocol 2025-11-25.