|
| 1 | +# MCP Run Python |
| 2 | + |
| 3 | +[Model Context Protocol](https://modelcontextprotocol.io/) server to run Python code in a sandbox. |
| 4 | + |
| 5 | +The code is executed using [Pyodide](https://pyodide.org) in [Deno](https://deno.com/) and is therefore isolated from |
| 6 | +the rest of the operating system. |
| 7 | + |
| 8 | +**See <https://ai.pydantic.dev/mcp/run-python/> for complete documentation.** |
| 9 | + |
| 10 | +The server can be run with `deno` installed using: |
| 11 | + |
| 12 | +```bash |
| 13 | +deno run \ |
| 14 | + -N -R=node_modules -W=node_modules --node-modules-dir=auto \ |
| 15 | + jsr:@pydantic/mcp-run-python [stdio|streamable_http|sse|warmup] |
| 16 | +``` |
| 17 | + |
| 18 | +where: |
| 19 | + |
| 20 | +- `-N -R=node_modules -W=node_modules` (alias of `--allow-net --allow-read=node_modules --allow-write=node_modules`) |
| 21 | + allows network access and read+write access to `./node_modules`. These are required so pyodide can download and cache |
| 22 | + the Python standard library and packages |
| 23 | +- `--node-modules-dir=auto` tells deno to use a local `node_modules` directory |
| 24 | +- `stdio` runs the server with the |
| 25 | + [Stdio MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) — suitable for |
| 26 | + running the process as a subprocess locally |
| 27 | +- `streamable_http` runs the server with the |
| 28 | + [Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) - |
| 29 | + suitable for running the server as an HTTP server to connect locally or remotely. This supports stateful requests, but |
| 30 | + does not require the client to hold a stateful connection like SSE |
| 31 | +- `sse` runs the server with the |
| 32 | + [SSE MCP transport](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse) — |
| 33 | + suitable for running the server as an HTTP server to connect locally or remotely. Note that the SSE transport has been |
| 34 | + [deprecated in newer MCP protocol versions](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#backwards-compatibility) |
| 35 | + and is there to maintain backwards compatibility. |
| 36 | +- `warmup` will run a minimal Python script to download and cache the Python standard library. This is also useful to |
| 37 | + check the server is running correctly. |
| 38 | + |
| 39 | +Here's an example of using `@pydantic/mcp-run-python` with Pydantic AI: |
| 40 | + |
| 41 | +```python |
| 42 | +from pydantic_ai import Agent |
| 43 | +from pydantic_ai.mcp import MCPServerStdio |
| 44 | + |
| 45 | +import logfire |
| 46 | + |
| 47 | +logfire.configure() |
| 48 | +logfire.instrument_mcp() |
| 49 | +logfire.instrument_pydantic_ai() |
| 50 | + |
| 51 | +server = MCPServerStdio('deno', |
| 52 | + args=[ |
| 53 | + 'run', |
| 54 | + '-N', |
| 55 | + '-R=node_modules', |
| 56 | + '-W=node_modules', |
| 57 | + '--node-modules-dir=auto', |
| 58 | + 'jsr:@pydantic/mcp-run-python', |
| 59 | + 'stdio', |
| 60 | + ]) |
| 61 | +agent = Agent('claude-3-5-haiku-latest', toolsets=[server]) |
| 62 | + |
| 63 | + |
| 64 | +async def main(): |
| 65 | + async with agent: |
| 66 | + result = await agent.run('How many days between 2000-01-01 and 2025-03-18?') |
| 67 | + print(result.output) |
| 68 | + #> There are 9,208 days between January 1, 2000, and March 18, 2025.w |
| 69 | + |
| 70 | +if __name__ == '__main__': |
| 71 | + import asyncio |
| 72 | + asyncio.run(main()) |
| 73 | +``` |
0 commit comments