Agent Sandbox Registry

python-sdk

MCP Server Design

docs/en/design/mcp-server.md

MCP Server Design

Note: The abx commands shown on this page are provided by the Node.js CLI in the cli repository (npm install -g @agent-sandbox/cli). CLI-specific documentation (CLI design, tutorial, reference) lives there too; this repository documents the Python SDK (agent-sandbox) and the container-side runtime (agent-sandbox-server).

Agent Sandbox MCP Server exposes sandbox capabilities as MCP (Model Context Protocol) Tools, allowing AI Agents (Cursor, Claude Desktop, VS Code, etc.) to directly operate cloud sandboxes.

Implemented surface (kept in sync with client-sdk/src/agent_sandbox/agent/):


1. Tools Definition

All 7 tools are defined in TOOL_SCHEMAS (agent/tools.py). Omitting sandbox_id targets the default sandbox (see Section 2).

create_sandbox

{
  "name": "create_sandbox",
  "description": "Create a cloud sandbox and make it the session default. When template is omitted, use the MCP server's configured template (code-interpreter-v1 for abx mcp start).",
  "inputSchema": {
    "type": "object",
    "properties": {
      "template": {
        "type": "string",
        "description": "Sandbox template name; omitted means the server template"
      },
      "timeout": {
        "type": "integer",
        "description": "Sandbox timeout in seconds, default 300",
        "default": 300
      },
      "envs": {
        "type": "object",
        "description": "Environment variable key-value pairs",
        "additionalProperties": { "type": "string" }
      }
    }
  },
  "returns": {
    "sandbox_id": "string — Sandbox ID",
    "status": "string — Sandbox status",
    "url": "string — Sandbox access URL"
  }
}

run_code

{
  "name": "run_code",
  "description": "Execute code in the sandbox (via the code interpreter). Supports Python, JavaScript, and more. Uses the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "code": { "type": "string", "description": "Code to execute" },
      "language": {
        "type": "string",
        "description": "Programming language, default python",
        "enum": ["python", "javascript", "shell", "typescript", "r"],
        "default": "python"
      },
      "sandbox_id": {
        "type": "string",
        "description": "Sandbox ID; uses the default sandbox when omitted"
      },
      "timeout": {
        "type": "integer",
        "description": "Execution timeout in seconds, default 30",
        "default": 30
      }
    },
    "required": ["code"]
  },
  "returns": {
    "stdout": "string",
    "stderr": "string",
    "exit_code": "integer",
    "output_files": "array — [{name, path, size}] generated files"
  }
}

run_command

{
  "name": "run_command",
  "description": "Execute a shell command in the sandbox. Uses the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "command": { "type": "string", "description": "Shell command" },
      "sandbox_id": { "type": "string", "description": "Sandbox ID" },
      "cwd": {
        "type": "string",
        "description": "Working directory; omitted uses the image workdir",
        "default": "/app"
      },
      "timeout": {
        "type": "integer",
        "description": "Execution timeout in seconds, default 60",
        "default": 60
      }
    },
    "required": ["command"]
  },
  "returns": {
    "stdout": "string",
    "stderr": "string",
    "exit_code": "integer"
  }
}

read_file

{
  "name": "read_file",
  "description": "Read file content from the sandbox. Uses the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": { "type": "string", "description": "Absolute file path" },
      "sandbox_id": { "type": "string", "description": "Sandbox ID" },
      "encoding": {
        "type": "string",
        "description": "File encoding, default utf-8",
        "default": "utf-8"
      }
    },
    "required": ["path"]
  },
  "returns": { "content": "string" }
}

write_file

{
  "name": "write_file",
  "description": "Create or overwrite a file in the sandbox. Uses the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": { "type": "string", "description": "Absolute file path" },
      "content": { "type": "string", "description": "File content" },
      "sandbox_id": { "type": "string", "description": "Sandbox ID" }
    },
    "required": ["path", "content"]
  },
  "returns": { "success": "boolean", "bytes_written": "integer" }
}

list_files

{
  "name": "list_files",
  "description": "List files and subdirectories in a sandbox directory. Uses the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Directory path, default /",
        "default": "/app"
      },
      "sandbox_id": { "type": "string", "description": "Sandbox ID" }
    }
  },
  "returns": {
    "files": "array — [{name, path, type, size}]"
  }
}

kill_sandbox

