Universal MCP toolkit + agent runtime to expose tools, connect multiple MCP servers (HTTP/stdio), and orchestrate them with LLMs — with production controls (budgets, logs, retries, redaction).
For who
- Devs building MCP servers (Python/TypeScript) and want “tools in minutes”
- Teams shipping agent workflows across many tools/servers
- Anyone who needs production guardrails (cost, security, observability)
What you get
- ✅ Expose Python functions as MCP tools (HTTP, stdio, in-process)
- ✅ Unified agent to orchestrate tools across multiple servers
- ✅ PolyMCP Inspector: test/debug/monitor MCP servers in a web UI
- ✅ Security + reliability: redaction, allowlists, retries, health checks
- ✅ Skills system: load only relevant tools (token savings)
- ✅ LLM providers: OpenAI, Anthropic (Claude), Ollama, DeepSeek, Kimi (e custom providers)
🎉 What's New (open)
Authentication System
- 🔐 Pluggable auth: JWT, OAuth2 (RFC 6749), API keys, custom providers
- 🔄 Auto-refresh with exponential backoff + jitter
- 🛡️ Thread-safe token management & automatic retry on 401/403
- 🎯 Drop-in auth wrapper for UnifiedPolyAgent (no code changes needed)
Security & Isolation
- 🐳 Docker executor: run code in isolated containers
Production Stdio Client
- 🔧 Robust JSON-RPC line parsing with timeout handling
- 🛡️ Graceful shutdown: proper pipe cleanup & process termination
- 🎭 Battle-tested with Playwright, filesystem, and custom servers
Enhanced Security & Reliability
- 🔒 Multi-layered auth with circuit breakers
- 📊 Health checks, structured logs, and metrics
- 🔄 Transient failure retry with intelligent backoff
- 🛡️ Input validation, schema enforcement, workspace isolation
pip install polymcpCreate server.py:
from polymcp.polymcp_toolkit import expose_tools_http
def greet(name: str) -> str:
"""Say hello."""
return f"Hello, {name}!"
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
app = expose_tools_http(tools=[greet, add], title="My MCP Tools")Run:
uvicorn server:app --reloadYou now have:
GET /mcp/list_toolsPOST /mcp/invoke/<tool_name>
IMPORTANT: MCP base URL
When connecting an agent or generating skills, always use the MCP base path:
✅ Correct:
http://localhost:8000/mcp
❌ Wrong:http://localhost:8000Quick check:
GET http://localhost:8000/mcp/list_toolsshould return your tools listPOST http://localhost:8000/mcp/invoke/<tool_name>invokes a toolIf you see
405 Method Not Allowedonhttp://localhost:8000/, you're hitting the wrong endpoint (missing/mcp).
import asyncio
from polymcp.polyagent import UnifiedPolyAgent, OpenAIProvider
async def main():
async with UnifiedPolyAgent(
llm_provider=OpenAIProvider(),
mcp_servers=["http://localhost:8000/mcp"],
) as agent:
out = await agent.run_async("Greet Luca and then add 5 + 10")
print(out)
asyncio.run(main())from polymcp.polyagent import UnifiedPolyAgent
agent = UnifiedPolyAgent(
llm_provider=llm,
# Budget controls
max_tokens=100000,
max_tool_calls=20,
max_wall_time=300.0,
# Security
redact_logs=True,
tool_allowlist={"greet", "add"},
# Observability
enable_structured_logs=True,
log_file="agent.log",
# Resilience
max_retries=3,
enable_health_checks=True,
enable_rate_limiting=True,
# Architecture
use_planner=True,
use_validator=True,
)polymcp inspector
# opens http://localhost:6274Inspector highlights
- Multi-server dashboard (HTTP + stdio)
- Interactive tool testing + live request/response
- Metrics (latency, success rate, calls)
- Export reports (json/markdown/html)
- Test suites for regression
agent = UnifiedPolyAgent(
llm_provider=llm,
mcp_servers=["http://localhost:8000/mcp"],
stdio_servers=[{"command": "npx", "args": ["@playwright/mcp@latest"]}],
)from polymcp import expose_tools_stdio
def calculate(a: int, b: int) -> int:
return a + b
server = expose_tools_stdio(
tools=[calculate],
server_name="Math Tools",
server_version="1.0.0"
)
if __name__ == "__main__":
server.run()Skills are generated by discovering tools from your MCP servers and auto-categorizing them.
Use the MCP base URL (include /mcp):
polymcp skills generate --servers "http://localhost:8000/mcp" --output ./mcp_skills --verboseEnable stdio discovery:
polymcp skills generate --stdio --servers "npx -y @playwright/mcp@latest" --output ./mcp_skills --verboseThen enable them in your agent:
agent = UnifiedPolyAgent(
llm_provider=llm,
skills_enabled=True,
skills_dir="./mcp_skills",
mcp_servers=["http://localhost:8000/mcp"], # optional if using HTTP tools too
stdio_servers=[{"command":"npx","args":["-y","@playwright/mcp@latest"]}], # optional
)agent = UnifiedPolyAgent(
llm_provider=llm,
skills_dir="./skills",
mcp_servers=["http://localhost:8000/mcp"],
)PolyMCP also ships a TypeScript implementation for Node/TS ecosystems:
- schema validation (Zod)
- HTTP + stdio servers
- agent framework + tooling
📖 See: polymcp-ts/README.md
- GitHub: https://github.com/llm-use/polymcp
- PyPI: https://pypi.org/project/polymcp/
- Website: https://www.poly-mcp.com
- Examples:
examples/
MIT

