Skip to main content
Glama

Sandbox MCP

AI coding agents are powerful because they can execute code. That is also their biggest risk: experimentation can modify the developer's environment.

An agent that is genuinely useful has to be able to run npm install, apply a migration, try a build, or run code it has not read. Every one of those actions, performed on your machine, can install something you did not want, overwrite work in progress, burn your CPU, read your credentials, or leave behind an environment that no longer builds.

The usual answers are both bad. Deny the agent those tools and it can only guess. Allow them and you are trusting a probabilistic system with your laptop.

Sandbox MCP is the third answer: give the agent somewhere real to work that is not your machine.

"Experiment with this project, but don't touch my actual environment."


Without a sandbox

flowchart TD
    CC["Claude Code"] --> HOST["Your machine"]
    HOST --> A["npm install"]
    HOST --> B["scripts"]
    HOST --> C["migrations"]
    HOST --> D["file modifications"]
    HOST --> E["arbitrary execution"]

    classDef danger fill:#fdeceb,stroke:#d1453b,color:#7a1f18
    classDef actor fill:#eef2f7,stroke:#5b6b7f,color:#22303f
    class HOST,A,B,C,D,E danger
    class CC actor

Related MCP server: Docker MCP Server

With Sandbox MCP

flowchart TD
    CC["Claude Code"] --> MCP["FastMCP"]
    MCP --> POL["Experiment policy"]
    POL --> SBX["Docker sandbox"]
    SBX --> WORK["execute · modify · test<br/>build · experiment"]
    WORK --> RES["Results"]
    RES --> CC

    classDef safe fill:#e7f4ea,stroke:#2f7d4f,color:#14432a
    classDef actor fill:#eef2f7,stroke:#5b6b7f,color:#22303f
    class SBX,WORK safe
    class CC,MCP,POL,RES actor

What makes this different from a Docker MCP server

Existing Docker MCP implementations expose Docker operations to AI agents. Sandbox MCP exposes an experimentation abstraction.

That is not a wording preference; it changes what the agent can do.

A Docker MCP server

Sandbox MCP

Tools

docker_run, docker_exec, docker_ps

create_experiment, run_tests, inspect_changes

The agent decides

flags, mounts, network mode, privileges

what it wants to find out

Isolation

whatever the agent passed

enforced by policy before Docker is called

Host filesystem

reachable via -v $(pwd):/app

not reachable; the project is snapshot-copied

"What changed?"

ask the agent to diff it

inspect_changes, against a baseline taken pre-container

Failure mode

an agent that mounts / writable

a request the policy engine rejects

The agent never receives Docker API access. It states an intent; the server decides how that intent is realised.

flowchart TB
    CC["Claude Code"] -- "MCP tool call" --> SERVER

    subgraph SERVER["Sandbox MCP · the only component holding the socket"]
        direction LR
        POL["Policy / Security<br/><i>validates · clamps · refuses</i>"]
        EXP["Experiment Manager<br/><i>lifecycle · state machine</i>"]
        JOB["Job Manager<br/><i>async · timeouts · cancellation</i>"]
        COL["Result Collector<br/><i>diffs · artifacts · reports</i>"]
        POL --> EXP --> JOB --> COL
    end

    SERVER --> API["Docker Engine API<br/><i>/var/run/docker.sock — SDK only, no docker CLI</i>"]
    API --> SBX["Disposable sandbox<br/><i>no socket · no host filesystem · no network</i>"]
    SBX --> OUT["Structured result<br/><i>back to Claude Code</i>"]

    classDef actor fill:#eef2f7,stroke:#5b6b7f,color:#22303f
    classDef infra fill:#eaf1fb,stroke:#3a6ea8,color:#173352
    classDef safe fill:#e7f4ea,stroke:#2f7d4f,color:#14432a
    class CC,POL,EXP,JOB,COL,OUT actor
    class API infra
    class SBX safe
    style SERVER fill:#fbfcfd,stroke:#9aa7b4,color:#22303f

Docker is the isolation mechanism. MCP is the agent interface. Sandbox MCP is the experimentation layer.

There is deliberately no orchestrator here. The agent already is one: Claude Code plans, reads output, forms a hypothesis and retries better than any loop this server could ship. Putting a second, dumber loop underneath it would only compete with the caller. This project's job is the surface the agent drives — and making that surface one it cannot hurt you with.


The central abstraction: an experiment

Experiment:      exp_2859b8eb8656
Project:         payments-service
Base image:      node:22-slim
Network:         disabled
CPU:             2 cores
Memory:          1GB
Timeout:         300s
Status:          READY

Commands:        1. npm install --no-audit --no-fund   (exit 1, EBADENGINE)
                 2. npm install --no-audit --no-fund   (exit 0)
                 3. npm test                           (37 passed, 3 failed)
                 4. npm test                           (40 passed, 0 failed)

Changes:         3 files modified, +9 -4

Experiments move through an explicit, validated state machine. An illegal transition is an error, not a silently corrupted record — which matters, because DESTROYED is what tells the server a container no longer exists.

stateDiagram-v2
    direction TB
    [*] --> CREATING
    CREATING --> READY: sandbox provisioned
    READY --> RUNNING: command submitted
    RUNNING --> READY: exit 0

    state "terminal, but the sandbox is still alive" as OUTCOME {
        direction LR
        COMPLETED
        FAILED
        TIMEOUT
        CANCELLED
    }

    CREATING --> FAILED: could not start
    RUNNING --> OUTCOME
    OUTCOME --> RUNNING: more work
    OUTCOME --> DESTROYED: destroy_experiment
    READY --> DESTROYED: destroy_experiment
    DESTROYED --> [*]

Security model

The Docker socket is a highly privileged interface — access to it is effectively root on the host. It is held by the server and by nothing else. The agent talks to the server; the server talks to Docker.

Filesystem

The project is copied, not mounted:

flowchart LR
    HOST["HOST PROJECT<br/><i>read once, never written</i>"]
    SNAP["SANDBOX COPY<br/><i>also the baseline every diff uses</i>"]
    CON["DOCKER CONTAINER"]

    HOST -- "snapshot: filtered, read-only pass" --> SNAP
    SNAP -- "put_archive" --> CON
    CON -. "no path back" .-x HOST

    classDef host fill:#fdeceb,stroke:#d1453b,color:#7a1f18
    classDef safe fill:#e7f4ea,stroke:#2f7d4f,color:#14432a
    class HOST host
    class SNAP,CON safe
  • Default strategy is COPY_TO_SANDBOX. READ_ONLY_BIND_MOUNT exists for large repositories you only need to read. Writable host bind mounts are not implemented — there is no configuration that produces one.

  • .env files, *.pem, *.key, id_rsa*, .netrc, .ssh/, .aws/, .gnupg/, .kube/ and similar are never copied, regardless of configuration. Build output (node_modules, dist, target, …) is skipped by default and that list is configurable.

  • Project paths are resolved before they are checked, so a symlink cannot launder a denied location. The home directory and filesystem root are refused outright.

  • Paths inside the sandbox are confined to the workspace: ../../etc/passwd and /etc/shadow are rejected by every tool that takes a path.

