Are you the author? Sign in to claim
๐จ Throwaway Docker sandbox for agents: run code/commands in isolated, resource-limited containers with structured resul
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.
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--rm ephemeral container, work dir is a fresh temp mount, removed afterdocker kills the containersecure: true โ read-only rootfs + tmpfs /tmpnode 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'
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:
took 258ms โ 559ms, mem 512m โ 256m).run() has always taken { path: content } files and written them into /work beside 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./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.POST /api/exec?stream=1 โ an event stream ending with the logged run), and run({ onData }) gives the same live chunks to any caller โ the CLI, an agent, anything.#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 with ANVIL_CORTEX_URL).โฆ/#run=<id>), so any run in the log can be linked, bookmarked or handed to someone else.DELETE on the API โ a stray GET can never prune anything.3 / 7 count); Esc clears it. Composes with the status filters, so you can find "that curl run that failed" in a long history.python 3 ยท node 1 ยท bash 1).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).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.
{
"mcpServers": {
"anvil": { "command": "node", "args": ["/abs/path/to/anvil/mcp/mcp-server.js"] }
}
}
| Tool | Use it toโฆ |
|---|---|
anvil_run_code | Run a bash / node / python snippet, get structured output. |
anvil_run_command | Run a shell command with supplied files and/or a host dir mounted read-only at /repo (e.g. run a test suite). |
anvil_check | Docker availability + language presets. |
{ "name": "anvil_run_command",
"arguments": { "image": "node:22-alpine", "mount": "/path/to/repo/src",
"cmd": "node --check /repo/core.js && echo OK" } }
{ "ok": true, "exit_code": 0, "timed_out": false, "duration_ms": 178,
"image": "python:3.12-alpine", "stdout": "...", "stderr": "" }
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:
| ๐ฐ๏ธ | agent-hq | coordinate โ shared memory, a kanban agents claim work from, a registry, a cost ledger |
| ๐ | lens | read code โ token-budgeted retrieval โ search, outlines, surgical reads |
| โ | anvil | run safely โ a throwaway Docker sandbox: network off, capped, timed |
| ๐ง | cortex | remember โ an Obsidian-compatible second brain, wikilinked |
| ๐งญ | scout | read the web โ a URL becomes clean, cached, searchable markdown |
| ๐ฏ | recall | recall it all โ one query across brain, team, reading and code |
| ๐ | iris | 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.
40+ tools for querying dashboards, alerts, datasources, and logs in Grafana
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases