mcp-python-exec-sandbox 0.1.0__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.
Files changed (41) hide show
  1. mcp_python_exec_sandbox-0.1.0/.devcontainer/Dockerfile +5 -0
  2. mcp_python_exec_sandbox-0.1.0/.devcontainer/devcontainer.json +12 -0
  3. mcp_python_exec_sandbox-0.1.0/.gitignore +7 -0
  4. mcp_python_exec_sandbox-0.1.0/CLAUDE.md +51 -0
  5. mcp_python_exec_sandbox-0.1.0/LICENSE +21 -0
  6. mcp_python_exec_sandbox-0.1.0/PKG-INFO +9 -0
  7. mcp_python_exec_sandbox-0.1.0/README.md +284 -0
  8. mcp_python_exec_sandbox-0.1.0/e2e_tests/__init__.py +0 -0
  9. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_data_science.py +559 -0
  10. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_docker_sandbox.py +227 -0
  11. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_mcp_protocol.py +245 -0
  12. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_package_install.py +74 -0
  13. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_real_execution.py +68 -0
  14. mcp_python_exec_sandbox-0.1.0/e2e_tests/test_sandbox_enforcement.py +88 -0
  15. mcp_python_exec_sandbox-0.1.0/profiles/Dockerfile +16 -0
  16. mcp_python_exec_sandbox-0.1.0/profiles/sandbox_macos.sb +39 -0
  17. mcp_python_exec_sandbox-0.1.0/profiles/warmup_packages.txt +18 -0
  18. mcp_python_exec_sandbox-0.1.0/pyproject.toml +24 -0
  19. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/__init__.py +3 -0
  20. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/__main__.py +77 -0
  21. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/cache.py +81 -0
  22. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/config.py +34 -0
  23. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/errors.py +21 -0
  24. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/executor.py +87 -0
  25. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/output.py +46 -0
  26. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/sandbox.py +99 -0
  27. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/sandbox_docker.py +60 -0
  28. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/sandbox_linux.py +58 -0
  29. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/sandbox_macos.py +93 -0
  30. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/script.py +114 -0
  31. mcp_python_exec_sandbox-0.1.0/src/mcp_python_exec_sandbox/server.py +234 -0
  32. mcp_python_exec_sandbox-0.1.0/tests/__init__.py +0 -0
  33. mcp_python_exec_sandbox-0.1.0/tests/conftest.py +15 -0
  34. mcp_python_exec_sandbox-0.1.0/tests/test_config.py +81 -0
  35. mcp_python_exec_sandbox-0.1.0/tests/test_executor.py +131 -0
  36. mcp_python_exec_sandbox-0.1.0/tests/test_integration.py +137 -0
  37. mcp_python_exec_sandbox-0.1.0/tests/test_output.py +77 -0
  38. mcp_python_exec_sandbox-0.1.0/tests/test_sandbox.py +113 -0
  39. mcp_python_exec_sandbox-0.1.0/tests/test_script.py +171 -0
  40. mcp_python_exec_sandbox-0.1.0/tests/test_server.py +24 -0
  41. mcp_python_exec_sandbox-0.1.0/uv.lock +1393 -0
