fix(sdk): repair tool schemas via cross-tool $defs pool with transitive closure - #368
Open
bensynapse wants to merge 1 commit into
Open
fix(sdk): repair tool schemas via cross-tool $defs pool with transitive closure#368bensynapse wants to merge 1 commit into
bensynapse wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Author
|
@googlebot rescan |
…ve closure The hosted MCP server's upload_design_md outputSchema references #/$defs/ScreenInstance without shipping $defs (google-labs-code#367), and strict MCP clients drop the entire tool list when AJV fails to compile it. The existing repair only injected hardcoded stub definitions that had drifted from the backend (wrong SelectedScreenInstance shape, missing ScreenInstance members, unrepresentable File -> UserFeedback ref). - collectDefPool() harvests every $defs entry across the tools/list response so repair can inject the backend's real definitions - repairSchema() resolves from the pool first, falls back to stubs, and iterates to a fixpoint so defs introducing new refs (e.g. File -> UserFeedback) are fully repaired - Fallback stubs synced with the live backend shapes (2026-08-21) Verified against a live tools/list capture: all 15 tools fully resolve after repair. 198/198 package tests pass.
bensynapse
force-pushed
the
fix/dynamic-schema-repair-pool
branch
from
August 21, 2026 09:33
db79ef6 to
9ba4128
Compare
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
The hosted Stitch MCP server (
https://stitch.googleapis.com/mcp) emits atools/listin whichupload_design_md'soutputSchemareferences#/$defs/ScreenInstancebut ships no$defsblock (see #367). Clients that eagerly compile tool schemas — AJV inside@modelcontextprotocol/sdk, and strict clients such as kimi-code — fail schema registration and drop all 15 tools, making the integration unusable.The SDK's existing repair (
WELL_KNOWN_DEFSstubs, #353/#355) prevents the crash, but only by injecting hardcoded partial shapes that have drifted from the backend:SelectedScreenInstancestub hasscreenId/instanceId; the backend's real shape isid/sourceScreenwithrequired: ["id", "sourceScreen"].ScreenInstancestub is missingisResized,needsLayout,textContent, the recursivevariantScreenInstanceproperty, and theTEXT_INSTANCEenum member.Filestub omits the backend'suserFeedback → #/$defs/UserFeedbackref — one-shot stub injection cannot represent defs that introduce new refs.Fix
Repair dynamically from the response itself, stubs only as fallback:
collectDefPool(tools)(new, exported): harvests every$defsentry across all input/output schemas in thetools/listresponse. The backend defines each entity properly in at least one tool's schema (e.g.create_project'soutputSchemahas the realScreenInstance), so the pool captures the authoritative shapes.repairSchema(schema, defPool?): resolves missing defs from the pool first (real backend definitions, deep-cloned so schemas share no mutable state), falling back toWELL_KNOWN_DEFS. Iterates to a fixpoint so injected defs that introduce new refs (File → UserFeedback) are fully repaired. Signature is backward compatible.tools/liston 2026-08-21) so the fallback path is faithful too.Verification
upload_design_mdshape from MCP tools/list emits unresolvable $ref in outputSchema (upload_design_md dangling, ScreenInstance recursive) — clients drop all tools #367.tsc --noEmitclean; prettier clean.repairToolSchemasto a livetools/listcaptured from the hosted endpoint today — all 15 tools' schemas fully resolve after repair (previouslyupload_design_md'soutputSchemawas unresolvable). This also unblocks strict non-SDK clients (kimi-code) when the SDK/proxy layer sits in front.Mitigates #367 — the hosted server still needs the server-side schema fix, but this makes every SDK and proxy consumer immune to it.