{
  "name": "kill_sandbox",
  "description": "Destroy the specified sandbox, or the default sandbox when sandbox_id is omitted.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sandbox_id": {
        "type": "string",
        "description": "Sandbox ID to destroy; destroys the default sandbox when omitted"
      }
    }
  },
  "returns": { "success": "boolean" }
}

2. Session Binding Design

Default Sandbox Concept

The MCP Server introduces a "default sandbox" concept to simplify Agent operations:

graph TD
    A["Agent's first tool call (no sandbox_id)"] --> B[MCP Server automatically creates a default sandbox]
    B --> C["Subsequent calls without sandbox_id reuse the default sandbox"]

Behavior rules (implemented by SandboxManager in agent/mcp.py):

  1. create_sandbox creates a sandbox and makes it the default. Later calls that omit sandbox_id use that sandbox. Earlier sandboxes stay alive until kill_sandbox or the session ends
  2. When there is no default yet, the first tool call that omits sandbox_id lazily creates one. Concurrent lazy creates share a single sandbox
  3. Default template: code-interpreter-v1 when started via abx mcp start (the CLI default); base when constructing SandboxMCPServer / the HTTP SessionStore programmatically without an explicit template. create_sandbox uses that server template when template is omitted
  4. kill_sandbox without sandbox_id destroys the default sandbox, and returns an error when there is no default. Session end destroys every sandbox in the session — STDIO EOF / server shutdown, or HTTP DELETE /mcp / idle session TTL expiry
  5. An explicit sandbox_id addresses that sandbox and does not change the default. Each use calls Sandbox.set_timeout with the timeout from create, extending the lifetime
sequenceDiagram
    participant Agent
    participant MCP as MCP Server
    participant SB1 as sb-001
    participant SB2 as sb-002

    Note over Agent,MCP: Session starts
    Agent->>MCP: run_code("print(1)")
    MCP->>SB1: Auto-create default sandbox sb-001
    Agent->>MCP: run_code("print(2)")
    MCP->>SB1: Reuse sb-001
    Agent->>MCP: create_sandbox(template=...)
    MCP->>SB2: Create sb-002 and make it the default
    Agent->>MCP: write_file / run_code (no sandbox_id)
    MCP->>SB2: Use sb-002
    Agent->>MCP: run_code("...", sandbox_id=sb-001)
    MCP->>SB1: Explicit id still addresses sb-001
    Note over Agent,MCP: Session ends
    MCP->>SB1: Destroy sb-001 and sb-002

3. Transport Methods

STDIO — Local IDE Integration

graph LR
    IDE["IDE / Agent<br/>Cursor, Claude, VS Code"] <-->|"STDIO stdin/stdout<br/>newline-delimited JSON-RPC 2.0"| MCP["MCP Server<br/>python -m agent_sandbox.agent.mcp"]
    MCP --> SM[SandboxManager]
    SM --> FC[Alibaba Cloud FC]

Streamable HTTP — Remote Deployment

graph LR
    A["Client A - Cursor"] <-->|"Streamable HTTP<br/>POST /mcp"| MCP["MCP Server<br/>FC function / uvicorn"]
    B["Client B - Claude"] <-->|"Streamable HTTP<br/>POST /mcp"| MCP
    MCP --> SM["SessionStore<br/>routes by Mcp-Session-Id"]
    SM --> FC[Alibaba Cloud FC]

Authentication

Environment Variables

Variable Purpose
ABX_SANDBOX_API_KEY Sandbox backend API key
ABX_SANDBOX_BASE_URL Platform API URL
ABX_SANDBOX_DOMAIN Sandbox domain
ABX_DEFAULT_TEMPLATE Default sandbox template
ABX_MCP_AUTH_TOKEN Bearer token for client authentication (HTTP transport)

4. Server Architecture

graph TD
    subgraph MCP["MCP Server"]
        TL["Transport Layer\nSTDIO (mcp.py) / Streamable HTTP (mcp_http.py)"]
        TR["Tool Registry\n7 P0 tools (agent/tools.py)"]
        SM["SandboxManager / SessionStore"]
        RR["JSON-RPC Router\ninitialize / tools/list / tools/call / ping"]
        SC["Sandbox Client\nagent_sandbox SDK"]
    end
    TL --> RR
    TR --> RR
    SM --> RR
    RR --> SC
    SC --> FC["Alibaba Cloud FC Sandbox Runtime"]

