# MCP Code Execution Tool A Rust-based tool that provides both a command-line interface and an MCP (Model Context Protocol) server for executing JavaScript, TypeScript, and Python code in isolated environments. **Repository:** English | [中文](./README_zh.md) ## Features - Execute JavaScript, TypeScript, and Python code in isolated environments - **JavaScript/TypeScript**: Powered by Deno runtime - **Python**: Powered by `uv` with automatic dependency management - Automatic code caching using blake3 hashing for faster repeated executions - Support for ESM and CommonJS modules in JavaScript - Automatic Python dependency parsing and installation - Separate log capture and execution result handling - Available as both CLI tool (`run_code_rmcp`) and MCP server (`script_runner`) ## Installation ### Install CLI Tool ```bash # Clone the repository git clone https://github.com/nuwax-ai/run_code_rmcp.git cd run_code_rmcp # Install the CLI tool (run_code_rmcp) cargo install --path . # Or install both CLI tool and MCP server cargo install --path . --features mcp cargo install --path . --bin script_runner --features mcp ``` ### System Requirements - **Rust**: 1.85 or higher (for building) - **Deno**: Required for JavaScript/TypeScript execution - **uv**: Required for Python execution and dependency management Install Deno: ```bash curl -fsSL https://deno.land/install.sh | sh ``` Install uv: ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` ## Usage ### CLI Tool: run_code_rmcp The `run_code_rmcp` command allows you to execute code directly from the command line. #### Basic Syntax ```bash run_code_rmcp [OPTIONS] ``` **Options:** - `--show-logs`: Display execution logs - `--clear-cache`: Clear cache before execution - `--use-mcp`: Use MCP SDK integration (requires mcp feature) **Commands:** - `js`: Execute JavaScript code - `ts`: Execute TypeScript code - `python`: Execute Python code - `clear-cache`: Clear cached files #### Execute JavaScript/TypeScript ```bash # Execute a JavaScript file run_code_rmcp --show-logs js -f fixtures/test_js.js # Execute with parameters run_code_rmcp --show-logs js -f fixtures/test_js_params.js -p '{"name":"User"}' # Execute TypeScript run_code_rmcp --show-logs ts -f fixtures/test_ts.ts # Execute inline code run_code_rmcp js -c "function handler() { return 'Hello!'; }" ``` #### Execute Python ```bash # Execute a Python file run_code_rmcp --show-logs python -f fixtures/test_python.py # Execute with parameters run_code_rmcp --show-logs python -f fixtures/test_python_params.py -p '{"a":10, "b":20}' # Execute inline code run_code_rmcp python -c "def handler(): return 'Hello from Python!'" ``` #### Cache Management ```bash # Clear all cache run_code_rmcp clear-cache --language all # Clear specific language cache run_code_rmcp clear-cache --language python run_code_rmcp clear-cache --language js run_code_rmcp clear-cache --language ts # Clear cache before execution run_code_rmcp --clear-cache js -f fixtures/test_js.js ``` ### Using as a Rust Library ```toml [dependencies] run_code_rmcp = { git = "https://github.com/nuwax-ai/run_code_rmcp.git" } ``` ```rust use run_code_rmcp::{CodeExecutor, LanguageScript}; #[tokio::main] async fn main() -> Result<(), Box> { // Execute JavaScript let js_result = CodeExecutor::execute_with_params_compat( "function handler() { return {success: true}; }", LanguageScript::Js, None ).await?; // Execute Python let py_result = CodeExecutor::execute_with_params_compat( "def handler(): return {'success': True}", LanguageScript::Python, None ).await?; Ok(()) } ``` ### MCP Server: script_runner The `script_runner` is an MCP server that provides tools for AI assistants. #### Starting the Server ```bash # Start MCP server script_runner # Start with verbose logging script_runner --verbose ``` The server communicates via stdio and waits for MCP protocol JSON requests. #### Available Tools The MCP server provides the following tools: 1. **run_javascript** - Execute JavaScript code 2. **run_typescript** - Execute TypeScript code 3. **run_python** - Execute Python code Each tool accepts: - `code` (string): The code to execute - `params` (object, optional): Parameters to pass to the handler function #### Integration with AI Assistants Add to your MCP client configuration (e.g., Claude Desktop): ```json { "name": "script-runner", "command": "script_runner", "transport": "stdio" } ``` ## Code Structure ### Handler Functions Your scripts should define a handler function that returns the result. #### JavaScript/TypeScript Supports both `main` and `handler` functions (main takes priority): ```javascript // This function takes priority function main(input) { console.log("Processing with main:", input); return { result: "Hello from main!" }; } // This function is used if main is not defined function handler(input) { console.log("Processing with handler:", input); return { result: "Hello from handler!" }; } ``` ESM modules are also supported: ```javascript import { serve } from "https://deno.land/std/http/server.ts"; function handler(input) { return { message: "ESM works!" }; } ``` #### Python Supports both `handler` and `main` functions (handler takes priority): ```python import pandas as pd # This function takes priority def handler(args): print(f"Processing: {args}") data = pd.DataFrame({"a": [1, 2, 3]}) return {"result": data.to_dict()} # This function is used if handler is not defined def main(args): return {"result": "Using main instead"} ``` ### Parameter Passing Parameters are passed to your handler function: ```bash run_code_rmcp js -f script.js -p '{"name": "User", "count": 42}' ``` In your code: ```javascript function handler(input) { // input = { name: "User", count: 42 } return `Hello ${input.name}, count: ${input.count}`; } ``` ### Python Dependencies Python dependencies are automatically detected and installed: ```python import requests import pandas as pd def handler(args): # Dependencies are automatically installed via uv response = requests.get("https://api.example.com") data = pd.DataFrame(response.json()) return data.to_dict() ``` ### Log Capture All console output is captured separately from the return value: ```javascript console.log("This goes to logs"); console.log("So does this"); function handler() { return "This is the result"; } ``` Result: ```json { "logs": ["This goes to logs", "So does this"], "result": "This is the result", "error": null } ``` ## Development ```bash # Build cargo build # Run with cargo cargo run -- --show-logs js -f fixtures/test_js.js # Run tests cargo test # Build with MCP feature cargo build --features mcp # Run MCP server with cargo cargo run --bin script_runner --features mcp ``` ## Environment Pre-warming The project includes a warm-up function to cache common dependencies: ```rust use run_code_rmcp::warm_up_all_envs; #[tokio::main] async fn main() -> Result<()> { // Pre-install common Python and JS/TS dependencies warm_up_all_envs(None, None, None, None).await?; Ok(()) } ``` ## TODO - [ ] TTS (Text-to-Speech) functionality - Currently has known issues ## License This project is licensed under the Apache License 2.0. See `LICENSE` and `NOTICE` files in the root directory for details.