mcpd, an MCP server for your sandbox.
mcpd turns a machine into an MCP server. Every tool it offers is a command it runs there, declared as JSON. The agent loop runs somewhere else.
substructure.ai builds mcpd. It is plain MCP over HTTP, so any client connects to it.
Declare a tool.
A tool is its schema and the command that runs it. Nothing else.
mcpd.json{ "tool": [ { "name": "bash", "description": "Run a bash command. This is a sandbox you can use for anything.", "inputSchema": { "type": "object", "required": ["command"], "properties": { "command": { "type": "string", "description": "The command to run." } } }, "_meta": { "dev.subs/exec": { "argv": ["/bin/bash", "-lc", "{command}"] } } } ] }Serve it. MCP is at /mcp on 127.0.0.1:8080 until you say otherwise.
Give it to an agent.
Declare the connection in subs.toml, then give it to an agent.
subs.toml[mcp.sandbox] url = "http://127.0.0.1:8080/mcp" [agent.coder] llm = "openrouter" model = "deepseek/deepseek-v4-flash-0731" system = "You are a coding agent." mcp = ["sandbox"]Hand the connection its token once. It never appears in the file.
Or any other client.
It is MCP over HTTP with a bearer token. Anything that speaks that connects to it.
Claude Code.
Codex.
~/.codex/config.toml[mcp_servers.sandbox] url = "http://127.0.0.1:8080/mcp" bearer_token_env_var = "MCPD_TOKEN"