One deliberate exception worth knowing: .npmrc is copied, because the real behaviour of npm install often depends on it. If yours holds an _authToken, add it to SANDBOX_MCP_SNAPSHOT_EXCLUDES.

Network

Disabled by default. network_mode is an explicit decision at creation time:

Mode

Behaviour

none

No interfaces at all. The default.

restricted

A private bridge network of its own — egress works, no reach to other sandboxes

enabled

The daemon's default bridge. Full egress.

restricted prevents lateral movement between sandboxes. It does not firewall egress; per-experiment network allowlists are listed under future extensions.

Environment variables

The host environment is never inherited. Variables cross the boundary only when named: "CI" forwards the host's value, "NODE_ENV=test" injects a literal.

Credential-shaped names (*_TOKEN, *_SECRET, *API_KEY*, AWS_*, DATABASE_URL, …) are refused even when explicitly allowlisted, because an agent asking for AWS_SECRET_ACCESS_KEY inside a throwaway container is never right. Set SANDBOX_MCP_STRICT_ENV_DENYLIST=false if you disagree.

Values are never written to the database or the logs — only names.

Container privileges

  • privileged=False, always. There is no setting that changes it.

  • cap_drop: ALL, then a small set added back: CHOWN, DAC_OVERRIDE, FOWNER, FSETID, SETUID, SETGID, KILL. That is what package managers actually need (they chown caches and drop privileges for lifecycle scripts). It excludes NET_RAW, MKNOD, SYS_ADMIN, SYS_CHROOT, SETPCAP and SETFCAP — the ones that matter for escape.

  • no-new-privileges:true.

  • The Docker socket is never mounted into a sandbox. There is no code path that does it, and an integration test asserts its absence.

  • SANDBOX_MCP_SANDBOX_USER runs containers as a non-root user where the toolchain tolerates it.

Resource limits

Every sandbox is capped, and a request may only ask for less than the configured ceiling. Asking for more is clamped, and the clamp is returned to the agent as a warning rather than failing silently.

Limit

Default

Ceiling

Enforced by

CPU

2 cores

4 cores

NanoCpus

Memory

2GB

8GB

Memory and MemorySwap (no swap escape)

Processes

512

2048

PidsLimit

Wall clock

120s

1800s

the job manager, which kills the process

/tmp

512MB

tmpfs

Captured output

1MB/stream

truncated, and flagged as truncated


Installation

Requires Python 3.12+ and a running Docker engine (Docker Desktop, OrbStack, Colima or Rancher Desktop).

git clone https://github.com/Dhananjay-JSR/sandbox-mcp.git
cd sandbox-mcp
uv sync                     # exact versions from uv.lock

Confirm the server can reach Docker before wiring it to anything:

uv run sandbox-mcp --check
{
  "docker_host": "unix:///var/run/docker.sock",
  "state_dir": "/Users/you/.sandbox-mcp",
  "defaults": { "base_image": "debian:bookworm-slim", "network_mode": "none", ... },
  "docker": { "server_version": "29.4.0", "api_version": "1.54" },
  "ok": true
}

ok: false with DOCKER_UNAVAILABLE means the daemon is not running or the socket is somewhere unusual. The server probes /var/run/docker.sock, ~/.docker/run/docker.sock, ~/.orbstack/run/docker.sock, ~/.colima/default/docker.sock and ~/.rd/docker.sock in that order — the Docker CLI's context is not consulted, so set DOCKER_HOST explicitly if yours is elsewhere.

Optional extras:

uv sync --extra dev     # pytest, ruff, mypy

Connecting Claude Code

claude mcp add sandbox -- uv --directory /absolute/path/to/sandbox-mcp run sandbox-mcp

Or, if you installed it into an environment already on your PATH:

claude mcp add sandbox -- sandbox-mcp

Then, inside Claude Code:

/mcp                       # should list "sandbox" as connected

Equivalent .mcp.json, if you prefer to commit the configuration:

{
  "mcpServers": {
    "sandbox": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/sandbox-mcp", "run", "sandbox-mcp"],
      "env": {
        "SANDBOX_MCP_LOG_LEVEL": "INFO"
      }
    }
  }
}

Remote (Streamable HTTP)

uv run sandbox-mcp --transport http --host 127.0.0.1 --port 8000
claude mcp add --transport http sandbox http://127.0.0.1:8000/mcp

Or run the server itself in a container:

docker compose up -d
claude mcp add --transport http sandbox http://127.0.0.1:8000/mcp

The compose file mounts the Docker socket into the server — read the warning at the top of it first, and do not expose port 8000 beyond localhost without authentication in front of it.

flowchart TD
    CC["Claude Code"] --> SRV["Sandbox MCP<br/><i>holds the socket</i>"]
    SRV --> ENG["Docker Desktop / OrbStack"]
    ENG --> SBX["Sandbox<br/><i>no socket · no host filesystem · no network</i>"]

    classDef actor fill:#eef2f7,stroke:#5b6b7f,color:#22303f
    classDef infra fill:#eaf1fb,stroke:#3a6ea8,color:#173352
    classDef safe fill:#e7f4ea,stroke:#2f7d4f,color:#14432a
    class CC,SRV actor
    class ENG infra
    class SBX safe

Tools

Tool

Purpose

create_experiment

Create a disposable environment and copy a project into it

execute_experiment

Run a command inside the sandbox (sync or background)

run_tests

Detect the test runner, run it, parse the results

read_sandbox_file

Read a file from the sandbox to investigate a failure

write_sandbox_file

Apply a candidate fix without shell-quoting hazards

inspect_changes

What changed, against the pre-container baseline

collect_artifacts

Lift build output, reports or logs out before teardown

get_experiment

Full state and a summary of what happened

list_experiments

Find earlier experiments, including ones left running

get_job_status

Poll a background command

get_job_result

Fetch a completed background result

cancel_job

Stop a running command and kill its process

destroy_experiment

