Skip to content

[@langchain/mcp-adapters] Cannot parse JSON Schema $defs references (works in Python, fails in JavaScript) #9419

@satya444

Description

@satya444

Checked other resources

  • This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • I added a very descriptive title to this issue.
  • I searched the LangChain.js documentation with the integrated search.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain.js rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).

Example Code

Python MCP Server (FastMCP + Pydantic v2)

from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP
from typing import List

mcp = FastMCP(name="test-server", stateless_http=True)

class NestedItem(BaseModel):
    id: str = Field(description="Item ID")
    name: str = Field(description="Item name")
    value: float = Field(description="Item value")

class Metadata(BaseModel):
    total_count: int = Field(description="Total count")
    timestamp: str = Field(description="Timestamp")

class ResponseModel(BaseModel):
    """Response with nested models - will generate $defs"""
    items: List[NestedItem] = Field(description="List of items")
    metadata: Metadata = Field(description="Response metadata")

@mcp.tool()
def query_data(search: str) -> ResponseModel:
    """Query tool that returns nested response"""
    return ResponseModel(
        items=[NestedItem(id="1", name="Test", value=100.0)],
        metadata=Metadata(total_count=1, timestamp="2024-01-01")
    )

JavaScript Client - FAILS ❌

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({
  mcpServers: {
    "test-server": {
      url: "http://localhost:8090/tools/mcp",
      transport: "streamable_http"
    }
  }
});

// ❌ This will fail with "can't resolve reference #/$defs/..." error
const tools = await client.getTools();

Python Client - WORKS ✅

from langchain_mcp_adapters.client import MultiServerMCPClient

# Connect to the same server
client = MultiServerMCPClient({
    "test_server": {
        "url": "http://localhost:8090/tools/mcp",
        "transport": "streamable_http",
    }
})

# ✅ This works perfectly - no errors
tools = await client.get_tools()
print(f"Successfully loaded {len(tools)} tools")

Error Message and Stack Trace (if applicable)

MCPClientError: Failed to connect to streamable HTTP server "server-xxx, url: http://127.0.0.1:8090/tools/mcp": 
MCPClientError: Failed to load tools from server "server-xxx": 
Error: can't resolve reference #/$defs/ResponseModel from id #
    at MultiServerMCPClient._initializeStreamableHTTPConnection (node_modules/@langchain/mcp-adapters/src/client.ts:602:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async MultiServerMCPClient.initializeConnections (node_modules/@langchain/mcp-adapters/src/client.ts:269:11)
    at async MultiServerMCPClient.getTools (node_modules/@langchain/mcp-adapters/src/client.ts:322:7)

Description

The JavaScript @langchain/mcp-adapters library fails to parse JSON Schema responses from MCP servers when the schemas contain $defs references, which are standard in Pydantic v2 generated schemas.

Important: The Python langchain-mcp-adapters library (v0.1.13) correctly handles these same schemas without any issues. This bug is specific to the JavaScript implementation only.

Root Cause

When Pydantic v2 generates JSON schemas for models with nested structures, it uses the standard JSON Schema $defs feature to define reusable schemas and references them with $ref: "#/$defs/ModelName". The JavaScript adapter's internal schema parser cannot resolve these references.

Example Schema That Fails

{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/DataItem"
      }
    },
    "metadata": {
      "$ref": "#/$defs/Metadata"
    }
  },
  "$defs": {
    "DataItem": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "value": { "type": "number" }
      }
    },
    "Metadata": {
      "type": "object",
      "properties": {
        "total_count": { "type": "integer" }
      }
    }
  }
}

Key Finding

The exact same MCP server with the exact same Pydantic schemas works perfectly with the Python adapter but fails with the JavaScript adapter.

JavaScript adapter: ❌ FAILS
Python adapter: ✅ WORKS

Expected Behavior

  • Parse JSON Schemas with $defs definitions
  • Resolve all $ref references by looking up definitions in $defs
  • Successfully create LangChain tool instances

Actual Behavior

The adapter throws an error immediately when encountering a $ref to a $defs definition, failing to initialize any tools.

Impact

  • Any FastMCP-based Python server using Pydantic v2 (the default)
  • Any MCP server that generates JSON Schemas with $defs (standard practice)
  • Developers trying to use JavaScript frontends with Python MCP backends

References

System Info

Environment:

  • OS: macOS Darwin 24.6.0
  • Node.js: v22.15.1 (via nvm)
  • Yarn: 1.22.22

Packages (JavaScript - where bug exists):

  • @langchain/mcp-adapters: 1.0.0 ❌ FAILS
  • @langchain/core: 1.0.5
  • @langchain/langgraph: 1.0.0
  • @modelcontextprotocol/sdk: 1.18.2

Python packages (for comparison - works correctly):

  • langchain-mcp-adapters: 0.1.13 ✅ WORKS
  • Python: 3.11+

MCP Server:

  • FastMCP (Python)
  • Pydantic: v2.x
  • Generates standard JSON Schema with $defs references

Versions Tested:

  • @langchain/mcp-adapters@1.0.0 - ❌ Fails
  • @langchain/mcp-adapters@0.6.0 - ❌ Fails
  • langchain-mcp-adapters@0.1.13 (Python) - ✅ Works

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions