Skip to main content
declaw mcp wraps any stdio-based MCP server in a Declaw sandbox. Add declaw mcp -- before your existing server command in your MCP client config and the server runs inside a Firecracker microVM with:
  • Network deny-all by default — outbound traffic is blocked unless you explicitly allowlist domains with --network-allow.
  • Filesystem isolation — the server cannot read your host files (~/.ssh, ~/.aws, .env, etc.).
  • Environment forwarding — pass only the credentials the server needs with --env.
  • File upload — send local files into the sandbox with --file.
  • Automatic cleanup — the sandbox is destroyed when the MCP client disconnects (stdin closes).

Why sandbox MCP servers?

MCP servers run with the same permissions as your IDE. A malicious or compromised server can:
  • Read credentials from ~/.ssh/, ~/.aws/, ~/.npmrc, .env
  • Exfiltrate data to external endpoints
  • Modify files on your machine
  • Access cloud metadata services
declaw mcp eliminates these risks by running the server in an ephemeral microVM that has no access to your host filesystem or network.

Quick start

Prefix your MCP server command with declaw mcp --:
# Before (runs on your machine with full access)
npx -y @modelcontextprotocol/server-github

# After (runs in an isolated sandbox)
declaw mcp -- npx -y @modelcontextprotocol/server-github

Client configuration

Configure your MCP client to use declaw as the command. The -- separator separates Declaw flags from the MCP server command.
Edit ~/.cursor/mcp.json:
{
  "mcpServers": {
    "github": {
      "command": "declaw",
      "args": [
        "mcp",
        "--env", "GITHUB_PERSONAL_ACCESS_TOKEN",
        "--network-allow", "registry.npmjs.org,api.github.com,github.com,codeload.github.com",
        "--", "npx", "-y", "@modelcontextprotocol/server-github"
      ],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
      }
    }
  }
}

CLI flags

FlagShortDescription
--template-tSandbox template (default: mcp-server — includes Node.js + Python)
--timeoutSandbox timeout in seconds (default: 3600 / 1 hour)
--env-eForward environment variable into sandbox (KEY or KEY=VAL, repeatable)
--file-fUpload local file into sandbox (LOCAL_PATH:REMOTE_PATH, repeatable, max 100 MB)
--network-allowAllowed outbound domains (comma-separated). Without this flag, all outbound traffic is blocked.
--verbose-vPrint diagnostic logs to stderr

Environment forwarding

Use --env KEY to forward a variable from your shell environment into the sandbox. The MCP client’s env block sets variables in the process that launches declaw, and --env passes them through to the sandboxed server.
{
  "command": "declaw",
  "args": ["mcp", "--env", "API_KEY", "--", "my-server"],
  "env": { "API_KEY": "sk-..." }
}
You can also set a value directly with --env KEY=VAL:
declaw mcp --env MY_VAR=hello -- my-server

Network allowlist

Without --network-allow, all outbound traffic is blocked (deny-all) and an informational message is printed to stderr: [declaw] network: deny-all (use --network-allow to permit outbound hosts). Specify only the domains the server needs:
declaw mcp \
  --network-allow "api.github.com,github.com,codeload.github.com" \
  -- npx -y @modelcontextprotocol/server-github
Multiple domains are comma-separated in a single flag value.

File upload

Upload local files into the sandbox before the server starts. Useful for single-file MCP servers (e.g. FastMCP scripts):
{
  "command": "declaw",
  "args": [
    "mcp",
    "-f", "/path/to/server.py:/tmp/server.py",
    "--", "python3", "/tmp/server.py"
  ]
}
The format is LOCAL_PATH:REMOTE_PATH. The flag is repeatable for multiple files. Maximum file size is 100 MB.

How it works

declaw mcp creates a Firecracker microVM, starts your MCP server command inside it via stdio, and bridges stdin/stdout between your MCP client and the sandboxed process:
┌──────────────┐  stdin/stdout  ┌─────────────────┐  Declaw API  ┌──────────────────────┐
│  MCP Client  │ ◄────────────► │  declaw mcp CLI │ ◄──────────► │  Firecracker microVM │
│  (Cursor,    │                │  (local process) │              │                      │
│   Claude,    │                │                  │              │  ┌────────────────┐  │
│   etc.)      │                │                  │              │  │  MCP Server    │  │
└──────────────┘                └─────────────────┘              │  │  (your command) │  │
                                                                 │  └────────────────┘  │
                                                                 │  Network: deny-all   │
                                                                 └──────────────────────┘
  1. Sandbox creation — boots a microVM with the mcp-server template (Node.js + Python pre-installed).
  2. File upload — if --file flags are present, files are uploaded before the server starts.
  3. Stdio bridge — the CLI starts the server command via the stdio API and pipes local stdin/stdout to the remote process. MCP JSON-RPC messages flow transparently.
  4. Network enforcement — all outbound traffic is blocked by default. --network-allow adds domain-level exceptions via the L7 TCP proxy.
  5. Cleanup — when the MCP client disconnects (stdin closes), the CLI terminates the sandbox.

Examples

GitHub MCP server with scoped network access

declaw mcp \
  --env GITHUB_PERSONAL_ACCESS_TOKEN \
  --network-allow "registry.npmjs.org,api.github.com,github.com,codeload.github.com" \
  -- npx -y @modelcontextprotocol/server-github

Custom FastMCP server (single file)

declaw mcp \
  -f ./my_tools.py:/tmp/my_tools.py \
  -- python3 /tmp/my_tools.py

Filesystem MCP server (no network needed)

declaw mcp -- npx -y @modelcontextprotocol/server-filesystem /tmp

Verbose mode for debugging

declaw mcp -v \
  --network-allow "api.example.com" \
  -- node server.js
Diagnostic output goes to stderr (invisible to the MCP client).

Next steps