fix(agent-kit): pass MCP tool schemas through adapters as JSON Schema#319
Open
ATOM00blue wants to merge 1 commit into
Open
fix(agent-kit): pass MCP tool schemas through adapters as JSON Schema#319ATOM00blue wants to merge 1 commit into
ATOM00blue wants to merge 1 commit into
Conversation
MCP tools failed with "TypeError: Cannot read properties of undefined (reading 'def')" when building an LLM request. listMCPTools converted the MCP JSON Schema into a Zod schema via @dmitryrechkin/json-schema-to-zod, which bundles Zod v3, while the model adapters call Zod v4's toJSONSchema() on those schemas. The v3/v4 mismatch made toJSONSchema() read .def on an incompatible schema and crash. MCP tools already expose a JSON Schema on mcp.tool.inputSchema, so the round-trip is unnecessary. Stop producing the incompatible Zod schema in listMCPTools and have the Anthropic, OpenAI and Gemini adapters fall back to the raw inputSchema. The unused json-schema-to-zod dependency is removed.
🦋 Changeset detectedLatest commit: 5e7c6d7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
Fixes MCP tool crashes caused by a Zod v3/v4 mismatch by avoiding JSON Schema → Zod → JSON Schema conversion for MCP-provided tool schemas and passing the original MCP JSON Schema through the request adapters.
Changes:
- Stop converting MCP tool
inputSchemainto Zod inAgent.listMCPTools; keep raw MCP JSON Schema onmcp.tool.inputSchema. - Update Anthropic/OpenAI/Gemini adapters to use
t.mcp.tool.inputSchemawhent.parametersis absent (Gemini still strips unsupported fields). - Remove
@dmitryrechkin/json-schema-to-zoddependency and add a regression test covering all three adapters’ request parsers.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/agent-kit/src/agent.ts | Removes MCP JSONSchema→Zod conversion and stores MCP tools with raw inputSchema on mcp.tool. |
| packages/agent-kit/src/agent.mcp.test.ts | Adds regression test ensuring MCP tool schemas flow through all adapters without throwing. |
| packages/agent-kit/src/adapters/anthropic.ts | Falls back to MCP inputSchema when Zod parameters are absent. |
| packages/agent-kit/src/adapters/openai.ts | Falls back to MCP inputSchema when Zod parameters are absent. |
| packages/agent-kit/src/adapters/gemini.ts | Falls back to MCP inputSchema and recursively strips unsupported fields (e.g., additionalProperties). |
| packages/agent-kit/package.json | Drops @dmitryrechkin/json-schema-to-zod dependency. |
| packages/agent-kit/pnpm-lock.yaml | Removes @dmitryrechkin/json-schema-to-zod and updates lock entries. |
| .changeset/quiet-tigers-flow.md | Adds changeset entry for patch release describing the MCP crash fix. |
Files not reviewed (1)
- packages/agent-kit/pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+86
to
91
| parameters: t.parameters | ||
| ? z.toJSONSchema(t.parameters, { target: "draft-7" }) | ||
| : t.mcp?.tool?.inputSchema, | ||
| strict: | ||
| typeof t.strict !== "undefined" ? t.strict : Boolean(t.parameters), // strict mode is only supported with parameters | ||
| }, |
Comment on lines
28
to
+37
| description: t.description, | ||
| parameters: t.parameters | ||
| ? geminiZodToJsonSchema(t.parameters) | ||
| : // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| (geminiZodToJsonSchema(z.object({})) as any), | ||
| : t.mcp?.tool?.inputSchema | ||
| ? // MCP tools already expose a JSON Schema; strip the fields Gemini | ||
| // does not accept and pass it through directly. | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| (recursiveGeminiZodToJsonSchema(t.mcp.tool.inputSchema) as any) | ||
| : // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| (geminiZodToJsonSchema(z.object({})) as any), |
| inngest@3.43.1: | ||
| resolution: {integrity: sha512-zG+BuENQFPUFNVM2sZRRhDXDTh3PAH6KPuus9a/ZTu7LGnAvE+HvHZFmRcBND2LFN6phQ6sIyqB34LV90wg3IA==} | ||
| engines: {node: '>=20'} | ||
| deprecated: 'CRITICAL SECURITY: upgrade to >=3.54.0' |
Comment on lines
+81
to
+96
| test("MCP tool schema flows through model adapters without crashing", async () => { | ||
| await newMCPServer(3002, createStreamableHTTPTransport); | ||
|
|
||
| const agent = new Agent({ | ||
| name: "test", | ||
| system: "noop", | ||
| mcpServers: [ | ||
| { | ||
| name: "test", | ||
| transport: { | ||
| type: "streamable-http", | ||
| url: "http://localhost:3002/mcp", | ||
| }, | ||
| }, | ||
| ], | ||
| }); |
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.
Summary
Fixes #312.
MCP tools crash with
TypeError: Cannot read properties of undefined (reading 'def')when
network.run()builds an LLM request.listMCPToolsconverts each MCP tool'sJSON Schema into a Zod schema via
@dmitryrechkin/json-schema-to-zod, which bundlesZod v3, but the model adapters call Zod v4's
toJSONSchema()on those schemas. v4'stoJSONSchema()reads.def, which doesn't exist on a v3 schema, so it throws.MCP tools already expose a JSON Schema on
mcp.tool.inputSchema, so theJSON Schema -> Zod -> JSON Schema round-trip is unnecessary. This PR:
listMCPToolsand keeps the rawmcp.tool.inputSchemaon the tool;parametersis absent (the Gemini path still strips fields Gemini rejects);@dmitryrechkin/json-schema-to-zoddependency, which was thesource of the Zod v3/v4 mismatch.
Test plan
initMCP, and verifies the toolflows through all three adapters'
requestParserwithout throwing (fails beforethis change, passes after).
pnpm --filter @inngest/agent-kit test— all green.createTool/Zod-parameter tests still pass (non-MCP path unaffected).