Tear down; idempotent; returns the final report

compare_experiments

Rank several approaches and recommend one

check_sandbox_runtime

Confirm Docker is reachable and show the active policy

Notably absent: docker_run, docker_exec, docker_ps, docker_build, docker_pull. A test asserts that no tool name begins with docker_.

Resources

sandbox://experiments                              all experiments
sandbox://experiments/{experiment_id}              metadata + state history
sandbox://experiments/{experiment_id}/logs         every command, with output
sandbox://experiments/{experiment_id}/diff         unified diff
sandbox://experiments/{experiment_id}/artifacts    collected files

The primary demo: Node 20 → Node 22

examples/node-upgrade/ is a real, dependency-free Node library pinned to Node 20. It fails on Node 22 for two independent and entirely realistic reasons:

  1. package.json declares engines.node: ">=18 <21" and .npmrc sets engine-strict=true, so npm install fails with EBADENGINE before a single test runs.

  2. src/crypto.js calls crypto.createCipher, deprecated since Node 10 and removed in Node 22.0.0.

Ask Claude Code:

Determine whether examples/node-upgrade can be upgraded from Node 20 to Node 22. You may install dependencies, modify files, run tests and experiment freely, but do not modify my actual working tree.

What happens — every figure below is from an actual run, and the whole thing works with the network disabled:

sequenceDiagram
    autonumber
    participant CC as Claude Code
    participant S as Sandbox MCP
    participant D as Disposable sandbox

    CC->>S: create_experiment(node:22-slim, network none)
    S->>D: snapshot 13 files, start container
    S-->>CC: exp_2859b8eb8656 · READY

    CC->>S: execute_experiment("npm install")
    S-->>CC: exit 1 · EBADENGINE
    CC->>S: read_sandbox_file("package.json")
    S-->>CC: engines.node ">=18 <21"
    CC->>S: write_sandbox_file("package.json", ">=18")
    CC->>S: execute_experiment("npm install")
    S-->>CC: exit 0

    CC->>S: run_tests()
    S-->>CC: 37 passed · 3 failed<br/>seal produces hex output<br/>seal and open round-trip<br/>seal round-trips unicode
    CC->>S: read_sandbox_file("src/crypto.js")
    S-->>CC: crypto.createCipher(...)
    CC->>S: write_sandbox_file("src/crypto.js", createCipheriv + scrypt key + IV)
    CC->>S: run_tests()
    S-->>CC: 40 passed · 0 failed

    CC->>S: inspect_changes()
    S-->>CC: 3 modified · +9 -4
    CC->>S: collect_artifacts(["src/crypto.js"])
    S-->>CC: kept for the developer
    CC->>S: destroy_experiment()
    S->>D: remove container and snapshot
    S-->>CC: report · host working tree UNCHANGED
Experiment:         Node 20 → Node 22
Result:             COMPATIBLE (with 2 source changes)
Tests:              40 passed, 0 failed
Changes:            3 files modified (+9 -4)
Host working tree:  UNCHANGED
Sandbox:            DESTROYED

That last pair of lines is the product. This exact sequence runs as a test:

uv run pytest tests/integration/test_node_upgrade_demo.py -m integration

Other things this makes possible

  • Dependency upgrade — "try upgrading React to the latest compatible version; don't modify my working tree." Needs network_mode="restricted" to reach the registry.

  • Database migration — create an experiment on postgres:16, run the migration, report whether it applied, destroy it.

  • Build debugging — "work out why this build fails; experiment freely."

  • Multi-approach debuggingexamples/failing-project/ is a Python project whose money arithmetic is done in floats; 3 of its 14 tests fail. Three fixes are plausible (round(), Decimal, truncation) and they are not equivalent. Run each in its own experiment, then call compare_experiments, which ranks them on failures, exit code, change size and duration, and recommends one.


Why there is no orchestration layer

An earlier cut of this server shipped a LangGraph loop — plan, test, diagnose, fix, retest — behind a run_autonomous_experiment tool. It was removed, on purpose.

The caller is already an agent. Claude Code reads a failing test, forms a hypothesis, edits a file and retries; it does that better than a graph of hardcoded repair strategies ever will, because it has judgement and the strategies had a lookup table. Shipping a second, weaker loop underneath a strong one does not add a capability — it competes with the caller for the same decision, and it is the one more likely to be wrong.

What is left is the part the agent genuinely cannot do for itself: the isolation boundary, the policy that enforces it, the state machine, the baseline diff, and the audit trail. Those are the product.

Concretely, the loop lives in the transcript instead of inside the server:

flowchart LR
    DEC["Decide the next step<br/><i>Claude Code — the loop lives here</i>"]
    ACT["Call a tool"]
    SRV["Sandbox MCP<br/><i>enforces · refuses · records</i>"]
    OBS["Read the full output"]

    DEC --> ACT --> SRV --> OBS --> DEC

    classDef actor fill:#eef2f7,stroke:#5b6b7f,color:#22303f
    classDef safe fill:#e7f4ea,stroke:#2f7d4f,color:#14432a
    class DEC,ACT,OBS actor
    class SRV safe

That is the primary demo, and it is what the integration suite runs.

Observability

Every operation emits a structured JSON event to stderr (stdout carries the MCP protocol under stdio transport):

{"event": "command_completed", "experiment_id": "exp_2859b8eb8656",
 "job_id": "job_4f1c8a2b90de", "operation": "job.run", "status": "COMPLETED",
 "exit_code": 0, "duration_ms": 1432, "timestamp": "2026-09-07T10:29:41Z"}

Credential-shaped keys are scrubbed at the processor level, so no individual call site can leak by forgetting.

Everything needed to answer "what exactly did the agent do?" is persisted in SQLite (~/.sandbox-mcp/sandbox.db): experiments, jobs with their commands, exit codes and captured output, state transitions with timestamps and reasons, artifacts with checksums, the pre-container baseline, and the change statistics — which are written before teardown, so a destroyed experiment is still comparable against a live one.

The database stores no secrets: environment variable names, never values.


Project layout

