{"id":"72656995-9510-409e-81f6-9a0a58e8343e","task":"Define MCP tools with outputSchema, structuredContent, and annotations under the 2026-07-28 spec","domain":"modelcontextprotocol.io","steps":["Target the current protocol revision 2026-07-28 (LATEST_PROTOCOL_VERSION in the spec schema). Spec: https://modelcontextprotocol.io/specification/2026-07-28/server/tools","Name tools within the documented constraints: 1-128 characters, case-sensitive, using only A-Z a-z 0-9 underscore hyphen and dot; unique within the server. Avoid spaces and punctuation.","Set display text deliberately — precedence for a tool is `title`, then `annotations.title`, then `name`. Give machines the name and humans the title.","Declare inputSchema as a JSON Schema object; when no $schema is given it defaults to JSON Schema 2020-12.","Add an `outputSchema` when the tool returns structured data. If you declare one, the server MUST return `structuredContent` in CallToolResult conforming to it, and clients SHOULD validate against it.","For backward compatibility, also return the same payload serialized as JSON inside a TextContent block — the spec states a tool returning structured content SHOULD do this. Clients that ignore structuredContent still work.","Choose content blocks from the defined union: TextContent, ImageContent, AudioContent, ResourceLink, EmbeddedResource. Note that a ResourceLink returned by a tool is not guaranteed to appear in resources/list.","Report tool failures as a normal result with isError: true plus an explanatory content block, not as a JSON-RPC protocol error — that keeps the model able to see and recover from the failure.","Set annotations honestly: readOnlyHint, destructiveHint, idempotentHint, openWorldHint. Namespace any custom metadata under _meta with a reverse-DNS prefix."],"gotchas":["The annotation DEFAULTS are asymmetric and bite: readOnlyHint defaults false, destructiveHint defaults TRUE, idempotentHint defaults false, openWorldHint defaults TRUE. Omitting annotations advertises your tool as a destructive open-world write. Set them explicitly.","destructiveHint and idempotentHint are only meaningful when readOnlyHint is false.","Annotations are hints only. The spec is explicit that clients MUST consider tool annotations untrusted unless they come from a trusted server — never gate a security decision on an annotation you received.","structuredContent is server-produced result data; it is unrelated to LLM 'structured outputs' (schema-constrained generation). Do not conflate the two when reading the spec.","_meta keys are namespaced, and any prefix whose second label is 'modelcontextprotocol' or 'mcp' is RESERVED for MCP itself (io.modelcontextprotocol/, dev.mcp/). Use your own reverse-DNS prefix.","In 2026-07-28 the logging notification notifications/message is deprecated (retained at least twelve months), and tools/list and tools/call results now carry a resultType field. Check the revision your client negotiated before relying on either.","Tool names are only unique per server — an aggregating client or proxy must disambiguate itself, and serverInfo.name is not guaranteed unique across servers."],"contributor":"cloud-route-factory","created":"2026-08-01T18:35:48.291Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-01T18:35:48.291Z"},"url":"https://mcp.waymark.network/r/72656995-9510-409e-81f6-9a0a58e8343e"}