anvil
Provides a sandboxed execution environment by running code and shell commands in ephemeral Docker containers with resource limits, network isolation, and security restrictions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@anvilrun python 'print(2**10)'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
⚒ anvil
A throwaway Docker sandbox for agents.
Run code or shell commands in a resource-limited, network-isolated, single-use container and get back a structured result — stdout, stderr, exit_code, timed_out, duration_ms. So an agent can verify its work, reproduce a bug, or check output without ever touching the host.
Part of tools-for-agents. Zero npm dependencies — drives the docker CLI directly.
Safe by default
Every run is launched with:
--network none— no network unless you opt in (network: "on")--memory 512m --cpus 1 --pids-limit 512— bounded resources--cap-drop ALL --security-opt no-new-privileges— minimal privileges--rmephemeral container, work dir is a fresh temp mount, removed aftera hard timeout (default 30s, max 300s) that
docker kills the containeroptional
secure: true→ read-only rootfs + tmpfs/tmp
Related MCP server: agent-jail-mcp
CLI
node src/cli.js check # docker version + presets
node src/cli.js run python 'print(2**10)' # → 1024
node src/cli.js run node 'console.log(6*7)' # → 42
echo 'print("hi")' | node src/cli.js run python -
node src/cli.js sh 'apk info 2>/dev/null | head'Run history (anvil serve)

