Stateful Execution
Relevant source files
The following files were used as context for generating this wiki page:
Stateful Execution within the MCP Server Code Execution Mode allows for a persistent Python environment where variables, functions, and imports are retained across multiple tool calls. Unlike traditional stateless execution models that spin up a fresh environment for every request, this system maintains a warm container sandbox that stays active between calls, enabling complex, multi-step workflows.
The system achieves this persistence through a combination of a long-lived container process and a host-mediated bridge. This architecture ensures that the LLM agent can build logic incrementally, defining state in one request and utilizing it in subsequent ones, while maintaining strict security boundaries via rootless containerization.
Sources: mcp_server_code_execution_mode.py:1680-1685, README.md:167-172, ARCHITECTURE.md:12-25
Architecture and Components
The stateful nature of the execution environment is driven by the RootlessContainerSandbox and its interaction with the MCPBridge. When a code execution request is received, the bridge checks for an existing, running process. If found and active, the code is sent to the existing sandbox rather than creating a new one.
Component Interaction
The diagram shows how the Bridge communicates with a persistent Sandbox where an internal queue manages incoming code execution requests within a shared global namespace.
Sources: mcp_server_code_execution_mode.py:615-625, ARCHITECTURE.md:46-55
Key Classes and Logic
- RootlessContainerSandbox: Manages the lifecycle of the container. It uses
_ensure_startedto check ifself._processis active before launching a new instance. Sources: mcp_server_code_execution_mode.py:685-690 - entrypoint.py: A generated Python script injected into the container. It contains a
_main_loopthat reads from an_EXECUTION_QUEUE, allowing it to process sequential code snippets without terminating the Python interpreter. Sources: mcp_server_code_execution_mode.py:1044-1052 - _GLOBAL_NAMESPACE: A dictionary maintained within the entrypoint that serves as the execution context for
eval()andexec(), ensuring state retention. Sources: mcp_server_code_execution_mode.py:1018-1030
Persistence Mechanisms
The system supports two primary levels of state: Session Persistence (in-memory during a running container) and Cross-Session Persistence (on-disk storage).
Session Persistence
Variables and imports are stored in the sandbox's memory. As long as the container does not time out or crash, any object defined in the global scope remains accessible.
Cross-Session Persistence (Persistent Memory System)
For data that must survive container restarts, a JSON-based memory system is provided. This system maps a host directory (~/MCPs/user_tools/memory/) to a container directory (/projects/memory/).
| Function | Description |
|---|---|
save_memory(key, value) | Stores JSON-serializable data to disk. |
load_memory(key) | Retrieves data by key. |
update_memory(key, fn) | Performs an atomic read-modify-write operation. |
save_tool(func) | Appends a Python function to user_tools.py for future availability. |
Sources: mcp_server_code_execution_mode.py:795-885, GUIDE.md:386-410
Data Flow for Stateful Requests
The following sequence illustrates how the host bridge and container entrypoint maintain state through an execution loop.
This diagram highlights the internal loop where the Global Namespace persists between separate JSON-RPC execution calls from the host.
Sources: mcp_server_code_execution_mode.py:730-760, tests/test_entrypoint.py:100-120
Configuration for Persistence
The behavior of the stateful sandbox can be tuned via environment variables, specifically regarding how long a "warm" runtime stays active.
| Variable | Default | Description |
|---|---|---|
MCP_BRIDGE_RUNTIME_IDLE_TIMEOUT | 300s | Shutdown delay for the runtime after inactivity. |
MCP_BRIDGE_STATE_DIR | ~/MCPs | Host directory for IPC and persistent state. |
Sources: mcp_server_code_execution_mode.py:115-122, README.md:275-285
Conclusion
Stateful execution transforms the run_python tool from a simple script runner into a dynamic execution environment. By maintaining a persistent global namespace and providing dedicated memory and tool-saving functions, the system allows LLM agents to perform complex data science tasks, manage long-running state machines, and build reusable custom tools, all while remaining isolated within a secure, rootless container.
Sources: STATUS.md:25-35, GUIDE.md:465-475