@@ -0,0 +1,5 @@
1
+ FROM ubuntu:24.04
2
+ RUN apt-get update && apt-get install -y --no-install-recommends \
3
+ bubblewrap ca-certificates curl && \
4
+ rm -rf /var/lib/apt/lists/*
5
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "mcp-python-exec-sandbox-dev",
3
+ "build": {
4
+ "dockerfile": "Dockerfile"
5
+ },
6
+ "postCreateCommand": "uv sync --dev",
7
+ "customizations": {
8
+ "vscode": {
9
+ "extensions": ["ms-python.python"]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ .pytest_cache/
@@ -0,0 +1,51 @@
1
+ # CLAUDE.md
2
+
3
+ ## Project
4
+
5
+ MCP server for sandboxed Python execution. Scripts run in ephemeral, isolated environments with inline dependencies (PEP 723) via `uv`. Zero host pollution.
6
+
7
+ ## Stack
8
+
9
+ - Python 3.13+, no runtime deps beyond `fastmcp` and `tomli-w`
10
+ - `uv` for script execution, dependency resolution, and Python version management
11
+ - `hatchling` build backend, `src/` layout
12
+
13
+ ## Structure
14
+
15
+ ```
16
+ src/mcp_python_exec_sandbox/ # Package source
17
+ server.py # FastMCP server + tool definitions
18
+ executor.py # uv subprocess orchestration
19
+ script.py # PEP 723 metadata parsing/merging
20
+ sandbox.py # Sandbox ABC + factory
21
+ sandbox_{linux,macos,docker}.py
22
+ config.py, cache.py, output.py, errors.py
23
+ tests/ # Unit + integration tests (mocked or local uv)
24
+ e2e_tests/ # End-to-end tests (require uv + network)
25
+ profiles/ # Dockerfile, macOS seatbelt profile, warmup packages
26
+ ```
27
+
28
+ ## Commands
29
+
30
+ ```bash
31
+ uv sync --dev # Install deps
32
+ uv run pytest tests/ -v # Unit + integration tests
33
+ uv run pytest e2e_tests/ -v # E2E tests (slow, needs network)
34
+ ```
35
+
36
+ ## Rules
37
+
38
+ - Run `uv run pytest tests/ -v` before committing. All tests must pass.
39
+ - Keep dependencies minimal. Do not add runtime deps without strong justification.
40
+ - No type checkers or linters are configured. Keep code straightforward and readable.
41
+ - Tool docstrings in `server.py` are user-facing — they become the MCP tool descriptions that agents see. Write them for an LLM audience: include examples, avoid unexplained jargon, link PEPs.
42
+ - Always pin versions in examples (e.g. `"pandas>=2.2"` not `"pandas"`).
43
+ - Sandbox backends must degrade gracefully: if the tool (bwrap, sandbox-exec, docker) is missing, fall back to `NoopSandbox` with a warning.
44
+
45
+ ## Contribution format
46
+
47
+ - One logical change per commit. Descriptive commit message (imperative mood).
48
+ - Keep PRs focused. Separate refactors from feature work.
49
+ - Add tests for new functionality: unit tests in `tests/`, E2E in `e2e_tests/` if it needs real execution.
50
+ - Update tool docstrings in `server.py` if changing tool behavior.
51
+ - Update `README.md` if changing user-facing config or adding features.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 mcp-python-executor contributors
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.
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-python-exec-sandbox
3
+ Version: 0.1.0
4
+ Summary: MCP server for secure Python script execution with automatic dependency management
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.13
8
+ Requires-Dist: fastmcp<3,>=2.0
9
+ Requires-Dist: tomli-w>=1.0
@@ -0,0 +1,284 @@
1
+ # mcp-python-exec-sandbox
2
+
3
+ Sandboxed Python execution for AI agents. Scripts run in ephemeral, isolated environments with inline dependencies ([PEP 723](https://peps.python.org/pep-0723/)) -- **zero host pollution, zero leftover venvs, zero package conflicts**.
4
+
5
+ ## Why?
6
+
7
+ Every coding agent can already run Python on your host. The problem is what happens next: packages accumulate, venvs sprawl, and a rogue `pip install` breaks your system. **mcp-python-exec-sandbox** eliminates this:
8
+
9
+ - Scripts execute in a sandbox (bubblewrap on Linux, sandbox-exec on macOS, Docker everywhere)
10
+ - Dependencies are declared inline and resolved ephemerally via `uv`
11
+ - Nothing touches your host's Python, site-packages, or virtualenvs
12
+ - Each execution is isolated and disposable
13
+
14
+ ## Features
15
+
16
+ - **Sandboxed execution** -- platform-specific isolation prevents host filesystem access
17
+ - **PEP 723 inline metadata** -- declare dependencies directly in scripts with `# /// script` blocks
18
+ - **Multi-version Python** -- run scripts on Python 3.13, 3.14, or 3.15 (uv downloads the right version automatically)
19
+ - **Ephemeral environments** -- dependencies are resolved per-execution, never persisted
20
+ - **Package caching** -- uv's global cache makes repeat installs near-instant
21
+ - **Timeout enforcement** -- configurable per-execution timeouts
22
+ - **Output truncation** -- prevents runaway output from overwhelming the agent
23
+
24
+ ## Prerequisites
25
+
26
+ All setups require:
27
+
28
+ - **Python 3.13+** -- to run the MCP server process
29
+ - **[uv](https://docs.astral.sh/uv/getting-started/installation/)** -- manages script execution, dependency resolution, and Python version downloads. Also provides `uvx` for running the server without installing it globally.
30
+
31
+ Additional requirements depend on your chosen sandbox backend:
32
+
33
+ | Setup | Additional requirements | Install |
34
+ |-------|------------------------|---------|
35
+ | **Native sandbox (Linux)** | [bubblewrap](https://github.com/containers/bubblewrap) | `sudo apt install bubblewrap` |
36
+ | **Native sandbox (macOS)** | None -- `sandbox-exec` is built into macOS | -- |
37
+ | **Docker sandbox** | [Docker Engine](https://docs.docker.com/engine/install/) | See Docker docs |
38
+ | **No sandbox** | None | -- |
39
+
40
+ > **Host Python vs. execution Python:** These are independent. Python 3.13+ is needed to run the server process itself. The `--python-version` flag controls which Python version your *scripts* execute on -- uv downloads the target version automatically. You do not need to install Python 3.14 or 3.15 on your host to run scripts on those versions.
41
+
42
+ ## Quick start
43
+
44
+ ### Claude Code (native sandbox -- recommended)
45
+
46
+ ```bash
47
+ claude mcp add python-sandbox -- uvx mcp-python-exec-sandbox --sandbox-backend native
48
+ ```
49
+
50
+ ### Claude Code (Docker sandbox)
51
+
52
+ ```bash
53
+ docker build -t mcp-python-exec-sandbox profiles/
54
+ claude mcp add python-sandbox -- uvx mcp-python-exec-sandbox --sandbox-backend docker
55
+ ```
56
+
57
+ > The Docker image build requires the repo source. Clone it first: `git clone https://github.com/lu-zhengda/mcp-python-exec-sandbox.git`
58
+
59
+ ### Claude Code (no sandbox)
60
+
61
+ ```bash
62
+ claude mcp add python-sandbox -- uvx mcp-python-exec-sandbox --sandbox-backend none
63
+ ```
64
+
65
+ ### Manual JSON config
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "python-sandbox": {
71
+ "command": "uvx",
72
+ "args": ["mcp-python-exec-sandbox", "--sandbox-backend", "native"]
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## Multi-version Python
79
+
80
+ Use `--python-version` to target a specific Python version. uv downloads it automatically -- no manual install needed.
81
+
82
+ ```bash
83
+ # Python 3.13 (default)
84
+ uvx mcp-python-exec-sandbox --python-version 3.13
85
+
86
+ # Python 3.14
87
+ uvx mcp-python-exec-sandbox --python-version 3.14
88
+
89
+ # Python 3.15
90
+ uvx mcp-python-exec-sandbox --python-version 3.15
91
+ ```
92
+
93
+ This works across all sandbox backends. The Docker sandbox uses uv inside the container to manage Python versions, so the same `--python-version` flag applies.
94
+
95
+ ## Tools
96
+
97
+ ### `execute_python`
98
+
99
+ Execute a Python script with automatic dependency management.
100
+
101
+ | Parameter | Type | Default | Description |
102
+ |-----------|------|---------|-------------|
103
+ | `script` | str | required | Python source code, may include PEP 723 inline metadata |
104
+ | `dependencies` | list[str] | `[]` | Extra PEP 508 dependency specifiers to merge |
105
+ | `timeout_seconds` | int | 30 | Maximum execution time (1--300) |
106
+
107
+ ```python
108
+ # Simple script
109
+ execute_python(script="print('hello world')")
110
+
111
+ # Script with dependencies
112
+ execute_python(
113
+ script="import requests; print(requests.get('https://httpbin.org/get').status_code)",
114
+ dependencies=["requests"]
115
+ )
116
+
117
+ # Script with inline PEP 723 metadata
118
+ execute_python(script="""
119
+ # /// script
120
+ # dependencies = ["pandas", "matplotlib"]
121
+ # ///
122
+
123
+ import pandas as pd
124
+ print(pd.DataFrame({'a': [1,2,3]}).describe())
125
+ """)
126
+ ```
127
+
128
+ ### `check_environment`
129
+
130
+ Returns information about the execution environment: Python version, uv version, platform, sandbox status, and configuration.
131
+
132
+ ### `validate_script`
133
+
134
+ Validates a script's PEP 723 metadata and dependencies without executing it.
135
+
136
+ | Parameter | Type | Default | Description |
137
+ |-----------|------|---------|-------------|
138
+ | `script` | str | required | Python source code to validate |
139
+ | `dependencies` | list[str] | `[]` | Extra dependency specifiers to validate |
140
+
141
+ ## Sandbox backends
142
+
143
+ | Backend | Platform | Tool | Notes |
144
+ |---------|----------|------|-------|
145
+ | `native` | Linux | bubblewrap | Namespace isolation, network allowed |
146
+ | `native` | macOS | sandbox-exec | Seatbelt profiles, network allowed |
147
+ | `docker` | Any | Docker | Container isolation, resource limits |
148
+ | `none` | Any | -- | No sandboxing (not recommended) |
149
+
150
+ If the requested sandbox tool is unavailable, the server falls back to `none` with a warning.
151
+
152
+ ### Docker sandbox setup
153
+
154
+ ```bash
155
+ docker build -t mcp-python-exec-sandbox profiles/
156
+ ```
157
+
158
+ ## CLI options
159
+
160
+ ```
161
+ mcp-python-exec-sandbox [OPTIONS]
162
+
163
+ Options:
164
+ --python-version TEXT Python version for execution (default: 3.13)
165
+ --sandbox-backend TEXT native | docker | none (default: native)
166
+ --max-timeout INT Maximum allowed timeout in seconds (default: 300)
167
+ --default-timeout INT Default timeout in seconds (default: 30)
168
+ --max-output-bytes INT Maximum output size in bytes (default: 102400)
169
+ --no-warm-cache Skip cache warming on startup
170
+ --uv-path TEXT Path to uv binary (default: uv)
171
+ ```
172
+
173
+ ## Development
174
+
175
+ ### Setup
176
+
177
+ ```bash
178
+ git clone https://github.com/lu-zhengda/mcp-python-exec-sandbox.git
179
+ cd mcp-python-exec-sandbox
180
+ uv sync --dev
181
+ ```
182
+
183
+ ### Project structure
184
+
185
+ ```
186
+ src/mcp_python_exec_sandbox/ # Package source
187
+ server.py # FastMCP server + tool definitions
188
+ executor.py # uv subprocess orchestration
189
+ script.py # PEP 723 metadata parsing/merging
190
+ sandbox.py # Sandbox ABC + factory
191
+ sandbox_{linux,macos,docker}.py
192
+ config.py, cache.py, output.py, errors.py
193
+ tests/ # Unit + integration tests (mocked or local uv)
194
+ e2e_tests/ # End-to-end tests (require uv + network)
195
+ profiles/ # Dockerfile, macOS seatbelt profile, warmup packages
196
+ .devcontainer/ # Devcontainer for Linux sandbox testing from macOS
197
+ ```
198
+
199
+ ### Running tests
200
+
201
+ **Unit and integration tests** -- fast, run everywhere:
202
+
203
+ ```bash
204
+ uv run pytest tests/ -v
205
+ ```
206
+
207
+ **E2E tests** -- require `uv` and network access. These exercise real script execution, package installation, MCP protocol flow, and sandbox enforcement:
208
+
209
+ ```bash
210
+ uv run pytest e2e_tests/ -v
211
+ ```
212
+
213
+ ### Docker sandbox tests
214
+
215
+ The Docker E2E tests (`e2e_tests/test_docker_sandbox.py`) verify execution, dependency installation, read-only filesystem enforcement, host isolation, and timeout handling through the Docker backend.
216
+
217
+ Prerequisites:
218
+
219
+ 1. Docker must be installed and running
220
+ 2. Build the sandbox image:
221
+
222
+ ```bash
223
+ docker build -t mcp-python-exec-sandbox profiles/
224
+ ```
225
+
226
+ Then run:
227
+
228
+ ```bash
229
+ uv run pytest e2e_tests/test_docker_sandbox.py -v
230
+ ```
231
+
232
+ These tests are automatically skipped if Docker is unavailable or the image hasn't been built.
233
+
234
+ ### Linux sandbox tests (devcontainer)
235
+
236
+ The Linux sandbox tests (`e2e_tests/test_sandbox_enforcement.py::test_linux_sandbox_blocks_etc_shadow`) use bubblewrap (`bwrap`) for namespace isolation. They are skipped on macOS because `bwrap` is Linux-only.
237
+
238
+ To run them from macOS, use the included devcontainer which provides Ubuntu 24.04 with `bwrap` pre-installed:
239
+
240
+ **VS Code:**
241
+
242
+ 1. Install the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
243
+ 2. Open the project and select **Reopen in Container**
244
+ 3. In the integrated terminal:
245
+
246
+ ```bash
247
+ uv run pytest e2e_tests/test_sandbox_enforcement.py -v
248
+ ```
249
+
250
+ **CLI:**
251
+
252
+ ```bash
253
+ # Install the devcontainer CLI (once)
254
+ npm install -g @devcontainers/cli
255
+
256
+ # Build and start the container
257
+ devcontainer up --workspace-folder .
258
+
259
+ # Run the Linux sandbox tests inside the container
260
+ devcontainer exec --workspace-folder . uv run pytest e2e_tests/test_sandbox_enforcement.py -v
261
+ ```
262
+
263
+ ### Test matrix
264
+
265
+ | Test suite | Command | Requirements |
266
+ |------------|---------|-------------|
267
+ | Unit tests | `uv run pytest tests/ -v` | `uv` |
268
+ | Integration tests | `uv run pytest tests/test_integration.py -v` | `uv` |
269
+ | E2E (general) | `uv run pytest e2e_tests/ -v` | `uv`, network |
270
+ | E2E (Docker sandbox) | `uv run pytest e2e_tests/test_docker_sandbox.py -v` | `uv`, Docker, sandbox image |
271
+ | E2E (Linux/bwrap sandbox) | `uv run pytest e2e_tests/test_sandbox_enforcement.py -v` | `uv`, Linux with `bwrap` (or devcontainer) |
272
+
273
+ ### Contributing
274
+
275
+ - One logical change per commit. Descriptive commit message (imperative mood).
276
+ - Run `uv run pytest tests/ -v` before committing -- all tests must pass.
277
+ - Add tests for new functionality: unit tests in `tests/`, E2E in `e2e_tests/` if it needs real execution.
278
+ - Keep dependencies minimal. Do not add runtime deps without strong justification.
279
+ - Tool docstrings in `server.py` are user-facing MCP tool descriptions. Write them for an LLM audience.
280
+ - Sandbox backends must degrade gracefully: if the tool is missing, fall back to `NoopSandbox` with a warning.
281
+
282
+ ## License
283
+
284
+ MIT
File without changes