Universal Python code execution MCP server - one tool to rule them all
Project description
MCP Code Mode ๐โก
Universal Python code execution MCP server - one tool to rule them all.
Inspired by Cloudflare's Code Mode: LLMs are better at writing code than making tool calls because they've trained on millions of real repositories.
Why Code Mode?
Traditional approach (many tools):
User: "Get weather for Austin and save to file"
LLM: [tool_call: get_weather(location="Austin")]
โ waits for response...
LLM: [tool_call: write_file(path="weather.txt", content=...)]
โ waits for response...
Code Mode approach (one tool):
User: "Get weather for Austin and save to file"
LLM: [run_python]
import requests
weather = requests.get("https://wttr.in/Austin?format=j1").json()
temp = weather['current_condition'][0]['temp_F']
with open("weather.txt", "w") as f:
f.write(f"Austin: {temp}ยฐF")
print(f"Saved! Temperature: {temp}ยฐF")
Benefits
| Traditional Tools | Code Mode |
|---|---|
| โ LLMs struggle with synthetic tool-call format | โ LLMs excel at writing real code |
| โ Each tool call = round trip to LLM | โ Complex workflows in one execution |
| โ Managing 20+ extensions | โ One universal tool |
| โ Token waste passing data between calls | โ Efficient data flow in code |
| โ Limited to pre-built capabilities | โ Anything Python can do |
Works With Any MCP Client
- โ Goose (Block's AI agent)
- โ Claude Desktop
- โ Cursor
- โ VS Code with Copilot
- โ Any MCP-compatible agent
Features
๐ Universal Execution
Write Python to accomplish any task - HTTP requests, file operations, data processing, web scraping, image manipulation, and more.
๐ฆ Auto-Install Dependencies
Missing a package? Code Mode detects ModuleNotFoundError, installs the package, and retries automatically.
๐ Streaming Output
See results in real-time! run_python_stream shows output line-by-line as your code executes. Perfect for long-running tasks, progress bars, and monitoring live operations.
๐ผ๏ธ Automatic File Display
Generated images, logs, or data files? Code Mode automatically detects and displays them in your MCP client! Supports:
- Images: PNG, JPG, GIF, SVG, etc. (displayed inline)
- Text Files: JSON, logs, source code, CSV, etc. (shown with syntax highlighting)
- Resources: PDFs, archives (available for download)
Just print the file path and Code Mode handles the rest!
๐ Code Analysis Before Execution
Every code execution is automatically analyzed for security and quality issues:
- Syntax validation - Catch errors before running
- Security scanning - Detect eval(), exec(), os.system(), shell injection
- Risk detection - Warn about file deletion, path traversal, hardcoded secrets
- Severity levels - Critical (blocks execution), Warning, Info
- Smart suggestions - Get safer alternatives for risky patterns
Analysis is automatic and configurable - see issues before they cause problems!
๐ Resource Usage Tracking (NEW!)
Monitor code execution performance in real-time:
- CPU usage - Track peak CPU utilization
- Memory consumption - Monitor RAM usage (current + peak)
- Thread count - See concurrent thread usage
- Automatic warnings - Get alerts when exceeding configurable thresholds
- Execution logs - All metrics saved for historical analysis
Perfect for optimizing code performance and detecting resource-heavy operations!
๐ง Learning System
Records error patterns and solutions. Future executions benefit from past learnings. Persists across sessions.
๐ Intelligent Retry
run_with_retry analyzes failures and suggests fixes based on error patterns and past learnings.
๐ณ Optional Docker Sandbox
Run code in isolated Docker containers for enhanced security.
โ๏ธ Configurable
Adjust timeouts, execution modes, package restrictions, and more.
Installation
From PyPI (when published)
# Using uv (recommended)
uv tool install mcp-pyrunner
# Using pip
pip install mcp-pyrunner
From Source
git clone https://github.com/anaseqal/codemode.git
cd codemode
uv sync
Configuration
Goose
If installed from PyPI:
Edit ~/.config/goose/config.yaml:
extensions:
codemode:
type: stdio
enabled: true
cmd: uvx
args: ["mcp-pyrunner"]
If running from source (local development):
extensions:
codemode:
type: stdio
enabled: true
cmd: uv
args: ["run", "--directory", "/path/to/codemode", "mcp-pyrunner"]
# Replace /path/to/codemode with actual path (e.g., ~/codemode)
Or use the UI: Extensions โ Add Custom Extension โ STDIO โ Command: uv run --directory /path/to/codemode mcp-pyrunner
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
If installed from PyPI:
{
"mcpServers": {
"codemode": {
"command": "uvx",
"args": ["mcp-pyrunner"]
}
}
}
If running from source:
{
"mcpServers": {
"codemode": {
"command": "uv",
"args": ["run", "--directory", "/path/to/codemode", "mcp-pyrunner"]
}
}
}
Cursor
Add to .cursor/mcp.json:
If installed from PyPI:
{
"mcpServers": {
"codemode": {
"command": "uvx",
"args": ["mcp-pyrunner"]
}
}
}
If running from source:
{
"mcpServers": {
"codemode": {
"command": "uv",
"args": ["run", "--directory", "/path/to/codemode", "mcp-pyrunner"]
}
}
}
Available Tools
| Tool | Description |
|---|---|
get_system_context |
Get environment info (OS, Python, pip versions, package managers, learnings) |
analyze_code_tool |
Analyze code for security/quality issues without executing |
run_python |
Execute Python code (auto-analyzes, auto-installs packages, auto-displays files) |
run_python_stream |
Execute with real-time streaming output (auto-analyzes, auto-displays files) |
run_with_retry |
Execute with intelligent retry and error analysis |
add_learning |
Record solutions for future reference |
get_learnings |
View/search past learnings |
pip_install |
Pre-install a specific package |
configure |
View/update settings |
Usage Examples
Code Analysis
User: "Analyze this code for security issues"
โ analyze_code_tool:
code = '''
import os
password = "hardcoded123"
os.system(f"rm {user_file}")
result = eval(user_input)
'''
# Result:
๐ CODE ANALYSIS REPORT
============================================================
๐จ CRITICAL ISSUES (2):
๐จ [CRITICAL] Dangerous operation 'os.system()' detected (line 4)
๐ก Suggestion: Use subprocess.run() instead for better security
๐จ [CRITICAL] Dangerous function 'eval()' detected (line 5)
๐ก Suggestion: Executes arbitrary code - use ast.literal_eval() for safe evaluation
โน๏ธ INFORMATION (1):
โน๏ธ [INFO] Potential hardcoded password
๐ก Suggestion: Use environment variables or secure vaults instead
============================================================
โ ๏ธ Code has security concerns - review before executing
# Analysis runs automatically on every execution!
# Configure strictness with:
# configure(action="set", key="code_analysis.block_on_critical", value="true")
Resource Tracking
User: "Calculate fibonacci numbers up to 1 million"
โ run_python:
def fibonacci(n):
a, b = 0, 1
result = []
while a < n:
result.append(a)
a, b = b, a + b
return result
fib = fibonacci(1000000)
print(f"Generated {len(fib)} Fibonacci numbers")
print(f"Largest: {fib[-1]:,}")
# Automatic resource tracking output:
๐ RESOURCE USAGE:
โ CPU: 45.2%
โ Memory: 12.4MB (peak: 15.8MB)
โ Threads: 1
โ Time: 0.15s
# If resources exceed thresholds:
โ ๏ธ RESOURCE WARNINGS:
โข High CPU usage: 92.3% (threshold: 90%)
โข High memory usage: 520MB (threshold: 500MB)
# Configure thresholds:
# configure(action="set", key="resource_tracking.warn_cpu_percent", value="80")
# configure(action="set", key="resource_tracking.warn_memory_mb", value="1000")
Web Scraping
User: "Scrape the top 10 posts from Hacker News"
โ run_python:
import requests
from bs4 import BeautifulSoup
resp = requests.get("https://news.ycombinator.com")
soup = BeautifulSoup(resp.text, "html.parser")
for i, item in enumerate(soup.select(".titleline > a")[:10], 1):
print(f"{i}. {item.text}")
print(f" {item['href']}\n")
Data Processing
User: "Analyze sales.csv and show monthly totals"
โ run_python:
import pandas as pd
df = pd.read_csv("sales.csv")
df["date"] = pd.to_datetime(df["date"])
monthly = df.groupby(df["date"].dt.to_period("M"))["amount"].sum()
print("Monthly Sales:")
for period, total in monthly.items():
print(f" {period}: ${total:,.2f}")
API Integration
User: "Get the current Bitcoin price in USD"
โ run_python:
import requests
data = requests.get("https://api.coinbase.com/v2/prices/BTC-USD/spot").json()
price = float(data["data"]["amount"])
print(f"Bitcoin: ${price:,.2f} USD")
Image Processing
User: "Resize all images in ./photos to 800x600"
โ run_python:
from pathlib import Path
from PIL import Image
photos = Path("./photos")
for img_path in photos.glob("*.jpg"):
img = Image.open(img_path)
img.thumbnail((800, 600))
img.save(img_path)
print(f"Resized: {img_path.name}")
Streaming Output (Real-Time Progress)
User: "Scrape top 20 HN posts with progress updates"
โ run_python_stream:
import requests
from bs4 import BeautifulSoup
import time
print("๐ Starting to scrape Hacker News...")
resp = requests.get("https://news.ycombinator.com")
soup = BeautifulSoup(resp.text, "html.parser")
stories = soup.select(".titleline > a")[:20]
print(f"๐ Found {len(stories)} stories. Processing...\n")
for i, story in enumerate(stories, 1):
# Show progress in real-time
progress = "โ" * i + "โ" * (20 - i)
print(f"[{progress}] {i}/20: {story.text}")
time.sleep(0.5) # See each item appear live!
print("\nโ
Scraping complete!")
# Output appears LINE BY LINE as the code runs,
# not all at once at the end!
Automatic File Display
User: "Take a screenshot of example.com and create a summary report"
โ run_python:
from playwright.sync_api import sync_playwright
import json
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
# Take screenshot
screenshot_path = "/tmp/example_screenshot.png"
page.screenshot(path=screenshot_path)
# Create report
report = {
"url": "https://example.com",
"title": page.title(),
"screenshot": screenshot_path,
"timestamp": "2025-01-26T12:00:00"
}
report_path = "/tmp/report.json"
with open(report_path, "w") as f:
json.dump(report, f, indent=2)
browser.close()
# Print file paths - Code Mode auto-detects and displays them!
print(f"Screenshot saved to: {screenshot_path}")
print(f"Report saved to: {report_path}")
# Result: Your MCP client displays the screenshot IMAGE inline
# and shows the JSON content formatted - no manual handling needed!
Configuration Options
View current config:
โ configure()
Update settings:
โ configure(action="set", key="execution_mode", value="docker")
โ configure(action="set", key="default_timeout", value="120")
| Setting | Values | Description |
|---|---|---|
execution_mode |
direct, docker |
How to run code |
default_timeout |
integer | Default timeout (seconds) |
max_retries |
integer | Default retry attempts |
auto_install |
true, false |
Auto-install packages |
docker_image |
string | Docker image for sandbox |
code_analysis.enabled |
true, false |
Enable code analysis |
code_analysis.block_on_critical |
true, false |
Block execution on critical issues |
code_analysis.show_report |
true, false |
Show analysis report in output |
resource_tracking.enabled |
true, false |
Enable resource usage tracking |
resource_tracking.show_in_output |
true, false |
Display metrics in output |
resource_tracking.warn_cpu_percent |
integer | CPU usage warning threshold (%) |
resource_tracking.warn_memory_mb |
integer | Memory usage warning threshold (MB) |
Learning System
When you solve an error, record it:
โ add_learning(
error_pattern="SSL: CERTIFICATE_VERIFY_FAILED",
solution="Use verify=False or install/update certifi",
context="HTTPS requests on systems with cert issues",
tags="ssl,https,certificates"
)
View learnings:
โ get_learnings()
โ get_learnings(search="ssl")
Learnings persist in ~/.mcp-pyrunner/learnings.json and improve future executions.
Data Storage
Code Mode stores data in ~/.mcp-pyrunner/:
~/.mcp-pyrunner/
โโโ config.json # User configuration
โโโ learnings.json # Error patterns and solutions
โโโ execution_log.json # Recent execution history
Security Considerations
โ ๏ธ Code Mode executes arbitrary Python code.
Direct mode (default):
- Code runs with your user permissions
- Full filesystem and network access
- Fast execution
Docker mode (more secure):
- Code runs in isolated container
- Limited resources (512MB RAM, 1 CPU)
- Network access available
- Slower startup
Enable Docker mode:
โ configure(action="set", key="execution_mode", value="docker")
Testing
# Run tests
uv run pytest
# Test with MCP Inspector
uv run mcp dev src/mcp_codemode/server.py
# Open http://localhost:5173
Contributing
Contributions welcome! Areas of interest:
-
Streaming output for long-running codeโ DONE! -
Automatic file display (images, text, resources)โ DONE! -
Enhanced system context (pip version, package managers)โ DONE! -
Code analysis before executionโ DONE! -
Resource usage trackingโ DONE! - Vector DB for semantic learning search
- Pyodide/WASM sandboxing option
- Multi-file project support
License
MIT
Acknowledgments
- Cloudflare's Code Mode for the inspiration
- Model Context Protocol for the standard
- Block's Goose for being an excellent MCP client
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_pyrunner-0.1.6.tar.gz.
File metadata
- Download URL: mcp_pyrunner-0.1.6.tar.gz
- Upload date:
- Size: 265.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34041d1eb37b19cebf68baa7a3f66bf5cb49a24d14481599735ba4d9ddd6e2f7
|
|
| MD5 |
0dd2c4e358115a33628ac831364f47dd
|
|
| BLAKE2b-256 |
dce7e1df4f43a58afa066bfde99ea2500daf0b0d8f7fc151d8e209fe9955a060
|
File details
Details for the file mcp_pyrunner-0.1.6-py3-none-any.whl.
File metadata
- Download URL: mcp_pyrunner-0.1.6-py3-none-any.whl
- Upload date:
- Size: 29.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ffbbeaf39b54137c0991d2c418c498fdc7d996c6611834c6a5bfccd38995ae4
|
|
| MD5 |
7b77b7f946c97f7da0fa220fc0979f60
|
|
| BLAKE2b-256 |
b2f8cee1e5b5d859245222770eec25ad50c418ad9a83c36db59c4890035e19a1
|