polymcp 1.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- polymcp-1.3.3/LICENSE +21 -0
- polymcp-1.3.3/MANIFEST.in +9 -0
- polymcp-1.3.3/PKG-INFO +350 -0
- polymcp-1.3.3/README.md +285 -0
- polymcp-1.3.3/polymcp/__init__.py +73 -0
- polymcp-1.3.3/polymcp/cli/__init__.py +11 -0
- polymcp-1.3.3/polymcp/cli/__main__.py +10 -0
- polymcp-1.3.3/polymcp/cli/commands/__init__.py +3 -0
- polymcp-1.3.3/polymcp/cli/commands/agent.py +320 -0
- polymcp-1.3.3/polymcp/cli/commands/config.py +216 -0
- polymcp-1.3.3/polymcp/cli/commands/init.py +856 -0
- polymcp-1.3.3/polymcp/cli/commands/inspector.py +156 -0
- polymcp-1.3.3/polymcp/cli/commands/server.py +291 -0
- polymcp-1.3.3/polymcp/cli/commands/skills.py +475 -0
- polymcp-1.3.3/polymcp/cli/commands/test.py +333 -0
- polymcp-1.3.3/polymcp/cli/main.py +83 -0
- polymcp-1.3.3/polymcp/cli/utils/__init__.py +9 -0
- polymcp-1.3.3/polymcp/cli/utils/config.py +144 -0
- polymcp-1.3.3/polymcp/cli/utils/registry.py +208 -0
- polymcp-1.3.3/polymcp/cli/utils/validation.py +192 -0
- polymcp-1.3.3/polymcp/inspector/__init__.py +12 -0
- polymcp-1.3.3/polymcp/inspector/server.py +1450 -0
- polymcp-1.3.3/polymcp/inspector/static/index.html +1324 -0
- polymcp-1.3.3/polymcp/mcp_stdio_client.py +355 -0
- polymcp-1.3.3/polymcp/polyagent/__init__.py +59 -0
- polymcp-1.3.3/polymcp/polyagent/agent.py +289 -0
- polymcp-1.3.3/polymcp/polyagent/auth_base.py +49 -0
- polymcp-1.3.3/polymcp/polyagent/codemode_agent.py +936 -0
- polymcp-1.3.3/polymcp/polyagent/jwt_auth.py +400 -0
- polymcp-1.3.3/polymcp/polyagent/llm_providers.py +252 -0
- polymcp-1.3.3/polymcp/polyagent/mcp_url.py +37 -0
- polymcp-1.3.3/polymcp/polyagent/oauth2_auth.py +273 -0
- polymcp-1.3.3/polymcp/polyagent/skill_generator.py +1520 -0
- polymcp-1.3.3/polymcp/polyagent/skill_loader.py +609 -0
- polymcp-1.3.3/polymcp/polyagent/skill_matcher.py +599 -0
- polymcp-1.3.3/polymcp/polyagent/tool_normalize.py +32 -0
- polymcp-1.3.3/polymcp/polyagent/unified_agent.py +2581 -0
- polymcp-1.3.3/polymcp/polyagent/unified_auth_wrapper.py +87 -0
- polymcp-1.3.3/polymcp/polymcp_toolkit/__init__.py +24 -0
- polymcp-1.3.3/polymcp/polymcp_toolkit/expose.py +525 -0
- polymcp-1.3.3/polymcp/polymcp_toolkit/expose_tools_stdio.py +679 -0
- polymcp-1.3.3/polymcp/polymcp_toolkit/expose_tools_wasm.py +976 -0
- polymcp-1.3.3/polymcp/polymcp_toolkit/mcp_auth.py +577 -0
- polymcp-1.3.3/polymcp/sandbox/__init__.py +16 -0
- polymcp-1.3.3/polymcp/sandbox/docker_executor.py +828 -0
- polymcp-1.3.3/polymcp/sandbox/executor.py +303 -0
- polymcp-1.3.3/polymcp/sandbox/tools_api.py +248 -0
- polymcp-1.3.3/polymcp/tools/advances_tools.py +265 -0
- polymcp-1.3.3/polymcp/tools/auth_server.py +208 -0
- polymcp-1.3.3/polymcp/tools/summarize_tool.py +109 -0
- polymcp-1.3.3/polymcp/version.py +1 -0
- polymcp-1.3.3/polymcp.egg-info/PKG-INFO +350 -0
- polymcp-1.3.3/polymcp.egg-info/SOURCES.txt +58 -0
- polymcp-1.3.3/polymcp.egg-info/dependency_links.txt +1 -0
- polymcp-1.3.3/polymcp.egg-info/entry_points.txt +2 -0
- polymcp-1.3.3/polymcp.egg-info/requires.txt +43 -0
- polymcp-1.3.3/polymcp.egg-info/top_level.txt +2 -0
- polymcp-1.3.3/pyproject.toml +130 -0
- polymcp-1.3.3/setup.cfg +4 -0
- polymcp-1.3.3/tests/test_basic.py +185 -0
polymcp-1.3.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 llm-use
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
polymcp-1.3.3/PKG-INFO
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: polymcp
|
|
3
|
+
Version: 1.3.3
|
|
4
|
+
Summary: Universal MCP Agent & Toolkit for intelligent LLM tool orchestration
|
|
5
|
+
Author: PolyMCP
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/llm-use/polymcp
|
|
8
|
+
Project-URL: Repository, https://github.com/llm-use/polymcp
|
|
9
|
+
Project-URL: Documentation, https://github.com/llm-use/polymcp#readme
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/llm-use/polymcp/issues
|
|
11
|
+
Keywords: mcp,llm,agent,ai,tools,orchestration
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: fastapi>=0.109.0
|
|
27
|
+
Requires-Dist: uvicorn[standard]>=0.27.0
|
|
28
|
+
Requires-Dist: pydantic>=2.5.0
|
|
29
|
+
Requires-Dist: requests>=2.31.0
|
|
30
|
+
Requires-Dist: docstring-parser>=0.15
|
|
31
|
+
Requires-Dist: httpx>=0.28.1
|
|
32
|
+
Requires-Dist: click>=8.1.0
|
|
33
|
+
Requires-Dist: rich>=13.7.0
|
|
34
|
+
Requires-Dist: jinja2>=3.1.0
|
|
35
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
36
|
+
Requires-Dist: gitpython>=3.1.0
|
|
37
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
38
|
+
Requires-Dist: python-jose[cryptography]>=3.3.0
|
|
39
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4
|
|
40
|
+
Requires-Dist: python-multipart>=0.0.6
|
|
41
|
+
Requires-Dist: docker>=7.0.0
|
|
42
|
+
Provides-Extra: openai
|
|
43
|
+
Requires-Dist: openai>=1.10.0; extra == "openai"
|
|
44
|
+
Provides-Extra: anthropic
|
|
45
|
+
Requires-Dist: anthropic>=0.8.0; extra == "anthropic"
|
|
46
|
+
Provides-Extra: all
|
|
47
|
+
Requires-Dist: openai>=1.10.0; extra == "all"
|
|
48
|
+
Requires-Dist: anthropic>=0.8.0; extra == "all"
|
|
49
|
+
Provides-Extra: production
|
|
50
|
+
Requires-Dist: sqlalchemy>=2.0.23; extra == "production"
|
|
51
|
+
Requires-Dist: redis>=5.0.1; extra == "production"
|
|
52
|
+
Requires-Dist: slowapi>=0.1.9; extra == "production"
|
|
53
|
+
Requires-Dist: alembic>=1.12.1; extra == "production"
|
|
54
|
+
Provides-Extra: dev
|
|
55
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
56
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
57
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
58
|
+
Requires-Dist: black>=23.12.0; extra == "dev"
|
|
59
|
+
Requires-Dist: flake8>=7.0.0; extra == "dev"
|
|
60
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
|
61
|
+
Requires-Dist: httpx>=0.26.0; extra == "dev"
|
|
62
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
63
|
+
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
64
|
+
Dynamic: license-file
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<img src="poly-mcp.png" alt="PolyMCP Logo" width="500"/>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<div align="center">
|
|
71
|
+
|
|
72
|
+
[](https://pypi.org/project/polymcp/)
|
|
73
|
+
[](https://pypi.org/project/polymcp/)
|
|
74
|
+
[](https://github.com/llm-use/polymcp/blob/main/LICENSE)
|
|
75
|
+
[](https://github.com/llm-use/polymcp/stargazers)
|
|
76
|
+
[](https://www.poly-mcp.com)
|
|
77
|
+
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
**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).
|
|
81
|
+
|
|
82
|
+
**For who**
|
|
83
|
+
- Devs building **MCP servers** (Python/TypeScript) and want “tools in minutes”
|
|
84
|
+
- Teams shipping **agent workflows** across many tools/servers
|
|
85
|
+
- Anyone who needs **production guardrails** (cost, security, observability)
|
|
86
|
+
|
|
87
|
+
**What you get**
|
|
88
|
+
- ✅ Expose Python functions as MCP tools (HTTP, stdio, in-process)
|
|
89
|
+
- ✅ Unified agent to orchestrate tools across multiple servers
|
|
90
|
+
- ✅ PolyMCP Inspector: test/debug/monitor MCP servers in a web UI
|
|
91
|
+
- ✅ Security + reliability: redaction, allowlists, retries, health checks
|
|
92
|
+
- ✅ Skills system: load only relevant tools (token savings)
|
|
93
|
+
- ✅ LLM providers: OpenAI, Anthropic (Claude), Ollama, DeepSeek, Kimi (e custom providers)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary><b>🎉 What's New</b> (open)</summary>
|
|
99
|
+
|
|
100
|
+
### PolyMCP PYTHON VERSION UPDATE
|
|
101
|
+
|
|
102
|
+
**Authentication System**
|
|
103
|
+
- 🔐 Pluggable auth: JWT, OAuth2 (RFC 6749), API keys, custom providers
|
|
104
|
+
- 🔄 Auto-refresh with exponential backoff + jitter
|
|
105
|
+
- 🛡️ Thread-safe token management & automatic retry on 401/403
|
|
106
|
+
- 🎯 Drop-in auth wrapper for UnifiedPolyAgent (no code changes needed)
|
|
107
|
+
|
|
108
|
+
**Security & Isolation**
|
|
109
|
+
- 🐳 Docker executor: run code in isolated containers
|
|
110
|
+
|
|
111
|
+
**Production Stdio Client**
|
|
112
|
+
- 🔧 Robust JSON-RPC line parsing with timeout handling
|
|
113
|
+
- 🛡️ Graceful shutdown: proper pipe cleanup & process termination
|
|
114
|
+
- 🎭 Battle-tested with Playwright, filesystem, and custom servers
|
|
115
|
+
|
|
116
|
+
**Enhanced Security & Reliability**
|
|
117
|
+
- 🔒 Multi-layered auth with circuit breakers
|
|
118
|
+
- 📊 Health checks, structured logs, and metrics
|
|
119
|
+
- 🔄 Transient failure retry with intelligent backoff
|
|
120
|
+
- 🛡️ Input validation, schema enforcement, workspace isolation
|
|
121
|
+
|
|
122
|
+
</details>
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Install
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pip install polymcp
|
|
130
|
+
````
|
|
131
|
+
|
|
132
|
+
## Quickstart (60s): expose 2 tools via MCP (HTTP)
|
|
133
|
+
|
|
134
|
+
Create `server.py`:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from polymcp.polymcp_toolkit import expose_tools_http
|
|
138
|
+
|
|
139
|
+
def greet(name: str) -> str:
|
|
140
|
+
"""Say hello."""
|
|
141
|
+
return f"Hello, {name}!"
|
|
142
|
+
|
|
143
|
+
def add(a: int, b: int) -> int:
|
|
144
|
+
"""Add two numbers."""
|
|
145
|
+
return a + b
|
|
146
|
+
|
|
147
|
+
app = expose_tools_http(tools=[greet, add], title="My MCP Tools")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Run:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
uvicorn server:app --reload
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
You now have:
|
|
157
|
+
|
|
158
|
+
* `GET /mcp/list_tools`
|
|
159
|
+
* `POST /mcp/invoke/<tool_name>`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
> **IMPORTANT: MCP base URL**
|
|
164
|
+
>
|
|
165
|
+
> When connecting an agent or generating skills, always use the MCP base path:
|
|
166
|
+
>
|
|
167
|
+
> ✅ Correct: `http://localhost:8000/mcp`
|
|
168
|
+
> ❌ Wrong: `http://localhost:8000`
|
|
169
|
+
>
|
|
170
|
+
> Quick check:
|
|
171
|
+
> - `GET http://localhost:8000/mcp/list_tools` should return your tools list
|
|
172
|
+
> - `POST http://localhost:8000/mcp/invoke/<tool_name>` invokes a tool
|
|
173
|
+
>
|
|
174
|
+
> If you see `405 Method Not Allowed` on `http://localhost:8000/`, you're hitting the wrong endpoint (missing `/mcp`).
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
## Quickstart: run an agent that uses your tools
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
import asyncio
|
|
181
|
+
from polymcp.polyagent import UnifiedPolyAgent, OpenAIProvider
|
|
182
|
+
|
|
183
|
+
async def main():
|
|
184
|
+
async with UnifiedPolyAgent(
|
|
185
|
+
llm_provider=OpenAIProvider(),
|
|
186
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
187
|
+
) as agent:
|
|
188
|
+
out = await agent.run_async("Greet Luca and then add 5 + 10")
|
|
189
|
+
print(out)
|
|
190
|
+
|
|
191
|
+
asyncio.run(main())
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Production config (safe defaults)
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from polymcp.polyagent import UnifiedPolyAgent
|
|
200
|
+
|
|
201
|
+
agent = UnifiedPolyAgent(
|
|
202
|
+
llm_provider=llm,
|
|
203
|
+
|
|
204
|
+
# Budget controls
|
|
205
|
+
max_tokens=100000,
|
|
206
|
+
max_tool_calls=20,
|
|
207
|
+
max_wall_time=300.0,
|
|
208
|
+
|
|
209
|
+
# Security
|
|
210
|
+
redact_logs=True,
|
|
211
|
+
tool_allowlist={"greet", "add"},
|
|
212
|
+
|
|
213
|
+
# Observability
|
|
214
|
+
enable_structured_logs=True,
|
|
215
|
+
log_file="agent.log",
|
|
216
|
+
|
|
217
|
+
# Resilience
|
|
218
|
+
max_retries=3,
|
|
219
|
+
enable_health_checks=True,
|
|
220
|
+
enable_rate_limiting=True,
|
|
221
|
+
|
|
222
|
+
# Architecture
|
|
223
|
+
use_planner=True,
|
|
224
|
+
use_validator=True,
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## PolyMCP Inspector (test/debug/monitor)
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
polymcp inspector
|
|
234
|
+
# opens http://localhost:6274
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Inspector highlights**
|
|
238
|
+
|
|
239
|
+
* Multi-server dashboard (HTTP + stdio)
|
|
240
|
+
* Interactive tool testing + live request/response
|
|
241
|
+
* Metrics (latency, success rate, calls)
|
|
242
|
+
* Export reports (json/markdown/html)
|
|
243
|
+
* Test suites for regression
|
|
244
|
+
|
|
245
|
+
<img src="PolyMCP_Inspector.png" alt="PolyMCP Inspector"/>
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Common workflows
|
|
250
|
+
|
|
251
|
+
### 1) Connect multiple servers (HTTP + stdio)
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
agent = UnifiedPolyAgent(
|
|
255
|
+
llm_provider=llm,
|
|
256
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
257
|
+
stdio_servers=[{"command": "npx", "args": ["@playwright/mcp@latest"]}],
|
|
258
|
+
)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 2) Stdio MCP server (Claude Desktop compatible)
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
from polymcp import expose_tools_stdio
|
|
265
|
+
|
|
266
|
+
def calculate(a: int, b: int) -> int:
|
|
267
|
+
return a + b
|
|
268
|
+
|
|
269
|
+
server = expose_tools_stdio(
|
|
270
|
+
tools=[calculate],
|
|
271
|
+
server_name="Math Tools",
|
|
272
|
+
server_version="1.0.0"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
if __name__ == "__main__":
|
|
276
|
+
server.run()
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 3) Skills system (load only relevant tools)
|
|
280
|
+
|
|
281
|
+
### Generate skills (CLI)
|
|
282
|
+
|
|
283
|
+
Skills are generated by discovering tools from your MCP servers and auto-categorizing them.
|
|
284
|
+
|
|
285
|
+
#### HTTP servers
|
|
286
|
+
Use the MCP base URL (include `/mcp`):
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
polymcp skills generate --servers "http://localhost:8000/mcp" --output ./mcp_skills --verbose
|
|
290
|
+
````
|
|
291
|
+
|
|
292
|
+
#### Stdio servers (Playwright, filesystem, etc.)
|
|
293
|
+
|
|
294
|
+
Enable stdio discovery:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
polymcp skills generate --stdio --servers "npx -y @playwright/mcp@latest" --output ./mcp_skills --verbose
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Then enable them in your agent:
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
agent = UnifiedPolyAgent(
|
|
304
|
+
llm_provider=llm,
|
|
305
|
+
skills_enabled=True,
|
|
306
|
+
skills_dir="./mcp_skills",
|
|
307
|
+
mcp_servers=["http://localhost:8000/mcp"], # optional if using HTTP tools too
|
|
308
|
+
stdio_servers=[{"command":"npx","args":["-y","@playwright/mcp@latest"]}], # optional
|
|
309
|
+
)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
```python
|
|
314
|
+
agent = UnifiedPolyAgent(
|
|
315
|
+
llm_provider=llm,
|
|
316
|
+
skills_dir="./skills",
|
|
317
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
318
|
+
)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## TypeScript implementation (PolyMCP-TS)
|
|
324
|
+
|
|
325
|
+
PolyMCP also ships a TypeScript implementation for Node/TS ecosystems:
|
|
326
|
+
|
|
327
|
+
* schema validation (Zod)
|
|
328
|
+
* HTTP + stdio servers
|
|
329
|
+
* agent framework + tooling
|
|
330
|
+
|
|
331
|
+
📖 See: `polymcp-ts/README.md`
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Docs & Links
|
|
336
|
+
|
|
337
|
+
* GitHub: [https://github.com/llm-use/polymcp](https://github.com/poly-mcp/polymcp)
|
|
338
|
+
* PyPI: [https://pypi.org/project/polymcp/](https://pypi.org/project/polymcp/)
|
|
339
|
+
* Website: [https://www.poly-mcp.com](https://www.poly-mcp.com)
|
|
340
|
+
* Examples: `examples/`
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Star History
|
|
345
|
+
|
|
346
|
+
[](https://www.star-history.com/#llm-use/Polymcp&type=date&legend=top-left)
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT
|
polymcp-1.3.3/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="poly-mcp.png" alt="PolyMCP Logo" width="500"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/polymcp/)
|
|
8
|
+
[](https://pypi.org/project/polymcp/)
|
|
9
|
+
[](https://github.com/llm-use/polymcp/blob/main/LICENSE)
|
|
10
|
+
[](https://github.com/llm-use/polymcp/stargazers)
|
|
11
|
+
[](https://www.poly-mcp.com)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
**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).
|
|
16
|
+
|
|
17
|
+
**For who**
|
|
18
|
+
- Devs building **MCP servers** (Python/TypeScript) and want “tools in minutes”
|
|
19
|
+
- Teams shipping **agent workflows** across many tools/servers
|
|
20
|
+
- Anyone who needs **production guardrails** (cost, security, observability)
|
|
21
|
+
|
|
22
|
+
**What you get**
|
|
23
|
+
- ✅ Expose Python functions as MCP tools (HTTP, stdio, in-process)
|
|
24
|
+
- ✅ Unified agent to orchestrate tools across multiple servers
|
|
25
|
+
- ✅ PolyMCP Inspector: test/debug/monitor MCP servers in a web UI
|
|
26
|
+
- ✅ Security + reliability: redaction, allowlists, retries, health checks
|
|
27
|
+
- ✅ Skills system: load only relevant tools (token savings)
|
|
28
|
+
- ✅ LLM providers: OpenAI, Anthropic (Claude), Ollama, DeepSeek, Kimi (e custom providers)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<details>
|
|
33
|
+
<summary><b>🎉 What's New</b> (open)</summary>
|
|
34
|
+
|
|
35
|
+
### PolyMCP PYTHON VERSION UPDATE
|
|
36
|
+
|
|
37
|
+
**Authentication System**
|
|
38
|
+
- 🔐 Pluggable auth: JWT, OAuth2 (RFC 6749), API keys, custom providers
|
|
39
|
+
- 🔄 Auto-refresh with exponential backoff + jitter
|
|
40
|
+
- 🛡️ Thread-safe token management & automatic retry on 401/403
|
|
41
|
+
- 🎯 Drop-in auth wrapper for UnifiedPolyAgent (no code changes needed)
|
|
42
|
+
|
|
43
|
+
**Security & Isolation**
|
|
44
|
+
- 🐳 Docker executor: run code in isolated containers
|
|
45
|
+
|
|
46
|
+
**Production Stdio Client**
|
|
47
|
+
- 🔧 Robust JSON-RPC line parsing with timeout handling
|
|
48
|
+
- 🛡️ Graceful shutdown: proper pipe cleanup & process termination
|
|
49
|
+
- 🎭 Battle-tested with Playwright, filesystem, and custom servers
|
|
50
|
+
|
|
51
|
+
**Enhanced Security & Reliability**
|
|
52
|
+
- 🔒 Multi-layered auth with circuit breakers
|
|
53
|
+
- 📊 Health checks, structured logs, and metrics
|
|
54
|
+
- 🔄 Transient failure retry with intelligent backoff
|
|
55
|
+
- 🛡️ Input validation, schema enforcement, workspace isolation
|
|
56
|
+
|
|
57
|
+
</details>
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install polymcp
|
|
65
|
+
````
|
|
66
|
+
|
|
67
|
+
## Quickstart (60s): expose 2 tools via MCP (HTTP)
|
|
68
|
+
|
|
69
|
+
Create `server.py`:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from polymcp.polymcp_toolkit import expose_tools_http
|
|
73
|
+
|
|
74
|
+
def greet(name: str) -> str:
|
|
75
|
+
"""Say hello."""
|
|
76
|
+
return f"Hello, {name}!"
|
|
77
|
+
|
|
78
|
+
def add(a: int, b: int) -> int:
|
|
79
|
+
"""Add two numbers."""
|
|
80
|
+
return a + b
|
|
81
|
+
|
|
82
|
+
app = expose_tools_http(tools=[greet, add], title="My MCP Tools")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Run:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uvicorn server:app --reload
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
You now have:
|
|
92
|
+
|
|
93
|
+
* `GET /mcp/list_tools`
|
|
94
|
+
* `POST /mcp/invoke/<tool_name>`
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
> **IMPORTANT: MCP base URL**
|
|
99
|
+
>
|
|
100
|
+
> When connecting an agent or generating skills, always use the MCP base path:
|
|
101
|
+
>
|
|
102
|
+
> ✅ Correct: `http://localhost:8000/mcp`
|
|
103
|
+
> ❌ Wrong: `http://localhost:8000`
|
|
104
|
+
>
|
|
105
|
+
> Quick check:
|
|
106
|
+
> - `GET http://localhost:8000/mcp/list_tools` should return your tools list
|
|
107
|
+
> - `POST http://localhost:8000/mcp/invoke/<tool_name>` invokes a tool
|
|
108
|
+
>
|
|
109
|
+
> If you see `405 Method Not Allowed` on `http://localhost:8000/`, you're hitting the wrong endpoint (missing `/mcp`).
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## Quickstart: run an agent that uses your tools
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
import asyncio
|
|
116
|
+
from polymcp.polyagent import UnifiedPolyAgent, OpenAIProvider
|
|
117
|
+
|
|
118
|
+
async def main():
|
|
119
|
+
async with UnifiedPolyAgent(
|
|
120
|
+
llm_provider=OpenAIProvider(),
|
|
121
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
122
|
+
) as agent:
|
|
123
|
+
out = await agent.run_async("Greet Luca and then add 5 + 10")
|
|
124
|
+
print(out)
|
|
125
|
+
|
|
126
|
+
asyncio.run(main())
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Production config (safe defaults)
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from polymcp.polyagent import UnifiedPolyAgent
|
|
135
|
+
|
|
136
|
+
agent = UnifiedPolyAgent(
|
|
137
|
+
llm_provider=llm,
|
|
138
|
+
|
|
139
|
+
# Budget controls
|
|
140
|
+
max_tokens=100000,
|
|
141
|
+
max_tool_calls=20,
|
|
142
|
+
max_wall_time=300.0,
|
|
143
|
+
|
|
144
|
+
# Security
|
|
145
|
+
redact_logs=True,
|
|
146
|
+
tool_allowlist={"greet", "add"},
|
|
147
|
+
|
|
148
|
+
# Observability
|
|
149
|
+
enable_structured_logs=True,
|
|
150
|
+
log_file="agent.log",
|
|
151
|
+
|
|
152
|
+
# Resilience
|
|
153
|
+
max_retries=3,
|
|
154
|
+
enable_health_checks=True,
|
|
155
|
+
enable_rate_limiting=True,
|
|
156
|
+
|
|
157
|
+
# Architecture
|
|
158
|
+
use_planner=True,
|
|
159
|
+
use_validator=True,
|
|
160
|
+
)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## PolyMCP Inspector (test/debug/monitor)
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
polymcp inspector
|
|
169
|
+
# opens http://localhost:6274
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Inspector highlights**
|
|
173
|
+
|
|
174
|
+
* Multi-server dashboard (HTTP + stdio)
|
|
175
|
+
* Interactive tool testing + live request/response
|
|
176
|
+
* Metrics (latency, success rate, calls)
|
|
177
|
+
* Export reports (json/markdown/html)
|
|
178
|
+
* Test suites for regression
|
|
179
|
+
|
|
180
|
+
<img src="PolyMCP_Inspector.png" alt="PolyMCP Inspector"/>
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Common workflows
|
|
185
|
+
|
|
186
|
+
### 1) Connect multiple servers (HTTP + stdio)
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
agent = UnifiedPolyAgent(
|
|
190
|
+
llm_provider=llm,
|
|
191
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
192
|
+
stdio_servers=[{"command": "npx", "args": ["@playwright/mcp@latest"]}],
|
|
193
|
+
)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 2) Stdio MCP server (Claude Desktop compatible)
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from polymcp import expose_tools_stdio
|
|
200
|
+
|
|
201
|
+
def calculate(a: int, b: int) -> int:
|
|
202
|
+
return a + b
|
|
203
|
+
|
|
204
|
+
server = expose_tools_stdio(
|
|
205
|
+
tools=[calculate],
|
|
206
|
+
server_name="Math Tools",
|
|
207
|
+
server_version="1.0.0"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
server.run()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 3) Skills system (load only relevant tools)
|
|
215
|
+
|
|
216
|
+
### Generate skills (CLI)
|
|
217
|
+
|
|
218
|
+
Skills are generated by discovering tools from your MCP servers and auto-categorizing them.
|
|
219
|
+
|
|
220
|
+
#### HTTP servers
|
|
221
|
+
Use the MCP base URL (include `/mcp`):
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
polymcp skills generate --servers "http://localhost:8000/mcp" --output ./mcp_skills --verbose
|
|
225
|
+
````
|
|
226
|
+
|
|
227
|
+
#### Stdio servers (Playwright, filesystem, etc.)
|
|
228
|
+
|
|
229
|
+
Enable stdio discovery:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
polymcp skills generate --stdio --servers "npx -y @playwright/mcp@latest" --output ./mcp_skills --verbose
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Then enable them in your agent:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
agent = UnifiedPolyAgent(
|
|
239
|
+
llm_provider=llm,
|
|
240
|
+
skills_enabled=True,
|
|
241
|
+
skills_dir="./mcp_skills",
|
|
242
|
+
mcp_servers=["http://localhost:8000/mcp"], # optional if using HTTP tools too
|
|
243
|
+
stdio_servers=[{"command":"npx","args":["-y","@playwright/mcp@latest"]}], # optional
|
|
244
|
+
)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
agent = UnifiedPolyAgent(
|
|
250
|
+
llm_provider=llm,
|
|
251
|
+
skills_dir="./skills",
|
|
252
|
+
mcp_servers=["http://localhost:8000/mcp"],
|
|
253
|
+
)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## TypeScript implementation (PolyMCP-TS)
|
|
259
|
+
|
|
260
|
+
PolyMCP also ships a TypeScript implementation for Node/TS ecosystems:
|
|
261
|
+
|
|
262
|
+
* schema validation (Zod)
|
|
263
|
+
* HTTP + stdio servers
|
|
264
|
+
* agent framework + tooling
|
|
265
|
+
|
|
266
|
+
📖 See: `polymcp-ts/README.md`
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Docs & Links
|
|
271
|
+
|
|
272
|
+
* GitHub: [https://github.com/llm-use/polymcp](https://github.com/poly-mcp/polymcp)
|
|
273
|
+
* PyPI: [https://pypi.org/project/polymcp/](https://pypi.org/project/polymcp/)
|
|
274
|
+
* Website: [https://www.poly-mcp.com](https://www.poly-mcp.com)
|
|
275
|
+
* Examples: `examples/`
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Star History
|
|
280
|
+
|
|
281
|
+
[](https://www.star-history.com/#llm-use/Polymcp&type=date&legend=top-left)
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
MIT
|