src/sandbox_mcp/
├── server.py            MCP tools and resources — the agent-facing surface
├── app.py               composition root; the only place the graph is wired
├── config.py            every tunable, in one auditable place
├── models.py            domain models (experiments, jobs, changes, reports)
├── errors.py            structured errors; no traceback ever reaches a client
├── logging.py           structured logging to stderr, with redaction
├── sandbox/
│   ├── interface.py     SandboxBackend — the seam other runtimes target
│   └── docker.py        Docker Engine API via the SDK; all hardening lives here
├── experiments/
│   ├── manager.py       the domain core
│   ├── state.py         the validated state machine
│   ├── repository.py    ExperimentRepository + the SQLite implementation
│   ├── changes.py       diffing the sandbox against its baseline
│   └── testing.py       test-runner detection and output parsing
├── execution/
│   ├── manager.py       job lifecycle: timeouts, cancellation, persistence
│   ├── jobs.py          live task registry and concurrency limits
│   └── executor.py      JobExecutor interface + the sandbox implementation
├── artifacts/manager.py pulling files out before teardown
└── security/
    ├── policy.py        validates and clamps every request
    ├── filesystem.py    path confinement and snapshotting
    └── resources.py     limit parsing

SandboxBackend, ExperimentRepository and JobExecutor are abstract. Docker implements the first; the MCP tool surface does not know it exists. Supporting Firecracker, Kubernetes Jobs or remote workers means one new implementation and no change to the agent-facing API — the in-memory FakeSandboxBackend the unit tests run against is the proof that the seam is real.

Three deviations from a literal reading of the brief, all deliberate: experiments/changes.py and experiments/testing.py exist as focused modules rather than being folded into manager.py; commands/results are columns on the jobs table rather than separate tables, since a job is a command and its result; and there is no orchestration/ package, for the reason given above.


Development

uv sync --extra dev

uv run pytest -m "not integration"     # 225 unit tests, no Docker needed
uv run pytest -m integration           # 23 tests against a live daemon
uv run pytest                          # everything

uv run ruff check . && uv run ruff format --check .
uv run mypy

The unit suite runs against FakeSandboxBackend and needs no daemon. The integration suite is the one that proves the product claim: the nine-step isolation checklist, the host tree unchanged byte-for-byte, the network genuinely off, secrets genuinely absent, the memory cap actually biting, timeouts killing the process, cancellation killing the process, hardening flags present on the real container, orphan containers swept at startup, and the full Node 20 → 22 demo.


MVP boundaries

Not built, on purpose: a web dashboard, authentication, cloud infrastructure, Kubernetes support, distributed scheduling, billing, multi-tenant production infrastructure. This is a polished local-first MVP.

Known limits, stated plainly:

  • Killing a timed-out command signals the command's own process. Descendants it spawned may survive until the sandbox is destroyed; pids_limit bounds the damage in the meantime.

  • restricted networking isolates sandboxes from each other but does not filter egress.

  • Change detection covers regular files. Symlinks are copied but not tracked in diffs.

  • Per-sandbox disk quotas need a storage driver that supports them (overlay2 on XFS with pquota); /tmp is capped via tmpfs, the workspace is not.

Future extensions

  1. Remote sandbox execution

  2. Firecracker isolation

  3. Kubernetes sandbox workers

  4. Persistent base-image cache

  5. Snapshot / restore

  6. Parallel experiments

  7. Experiment replay

  8. Resource usage analytics

  9. Network allowlists

  10. Human approval before applying changes

  11. Agent experiment benchmarking


Licence

MIT.

Available Tools

15 tools
cancel_jobCancel JobA

Stop a running command and kill its process inside the sandbox.

USE THIS when a command is clearly stuck or no longer needed. Safe on a job that already finished -- it returns the final state untouched.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesJob id to cancel.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
job_idYes
statusYes
stderrNo
stdoutNo
commandYes
exit_codeNo
duration_msNo
experiment_idYes
stderr_truncatedNo
stdout_truncatedNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that the tool stops a running command, kills its process, and is idempotent on finished jobs by returning the final state untouched. This gives the agent a clear mental model of side effects and edge-case safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the action, followed by a direct usage criterion and an idempotency note. Every sentence earns its place with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with an output schema, the description is sufficiently complete. It covers the core action, the circumstances that warrant cancellation, and the behavior on already-finished jobs, leaving no critical gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the sole parameter 'job_id' is already described as 'Job id to cancel.' The description adds no additional parameter-level meaning, but none is needed given the high schema coverage and single straightforward parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Stop a running command and kill its process inside the sandbox.' This clearly identifies the tool's purpose and distinguishes it from sibling tools that check status or retrieve results.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use the tool: 'USE THIS when a command is clearly stuck or no longer needed.' It also gives important guidance about safety on already-finished jobs, though it does not explicitly name alternative tools or when-not conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_sandbox_runtimeCheck Sandbox RuntimeA

Confirm the sandbox runtime is available and report the active defaults.

USE THIS first if create_experiment fails, to tell a stopped Docker daemon apart from a rejected request. Returns the Docker version the server is talking to and the isolation defaults every experiment starts from.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the burden. It conveys a read-only operation ('Confirm', 'report', 'Returns') and does not imply any side effects. However, it does not explicitly state 'does not modify state', leaving a small gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose followed by a precise usage scenario. Every sentence is necessary and there is no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers what the tool does, when to use it, and what it returns. Even without an output schema, the explicit mention of 'Docker version' and 'isolation defaults' gives the agent enough context to interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description cannot add parameter-level meaning beyond the schema. The baseline for 0 params is 4, but the description adequately covers the absence of inputs without needing extra clarification, thus earning a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Confirm the sandbox runtime is available and report the active defaults.' The verb and resource are specific, and it is easily distinguished from sibling tools like create_experiment or get_job_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is provided: 'USE THIS first if create_experiment fails' and explains the diagnostic value (distinguishing a stopped Docker daemon from a rejected request). This tells the agent exactly when to invoke this tool over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

collect_artifactsCollect ArtifactsA

Copy selected files out of a sandbox before it is destroyed.

USE THIS for build output, test reports, coverage, benchmark results or logs you want to keep or quote.

Patterns are workspace-relative shell globs ('dist/*.js'), or '/name' for a recursive search ('/junit.xml'). Files land in the server's own state directory; this tool cannot write anywhere on the developer's machine.

ParametersJSON Schema
NameRequiredDescriptionDefault
patternsYesWorkspace-relative globs, e.g. ['dist/*.js'].
experiment_idYesThe experiment to collect from.

Output Schema

