Skip to content

fix: wrap MCP tool schemas with jsonSchema() in _buildNativeTools#473

Merged
buger merged 1 commit intomainfrom
fix/mcp-tools-schema-wrapping
Mar 4, 2026
Merged

fix: wrap MCP tool schemas with jsonSchema() in _buildNativeTools#473
buger merged 1 commit intomainfrom
fix/mcp-tools-schema-wrapping

Conversation

@buger
Copy link
Collaborator

@buger buger commented Mar 4, 2026

Summary

  • Fix TypeError: Cannot read properties of undefined (reading 'typeName') when MCP tools with raw JSON Schema are passed to Vercel AI SDK
  • Wrap MCP tool schemas with jsonSchema() and tool() in _buildNativeTools()
  • Add 8 regression tests covering various MCP tool schema scenarios

Closes #472

Root cause

mcpBridge.getVercelTools() returns MCP tools with raw JSON Schema inputSchema objects (e.g. { type: 'object', properties: {...} }). These were added directly to nativeTools without wrapping. When streamText() calls prepareToolsAndToolChoice(), the SDK's asSchema() function misidentifies raw JSON Schema as Zod schemas (since they lack the schemaSymbol marker), falls through to zodSchema(), and crashes on parseDef() reading def.typeName from undefined.

Fix

// Before (crashes):
nativeTools[name] = mcpTool;  // Raw object with JSON Schema

// After (safe):
const mcpSchema = mcpTool.inputSchema || mcpTool.parameters;
const wrappedSchema = mcpSchema && mcpSchema._def
  ? mcpSchema
  : jsonSchema(mcpSchema || { type: 'object', properties: {} });
nativeTools[name] = tool({
  description: mcpTool.description || `MCP tool: ${name}`,
  inputSchema: wrappedSchema,
  execute: mcpTool.execute,
});

Test plan

  • 8 new tests in mcp-message-history.test.js:
    • Raw JSON Schema inputSchema wrapping
    • Empty inputSchema
    • Missing inputSchema
    • Missing description
    • Multiple MCP tools with raw JSON Schema
    • Execute function preservation after wrapping
    • Mixed Zod and raw JSON Schema tools
    • Complex nested JSON Schema
  • All 106 test suites pass (2631 tests)

🤖 Generated with Claude Code

MCP tools returned by getVercelTools() have raw JSON Schema inputSchema
objects. When passed directly to the Vercel AI SDK, asSchema() misidentifies
them as Zod schemas and crashes with TypeError: Cannot read 'typeName'.

Fix: wrap MCP tool schemas with jsonSchema() and tool() before adding
to nativeTools, matching how wrapTool() handles native tool schemas.

Adds 8 regression tests covering raw JSON Schema, empty schema, no schema,
no description, nested schemas, mixed Zod/JSON Schema, and execute
function preservation.

Closes #472

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@buger buger merged commit f6a285d into main Mar 4, 2026
14 checks passed
@buger buger deleted the fix/mcp-tools-schema-wrapping branch March 4, 2026 06:28
@probelabs
Copy link
Contributor

probelabs bot commented Mar 4, 2026

PR Overview: Fix MCP Tool Schema Wrapping

Summary

This PR fixes a TypeError: Cannot read properties of undefined (reading 'typeName') crash that occurs when MCP tools with raw JSON Schema are passed to the Vercel AI SDK's streamText() function.

Root Cause

The mcpBridge.getVercelTools() method returns MCP tools with raw JSON Schema inputSchema objects (e.g., { type: 'object', properties: {...} }). These were being added directly to nativeTools without proper wrapping. When the Vercel AI SDK's prepareToolsAndToolChoice() processes these tools, its asSchema() function misidentifies raw JSON Schema as Zod schemas (since they lack the schemaSymbol marker), falls through to zodSchema(), and crashes when parseDef() tries to read def.typeName from undefined.

Fix Applied

In _buildNativeTools(), MCP tool schemas are now properly wrapped:

  • Raw JSON Schema objects are wrapped with jsonSchema()
  • Already-wrapped Zod schemas (detected via _def property) are passed through unchanged
  • Each MCP tool is reconstructed using the tool() function with proper description, inputSchema, and execute properties

