loading…
Search for a command to run...
loading…
Executes Python code snippets safely without shell interpretation, supports parallel batch execution and helper utilities for task decomposition.
Executes Python code snippets safely without shell interpretation, supports parallel batch execution and helper utilities for task decomposition.
MCP Server Python License: MIT CI
Execute Python code snippets with shell-quoting-free execution via temporary files.
Features:
chunk_by_count(), suggest_batch_size() for task decompositionmcp required, uses stdlib for executionEver been frustrated when your AI agent tries to execute a simple one-liner and gets lost in shell quoting hell?
# Agent tries to run this:
print("Hello 'world' with \"quotes\" and $variables")
# Shell interprets quotes, variables, escapes...
# Result: SyntaxError, FileNotFoundError, or worse - unexpected behavior
This server solves the problem by:
Bonus: Batch execution lets you run 20 independent tasks in parallel instead of sequentially.
# Clone the repository
git clone https://github.com/neco001/py-executor.git
cd py-executor
# Install dependencies with uv
uv sync
# Run the server
uv run python server.py
Add to your MCP client configuration:
{
"mcpServers": {
"py-executor": {
"command": "uv",
"args": [
"--directory",
"/path/to/py-executor",
"run",
"python",
"server.py"
]
}
}
}
{
"mcpServers": {
"py-executor": {
"command": "python",
"args": ["/path/to/py-executor/server.py"]
}
}
}
run_python - Single ExecutionExecute a single Python code snippet. Use for stateful/dependent operations.
Parameters:
code: Python code to execute (max 1MB)timeout: Execution timeout in seconds (default 30, max 60)cwd: Optional working directory - uses local .venv if foundWhen to use:
Examples:
# Simple calculation
code = "result = 2 + 2\nprint(f'Result: {result}')"
# Data analysis on single dataset
code = "import pandas as pd\ndf = pd.DataFrame({'a': [1,2,3]})\nprint(df.sum())"
# File processing (single file)
code = "with open('data.txt', 'r') as f:\n content = f.read()\n print(len(content))"
run_python_batch - Parallel ExecutionExecute multiple Python code snippets in parallel (max 4 workers, max 20 snippets).
Parameters:
codes: List of Python code strings to execute (max 20, each max 1MB)timeout: Timeout per snippet in seconds (default 30, max 60)max_workers: Maximum parallel workers (default 4, hard capped at 4)cwd: Optional working directory - uses local .venv if foundWhen to use:
When NOT to use:
Examples:
# Processing multiple files independently
codes = [
"with open('file1.txt', 'r') as f: print(len(f.read()))",
"with open('file2.txt', 'r') as f: print(len(f.read()))",
"with open('file3.txt', 'r') as f: print(len(f.read()))"
]
run_python_batch(codes)
# Parallel data analysis on separate datasets
codes = [
"import pandas as pd; df = pd.read_csv('data1.csv'); print(df.shape)",
"import pandas as pd; df = pd.read_csv('data2.csv'); print(df.shape)",
"import pandas as pd; df = pd.read_csv('data3.csv'); print(df.shape)"
]
run_python_batch(codes)
# Independent calculations
codes = [
"result = sum(range(1000)); print(result)",
"import math; result = math.factorial(10); print(result)",
"import random; result = [random.randint(1, 100) for _ in range(5)]; print(result)"
]
run_python_batch(codes)
Internal functions to help agents split large tasks into batch-friendly chunks.
chunk_by_count(items: list, n: int) -> list[list]Split a list into n approximately equal-sized chunks.
files = ['file1.py', 'file2.py', 'file3.py', 'file4.py']
chunks = chunk_by_count(files, 2)
# Result: [['file1.py', 'file2.py'], ['file3.py', 'file4.py']]
# Use with run_python_batch:
chunks = chunk_by_count(files, 4)
codes = [f"process_files({chunk})" for chunk in chunks]
run_python_batch(codes)
chunk_by_size(code: str, max_bytes: int = 500000) -> list[str]Split a large code string into smaller chunks based on byte size.
large_code = "process_data('file1')\nprocess_data('file2')\n..."
chunks = chunk_by_size(large_code, 500000) # 500KB per chunk
run_python_batch(chunks)
suggest_batch_size(total_items: int, complexity: str = "medium") -> intSuggest an optimal batch size based on total items and task complexity.
files = list_of_100_files
workers = suggest_batch_size(len(files), "low") # Returns 4 for simple tasks
workers = suggest_batch_size(len(files), "high") # Returns 2 for heavy tasks
chunks = chunk_by_count(files, workers)
codes = [f"analyze_files({chunk})" for chunk in chunks]
run_python_batch(codes, max_workers=workers)
Complexity levels:
"low": Simple operations (e.g., file size checks) → max 4 workers"medium": Moderate operations (e.g., data parsing) → 3 workers"high": Heavy operations (e.g., ML inference) → 2 workers| Parameter | Limit |
|---|---|
| Max workers | 4 (hard cap) |
| Max batch size | 20 snippets |
| Max code size | 1MB per snippet |
| Max timeout | 60 seconds per snippet |
run_python_batch(codes: list[str])
└── ProcessPoolExecutor(max_workers=4)
├── Worker 1: _execute_single_snippet(0, code, timeout, cwd)
├── Worker 2: _execute_single_snippet(1, code, timeout, cwd)
├── Worker 3: _execute_single_snippet(2, code, timeout, cwd)
└── Worker 4: _execute_single_snippet(3, code, timeout, cwd)
└── UUID temp file → subprocess.run → cleanup
└── Results collected by index → ordered JSON response
Run in your terminal:
claude mcp add python-executor-mcp-server -- npx Security
Low riskAutomated heuristic from public metadata — not a security guarantee.