Convert MCP tool schemas to OpenAI, Anthropic, Gemini, and other LLM provider formats — zero dependencies
Project description
mcpschema
Convert MCP tool schemas to OpenAI, Anthropic, Gemini, and other LLM provider formats — zero dependencies.
mcpschema translates mcp.types.Tool inputSchema dicts into the
tool-call shapes used by OpenAI, Anthropic, Gemini, Ollama, DeepSeek, and
Mistral — so you can route an MCP server's tools to any LLM provider
without reimplementing the conversion per-provider. It runs as a library
and a CLI.
Quick Start
Install from source:
pip install git+https://github.com/prasad-a-abhishek/mcpschema.git
Convert a single MCP tool to any provider format:
from mcpschema import to_openai_tool, to_anthropic_tool, to_gemini_tool, to_ollama_tool
mcp_tool = {
"name": "git_log",
"description": "Get recent commits",
"inputSchema": {
"type": "object",
"properties": {"n": {"type": "integer", "default": 10, "description": "Number of commits"}},
"required": ["n"],
},
}
openai = to_openai_tool(mcp_tool) # {"type": "function", "function": {...}}
anthropic = to_anthropic_tool(mcp_tool) # {"name", "description", "input_schema"}
gemini = to_gemini_tool(mcp_tool) # {"name", "description", "parameters": {OBJECT,...}}
ollama = to_ollama_tool(mcp_tool) # + "system_prompt_suffix" for local-model prompting
Convert a whole server's tools in one call:
from mcpschema import convert_all
tools = server.list_tools() # any iterable of mcp.types.Tool
openai_batch = convert_all(tools, "openai")
⚡ Performance & Benchmarks
mcpschema is a thin, pure-Python library — every adapter is a single function. We benchmark against a hand-written equivalent (the de-facto "no library" path that every developer reaches for when they hit issue #235 of the MCP Python SDK).
The honest summary: mcpschema wins on batch conversion (saving per-tool function-call overhead) and ties the hand-written baseline on single-tool conversions. Full results in benchmarks/BENCHMARK.md include every workload — including the ones where the hand-written baseline is faster. Reproduce locally:
python benchmarks/run_benchmark.py
Why mcpschema? (Problem & Trade-Off Statement)
The MCP Python SDK ships no adapter module — developers integrating MCP
with non-MCP LLM providers each hand-roll their own inputSchema →
provider-format conversion. Three GitHub issues document the gap:
modelcontextprotocol/python-sdk#235— "Official Adapter Functions for LLM Providers in MCP Python SDK" (18 reactions, open since 2024)modelcontextprotocol/python-sdk#226— schema-conversion complexity (16 reactions)anthropics/claude-code#6915— multi-agent routing (89 reactions)
What mcpschema is: a focused, zero-dependency library that does ONE thing (schema conversion) and does it well. It is NOT an LLM client, NOT a MCP server, and NOT a replacement for the SDK.
What mcpschema is NOT:
- Not an LLM client. It only converts schemas; it never calls a provider.
- Not coupled to the MCP SDK. It accepts any object with
name,description,inputSchema(duck-typed), so the SDK stays out of your dependency tree. - Not a streaming/conversation manager. See the out-of-scope list below.
Trade-offs you accept by using mcpschema:
- Defaults are stripped on conversion (per the OpenAI/Anthropic/Gemini API specs). If you need to preserve them, copy them out before converting.
anyOf/oneOf/allOfare not in any provider's tool-call schema; we drop them rather than silently mis-modeling them.- New provider API changes require a small library update (each adapter is ~20 LOC).
Key Features & Complete API / CLI Reference
Library API
| Function | Returns | Provider |
|---|---|---|
to_openai_tool(tool) |
{"type":"function","function":{...}} |
OpenAI / GPT-4o / GPT-5 |
to_anthropic_tool(tool) |
{"name","description","input_schema"} |
Anthropic Claude |
to_gemini_tool(tool) |
{"name","description","parameters":{OBJECT,...}} |
Google Gemini |
to_ollama_tool(tool) |
OpenAI shape + system_prompt_suffix |
Ollama (local models) |
to_deepseek_tool(tool) |
OpenAI shape | DeepSeek |
to_mistral_tool(tool) |
OpenAI shape | Mistral |
convert(tool, "provider") |
dispatches to the right adapter | any |
convert_all(tools, "provider") |
list | any |
tool_from_dict(raw) |
MCPTool |
helper |
PROVIDERS |
dict mapping provider names to callables | — |
CLI
$ mcpschema --help
usage: mcpschema [-h] [--version] {providers,convert} ...
Convert MCP tool schemas to OpenAI, Anthropic, Gemini, Ollama, DeepSeek,
and Mistral tool-call formats.
$ mcpschema providers
mcpschema 0.1.0 supports 6 providers:
- anthropic
- deepseek
- gemini
- mistral
- ollama
- openai
$ mcpschema convert --provider openai --input '[{"name":"git_log","description":"...","inputSchema":{...}}]'
[
{
"type": "function",
"function": {
"name": "git_log",
"description": "...",
"parameters": {
"type": "object",
"properties": {"n": {"type": "integer"}},
"required": ["n"]
}
}
}
]
$ echo '[{...}]' | mcpschema convert --provider anthropic --input -
Flags:
--provider(required): target provider name (case-insensitive)--input(required): JSON payload (single dict, list, or-for stdin)--compact: emit single-line JSON instead of pretty-printed
Out of scope
- LLM provider authentication or API calls
- MCP server implementation
- Provider-specific parameter constraints (e.g. OpenAI's
max_itemslimits) - Streaming response parsing
- Multi-turn conversation management
- Tool result conversion (MCP → provider response format)
Limitations
- Defaults are stripped — none of OpenAI/Anthropic/Gemini/Ollama's
tool-call schemas accept
defaultvalues. anyOf/oneOf/allOfare dropped — these JSON-Schema keywords are not in any provider's tool format.- Deeply nested objects (>3 levels) may need flattening for some providers — we preserve nesting as deep as it goes.
- Schema validation is not strict — we coerce loose schemas (missing
type, missingproperties) to valid provider shapes rather than raising.
Tests
pytest tests/ -q
137 tests across 9 files. Coverage spans all 22 spec acceptance criteria plus angular sweep (empty/None inputs, unicode, large schemas, malformed schemas, regression guards, batch conversion, JSON-RPC round-trip).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcpschema-0.1.0.tar.gz.
File metadata
- Download URL: mcpschema-0.1.0.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d462d755c83bd5e80e9e5bb6f63a00224b6cafeb9cc19f12be15c631755e535f
|
|
| MD5 |
4016787a2b0c927a617a245af98741a0
|
|
| BLAKE2b-256 |
5a54578dec8fb4da7c7b511801f316f8dcde72fb3a88dac47f53bf7002c3317f
|
File details
Details for the file mcpschema-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcpschema-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab172dbce59bdaa7d333e7edf709303d3556c236a7bd6269712b30741020b12b
|
|
| MD5 |
5bc812cbe5faba8e4c8fb7183ee3a76e
|
|
| BLAKE2b-256 |
42d6041c05aab9953d2e00bceba2558422a9e8eb4efc2fb95494b749325fb676
|