Repository navigation
Keep tool output schemas open and additive for hosts that cache them - #13
Merged
Merged
Conversation
Some MCP hosts cache each tool's outputSchema when the connector is added and validate every later result against it. Closed zod objects (additionalProperties: false), required lists and enums turned every additive field, widened value set and newly optional field in 0.2.6 into validation failures for existing connections. - Build every output object with z.looseObject (outputObject helper), so no published object, at any depth, rejects unknown properties. - Publish values that may grow (statuses, transports, resolutions, delivery status/via, skip reasons, authentication) as strings with their current values in the description (openEnum helper). - Require only fields present since 0.2.5; later fields are optional in the schema but still returned. - whoami matches its 0.2.5 shape again: transport is "stdio" or "http" (the text keeps the Streamable HTTP label) and directory_names is always present. - Test that published output schemas are open with no enum/const, that required fields match 0.2.5, and that representative results of every tool validate against the published schemas and the 0.2.5 schemas apart from unknown properties. - Document output schema compatibility and the one-time reconnect for hosts that cached closed schemas from 0.2.6 and earlier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Some MCP chat hosts cache each tool's
outputSchemawhen the connector is added and validate everystructuredContentresult against that cached copy. Our zodz.object(...)output schemas publishedadditionalProperties: false, required lists and closed enums, so the additive changes in 0.2.6 (new fields such asuntrusted_content_notice,thread_topic, list items'reaction/attachmenttype), widened values (whoami.transport,wait_for_message.status) and the newly optionalwhoami.directory_namesmade the read tools fail for existing connections until users reconnected.Change
z.looseObjectvia a sharedoutputObjecthelper. The JSON Schema intools/listnow hasadditionalProperties: {}at every level and neverfalse.status/via,resolve_address.resolution,get_thread.source,wait_for_messagestatus/transport/skipreason,whoami.transport, downloadauthentication) are plain strings with their current values in the description (openEnumhelper). Input schemas keep their enums.transportisstdio/http(the text still says "Streamable HTTP"), anddirectory_namesis always present ([]when there is no directory).Compatibility audit against 0.2.5
I compared the
tools/listoutput schemas of v0.2.4, v0.2.5 and v0.2.6 (all tools, including the HTTP-onlyget_attachment_download_urland the stdio-onlysave_attachment):add_recipientskeptadd_tonext to the newrecipients. The only regressions apart from added fields were inwhoami:directory_namesbecame optional and was omitted, andtransportchanged fromhttptostreamable-http. Both are restored here.wait_for_messagegained the statusinterrupted, which is only returned during a server restart and can't be avoided.whoami,resolve_address,mark_readandreactas published. Every other tool fails only onadditionalProperties: falseagainst fields added in 0.2.6; only a reconnect fixes that.whoamiover HTTP: its cached enum isstdio | streamable-http, and the result is nowhttpagain. Over stdio it validates. Those users need one more reconnect. If that matters more thanwhoamifor 0.2.5-era connections, revert just the transport value insrc/tools/identity.ts(and the tests).Tests
New
test/output-schemas.test.tschecks:additionalProperties: false/unevaluatedProperties: falseand noenum/const. Exceptions go in a commented allowlist, which is currently empty.tools/listschemas intest/fixtures/output-schemas-0.2.5.json(descriptions stripped).A mutation check, putting
z.object/z.enumback, fails the first test with 53 findings. Updated the existingtransport/directory_namesassertions.npm run typecheck,npm run buildandnpm testall pass (184 tests).🤖 Generated with Claude Code