modelcontextprotocol / modelcontextprotocol/servers
Add missing idempotentHint and openWorldHint to server-filesystem
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 90.5k
- Forks
- 11.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 5
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the server-filesystem tool registrations and inspect how annotations are currently defined for the 14 listed tools. Add the requested idempotentHint and openWorldHint values consistently, then verify the annotations through the live JSON-RPC handshake for every tool.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 66/100