Files Changed Analysis

File Status Additions Deletions
npm/src/agent/ProbeAgent.js Modified 9 1
npm/tests/unit/mcp-message-history.test.js Modified 256 0

Pattern: Minimal production code change (8 net lines) with comprehensive regression test coverage (8 new tests).


Architecture & Impact Assessment

What This PR Accomplishes

  1. Prevents runtime crashes when MCP servers return tools with JSON Schema definitions
  2. Ensures compatibility between MCP tool format and Vercel AI SDK expectations
  3. Maintains backward compatibility with Zod-based MCP tool implementations

Key Technical Changes

  • ProbeAgent.js (line ~1879): Replaced direct assignment nativeTools[name] = mcpTool with proper schema wrapping logic
  • Schema detection: Checks for _def property to distinguish Zod schemas from raw JSON Schema
  • Default handling: Falls back to empty object schema if neither inputSchema nor parameters exist

Affected System Components

flowchart LR
    subgraph "MCP Layer"
        A[MCP Server] --> B[McpBridge]
        B --> C[getVercelTools]
    end
    
    subgraph "Agent Layer"
        D[ProbeAgent] --> E[_buildNativeTools]
        E --> F{Schema Type?}
        F -->|Zod _def| G[Pass through]
        F -->|Raw JSON| H[Wrap with jsonSchema]
        G --> I[tool wrapper]
        H --> I
    end
    
    subgraph "Vercel AI SDK"
        I --> J[streamText]
        J --> K[prepareToolsAndToolChoice]
        K --> L[asSchema]
    end
    
    C --> E
    
    style H fill:#90EE90
    style I fill:#87CEEB
Loading

Scope Discovery & Context Expansion

Directly Related Files

  • npm/src/agent/mcp/client.js - Contains getVercelTools() that returns raw JSON Schema tools
  • npm/src/agent/mcp/xmlBridge.js - Alternative bridge with same getVercelTools() interface

Test Coverage Added

8 new tests in mcp-message-history.test.js:

  1. Raw JSON Schema inputSchema wrapping
  2. Empty inputSchema handling
  3. Missing inputSchema handling
  4. Missing description handling
  5. Multiple MCP tools with raw JSON Schema
  6. Execute function preservation after wrapping
  7. Mixed Zod and raw JSON Schema tools
  8. Complex nested JSON Schema

Potential Related Areas (not requiring changes)

  • Other consumers of mcpBridge.getVercelTools() - now protected at the _buildNativeTools level
  • Future MCP tool implementations - will automatically benefit from this fix

Review Notes

  • Low risk change: The fix is defensive and handles edge cases gracefully
  • Well-tested: 8 regression tests cover the reported issue and edge cases
  • Minimal footprint: Only 8 net lines of production code changed
  • No breaking changes: Existing Zod-based tools continue to work via the _def check
Metadata
  • Review Effort: 1 / 5
  • Primary Label: bug

Powered by Visor from Probelabs

Last updated: 2026-03-04T07:00:04.505Z | Triggered by: pr_opened | Commit: 80b6bd8

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs
Copy link
Contributor

probelabs bot commented Mar 4, 2026

Security Issues (1)

Severity Location Issue
🟠 Error system:0
ProbeAgent execution failed: Error: Failed to get response from AI model. No output generated. Check the stream for errors.

Security Issues (1)

Severity Location Issue
🟠 Error system:0
ProbeAgent execution failed: Error: Failed to get response from AI model. No output generated. Check the stream for errors.
\n\n \n\n

Performance Issues (1)

Severity Location Issue
🟠 Error contract:0
Output schema validation failed: must have required property 'issues'

Quality Issues (1)

Severity Location Issue
🟠 Error system:0
ProbeAgent execution failed: Error: Failed to get response from AI model. No output generated. Check the stream for errors.

Powered by Visor from Probelabs

Last updated: 2026-03-04T06:47:50.427Z | Triggered by: pr_opened | Commit: 80b6bd8

💡 TIP: You can chat with Visor using /visor ask <your question>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: MCP tool schemas crash in _buildNativeTools — raw JSON Schema misidentified as Zod

1 participant