| Name | mcp-run-python JSON |
| Version |
0.0.21
JSON |
| download |
| home_page | None |
| Summary | Model Context Protocol server to run Python code in a sandbox. |
| upload_time | 2025-09-04 02:02:46 |
| maintainer | None |
| docs_url | None |
| author | Samuel Colvin |
| requires_python | >=3.10 |
| license | None |
| keywords |
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
<div align="center">
<h1>MCP Run Python</h1>
</div>
<div align="center">
<a href="https://github.com/pydantic/mcp-run-python/actions/workflows/ci.yml?query=branch%3Amain"><img src="https://github.com/pydantic/mcp-run-python/actions/workflows/ci.yml/badge.svg?event=push" alt="CI"></a>
<a href="https://pypi.python.org/pypi/mcp-run-python"><img src="https://img.shields.io/pypi/v/mcp-run-python.svg" alt="PyPI"></a>
<a href="https://github.com/pydantic/mcp-run-python"><img src="https://img.shields.io/pypi/pyversions/mcp-run-python.svg" alt="versions"></a>
<a href="https://github.com/pydantic/mcp-run-python/blob/main/LICENSE"><img src="https://img.shields.io/github/license/pydantic/mcp-run-python.svg" alt="license"></a>
<a href="https://logfire.pydantic.dev/docs/join-slack/"><img src="https://img.shields.io/badge/Slack-Join%20Slack-4A154B?logo=slack" alt="Join Slack" /></a>
</div>
<br/>
<div align="center">
MCP server to run Python code in a sandbox.
</div>
<br/>
Code is executed using [Pyodide](https://pyodide.org) in [Deno](https://deno.com/) and is therefore isolated from
the rest of the operating system.
## Features
- **Secure Execution**: Run Python code in a sandboxed WebAssembly environment
- **Package Management**: Automatically detects and installs required dependencies
- **Complete Results**: Captures standard output, standard error, and return values
- **Asynchronous Support**: Runs async code properly
- **Error Handling**: Provides detailed error reports for debugging
_(This code was previously part of [Pydantic AI](https://github.com/pydantic/pydantic-ai) but was moved to a separate repo to make it easier to maintain.)_
## Usage
To use this server, you must have both Python and [Deno](https://deno.com/) installed.
The server can be run with `deno` installed using `uvx`:
```bash
uvx mcp-run-python [-h] [--version] [--port PORT] [--deps DEPS] {stdio,streamable-http,example}
```
where:
- `stdio` runs the server with the
[Stdio MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) — suitable for
running the process as a subprocess locally
- `streamable-http` runs the server with the
[Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) -
suitable for running the server as an HTTP server to connect locally or remotely. This supports stateful requests, but
does not require the client to hold a stateful connection like SSE
- `example` will run a minimal Python script using `numpy`, useful for checking that the package is working, for the code
to run successfully, you'll need to install `numpy` using `uvx mcp-run-python --deps numpy example`
## Usage with Pydantic AI
Then you can use `mcp-run-python` with Pydantic AI:
```python
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio
from mcp_run_python import deno_args_prepare
import logfire
logfire.configure()
logfire.instrument_mcp()
logfire.instrument_pydantic_ai()
server = MCPServerStdio('uvx', args=['mcp-run-python@latest', 'stdio'], timeout=10)
agent = Agent('claude-3-5-haiku-latest', toolsets=[server])
async def main():
async with agent:
result = await agent.run('How many days between 2000-01-01 and 2025-03-18?')
print(result.output)
#> There are 9,208 days between January 1, 2000, and March 18, 2025.w
if __name__ == '__main__':
import asyncio
asyncio.run(main())
```
## Usage in codes as an MCP server
First install the `mcp-run-python` package:
```bash
pip install mcp-run-python
# or
uv add mcp-run-python
```
With `mcp-run-python` installed, you can also run deno directly with `prepare_deno_env` or `async_prepare_deno_env`
```python
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio
from mcp_run_python import async_prepare_deno_env
import logfire
logfire.configure()
logfire.instrument_mcp()
logfire.instrument_pydantic_ai()
async def main():
async with async_prepare_deno_env('stdio') as deno_env:
server = MCPServerStdio('deno', args=deno_env.args, cwd=deno_env.cwd, timeout=10)
agent = Agent('claude-3-5-haiku-latest', toolsets=[server])
async with agent:
result = await agent.run('How many days between 2000-01-01 and 2025-03-18?')
print(result.output)
#> There are 9,208 days between January 1, 2000, and March 18, 2025.w
if __name__ == '__main__':
import asyncio
asyncio.run(main())
```
**Note**: `prepare_deno_env` can take `deps` as a keyword argument to install dependencies.
As well as returning the args needed to run `mcp_run_python`, `prepare_deno_env` creates a new deno environment
and installs the dependencies so they can be used by the server.
## Usage in code with `code_sandbox`
`mcp-run-python` includes a helper function `code_sandbox` to allow you to easily run code in a sandbox.
```py
from mcp_run_python import code_sandbox
code = """
import numpy
a = numpy.array([1, 2, 3])
print(a)
a
"""
async def main():
async with code_sandbox(dependencies=['numpy']) as sandbox:
result = await sandbox.eval(code)
print(result)
if __name__ == '__main__':
import asyncio
asyncio.run(main())
```
Under the hood, `code_sandbox` runs an MCP server using `stdio`. You can run multiple code blocks with a single sandbox.
## Logging
MCP Run Python supports emitting stdout and stderr from the python execution as [MCP logging messages](https://github.com/modelcontextprotocol/specification/blob/eb4abdf2bb91e0d5afd94510741eadd416982350/docs/specification/draft/server/utilities/logging.md?plain=1).
For logs to be emitted you must set the logging level when connecting to the server. By default, the log level is set to the highest level, `emergency`.
## Dependencies
`mcp_run_python` uses a two step process to install dependencies while avoiding any risk that sandboxed code can
edit the filesystem.
* `deno` is first run with write permissions to the `node_modules` directory and dependencies are installed, causing wheels to be written to ``
* `deno` is then run with read-only permissions to the `node_modules` directory to run untrusted code.
Dependencies must be provided when initializing the server so they can be installed in the first step.
Raw data
{
"_id": null,
"home_page": null,
"name": "mcp-run-python",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": null,
"author": "Samuel Colvin",
"author_email": "Samuel Colvin <samuel@pydantic.dev>",
"download_url": "https://files.pythonhosted.org/packages/66/e0/dba9a1fdb5e5173ee29fb6cf55cdfbf03b45a43f7d8d6bd3c3d398031507/mcp_run_python-0.0.21.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n <h1>MCP Run Python</h1>\n</div>\n<div align=\"center\">\n <a href=\"https://github.com/pydantic/mcp-run-python/actions/workflows/ci.yml?query=branch%3Amain\"><img src=\"https://github.com/pydantic/mcp-run-python/actions/workflows/ci.yml/badge.svg?event=push\" alt=\"CI\"></a>\n <a href=\"https://pypi.python.org/pypi/mcp-run-python\"><img src=\"https://img.shields.io/pypi/v/mcp-run-python.svg\" alt=\"PyPI\"></a>\n <a href=\"https://github.com/pydantic/mcp-run-python\"><img src=\"https://img.shields.io/pypi/pyversions/mcp-run-python.svg\" alt=\"versions\"></a>\n <a href=\"https://github.com/pydantic/mcp-run-python/blob/main/LICENSE\"><img src=\"https://img.shields.io/github/license/pydantic/mcp-run-python.svg\" alt=\"license\"></a>\n <a href=\"https://logfire.pydantic.dev/docs/join-slack/\"><img src=\"https://img.shields.io/badge/Slack-Join%20Slack-4A154B?logo=slack\" alt=\"Join Slack\" /></a>\n</div>\n<br/>\n<div align=\"center\">\n MCP server to run Python code in a sandbox.\n</div>\n<br/>\n\nCode is executed using [Pyodide](https://pyodide.org) in [Deno](https://deno.com/) and is therefore isolated from\nthe rest of the operating system.\n\n## Features\n\n- **Secure Execution**: Run Python code in a sandboxed WebAssembly environment\n- **Package Management**: Automatically detects and installs required dependencies\n- **Complete Results**: Captures standard output, standard error, and return values\n- **Asynchronous Support**: Runs async code properly\n- **Error Handling**: Provides detailed error reports for debugging\n\n_(This code was previously part of [Pydantic AI](https://github.com/pydantic/pydantic-ai) but was moved to a separate repo to make it easier to maintain.)_\n\n## Usage\n\nTo use this server, you must have both Python and [Deno](https://deno.com/) installed.\n\nThe server can be run with `deno` installed using `uvx`:\n\n```bash\nuvx mcp-run-python [-h] [--version] [--port PORT] [--deps DEPS] {stdio,streamable-http,example}\n```\n\nwhere:\n\n- `stdio` runs the server with the\n [Stdio MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) \u2014 suitable for\n running the process as a subprocess locally\n- `streamable-http` runs the server with the\n [Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) -\n suitable for running the server as an HTTP server to connect locally or remotely. This supports stateful requests, but\n does not require the client to hold a stateful connection like SSE\n- `example` will run a minimal Python script using `numpy`, useful for checking that the package is working, for the code\n to run successfully, you'll need to install `numpy` using `uvx mcp-run-python --deps numpy example`\n\n## Usage with Pydantic AI\n\nThen you can use `mcp-run-python` with Pydantic AI:\n\n```python\nfrom pydantic_ai import Agent\nfrom pydantic_ai.mcp import MCPServerStdio\nfrom mcp_run_python import deno_args_prepare\n\nimport logfire\n\nlogfire.configure()\nlogfire.instrument_mcp()\nlogfire.instrument_pydantic_ai()\n\nserver = MCPServerStdio('uvx', args=['mcp-run-python@latest', 'stdio'], timeout=10)\nagent = Agent('claude-3-5-haiku-latest', toolsets=[server])\n\n\nasync def main():\n async with agent:\n result = await agent.run('How many days between 2000-01-01 and 2025-03-18?')\n print(result.output)\n #> There are 9,208 days between January 1, 2000, and March 18, 2025.w\n\nif __name__ == '__main__':\n import asyncio\n asyncio.run(main())\n```\n\n## Usage in codes as an MCP server\n\nFirst install the `mcp-run-python` package:\n\n```bash\npip install mcp-run-python\n# or\nuv add mcp-run-python\n```\n\nWith `mcp-run-python` installed, you can also run deno directly with `prepare_deno_env` or `async_prepare_deno_env`\n\n\n```python\nfrom pydantic_ai import Agent\nfrom pydantic_ai.mcp import MCPServerStdio\nfrom mcp_run_python import async_prepare_deno_env\n\nimport logfire\n\nlogfire.configure()\nlogfire.instrument_mcp()\nlogfire.instrument_pydantic_ai()\n\n\nasync def main():\n async with async_prepare_deno_env('stdio') as deno_env:\n server = MCPServerStdio('deno', args=deno_env.args, cwd=deno_env.cwd, timeout=10)\n agent = Agent('claude-3-5-haiku-latest', toolsets=[server])\n async with agent:\n result = await agent.run('How many days between 2000-01-01 and 2025-03-18?')\n print(result.output)\n #> There are 9,208 days between January 1, 2000, and March 18, 2025.w\n\nif __name__ == '__main__':\n import asyncio\n asyncio.run(main())\n```\n\n**Note**: `prepare_deno_env` can take `deps` as a keyword argument to install dependencies.\nAs well as returning the args needed to run `mcp_run_python`, `prepare_deno_env` creates a new deno environment\nand installs the dependencies so they can be used by the server.\n\n## Usage in code with `code_sandbox`\n\n`mcp-run-python` includes a helper function `code_sandbox` to allow you to easily run code in a sandbox.\n\n```py\nfrom mcp_run_python import code_sandbox\n\ncode = \"\"\"\nimport numpy\na = numpy.array([1, 2, 3])\nprint(a)\na\n\"\"\"\n\nasync def main():\n async with code_sandbox(dependencies=['numpy']) as sandbox:\n result = await sandbox.eval(code)\n print(result)\n\n\nif __name__ == '__main__':\n import asyncio\n\n asyncio.run(main())\n```\n\nUnder the hood, `code_sandbox` runs an MCP server using `stdio`. You can run multiple code blocks with a single sandbox.\n\n## Logging\n\nMCP Run Python supports emitting stdout and stderr from the python execution as [MCP logging messages](https://github.com/modelcontextprotocol/specification/blob/eb4abdf2bb91e0d5afd94510741eadd416982350/docs/specification/draft/server/utilities/logging.md?plain=1).\n\nFor logs to be emitted you must set the logging level when connecting to the server. By default, the log level is set to the highest level, `emergency`.\n\n## Dependencies\n\n`mcp_run_python` uses a two step process to install dependencies while avoiding any risk that sandboxed code can\nedit the filesystem.\n\n* `deno` is first run with write permissions to the `node_modules` directory and dependencies are installed, causing wheels to be written to ``\n* `deno` is then run with read-only permissions to the `node_modules` directory to run untrusted code.\n\nDependencies must be provided when initializing the server so they can be installed in the first step.\n",
"bugtrack_url": null,
"license": null,
"summary": "Model Context Protocol server to run Python code in a sandbox.",
"version": "0.0.21",
"project_urls": {
"Changelog": "https://github.com/pydantic/mcp-run-python/releases",
"Homepage": "https://github.com/pydantic/mcp-run-python",
"Source": "https://github.com/pydantic/mcp-run-python"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "0e3dfad699dcb312f91f6a7fc4509c74b0cba8ddd8e2b6f0fd75e8d4b1436d91",
"md5": "08615d5e070f72feb5add8955bb20675",
"sha256": "18b8bc4129e7b5be084904c5bbfb7fc7d1caae9f84fb2d84aa194180e732dc09"
},
"downloads": -1,
"filename": "mcp_run_python-0.0.21-py3-none-any.whl",
"has_sig": false,
"md5_digest": "08615d5e070f72feb5add8955bb20675",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 26103,
"upload_time": "2025-09-04T02:02:44",
"upload_time_iso_8601": "2025-09-04T02:02:44.961719Z",
"url": "https://files.pythonhosted.org/packages/0e/3d/fad699dcb312f91f6a7fc4509c74b0cba8ddd8e2b6f0fd75e8d4b1436d91/mcp_run_python-0.0.21-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "66e0dba9a1fdb5e5173ee29fb6cf55cdfbf03b45a43f7d8d6bd3c3d398031507",
"md5": "21bb3dc328a020b4149b81fc794111a2",
"sha256": "1ea77501b7bccb637192186adf7fc2048e21ee0c1c515de9e35c0c2f61916c04"
},
"downloads": -1,
"filename": "mcp_run_python-0.0.21.tar.gz",
"has_sig": false,
"md5_digest": "21bb3dc328a020b4149b81fc794111a2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 23296,
"upload_time": "2025-09-04T02:02:46",
"upload_time_iso_8601": "2025-09-04T02:02:46.120889Z",
"url": "https://files.pythonhosted.org/packages/66/e0/dba9a1fdb5e5173ee29fb6cf55cdfbf03b45a43f7d8d6bd3c3d398031507/mcp_run_python-0.0.21.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-04 02:02:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pydantic",
"github_project": "mcp-run-python",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "mcp-run-python"
}