ParametersJSON Schema
NameRequiredDescription
skippedNo
artifactsYes
total_bytesNo
experiment_idYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it delivers useful behavioral context: files land in the server's state directory, the tool cannot write on the developer's machine, and it must be used before sandbox destruction. It stops short of explaining edge-case behavior such as no matching patterns, but the disclosed storage location and limitations are meaningful and non-obvious.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. The purpose is front-loaded, use cases are in the second sentence, and the critical path/pattern details are in the third. Every sentence contributes new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with an output schema present, the description covers the core purpose, when to use it, path semantics, output location, and an important limitation. It does not explicitly mention sibling alternatives or what happens if a pattern matches nothing, but an agent has enough information to select and call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents both parameters at 100% coverage. The description adds value by detailing pattern semantics beyond the schema: workspace-relative shell globs, the '**/name' recursive form, and concrete examples. The experiment_id parameter is not further enriched, but the schema already explains it sufficiently.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Copy selected files out of a sandbox before it is destroyed.' This clearly identifies what the tool does and emphasizes the critical timing constraint. It also distinguishes itself from siblings like read_sandbox_file by describing a copy-out operation rather than inline reading.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit use cases: 'USE THIS for build output, test reports, coverage, benchmark results or logs you want to keep or quote.' This is strong when-to-use guidance. It does not explicitly name alternatives or state when not to use it, but the timing constraint 'before it is destroyed' and the restriction about not writing to the developer's machine provide clear operational context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_experimentsCompare ExperimentsA

Compare two or more experiments side by side.

USE THIS when you tried several approaches -- three candidate fixes, two runtime versions, a couple of dependency upgrades -- and have to recommend one. Run each approach in its own experiment, then compare.

RETURNS per-experiment test results, failing test names, exit codes, change size, duration and artifact counts, plus a recommendation when the evidence supports one. Destroyed experiments are still comparable: their findings were recorded before teardown.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelsNoOptional experiment_id -> human label, e.g. {'exp_a': 'Node 22'}.
experiment_idsYesTwo or more experiment ids.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesNo
dimensionsNoPer-dimension map of experiment_id -> value.
experimentsYes
recommendationNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, and it does well: it discloses the return fields (test results, failing test names, exit codes, change size, duration, artifact counts), conditional recommendation behavior, and that destroyed experiments remain comparable. It does not explicitly state whether the operation is read-only or whether comparing triggers any side effects, but the described behavior is otherwise transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections: a terse one-line purpose, a concrete 'USE THIS' scenario, and a focused 'RETURNS' list. Every sentence earns its place, and the most decision-relevant information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has moderate complexity, an output schema, complete parameter schema coverage, and no annotations. The description covers purpose, usage context, return behavior, and the destroyed-experiment edge case. It could be more complete by explicitly stating that this is a read-only analytic comparison that does not run or modify experiments, but it is otherwise sufficient for an agent to select and call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents experiment_ids and labels with examples. The description adds context about comparing destroyed experiments, which relates to how experiment_ids may be interpreted, but it does not add meaningful parameter-level semantics beyond what the schema provides. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool compares two or more experiments side by side, with a specific verb ('compare') and resource ('experiments'). It also names the core differentiating output (per-experiment results plus a recommendation), which separates it from siblings like get_experiment, list_experiments, and run_tests.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit scenario: use this when several approaches were tried and a recommendation is needed. It advises running each approach in its own experiment first. However, it does not explicitly state when NOT to use it or name alternative tools such as run_tests or get_experiment for simpler lookup needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_experimentCreate ExperimentA

Create a disposable, isolated environment and copy a project into it.

USE THIS when you are about to do something you should not do on the developer's machine: install dependencies, run a build or a migration, try an upgrade, run unfamiliar code, or explore a fix you are not sure about. Reach for it before the risky step, not after.

The project is SNAPSHOT-COPIED into the sandbox. Files you change inside never propagate back; the developer's working tree is untouched by construction. Secrets (.env files, keys, credential directories) are withheld from the copy, as are node_modules and other build output.

RETURNS an experiment_id plus the isolation actually applied -- read the warnings field, which tells you where your request was clamped.

SAFETY: network is disabled unless you ask for it; no host environment variable is passed unless you name it, and credential-shaped names are refused even then; CPU, memory, PIDs and wall-clock are capped.

ParametersJSON Schema
NameRequiredDescriptionDefault
timeoutNoDefault per-command wall-clock limit in seconds.
cpu_limitNoCPU cores. Clamped.
objectiveNoWhat you are trying to find out. Shows up in the report.
base_imageNoDocker image to run in, e.g. 'node:22-slim', 'python:3.12-slim'. Choose the runtime the experiment is actually about.
memory_limitNoMemory, e.g. '2GB'. Clamped.
network_modeNo'none' (default, no network at all), 'restricted' (egress on a private bridge, no reach to other sandboxes), or 'enabled'. Use 'restricted' when you must install packages.
project_pathNoAbsolute path to the project to copy in. Omit for an empty sandbox. Must not be a home or system directory.
mount_strategyNo'COPY_TO_SANDBOX' (default, safest) or 'READ_ONLY_BIND_MOUNT' for a large repo you only need to read. Writable host mounts do not exist.
setup_commandsNoCommands to run once the sandbox is ready, in order. Stops at the first failure and reports it.
environment_allowlistNoEnvironment variables to expose. 'NAME' forwards the host's value; 'NAME=value' injects a literal. Nothing else crosses the boundary.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYes
warningsNo
base_imageYes
setup_jobsNo
files_copiedNo
network_modeYesHow much of the network the sandbox can see. ``NONE`` -- no interfaces at all. The default. ``RESTRICTED`` -- an isolated bridge network shared by nothing else; egress works, but the sandbox cannot reach other sandboxes or the host's service ports. ``ENABLED`` -- the daemon's default bridge. Full egress.
project_nameYes
experiment_idYes
mount_strategyYesHow the project reaches the sandbox. ``COPY_TO_SANDBOX`` -- snapshot the tree, hand the copy to the container. The host tree is unreachable. ``READ_ONLY_BIND_MOUNT`` -- bind the real tree read-only. Faster on large repos; writes to it fail by construction.
workspace_pathYes
resource_limitsYes
environment_passedNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it delivers thoroughly: snapshot-copy semantics, no propagation back to the developer's tree, secrets withheld, network disabled by default, environment variables refused unless allowlisted, credential-shaped names rejected, and resource caps. It also tells the agent to read the warnings field for clamped settings.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but every sentence earns its place. It is front-loaded with the core definition, uses clear section markers for usage, returns, and safety, and the length is justified for a safety-critical tool with 10 parameters and no annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, 10 parameters, zero annotations, and presence of an output schema, the description is complete. It covers creation semantics, safety properties, usage timing, return behavior, warning handling, and resource restrictions. Nothing an agent needs to decide whether and how to invoke create_experiment is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful cross-parameter behavioral context: it explains how project_path is snapshot-copied, how environment_allowlist is enforced, how network_mode defaults to disabled, and how cpu/memory limits are clamped. This goes beyond what the individual parameter descriptions state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Create a disposable, isolated environment and copy a project into it.' It clearly identifies the tool's core purpose and scope, distinguishing it from siblings like execute_experiment, get_experiment, and destroy_experiment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use this tool: before risky operations like installing dependencies, running builds, migrations, or unfamiliar code. It warns to 'reach for it before the risky step, not after,' but does not explicitly name alternative tools or exclusion cases, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