5. Installation and CLI

The Python server is registered in an IDE like any STDIO MCP server. The entry is python -m agent_sandbox.agent.mcp; the IDE passes the credentials in env. Examples are in Section 6.

The abx mcp install --target cursor|claude|vscode (merges an agent-sandbox entry into the IDE config), abx mcp status (server name, transport, tool list, whether an API key is configured, per-IDE install flags), abx mcp start|stop and abx mcp deploy commands belong to the Node.js CLI; their design is the CLI's MCP Server design.

6. Configuration Examples

Claude Desktop

// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "agent-sandbox": {
      "command": "python",
      "args": ["-m", "agent_sandbox.agent.mcp"],
      "env": {
        "ABX_SANDBOX_API_KEY": "your-api-key"
      }
    }
  }
}

Cursor

// ~/.cursor/mcp.json
{
  "mcpServers": {
    "agent-sandbox": {
      "command": "python",
      "args": ["-m", "agent_sandbox.agent.mcp"],
      "env": {
        "ABX_SANDBOX_API_KEY": "your-api-key"
      }
    }
  }
}

VS Code

// .vscode/mcp.json
{
  "servers": {
    "agent-sandbox": {
      "type": "stdio",
      "command": "/path/to/python",
      "args": ["-m", "agent_sandbox.agent.mcp"]
    }
  }
}

The CLI's abx mcp install writes the equivalent entries with command set to abx and args set to ["mcp", "start"].

Remote (Streamable HTTP)

After deploying the HTTP app (Section 7), point clients at the endpoint; add a Bearer header when a token is configured:

{
  "mcpServers": {
    "agent-sandbox-remote": {
      "url": "https://<FC_HTTP_TRIGGER_URL>/mcp",
      "headers": {
        "Authorization": "Bearer <BEARER_TOKEN>"
      }
    }
  }
}

7. FC Deployment

Status: abx mcp deploy generates a deployment artifact; automatic FC API deployment is not implemented. Manual deployment steps are printed after generation.

Architecture

The MCP Server can be deployed to Alibaba Cloud Function Compute (FC) as a Streamable HTTP endpoint, leveraging FC's MCP session affinity routing.

graph TB
    CLI["abx mcp deploy → artifact directory"]
    FC["FC function: agent-sandbox-mcp (created manually)"]
    Sandbox["Envd sandbox (separate FC instance)"]

    CLI --> FC
    FC --> Sandbox

    subgraph FC_Function ["FC function"]
        ASGI["app.py → agent_sandbox.agent.mcp_http:asgi_app"]
        Trigger["HTTP trigger: POST/GET/DELETE /mcp"]
        Session["Session affinity: Mcp-Session-Id"]
        Env["Env vars: ABX_SANDBOX_API_KEY / ABX_MCP_AUTH_TOKEN / ABX_DEFAULT_TEMPLATE"]
    end

Deployment Command

The artifact is generated by abx mcp deploy (options, region resolution, token sources); see the CLI's MCP Server design and CLI Design — mcp deploy. The sections below describe the artifact and the application it runs, which this SDK provides.

Artifact Contents

File Content
requirements.txt agent-sandbox[mcp], uvicorn>=0.29
app.py ASGI entry point reading ABX_MCP_AUTH_TOKEN, ABX_SANDBOX_API_KEY, ABX_SANDBOX_BASE_URL, ABX_SANDBOX_DOMAIN, ABX_DEFAULT_TEMPLATE from the FC function environment
config.yaml YAML deployment manifest (not an FC API payload): function_name, region, runtime (python3.10), handler (app.app), memory, timeout, environment_variables, http_trigger (methods POST/GET/DELETE + enable_session_affinity), optional custom_domain

abx mcp deploy also prints manual deployment steps (package the artifact, create the function via the FC console or SDK, create an HTTP trigger, enable Mcp-Session-Id affinity if supported) and an IDE config template with the Bearer token masked.

Key Design Points

See the MCP Integration guide for end-to-end usage; the full abx mcp deploy parameter reference is in the CLI repository (see Deployment Command).


The Node.js abx CLI has its own MCP server implementation and the commands around it: MCP Server design (CLI) (abx mcp install|start|stop|status|deploy, tool schemas as implemented in TypeScript, FC deployment) and CLI Command System.