-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Request: Add tool annotations — @modelcontextprotocol/server-everything v2.0.0
Context
We ran an automated scan of this server via live JSON-RPC handshake. This server exposes 13 tools with zero annotations. As the official MCP reference/test server — the one developers use to learn the protocol — it should demonstrate best practices, including annotation usage.
For reference, @modelcontextprotocol/server-filesystem annotates all 14 of its tools. This server exercises every MCP feature except tool annotations.
Current state — 0/13 tools annotated
Every tool returns empty annotations: {}.
Suggested annotations — per tool
| # | Tool | readOnlyHint |
destructiveHint |
idempotentHint |
openWorldHint |
|---|---|---|---|---|---|
| 1 | echo |
true |
false |
true |
false |
| 2 | get-annotated-message |
true |
false |
true |
false |
| 3 | get-env |
true |
false |
true |
false |
| 4 | get-resource-links |
true |
false |
true |
false |
| 5 | get-resource-reference |
true |
false |
true |
false |
| 6 | get-structured-content |
true |
false |
true |
false |
| 7 | get-sum |
true |
false |
true |
false |
| 8 | get-tiny-image |
true |
false |
true |
false |
| 9 | gzip-file-as-resource |
true |
false |
true |
false |
| 10 | toggle-simulated-logging |
false |
false |
true |
false |
| 11 | toggle-subscriber-updates |
false |
false |
true |
false |
| 12 | trigger-long-running-operation |
true |
false |
false |
false |
| 13 | simulate-research-query |
true |
false |
false |
false |
Suggested code change — top 3 priority tools
get-env (highest priority — security-sensitive)
server.registerTool(
"get-env",
{
description: "Returns all environment variables, helpful for debugging MCP server configuration",
inputSchema: {},
annotations: {
readOnlyHint: true,
idempotentHint: true,
openWorldHint: false,
},
},
handler
);toggle-simulated-logging (one of two non-read-only tools)
server.registerTool(
"toggle-simulated-logging",
{
description: "Toggles simulated, random-leveled logging on or off.",
inputSchema: { enabled: z.boolean().optional() },
annotations: {
readOnlyHint: false,
idempotentHint: true,
openWorldHint: false,
},
},
handler
);echo (read-only template — same pattern for most tools)
server.registerTool(
"echo",
{
description: "Echoes back the input string",
inputSchema: { message: z.string() },
annotations: {
readOnlyHint: true,
idempotentHint: true,
openWorldHint: false,
},
},
handler
);11 of the 13 tools are read-only and share the same annotation values — they can be annotated in a single pass.
Rationale for notable tools
get-env → readOnlyHint: true
Technically accurate — the tool only reads environment variables. However, get-env is the most security-sensitive tool on this server despite being read-only. Environment variables commonly contain API keys, tokens, database URLs, and secrets. The annotations correctly reflect the tool's behavior (read-only, not destructive), but see the chaining section below for why this tool deserves special attention.
toggle-simulated-logging / toggle-subscriber-updates → readOnlyHint: false
These toggle internal server state. While the effect is trivial in a test server, they do mutate state, so readOnlyHint: false is accurate.
trigger-long-running-operation / simulate-research-query → idempotentHint: false
These start new operations each time they're called. Each call creates a new progress stream.
Why this matters — the get-env problem and reference server role
The get-env chaining risk
get-env returns every environment variable on the machine: GITHUB_TOKEN, ANTHROPIC_API_KEY, DATABASE_URL, AWS_SECRET_ACCESS_KEY — whatever the developer has set. If an agent chains get-env into an outbound network call (fetch.post, github.create_issue, email.send), those credentials are exfiltrated.
readOnlyHint: true on get-env correctly signals the tool itself is safe. The risk is in composition — when the output flows to a tool with openWorldHint: true. This distinction is what enables a "allow local reads, gate outbound sends" pattern. But that pattern only works when the read-only tool actually declares readOnlyHint: true.
This isn't a theoretical concern — developers commonly install server-everything for experimentation alongside other servers, and the environment where MCP servers run is the same environment that holds real credentials.
This server should demonstrate annotations
This is the MCP reference server — the server-everything — designed to exercise every protocol feature. It currently demonstrates tools, resources, prompts, subscriptions, structured content, and progress. It does not demonstrate tool annotations, despite annotations being a defined part of the MCP tool spec.
Adding annotations serves double duty:
- The annotations themselves provide correct metadata for downstream tooling
- The server becomes a working example of how to annotate tools — which community server developers will reference when building their own
Impact
13 tools, all straightforward annotation values, no behavior changes. This is a metadata-only PR that makes the reference server a complete reference.
Found via automated scan with AgentWard. Enumerated via live JSON-RPC handshake, protocol 2025-11-25.