destroy_experimentDestroy ExperimentA

Destroy a sandbox and everything in it, returning a final report.

USE THIS as soon as an experiment has told you what you needed. Always call it -- a sandbox left running keeps consuming the developer's CPU and memory.

IDEMPOTENT: calling it on an already-destroyed experiment is safe and returns the stored report rather than an error.

RETURNS the final report, including what changed inside the sandbox, so you can summarise the experiment after it is gone.

ParametersJSON Schema
NameRequiredDescriptionDefault
experiment_idYesThe experiment to destroy.

Output Schema

ParametersJSON Schema
NameRequiredDescription
reportNo
statusYes
experiment_idYes
jobs_cancelledNo
snapshot_removedNo
already_destroyedNo
container_removedNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden and meets it: it discloses the destructive nature, idempotency ('calling it on an already-destroyed experiment is safe and returns the stored report rather than an error'), and the return contract ('what changed inside the sandbox'). This is exactly the disclosure an agent needs for a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and organized into clearly labeled sections (usage directive, idempotency, returns). Every sentence earns its place by adding a distinct piece of information — there is no filler, repetition, or vague phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive single-parameter tool with no annotations, the description is complete: it states the action, when to call it, the cost of not calling it, the idempotent re-call behavior, and the contents of the return. An output schema exists, so the return structure itself is already covered structurally.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — the sole parameter experiment_id is already documented as 'The experiment to destroy.' The description adds no parameter-specific detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'Destroy a sandbox and everything in it' — and adds the outcome ('returning a final report'). This clearly differentiates it from siblings like get_experiment (read-only), execute_experiment (run), and cancel_job (cancel a job, not destroy the sandbox).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'USE THIS as soon as an experiment has told you what you needed. Always call it.' It also supplies the rationale (a sandbox left running consumes CPU and memory) and implicitly tells the agent not to call it prematurely — collect what you need first, then destroy.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_experimentExecute ExperimentA

Run a shell command inside a sandbox.

USE THIS for anything you would otherwise run in the developer's terminal: installs, builds, scripts, migrations, one-off exploration. The command runs in the container, never on the host.

RETURNS exit code, stdout, stderr and duration. A non-zero exit is a normal result, not an error -- read it and decide what to try next.

Set background=true for something long-running, then poll get_job_status and fetch get_job_result when it finishes. Otherwise this waits, bounded by the timeout, so it cannot hang your session.

ParametersJSON Schema
NameRequiredDescriptionDefault
commandYesShell command. Runs via /bin/sh in the workspace.
timeoutNoSeconds before the command is killed. Defaults to the experiment's.
workdirNoWorking directory. Must be inside the workspace.
backgroundNoReturn a job id immediately instead of waiting.
experiment_idYesThe experiment to run in.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
job_idYes
statusYes
stderrNo
stdoutNo
commandYes
exit_codeNo
duration_msNo
experiment_idYes
stderr_truncatedNo
stdout_truncatedNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly: it clarifies commands run in a container/workspace, never on the host; non-zero exits are normal results; background=true changes behavior; and timeout bounds prevent hangs. This is rich, honest behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four compact paragraphs, each with a distinct job: core action, usage guidance, return behavior, and background execution. The most important information is front-loaded and every sentence adds useful guidance without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers execution environment, return values, non-zero exit semantics, timeout behavior, and the background workflow. Combined with the 100% schema coverage and the presence of an output schema, an agent has enough context to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers 100% of parameters, so the baseline is 3. The description adds value beyond the schema by explaining how background=true should be used (poll get_job_status, fetch get_job_result) and by clarifying that timeout bounds execution. This elevates it above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a shell command inside a sandbox') and gives concrete examples like installs, builds, scripts, and migrations. It is clear what the tool does, but it does not explicitly distinguish itself from the sibling run_tests, which could overlap in the 'run things in the terminal' space.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: 'USE THIS for anything you would otherwise run in the developer's terminal.' It also describes the background workflow with get_job_status and get_job_result. However, it does not state exclusions or directly compare against alternatives like run_tests.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_experimentGet ExperimentA

Fetch an experiment's full state and a summary of what happened in it.

USE THIS to re-orient -- after a long gap, or to check whether a sandbox is still alive before sending more commands.

RETURNS status, base image, isolation settings, resource limits, how many commands ran and how many failed, the last test summary, change statistics and artifact count.

ParametersJSON Schema
NameRequiredDescriptionDefault
experiment_idYesThe experiment to describe.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYes
changesNo
sandboxNo
artifactsNo
objectiveYes
resourcesYes
base_imageYes
duration_msNo
commands_runYes
network_modeYesHow much of the network the sandbox can see. ``NONE`` -- no interfaces at all. The default. ``RESTRICTED`` -- an isolated bridge network shared by nothing else; egress works, but the sandbox cannot reach other sandboxes or the host's service ports. ``ENABLED`` -- the daemon's default bridge. Full egress.
project_nameYes
test_summaryNo
experiment_idYes
failed_commandsYes
host_working_treeNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It clearly indicates this is a read-style 'Fetch' operation and enumerates the state and summary contents returned: status, base image, isolation settings, resource limits, command counts, test summary, change statistics, and artifact count. This gives the agent a strong sense of what to expect without requiring the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core action, then gives concrete usage guidance, and finally a useful return summary. Every sentence earns its place, and the bullet-like return list improves scannability without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with an output schema, the description is complete: it explains when to use it, what it does, and what kind of information it returns. There are no significant gaps that would prevent an agent from selecting and invoking this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter experiment_id is already 100% described by the input schema ('The experiment to describe.'). The tool description adds no additional semantic detail about the parameter, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Fetch an experiment's full state and a summary of what happened in it.' Its return list makes the purpose concrete, but it does not explicitly differentiate from siblings like get_job_status or check_sandbox_runtime, so it stops short of full sibling-level clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit use cases: 'USE THIS to re-orient -- after a long gap, or to check whether a sandbox is still alive before sending more commands.' This is clear context for when to call it, but it does not name alternatives or state when not to use it, so it misses the strongest form of usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_job_resultGet Job ResultA

