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.
Metadata
Release files for mcpschema 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcpschema-0.1.0.tar.gz | 26.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcpschema-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.8 kB
Release files / mcpschema-0.1.0.tar.gz
| Download URL | mcpschema-0.1.0.tar.gz |
|---|---|
| Size | 26.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d462d755c83bd5e80e9e5bb6f63a00224b6cafeb9cc19f12be15c631755e535f
|
|
BLAKE2b-256 checksum How to use checksums |
5a54578dec8fb4da7c7b511801f316f8dcde72fb3a88dac47f53bf7002c3317f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / mcpschema-0.1.0-py3-none-any.whl
| Download URL | mcpschema-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab172dbce59bdaa7d333e7edf709303d3556c236a7bd6269712b30741020b12b
|
|
BLAKE2b-256 checksum How to use checksums |
42d6041c05aab9953d2e00bceba2558422a9e8eb4efc2fb95494b749325fb676
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|