> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Sandboxing

> Run any stdio-based MCP server inside a Firecracker microVM with network isolation, file upload, and environment forwarding — one prefix in your MCP client config.

**`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 --`:

```bash theme={null}
# 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.

<Tabs>
  <Tab title="Cursor">
    Edit `~/.cursor/mcp.json`:

    ```json theme={null}
    {
      "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_..."
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Desktop">
    Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
    or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

    ```json theme={null}
    {
      "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_..."
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Code">
    Add to your project's `.mcp.json` or `~/.claude/mcp.json`:

    ```json theme={null}
    {
      "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_..."
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Windsurf">
    Edit `~/.codeium/windsurf/mcp_config.json`:

    ```json theme={null}
    {
      "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_..."
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

## CLI flags

| Flag              | Short | Description                                                                                     |
| ----------------- | ----- | ----------------------------------------------------------------------------------------------- |
| `--template`      | `-t`  | Sandbox template (default: `mcp-server` — includes Node.js + Python)                            |
| `--timeout`       |       | Sandbox timeout in seconds (default: `3600` / 1 hour)                                           |
| `--env`           | `-e`  | Forward environment variable into sandbox (`KEY` or `KEY=VAL`, repeatable)                      |
| `--file`          | `-f`  | Upload local file into sandbox (`LOCAL_PATH:REMOTE_PATH`, repeatable, max 100 MB)               |
| `--network-allow` |       | Allowed outbound domains (comma-separated). Without this flag, all outbound traffic is blocked. |
| `--verbose`       | `-v`  | Print 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.

```json theme={null}
{
  "command": "declaw",
  "args": ["mcp", "--env", "API_KEY", "--", "my-server"],
  "env": { "API_KEY": "sk-..." }
}
```

You can also set a value directly with `--env KEY=VAL`:

```bash theme={null}
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:

```bash theme={null}
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):

```json theme={null}
{
  "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](/features/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](/features/stdio) 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](/architecture/security-proxy).
5. **Cleanup** — when the MCP client disconnects (stdin closes), the CLI
   terminates the sandbox.

## Examples

### GitHub MCP server with scoped network access

```bash theme={null}
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)

```bash theme={null}
declaw mcp \
  -f ./my_tools.py:/tmp/my_tools.py \
  -- python3 /tmp/my_tools.py
```

### Filesystem MCP server (no network needed)

```bash theme={null}
declaw mcp -- npx -y @modelcontextprotocol/server-filesystem /tmp
```

### Verbose mode for debugging

```bash theme={null}
declaw mcp -v \
  --network-allow "api.example.com" \
  -- node server.js
```

Diagnostic output goes to stderr (invisible to the MCP client).

## Next steps

* [CLI overview](/cli/overview) — install the CLI, authenticate, and explore all commands
* [Network policies](/features/networking) — domain allowlists, IP/CIDR rules, enforcement details
* [Stdio](/features/stdio) — the transport layer `declaw mcp` uses under the hood
* [Security overview](/security/overview) — PII scanning, prompt injection defense, audit logging
* [Cookbook: MCP server in sandbox](/cookbook/patterns/mcp-server-in-sandbox) — run MCP servers via the SDK
