# Sandbox Mode and Local Mode for Tool Execution in ML Intern: Security and Configuration Guide

> Understand ML Intern's sandbox mode vs local mode for tool execution. Securely isolate tools in Docker or run them directly on the host for speed. Choose the best mode for your needs.

- Repository: [Hugging Face/ml-intern](https://github.com/huggingface/ml-intern)
- Tags: security-and-configuration-guide
- Published: 2026-04-24

---

**ML Intern supports two distinct tool execution modes—sandbox mode which isolates tools in short-lived Docker containers for security, and local mode which runs tools directly in the host process for speed and state persistence—controlled by the `TOOL_EXECUTION_MODE` setting in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py).**

The huggingface/ml-intern repository provides an autonomous agent framework that balances safety against performance through configurable execution strategies. Understanding the difference between sandbox mode and local mode for tool execution in ML Intern is essential when deploying AI agents that interact with external code, filesystems, or network resources.

## How Tool Execution Mode Works in ML Intern

The agent's core dispatcher in [`agent/core/tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/tools.py) routes tool invocations to one of two execution backends based on the global configuration. When the agent loop ([`agent/core/agent_loop.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/agent_loop.py)) orchestrates tool usage during a session, it reads the `TOOL_EXECUTION_MODE` variable defined in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py) to determine whether to invoke the containerized runner or the local executor.

This architecture allows developers to switch between isolation strategies without modifying tool definitions, as the same tool call gets dispatched to either [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py) for Docker-based execution or [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py) for direct process execution.

## Key Differences Between Sandbox and Local Mode

### Process Isolation and Security

**Sandbox mode** executes each tool inside a transient Docker container with its own filesystem, restricted network access, and enforced resource limits. According to the implementation in [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py), this isolation prevents malicious or buggy code from affecting the host machine, automatically terminating containers that exceed CPU, memory, or timeout thresholds.

**Local mode** runs tools directly in the same Python process or a subprocess that hosts the ML Intern server, as implemented in [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py). This exposes the host environment to the tool's actions, meaning infinite loops, unhandled exceptions, or malicious operations can crash the server or compromise the underlying system.

### Performance and Overhead

Sandbox mode incurs latency from Docker container spin-up, code copying into the container, and teardown after execution. **Local mode** eliminates this overhead, offering significantly faster execution since tools run immediately without containerization delays.

### State Persistence Across Invocations

Each sandbox invocation receives a fresh environment with no retained state from previous calls unless the tool explicitly writes to external persistent stores like databases or cloud storage. Local mode allows tools to maintain **in-process state** through module-level variables or direct filesystem access, enabling tools to build up context across multiple executions within the same session.

## Configuration and Source Implementation

To switch execution strategies, modify the configuration constant in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py):

Enable sandbox mode for secure, isolated execution:

```python

# agent/config.py

TOOL_EXECUTION_MODE = "sandbox"   # Runs tools in Docker containers

```

Enable local mode for fast, stateful execution (the default):

```python

# agent/config.py

TOOL_EXECUTION_MODE = "local"     # Runs tools directly in host process

```

The [`agent/core/tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/tools.py) module implements the dispatch logic that reads this configuration at runtime. When `TOOL_EXECUTION_MODE` is set to `"sandbox"`, the agent calls container management functions from [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py). When set to `"local"`, execution flows through the native paths in [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py).

## Practical Execution Examples

### Executing Untrusted Code in Sandbox Mode

For arbitrary user code or shell commands requiring strict isolation:

```python
from agent.core import tools

# With TOOL_EXECUTION_MODE = "sandbox" in agent/config.py

result = tools.run_tool(
    name="run_python_code",
    args={"code": "print('Hello from sandbox')"}
)

```

The underlying implementation in [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py) creates constrained containers:

```python

# agent/tools/sandbox_tool.py (excerpt)

def execute_in_sandbox(command: List[str]) -> str:
    # Docker container spun up with limited CPU/memory and no network

    # Command runs inside container and output is captured

    ...

```

### Accessing Local Resources in Local Mode

For trusted utilities requiring filesystem persistence:

```python
from agent.core import tools

# With TOOL_EXECUTION_MODE = "local" in agent/config.py

result = tools.run_tool(
    name="read_cache",
    args={"key": "user_preferences"}
)

```

The local implementation allows direct state access without container boundaries:

```python

# agent/tools/local_tools.py (excerpt)

def read_cache(key: str) -> str:
    # Direct filesystem access, fast and stateful

    with open(f"/tmp/cache/{key}.txt") as f:
        return f.read()

```

## When to Use Each Execution Mode

**Use sandbox mode** when running untrusted code snippets, executing arbitrary shell commands, or invoking external services where security isolation is mandatory. This mode ensures that user-provided scripts cannot escape the container to compromise the host system.

**Use local mode** for fast, lightweight utilities that need to share in-process state, such as reading local cache files, updating databases, or performing quick calculations where the overhead of containerization would degrade performance unnecessarily.

## Summary

- **Sandbox mode** provides security isolation through Docker containerization implemented in [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py), preventing host system compromise but adding execution overhead.
- **Local mode** offers superior performance and state persistence through direct execution in [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py), allowing tools to maintain context across invocations.
- **Global configuration** is controlled by the `TOOL_EXECUTION_MODE` variable in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py), which the dispatcher in [`agent/core/tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/tools.py) evaluates to route calls appropriately.
- **Security vs. speed trade-off** dictates mode selection: sandbox for untrusted or dangerous operations, local for trusted, state-dependent utilities.

## Frequently Asked Questions

### What happens if I don't specify a tool execution mode in ML Intern?

ML Intern defaults to local mode when the `TOOL_EXECUTION_MODE` variable is unset or set to `"local"` in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py). In this configuration, tools execute directly within the host Python process using implementations from [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py), maximizing performance but providing no isolation from the host environment.

### Can I use both sandbox and local modes simultaneously in the same ML Intern session?

No, the execution mode is configured globally per session in [`agent/config.py`](https://github.com/huggingface/ml-intern/blob/main/agent/config.py) and applies consistently to all tool invocations. The dispatcher in [`agent/core/tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/tools.py) reads this configuration once and routes every tool call to either [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py) or [`agent/tools/local_tools.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/local_tools.py) for the duration of the agent loop execution.

### How does sandbox mode enforce resource limits and timeouts?

According to [`agent/tools/sandbox_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/sandbox_tool.py), the `execute_in_sandbox` function enforces CPU, memory, and execution time limits through Docker container constraints. The sandbox automatically kills containers that exceed these thresholds, preventing resource exhaustion attacks while the agent loop in [`agent/core/agent_loop.py`](https://github.com/huggingface/ml-intern/blob/main/agent/core/agent_loop.py) manages the overall orchestration timeline.

### Is filesystem state preserved between different tool calls in sandbox mode?

No, each tool invocation in sandbox mode receives a completely fresh Docker container with no persistent filesystem state from previous calls. Tools must explicitly write to external persistent stores such as databases or cloud storage to maintain context, unlike local mode where module-level variables and local filesystem changes persist between calls.