Skip to main content
Sandboxed workspaces (Bubblewrap, Docker, E2B, Daytona, K8s, OpenSandbox) cannot register host-side MCP clients directly: the MCP servers live inside the container or sandbox, and stdio sessions cannot cross that boundary. AgentScope solves this with an MCP gateway, a lightweight FastAPI process that runs inside the workspace, owns the upstream MCP sessions, and exposes them over a single authenticated HTTP endpoint that the host talks to. The gateway exposes a small REST surface (GET /health, GET/POST/DELETE /mcps, GET /mcps/{name}/tools, POST /mcps/{name}/tools/{tool}, PUT /mcps/{name}/runtime-headers) protected by a per-workspace bearer token minted at each initialize(). On the host, two adapters preserve the standard interfaces:
Updating HTTP headers at runtime works through the gateway proxy too, but the proxy must already be connected, since what changes is the live client on the gateway side. connect registers the current runtime headers along with the client, so they survive a reconnect. A RuntimeError is raised when the workspace image predates the endpoint or the gateway restarted and holds no live client.
This abstraction keeps the agent-side code identical across every workspace backend: a workspace returns MCPClient instances from list_mcps() regardless of whether the upstream session lives on the host (LocalWorkspace) or inside an isolated environment (all sandboxed workspaces).
The gateway is not published on a host-reachable network port. Each host-to-gateway call is executed inside the sandbox: GatewayMCPClient issues the request as a curl command run through the backend’s exec_shell, so the gateway only ever listens on the sandbox’s own loopback. Because the sandbox exposes no externally-listening service, this design avoids the attack surface an outward-facing gateway port would introduce.
BubblewrapWorkspace is the exception: it shares the host network namespace, so its gateway loopback is the host’s loopback and other local processes could reach the port. Two extra safeguards apply there: