Skip to content

v1.1.17

Choose a tag to compare

@github-actions github-actions released this 12 Aug 22:37
9573ef9

Fixed

  • Every tool was rejected by the client, because the advertised schemas declared JSON Schema draft-07. MCP has standardized on 2020-12, and hosts now refuse anything else — Tool '<name>' has an invalid outputSchema: JSON Schema declares an unsupported dialect ("$schema": "http://json-schema.org/draft-07/schema#"). The default validator supports JSON Schema 2020-12 only. The server starts and connects normally, so the failure presents as all 26 tools silently unavailable rather than as a crash. The dialect comes from the MCP SDK, not from this repo: server/mcp.js calls its Zod converter with no target, mapMiniTarget(undefined) resolves to draft-7, and every inputSchema and outputSchema is stamped draft-07 on the way out. Upgrading Zod does not fix it — both the v3 (zod-to-json-schema) and v4 (zod/v4-mini toJSONSchema) branches fall back to draft-07 without a target, verified empirically against SDK 1.30.0 + Zod 4.4.3 — so no dependency bump could have cleared this. The outgoing tools/list payload is now normalized at the transport boundary, the only public seam that does not reach into SDK internals: the 2020-12 dialect is re-stamped at each schema root, nested $schema declarations are stripped (illegal on a subschema), and the keywords that changed between the drafts are rewritten — definitions$defs with its #/definitions/… $refs repointed, tuple-form itemsprefixItems, additionalItemsitems, dependencies split into dependentRequired/dependentSchemas, and boolean exclusiveMinimum/exclusiveMaximum collapsed onto the numeric bound. Today's emitted schemas use none of those constructs, so the rewrite is a no-op on current output — it exists so a Zod construct added later cannot quietly reintroduce a draft-07-only keyword alongside a 2020-12 declaration, which would be worse than the bug it replaces. No tool, Zod schema, or handler changed; all 26 tools still register, and each now advertises https://json-schema.org/draft/2020-12/schema on both its input and output schema. Reported against the sibling server as sweetrb/apple-mail-mcp#147; all four Apple MCP servers were affected identically and are fixed in lockstep.

  • The dialect converter is now POSITION-AWARE, so it cannot corrupt a tool parameter that happens to be named after a schema keyword. The first cut of the converter recursed uniformly and then switched on every key it met — but the keys of a properties map are caller-chosen tool parameter names, not schema keywords. A tool declaring a parameter named definitions would have had it renamed to $defs on the wire; one named $schema would have been silently deleted while required went on naming it, producing a schema no input can satisfy; dependencies would have been restructured into dependentRequired/dependentSchemas and additionalItems dropped outright. The same class applied to instance data: enum, const, default and examples hold a caller's literal values, and recursing into them rewrote those literals as if they were schema keywords — a default of { "definitions": 1 } came back as { "$defs": 1 }. The walk now distinguishes the three positions: a name → schema map (properties, patternProperties, $defs, dependentSchemas) has only its values converted and its keys copied verbatim; data keywords (enum, const, default, examples, required, dependentRequired) pass through untouched; everything else is a schema and recurses as before. Verified latent, not live: no server in the fleet hits a corrupting name today — apple-notes-mcp's get-checklist-state has an output property named items, which happens to land in a safe branch — so this is fixed before the release rather than after. The advertised tools/list payload for all 26 tools is byte-identical across the fix (SHA-256 8eb7f7b7…45ac3f10 before and after), which is exactly the expected result for a latent defect.

Added

  • The outputSchema contract test now asserts the advertised dialect. The existing checks boot the real built server over stdio and inspect what it advertises — every tool has an outputSchema, none requires a field, none sets additionalProperties: false — but none of them looked at $schema, so a dialect that made the client discard every tool passed CI cleanly. The suite now fails any advertised schema that does not declare 2020-12, that mentions draft-07 anywhere, that uses a draft-07-only keyword (definitions, dependencies, additionalItems), or that declares $schema on more than one node. Unit tests for the converter itself cover each keyword rewrite and the transport wrapper.