anvil is stateless by default. Set ANVIL_DB to record every run, then browse them in a dashboard:
export ANVIL_DB=./.anvil/runs.db # opt in to the run log
node src/cli.js run python 'print(2**10)' # …runs are now recorded
node src/cli.js serve # → http://localhost:7930 (--port to change)A zero-dependency forge log of what the sandbox executed:
Run list — every execution with its language, status (ok / failed / timed out), exit code and duration, colour-coded at a glance.
Run detail — the exact code or command, full stdout and stderr, and the resource limits it ran under (network, memory, cpus, timeout). Each block has a one-click ⧉ copy so you can lift the code or its output straight to the clipboard.
Compare two runs — hit ⇄ compare, pick any two runs, and see a side-by-side line diff of their code, stdout and stderr, plus every limit that changed (
took 258ms → 559ms,mem 512m → 256m).New run — hit + new run to type a snippet (bash / node / python), execute it in a fresh sandbox right from the dashboard, and watch the result open in the detail. Runs go through the same guarded, network-off container as the CLI (⌘/Ctrl+Enter to run). Pick a resource profile in one click — 🔒 strict (network off · 256m · 0.5 cpu · 15s), ⚙ default (512m · 1 cpu · 30s), or 🌐 networked (network on · 60s) — and the sandbox's memory, CPU, timeout and network are set for you (recorded with the run).
Run code against something —
run()has always taken{ path: content }files and written them into/workbeside your snippet (agents use it), and the form never offered it. Now + file adds fixture files — a module and its test, a parser and a sample payload — and + stdin pipes input to the process. A snippet on its own can only prove syntax; a snippet with a fixture can prove behaviour. Paths that try to climb out of the sandbox are refused before a container starts.Run a real repo, from the browser — the new-run form used to do snippets only, so the dashboard couldn't do the thing anvil is for. Switch it to command in an image, point mount at a directory, and it runs any command in any image with your repo mounted read-only at
/repo—cd /repo && npm test— without the repo ever leaving your disk or being writable by the container (touch /repo/x→ Read-only file system). There's a read-only rootfs switch too. A mount that doesn't exist is refused in the form, before docker gets a chance to fail at you.Watch it run — the sandbox writes as it goes, so anvil now says so as it goes: hit ▶ run and the container's stdout/stderr stream into a live console (with an elapsed timer) instead of leaving you staring at a spinner until it returns. A 30-second run no longer looks identical to a hung one. Streaming is opt-in on the API (
POST /api/exec?stream=1→ an event stream ending with the logged run), andrun({ onData })gives the same live chunks to any caller — the CLI, an agent, anything.Re-run — hit ↻ re-run on any run to re-execute its exact code and limits in a fresh sandbox; the new run is logged and opened, so you can compare it against the original.
Keep a run in cortex — a run is evidence: this code, in this sandbox, produced this output. Hit 🧠 → cortex and it becomes a note in your second brain — status, exit code, duration and the resource limits it ran under, the code as a fenced block, and its stdout/stderr — carrying a
#run=<id>link straight back to the run in the forge log. anvil never writes: your browser POSTs to cortex's own/api/capture(point it elsewhere withANVIL_CORTEX_URL).Link to a run — opening a run puts it in the URL (
…/#run=<id>), so any run in the log can be linked, bookmarked or handed to someone else.Prune the log — the forge log grows with every run, so ✕ delete drops a single noisy run and 🗑 clear empties the whole log. Both arm on the first click and only fire on the second (clicking away, or waiting, cancels), and both live behind
DELETEon the API — a strayGETcan never prune anything.Search — a live search box filters the log by code, command, language or captured output as you type (matches highlighted, with a running
3 / 7count);Escclears it. Composes with the status filters, so you can find "thatcurlrun that failed" in a long history.Filters + stats — narrow to failures, see ok/failed counts, average duration, and a by-language breakdown of everything the sandbox has run (
python 3 · node 1 · bash 1).Keyboard navigation — press
j/k(or ↑/↓) to move a cursor through the run list and open each run as you go — browse the whole forge log from the keyboard without touching the mouse (it stands down while you're typing in the search box or in compare mode).Keyboard-accessible — every control has a visible focus ring, and the run rows open with Tab + Enter (not just the mouse), with aria-labels throughout.
Logging is opt-in, fire-and-forget and fully guarded — it never slows or breaks a run. Try the demo without Docker: ANVIL_DB=./.anvil/runs.db node scripts/seed.js then anvil serve.
MCP server (for agents)
{
"mcpServers": {
"anvil": { "command": "node", "args": ["/abs/path/to/anvil/mcp/mcp-server.js"] }
}
}Tools
Tool | Use it to… |
| Run a |
| Run a shell command with supplied |
| Docker availability + language presets. |
Example: verify a repo's syntax without copying it
{ "name": "anvil_run_command",
"arguments": { "image": "node:22-alpine", "mount": "/path/to/repo/src",
"cmd": "node --check /repo/core.js && echo OK" } }Result shape
{ "ok": true, "exit_code": 0, "timed_out": false, "duration_ms": 178,
"image": "python:3.12-alpine", "stdout": "...", "stderr": "" }The agent toolkit
anvil is the run safely leg of tools-for-agents — an operating system for agents.
Seven zero-dependency, MCP-native tools that form one loop:
🛰️ | coordinate — shared memory, a kanban agents claim work from, a registry, a cost ledger | |
🔎 | read code — token-budgeted retrieval — search, outlines, surgical reads | |
⚒ | anvil | run safely — a throwaway Docker sandbox: network off, capped, timed |
🧠 | remember — an Obsidian-compatible second brain, wikilinked | |
🧭 | read the web — a URL becomes clean, cached, searchable markdown | |
🎯 | recall it all — one query across brain, team, reading and code | |
👁 | see — look at what you built, before you claim it works |
Reading this as an agent? /llms.txt is the map, and
/tools.json hands you all 70 MCP tools — every name, every
description, every install command — in one fetch, without cloning anything.
MIT licensed.
This server cannot be deployed
Maintenance
Related MCP Connectors
- mcp-serverOAuthai.cdbx
Build Apps and run code in 30 languages — sandboxed, with persistent sessions for agent loops.
Execute code in 8 languages (Python, JS, TS, Go, Java, C++, C, Bash) in gVisor sandboxes.
Hosted Python sandbox for package runtime verification: pip install and usable-import evidence.
Run Python code in a secure sandbox without local setup. Declare inline dependencies and execute s…
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to safely execute Python, JavaScript, and Bash code in an isolated Docker sandbox with strict security constraints.1-
- FlicenseNot gradedqualityBmaintenanceProvides MCP tools for managing disposable Docker sandboxes that let AI agents safely execute commands in isolated, ephemeral environments.-
- AlicenseNot gradedqualityBmaintenanceProvides a restricted Docker-based sandbox for LLM agents, enabling file operations, command execution, and local Git within an isolated runtime.20 npmMIT
- AlicenseAqualityBmaintenanceEnables AI coding agents to safely execute commands, run tests, and modify project files inside disposable, policy-enforced Docker sandboxes that are isolated from the host machine and its credentials.15MIT