---
title: "Start MCP servers in a sandbox and get the URLs your agent connects to."
method: POST
path: "/v1/sandboxes/{id}/mcp"
tags: ["mcp"]
---

# Start MCP servers in a sandbox and get the URLs your agent connects to.

`POST /v1/sandboxes/{id}/mcp`

## Request

- Base URL: `https://api.withruntime.com`
- URL: `https://api.withruntime.com/v1/sandboxes/{id}/mcp`
- Auth: HTTP bearer

Starts the gateway in the sandbox and answers once it listens: each server has a Streamable HTTP URL, and every request needs the Authorization header returned. Servers install in the background (npm, uv or a pinned release, checked against its SHA-256) and report installing, then ready; poll GET .../mcp. They run as the sandbox's user behind its own network rules, which this never changes: a host the rules refuse is a warning. Needs exec.

## Path parameters

- `id` string, required: Resource identifier (UUID).

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `servers` object[], required
    - `id` string: A catalog server's id, from GET /v1/mcp/catalog.
    - `name` string: Its name in the URL (/mcp/<name>). The id by default; required for command.
    - `secrets` object: A setting the catalog marks secret, to the Runtime secret that fills it: {"GITHUB_PERSONAL_ACCESS_TOKEN": "GITHUB_TOKEN"}. The server sees only a placeholder; the egress proxy puts the value into its HTTPS requests to the secret's hosts.
    - `env` object: Plain settings. Proxy variables cannot be set.
    - `options` object
    - `command` string[]: Instead of id: your own stdio MCP server, a program in the sandbox and its arguments.
  - `port` integer: The gateway's port in the sandbox. Default 8765.
  - `replace` boolean: Stop a gateway already running and start this one.
  - `public` boolean: Serve the gateway at a public preview: URLs with no link token that never expire, for an agent to be configured with once. The Authorization header still guards every request, and it is kept across starts (after a restart, or with replace) until DELETE .../mcp. Needs an account with a kept top-up, as any public preview.

## Response `200`

Success

- object
  - `running` boolean, required
  - `port` integer, nullable
  - `public` boolean: The URLs are a public preview: no link token, no expiry.
  - `token` string: Send it as Authorization: Bearer <token>.
  - `headers` object: The headers every MCP request needs.
  - `urlExpiresAt` string, nullable: When the URLs' link token expires; read again for new ones. null for public URLs, which do not expire.
  - `servers` object[], required
    - `name` string, required
    - `status` 'installing' | 'ready' | 'failed', required
    - `message` string, nullable
    - `url` string, nullable: The server's Streamable HTTP endpoint.
  - `warnings` string[]

## Other responses

- `default`: Error

---

[API](https://skmtc.dev/withruntime/apis/runtime-cloud-api.md) · [All operations](https://skmtc.dev/withruntime/apis/runtime-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/withruntime/apis/runtime-cloud-api/revisions/6f4012286988?raw)
