Skip to main content
Glama
hileamlakB

PRIMS – Python Runtime Interpreter MCP Server

runner.py3.3 kB
"""Orchestrate sandbox execution of untrusted Python code.""" import asyncio import mimetypes import shutil import textwrap from typing import TypedDict from server.config import TIMEOUT_SECONDS, TMP_DIR from server.sandbox.downloader import download_files from server.sandbox.env import create_virtualenv __all__ = ["run_code"] # Precise schema for each artifact entry. class ArtifactMeta(TypedDict): name: str relative_path: str size: int mime: str # Typed return for run_code results. class RunCodeResult(TypedDict, total=False): """Result of running code in the sandbox. Optionally includes a feedback field with suggestions or warnings (list of strings). """ stdout: str stderr: str artifacts: list[ArtifactMeta] feedback: str async def run_code( *, code: str, requirements: list[str], files: list[dict[str, str]], run_id: str, session_id: str | None = None, ) -> RunCodeResult: """Execute *code* inside an isolated virtual-env and return captured output. Artifacts are returned as paths relative to the output directory. Only files inside output/ are included.""" if session_id: # Persist workspace for the lifetime of the client session. work = TMP_DIR / f"session_{session_id}" work.mkdir(parents=True, exist_ok=True) else: # Legacy per-run workspace (stateless behaviour). work = TMP_DIR / f"run_{run_id}" if work.exists(): shutil.rmtree(work) work.mkdir(parents=True, exist_ok=True) # Ensure mounts directory exists for all modes. (work / "mounts").mkdir(parents=True, exist_ok=True) # Directory where user code should place output/artifacts. (work / "output").mkdir(parents=True, exist_ok=True) await download_files(files, work / "mounts") py = await create_virtualenv(requirements, work) script_name = f"script_{run_id}.py" if session_id else "script.py" script = work / script_name script.write_text(textwrap.dedent(code)) proc = await asyncio.create_subprocess_exec( str(py), str(script), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=work, ) try: out, err = await asyncio.wait_for(proc.communicate(), timeout=TIMEOUT_SECONDS) except TimeoutError as err: proc.kill() await proc.wait() msg = f"Execution timed out after {TIMEOUT_SECONDS}s" raise RuntimeError(msg) from err # Collect artifacts inside the output directory. artifacts: list[ArtifactMeta] = [] output_dir = work / "output" for p in output_dir.rglob("*"): if p.is_file(): try: rel_path = p.relative_to(output_dir) except ValueError: continue # skip files not in output_dir size = p.stat().st_size mime, _ = mimetypes.guess_type(str(p)) artifacts.append( { "name": rel_path.name, "relative_path": rel_path.as_posix(), "size": size, "mime": mime or "application/octet-stream", } ) return {"stdout": out.decode(), "stderr": err.decode(), "artifacts": artifacts}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hileamlakB/Python-Runtime-Interpreter-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server