modelcontextprotocol / python-sdk

The official Python SDK for Model Context Protocol servers and clients
https://modelcontextprotocol.io
MIT License
666 stars 51 forks source link

MCP is using `inputSchema`, while Claude Python API is expecting `input_schema`, intended? #74

Closed ArsenicBismuth closed 6 days ago

ArsenicBismuth commented 6 days ago

I discussed this a bit here: https://github.com/modelcontextprotocol/python-sdk/discussions/71

But in short, the Tool object obtained from MCP is using camelCase inputSchema, while the Claude Python API is expecting input_schema. As a result, we can't directly assign the MCP output to Claude message API input:

The MCP tool output:

[Tool(name='brave_web_search', description='Performs a web search... ', inputSchema={'type': 'object', 'properties': {'query': {'type': 'string', 'description': 'Search query (max 400 chars, 50 words)'}, 'count': {'type': 'number', 'description': 'Number of results (1-20, default 10)', 'default': 10}, 'offset': {'type': 'number', 'description': 'Pagination offset (max 9, default 0)', 'default': 0}}, 'required': ['query']}), Tool(name='brave_local_search', description="Searches for local businesses...", inputSchema={'type': 'object', 'properties': {'query': {'type': 'string', 'description': "Local search query (e.g. 'pizza near Central Park')"}, 'count': {'type': 'number', 'description': 'Number of results (1-20, default 5)', 'default': 5}}, 'required': ['query']})]

Which causes this error:

anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'tools.0.input_schema: Field required'}}

My setup:

# During initialization
async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        # Initialize the connection with MCP server
        await session.initialize()

        tools_list = await session.list_tools()
        tool = tools_list.tools

On getting the response:

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1000,
    temperature=0,
    system=system_prompt,
    messages=message,
    tools=tools
)

Temporary fix:

tools = []
for tool in raw_tools:
    tools.append({
        "name": tool.name,
        "description": tool.description,
        "input_schema": tool.inputSchema
    })
jspahrsummers commented 6 days ago

Although we've been heavily inspired by the Anthropic API in the design of MCP, it's not meant to be 1:1 or coupled to it. There are indeed a few things like this that will require translation—it won't be a passthrough.