Fetch the completed result of a background command.

RETURNS the same shape as execute_experiment: exit code, stdout, stderr, duration. If the job is still running this waits for it, bounded by the job's own timeout.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesJob id to fetch.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
job_idYes
statusYes
stderrNo
stdoutNo
commandYes
exit_codeNo
duration_msNo
experiment_idYes
stderr_truncatedNo
stdout_truncatedNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses the return shape (exit code, stdout, stderr, duration) and a key blocking behavior (waits for running jobs bounded by the job's timeout). It does not cover timeout failures or cancellation scenarios, but the disclosed traits are valuable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise, front-loaded sentences: the first states the tool's purpose, the second supplies essential return and blocking behavior. No filler or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with an output schema, the description covers the essential context: what it returns, when it blocks, and how it relates to execute_experiment. It could explicitly mention that job_id comes from execute_experiment, but this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully describes job_id with 100% coverage. The description adds no extra parameter-level detail beyond the schema, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Fetch') and resource ('completed result of a background command'). It implicitly distinguishes from get_job_status by focusing on result delivery rather than status, though it does not explicitly name the sibling alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: the tool retrieves results of a background command and waits if the job is still running. However, it does not explicitly state when to prefer get_job_status or cancel_job, so no direct exclusion or alternative guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_job_statusGet Job StatusA

Check on a command started with background=true.

RETURNS status and elapsed milliseconds. Poll this, then call get_job_result once finished is true.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesJob id from execute_experiment.

Output Schema

ParametersJSON Schema
NameRequiredDescription
job_idYes
statusYes
commandYes
finishedNo
exit_codeNo
elapsed_msYes
experiment_idYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses read-only polling semantics, the elapsed-milliseconds return, and a terminal condition (`finished`). However, it does not specify the status vocabulary or failure-mode behavior — e.g., whether a failed or cancelled job ever reaches `finished`, which is a clear gap for an agent polling a background job.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no filler: purpose first, then return values, then the polling next-step. Every sentence earns its place and the key behavioral instruction is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, read-only polling tool with an output schema present, the description covers the core workflow completely: what it checks, what it returns, and what to do when done. The only meaningful omission is guidance for terminal states other than `finished` (failure/cancellation), but the output schema likely documents status values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and job_id is already documented as 'Job id from execute_experiment.' The description adds contextual value by tying job_id to commands started with background=true, but it doesn't add parameter-specific syntax or format details beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Check on a command started with background=true.' It also says what it returns (status, elapsed milliseconds), and the polling-then-result flow clearly distinguishes it from get_job_result, which retrieves the job's output rather than its status. The scope is precise and disambiguating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit usage flow: poll this for background commands, wait until `finished` is true, then switch to get_job_result. It names the sibling tool and the exact condition for switching, which is exactly the routing guidance an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspect_changesInspect ChangesA

Show what the experiment changed, against the project as it was copied in.

USE THIS before destroying a sandbox, and before telling the developer what you found. It is the evidence for your conclusion.

RETURNS created / modified / deleted file lists plus insertion and deletion counts, and optionally the unified diff. Build output and dependency directories are excluded, so a 30,000-file node_modules will not bury the two lines that matter.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_diffNoInclude unified diff bodies, not just statistics.
experiment_idYesThe experiment to inspect.
max_files_with_diffNoCap on files given line-level detail.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
changesNo
deletionsNo
truncatedNo
insertionsNo
experiment_idYes
files_createdNo
files_deletedNo
files_modifiedNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of explaining behavior. It explicitly states what the tool returns (created/modified/deleted file lists, insertion/deletion counts, optional unified diff) and mentions an important behavioral detail ('Build output and dependency directories are excluded'). It does not explicitly state that it is read-only, but the language implies a non-destructive inspection, which is transparent enough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise—three sentences that cover purpose, usage guidance, and output/exclusion details. Each sentence serves a distinct informative purpose with no redundancy. The structure flows logically from what it does, to when to use it, to what it returns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (3 parameters, 1 required, output described), the description is fully complete. It states the action, usage context, return format, and a key exclusion (build/dependency directories). There is no missing information that would prevent an agent from using the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All three parameters have schema descriptions with 100% coverage, so the baseline is 3. The descriptions are clear: include_diff, experiment_id, and max_files_with_diff are self-explanatory. The tool description adds no additional parameter-level context beyond what the schema already provides, so it neither improves nor degrades the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the primary action: showing what the experiment changed relative to the copied project. It also clarifies the scoped perspective ('against the project as it was copied in'), making the purpose unambiguous. However, it does not explicitly contrast with sibling tools, which would elevate it to a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides direct usage guidance: 'USE THIS before destroying a sandbox, and before telling the developer what you found.' This gives concrete scenarios when the tool is appropriate. It lacks an explicit 'when not to use' or alternative tool recommendation, but the provided triggers are specific and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_experimentsList ExperimentsA

List experiments, most recent first.

USE THIS to find a sandbox you created earlier, or to check for ones you forgot to destroy before creating another.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum rows.
statusNoFilter by status, e.g. 'READY', 'FAILED', 'DESTROYED'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It does reveal that results are ordered most recent first and that experiments are persistent resources that should be destroyed, which is useful context. However, it does not explicitly state that this is a read-only operation or describe any other behavioral nuances such as default status handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, with the core purpose in the first sentence and practical usage guidance in the second. Every sentence adds distinct value, and the structure front-loads the most important information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple listing tool with optional parameters and an output schema, so the description does not need to explain return values. It gives the ordering and the intended use cases. A slight gap is the absence of explicit guidance about when to prefer get_experiment for single-item lookup, but overall the tool is sufficiently contextualized.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% documentation coverage for both parameters, including defaults, constraints, and examples. The description adds no additional parameter-level meaning beyond what the schema contains, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'List experiments', and adds the ordering 'most recent first'. This distinguishes it from sibling tools like get_experiment, which retrieves a single experiment. The use-case reference to sandboxes also makes the tool's purpose concrete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use the tool: to find a previously created sandbox or to check for undestroyed experiments before creating another. It does not explicitly name alternatives or exclusion conditions, so it falls short of the strongest usage guidance, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_sandbox_fileRead Sandbox FileA

Read a file from inside the sandbox as text.

USE THIS to investigate a failure -- read the source, the config, a log -- without guessing from stack traces. Paths are workspace-relative and cannot escape it; this tool cannot read the developer's machine.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesWorkspace-relative path, e.g. 'src/index.js'.
experiment_idYesThe experiment to read from.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It states the tool is read-only, returns text, uses workspace-relative paths, and cannot escape the sandbox. It does not describe error behavior for missing files or binary files, but for a simple read tool the key safety and operational constraints are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tight and front-loaded. The first sentence states the core action, the second gives a concrete use case, and the third states a critical safety limitation. No sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity, high schema coverage, and presence of an output schema, the description is largely complete. It explains what, when, and the security boundary. Minor gaps like error behavior for nonexistent paths are left to the output schema and runtime errors.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description reinforces that paths are workspace-relative and cannot escape, which matches the schema's existing path description. It adds little beyond the schema for experiment_id, but no parameter meaning is left unclear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read a file from inside the sandbox as text.' It clearly distinguishes the tool from write_sandbox_file and other sibling operations by framing it as an investigation tool for reading source, config, or logs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage guidance: 'USE THIS to investigate a failure -- read the source, the config, a log -- without guessing from stack traces.' It also explains an important exclusion, noting it cannot read the developer's machine. It does not explicitly name a sibling alternative, but the read vs. write distinction is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_testsRun TestsA

Run the project's test suite inside a sandbox and parse the results.

USE THIS instead of execute_experiment when you want to know whether the project still works -- it detects the runner (npm, pytest, cargo, go, make) by looking at what is actually in the sandbox, and parses counts out of the output.

RETURNS exit code, stdout/stderr, duration and, when parseable, a summary with passed/failed/total and the names of failing tests. If test_summary.detected is false, trust the exit code, not the zeros.

Pass command to override detection.

ParametersJSON Schema
NameRequiredDescriptionDefault
commandNoExplicit test command. Omit to auto-detect.
timeoutNoSeconds before the run is killed.
experiment_idYesThe experiment to test in.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
job_idYes
statusYes
stderrNo
stdoutNo
commandYes
exit_codeNo
frameworkNo
duration_msNo
test_summaryNo
experiment_idYes
stderr_truncatedNo
stdout_truncatedNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of explaining behavior, and it does so well: auto-detects the runner, parses results, returns exit code/stdout/stderr/duration, and warns to trust exit code over zeros when test_summary.detected is false. It does not explicitly address side effects, but the sandbox context implies isolation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured into purpose, usage guidance, and return behavior, with no filler. Every sentence adds useful information, and the line breaks improve readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity—auto-detection, command override, parsed test summaries—the description is complete enough for an agent to call it correctly. It does not detail output schema fields, but it sufficiently describes what is returned, so no critical context appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers all three parameters with clear descriptions, and the tool description adds the important note that command overrides detection. experiment_id, timeout, and command are all semantically meaningful with no ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs the project's test suite inside a sandbox and parses results. It also explicitly contrasts with execute_experiment by framing this as the way to determine whether the project still works, which distinguishes it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit guidance to use this instead of execute_experiment when the goal is checking whether the project still works. It also explains that command can override auto-detection, giving concrete usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

write_sandbox_fileWrite Sandbox FileA

Write a file inside the sandbox, creating parent directories as needed.

USE THIS to apply a candidate fix. Prefer it over shell heredocs: no quoting to get wrong.

SAFETY: writes land in the sandbox copy only. There is no tool here that writes to the developer's project -- if a change is worth keeping, show them the diff from inspect_changes and let them apply it.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesWorkspace-relative path.
contentYesFull new contents of the file.
experiment_idYesThe experiment to write in.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, and it delivers: it discloses that writes are sandbox-only, that no tool writes to the developer's project, and that parent directories are created as needed. This is unusually clear behavioral context for a mutating tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tight and well-structured: the action is first, followed by when to use it, then a safety note. Each sentence earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, usage context, safety boundaries, and a key behavioral guarantee. Since the schema covers all parameters and an output schema exists, nothing essential is missing for an agent to correctly select and invoke this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents all three parameters with 100% coverage. The description adds very little parameter-specific meaning beyond referencing the sandbox context, so the baseline of 3 is appropriate because the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Write a file inside the sandbox.' It also adds a distinct behavioral detail, creating parent directories, and frames the tool's purpose as applying a candidate fix, clearly separating it from read_sandbox_file and other siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'USE THIS to apply a candidate fix' and instructs to prefer it over shell heredocs to avoid quoting issues. It also gives a clear when-not-to-use rule: writes only affect the sandbox, so permanent changes should be shown via inspect_changes and applied by the developer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 15 tool updatesv0.1.0
    • First observedcancel_job
    • First observedcheck_sandbox_runtime
    • First observedcollect_artifacts
    • First observedcompare_experiments
    • First observedcreate_experiment
    • First observeddestroy_experiment
    • First observedexecute_experiment
    • First observedget_experiment
    • First observedget_job_result
    • First observedget_job_status
    • First observedinspect_changes
    • First observedlist_experiments
    • First observedread_sandbox_file
    • First observedrun_tests
    • First observedwrite_sandbox_file

TDQS

A4.4/5.0
Disambiguation5/5

Each tool maps cleanly to a distinct lifecycle phase: create, execute, test, file operations, change inspection, artifact collection, job management, and teardown. Even execute_experiment versus run_tests is explicitly delineated, so there is no real ambiguity in choosing between tools.

Naming Consistency5/5

All names follow a consistent snake_case verb_noun pattern with predictable verbs like create, destroy, execute, get, list, read, write, cancel, and compare. The object nouns are similarly stable, making the toolset easy to navigate and predict.

Tool Count5/5

Fifteen tools sit at the upper edge of a well-scoped server, but every tool has a distinct purpose and none feels redundant. The background job helpers, runtime check, and comparison tool all earn their place in the sandbox workflow.

Completeness5/5

The toolset covers the full sandbox experiment lifecycle: create, run commands and tests, read and write files, inspect changes, collect artifacts, compare experiments, retrieve state, and destroy. It also includes job polling and a runtime health check, leaving no obvious dead ends for agent workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides AI coding agents with a secure, sandboxed environment for executing coding tasks including file operations, command execution, and testing. Features session management, policy enforcement, and Docker-based sandboxing for safe code execution and development workflows.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to safely execute code in isolated Docker containers with resource limits and security controls, supporting session management and automatic dependency installation.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to safely execute Python, JavaScript, and Bash code in an isolated Docker sandbox with strict security constraints.
    1
    -

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/Dhananjay-JSR/sandbox-mcp'

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