Metadata-Version: 2.4
Name: mcp-pyrunner
Version: 0.2.2
Summary: Universal Python code execution MCP server - one tool to rule them all
Project-URL: Homepage, https://github.com/anaseqal/codemode
Project-URL: Repository, https://github.com/anaseqal/codemode
Project-URL: Documentation, https://github.com/anaseqal/codemode#readme
Project-URL: Issues, https://github.com/anaseqal/codemode/issues
Author-email: Anas Eqal <anaseqal@example.com>
License: MIT
License-File: LICENSE
Keywords: agent,ai,claude,code-execution,codemode,cursor,goose,llm,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: aiohttp>=3.8.0
Requires-Dist: beautifulsoup4>=4.12.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: lxml>=4.9.0
Requires-Dist: mcp[cli]>=1.2.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: pillow>=10.0.0
Requires-Dist: psutil>=5.9.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: extended
Requires-Dist: matplotlib>=3.7.0; extra == 'extended'
Requires-Dist: opencv-python>=4.8.0; extra == 'extended'
Requires-Dist: playwright>=1.40.0; extra == 'extended'
Requires-Dist: scikit-learn>=1.3.0; extra == 'extended'
Requires-Dist: seaborn>=0.12.0; extra == 'extended'
Requires-Dist: selenium>=4.0.0; extra == 'extended'
Description-Content-Type: text/markdown

# MCP Code Mode 🐍⚡

**Universal Python code execution MCP server - one tool to rule them all.**

Inspired by [Cloudflare's Code Mode](https://blog.cloudflare.com/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!

### 📚 MCP Resources (NEW!)
Expose data as MCP resources for automatic LLM context:
- **learnings://database** - All learned error patterns and solutions
- **system://context** - System info, Python version, package managers
- **executions://recent** - Recent execution history with statistics

Compatible MCP clients can access these resources automatically, improving code generation without manual tool calls!

### 📡 Context Injection & Progress Reporting (NEW!)
Real-time progress updates and structured logging during execution:
- **Progress tracking** - See execution stages (analyzing, executing, processing) in real-time
- **Structured logging** - Detailed logs at each execution step via `ctx.info()`
- **Smart updates** - Progress bars show completion percentage for long-running tasks
- **Error reporting** - Immediate notification when issues occur

Tools with context injection: `run_python`, `run_python_stream`, `run_with_retry`

### 🏗️ Structured Output with Type Safety (NEW!)
Type-safe data models using Python dataclasses:
- **ExecutionResult** - Strongly-typed execution results with IDE autocomplete
- **CodeAnalysisResult** - Structured code analysis reports with issue tracking
- **ResourceMetrics** - Typed performance metrics
- **Learning** - Type-safe learning storage

Benefits: Better IDE support, type checking, self-documenting contracts, automatic JSON serialization

### ✨ MCP Prompts (NEW!)
Reusable prompt templates for common workflows:
- **🐛 debug_assistant** - Analyze errors with past learnings and step-by-step fixes
- **⚡ code_optimizer** - Improve performance, memory usage, or readability
- **👀 code_reviewer** - Comprehensive code review with security analysis
- **📈 data_explorer** - Data analysis and visualization guidance
- **🔌 api_tester** - API endpoint testing and validation

Simply invoke prompts with arguments to get expert guidance tailored to your task!

### 🧠 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)

```bash
# Using uv (recommended)
uv tool install mcp-pyrunner

# Using pip
pip install mcp-pyrunner
```

### From Source

```bash
git clone https://github.com/anaseqal/codemode.git
cd codemode
uv sync
```

## Configuration

### Goose

**If installed from PyPI:**

Edit `~/.config/goose/config.yaml`:

```yaml
extensions:
  codemode:
    type: stdio
    enabled: true
    cmd: uvx
    args: ["mcp-pyrunner"]
```

**If running from source (local development):**

```yaml
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:**
```json
{
  "mcpServers": {
    "codemode": {
      "command": "uvx",
      "args": ["mcp-pyrunner"]
    }
  }
}
```

**If running from source:**
```json
{
  "mcpServers": {
    "codemode": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/codemode", "mcp-pyrunner"]
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json`:

**If installed from PyPI:**
```json
{
  "mcpServers": {
    "codemode": {
      "command": "uvx",
      "args": ["mcp-pyrunner"]
    }
  }
}
```

**If running from source:**
```json
{
  "mcpServers": {
    "codemode": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/codemode", "mcp-pyrunner"]
    }
  }
}
```

## Available MCP Resources

MCP clients that support resources can automatically access these data sources without calling tools:

| Resource URI | Description |
|--------------|-------------|
| `learnings://database` | Complete learnings database with all error patterns and solutions |
| `system://context` | System information, Python version, package managers, configuration |
| `executions://recent` | Recent execution history with success/failure statistics and resource metrics |

Resources provide context to LLMs automatically, improving code generation quality without manual tool calls.

## 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

```bash
# 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! Features are prioritized by impact.

### ✅ Completed Features

**Core Features:**
- [x] ~~Streaming output for long-running code~~ ✅
- [x] ~~Automatic file display (images, text, resources)~~ ✅
- [x] ~~Enhanced system context (pip version, package managers)~~ ✅
- [x] ~~Code analysis before execution~~ ✅
- [x] ~~Resource usage tracking~~ ✅

**Advanced MCP SDK Features:**
- [x] ~~**MCP Resources**~~ ✅ - Expose learnings, system info, and execution logs as MCP resources
- [x] ~~**Context Injection**~~ ✅ - Real-time progress reporting and structured logging
- [x] ~~**Structured Output**~~ ✅ - Type-safe dataclasses for execution results and metrics
- [x] ~~**MCP Prompts**~~ ✅ - Reusable templates for debugging, optimization, review, data analysis, API testing

### 🚀 Next Priority

All high and medium impact features complete! 🎉

### 📊 Medium Impact (Completed!)

All medium impact features have been implemented!

### 🔮 Future Enhancements (Lower Priority)

Focus areas for future development:

- [ ] **Smart Completions** - Argument auto-completion for tool parameters (requires newer MCP SDK)
- [ ] **Visual Icons** - Icon support for tools/resources/prompts (requires FastMCP 2.14.0+)
- [ ] **Elicitation** - Request user input mid-execution for interactive workflows
- [ ] **OAuth Authentication** - Secure access to protected resources and APIs
- [ ] **Lifespan Context** - Shared database connections and resource pooling
- [ ] Vector DB for semantic learning search
- [ ] Pyodide/WASM sandboxing option
- [ ] Multi-file project support

## License

MIT

## Acknowledgments

- [Cloudflare's Code Mode](https://blog.cloudflare.com/code-mode/) for the inspiration
- [Model Context Protocol](https://modelcontextprotocol.io/) for the standard
- [Block's Goose](https://github.com/block/goose) for being an excellent MCP client
