Part 3 · The Deeper Protocol

MCP Server Design · ~7 min

Typed and Hinted

A tool's input schema is only half its contract. The other half — what it returns and what it promises about side effects — is where you let an agent trust a call without running it to find out.

Why this, for you: you've shaped how the agent calls your tool (Lesson 3). Now shape what comes back and what the call implies. A typed output the client can validate, plus honest behavior hints, are what let a host plan around your tool — auto-approve a read, double-check a delete — instead of treating every call as a black box.

The same craft that makes inputs unambiguous applies to outputs and side effects. Two fields carry it: outputSchema for the shape of what you return, and tool annotations for the behavior a call implies. Both are optional — and both change how a host treats your tool.

1 Output schema: structure the result, not just the input

inputSchema tells the agent how to call. outputSchema tells the client what to expect back, so the result can be validated rather than parsed hopefully out of a text blob. When you declare one, return both structuredContent (the validated object) and a serialized JSON copy in content for backwards compatibility with clients that don't read structured output.

# declare the shape you return, not just the shape you accept "name": "get_incident", "outputSchema": { "type": "object", "properties": { "id": { "type": "string" }, "severity": { "enum": ["sev1","sev2","sev3"] }, "open": { "type": "boolean" } }, "required": ["id","severity","open"] } # return BOTH — validated object plus a JSON copy for older clients structuredContent: { "id":"INC-42", "severity":"sev1", "open":true } content: [{ "type":"text", "text":"{\"id\":\"INC-42\",...}" }]

A typed return lets the client check fields before the agent reasons over them, and lets downstream tools consume the object directly. It's the output-side of the same poka-yoke idea: remove the guesswork.

2 Annotations: four hints about what a call does

Annotations are optional metadata on a tool that describe its behavior, so a host can decide how much ceremony a call needs before running it. The spec defines four:

AnnotationAsserts the tool…Host can…
readOnlyHintDoes not modify stateAuto-approve, run speculatively
destructiveHintMay make irreversible changesRequire confirmation first
idempotentHintRepeating is safe — same effectRetry without fear of duplication
openWorldHintTouches systems beyond a closed setTreat its reach as unbounded

Set idempotentHint: true on tools you've designed to be safely repeatable, so a host can retry a flaky call without creating a second issue or charging a card twice.

3 The trap: a hint is a claim, not a guarantee

Annotations are metadata only — the protocol does not enforce them, and the spec is explicit that they are not trustable from untrusted servers. A malicious server can label a destructive tool readOnlyHint: true to slip past an auto-approve policy.

Hints inform UX; they don't authorize

Treat annotations as a claim by the server, useful for hosts you trust and worthless as a security control for ones you don't. This is the same lesson as Part 2: trust is architectural. A readOnlyHint from a third-party server is a hint, not a sandbox — gate egress and writes regardless.

So annotate honestly for the hosts that trust you, and never rely on another server's annotations to bound what it can do. The two readers of your tool's contract — a trusting host and a hostile auditor — need different things, and the protocol only helps the first.

↪ Your win: a contract for results and side effects

Retrieval practice — recall, don't peek

Question 1The job of outputSchema on a tool is to…

Question 2When you declare an output schema, you should return…

Question 3A tool a host can safely retry without duplicating effects is marked…

Question 4Tool annotations from an untrusted server should be treated as…

Question 5 · spaced recall from Lesson 5Anthropic's floor for enabling tool search is roughly…

Ask me anything. Want help writing an outputSchema for a tool you have, or deciding which annotations to set on a write-tool? Next in Part 3: The Server Talks Back — when your server pauses a call to ask the user for input, or asks the host's model to reason — and what each adds to the trust surface.
✎ Feedback