---
title: MCP Server
description: "Reference for the Caged MCP server and available tools."
---

# MCP Server

The Caged MCP (Model Context Protocol) server bridges AI assistants like Claude Desktop, Cursor, and other MCP-compatible clients to Caged sandboxes and pipelines. It provides tools for file operations, terminal execution, pipeline management, and state store access.

## Installation

### Homebrew (macOS/Linux)

```bash
brew tap caged-dev/tap
brew install caged-mcp-server
```

### Go Install

```bash
go install github.com/caged-dev/mcp-server/cmd/mcp-server@latest
```

### Binary Download

Download from [GitHub Releases](https://github.com/caged-dev/mcp-server/releases).

## Configuration

Add to your MCP client configuration:

### Claude Desktop

`~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "caged": {
      "command": "caged-mcp-server",
      "env": {
        "CAGED_API_KEY": "caged_sk_..."
      }
    }
  }
}
```

### Cursor

`.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "caged": {
      "command": "caged-mcp-server",
      "env": {
        "CAGED_API_KEY": "caged_sk_..."
      }
    }
  }
}
```

### VS Code (Copilot)

`.vscode/mcp.json`:

```json
{
  "servers": {
    "caged": {
      "type": "stdio",
      "command": "caged-mcp-server",
      "env": {
        "CAGED_API_KEY": "caged_sk_..."
      }
    }
  }
}
```

## Environment Variables

| Variable | Description | Required |
|----------|-------------|----------|
| `CAGED_API_KEY` | API key from dashboard | Yes |
| `CAGED_API_URL` | API endpoint (default: `https://api.caged.dev`) | No |
| `CAGED_SANDBOX_ID` | Default sandbox ID for operations | No |

## Available Tools

### Sandbox Tools

#### `sandbox_list`

List all sandboxes for the authenticated account.

**Parameters:** None

**Returns:** Array of sandbox objects with id, status, template, created_at.

---

#### `sandbox_create`

Create and start a new sandbox.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `template` | string | No | Base image (default: `node-20`) |
| `cpus` | integer | No | vCPU count (default: 2) |
| `memory` | integer | No | Memory in MB (default: 512) |
| `disk` | integer | No | Disk in GB (default: 5) |
| `repo` | string | No | Git repo URL to clone |
| `branch` | string | No | Git branch (default: `main`) |

**Returns:** Created sandbox object.

---

#### `sandbox_get`

Get details of a specific sandbox.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |

**Returns:** Full sandbox object with status, resources, sessions.

---

#### `sandbox_destroy`

Destroy a sandbox permanently.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |

**Returns:** Confirmation message.

---

#### `sandbox_exec`

Execute a command in a sandbox.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |
| `command` | string | Yes | Command to execute |
| `timeout` | integer | No | Timeout in seconds (default: 60) |

**Returns:** Command output (stdout/stderr), exit code.

---

### File System Tools

#### `filesystem_read`

Read a file from a sandbox.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |
| `path` | string | Yes | File path |

**Returns:** File contents.

---

#### `filesystem_write`

Write content to a file in a sandbox.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |
| `path` | string | Yes | File path |
| `content` | string | Yes | File content |

**Returns:** Confirmation message.

---

#### `filesystem_list`

List directory contents.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `sandbox_id` | string | Yes | Sandbox ID |
| `path` | string | Yes | Directory path |

**Returns:** Array of file/directory entries.

---

### Pipeline Tools

#### `pipeline_list`

List all pipelines for the account.

**Parameters:** None

**Returns:** Array of pipeline objects.

---

#### `pipeline_get`

Get pipeline details.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |

**Returns:** Full pipeline definition with stages.

---

#### `pipeline_run`

Start a new pipeline run.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `env` | object | No | Environment variables |
| `repo` | string | No | Git repo URL |
| `branch` | string | No | Git branch |

**Returns:** Created run object.

---

#### `pipeline_runs`

List runs for a pipeline.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `limit` | integer | No | Max results (default: 20) |

**Returns:** Array of run objects.

---

#### `pipeline_cancel`

Cancel a running pipeline.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `run_id` | string | Yes | Run ID |

**Returns:** Confirmation message.

---

### Pipeline State Tools

Tools for managing the shared state store within pipeline runs. State allows stages to share data (analysis results, artifacts, configuration) without committing to git.

#### `pipeline_state_list`

List all state entries for a pipeline run.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `run_id` | string | Yes | Run ID |

**Returns:** Array of state entries:

```json
[
  {
    "key": "analysis_results",
    "value": "{\"files\": [...], \"score\": 85}",
    "type": "json",
    "mime_type": "application/json",
    "size_bytes": 42,
    "created_by": "analyze",
    "created_at": "2026-08-02T10:05:30Z",
    "expires_at": "2026-08-09T10:05:30Z"
  }
]
```

---

#### `pipeline_state_get`

Get a single state entry by key.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `run_id` | string | Yes | Run ID |
| `key` | string | Yes | State key |

**Returns:** State entry object, or error if not found.

**Example response:**

```json
{
  "key": "analysis_results",
  "value": "{\"files\": [\"src/main.ts\"], \"score\": 85}",
  "type": "json",
  "size_bytes": 42,
  "created_by": "analyze",
  "created_at": "2026-08-02T10:05:30Z",
  "expires_at": "2026-08-09T10:05:30Z"
}
```

---

#### `pipeline_state_set`

Create or update a state entry.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `run_id` | string | Yes | Run ID |
| `key` | string | Yes | State key (max 256 chars) |
| `value` | any | Yes | Value to store |
| `type` | string | No | Type: `string`, `json`, `file`, `patch`, `artifact` |
| `mime_type` | string | No | MIME type for file/artifact |
| `ttl_seconds` | integer | No | TTL in seconds (default: 604800 = 7 days) |

**Returns:** Created/updated state entry.

**Errors:**
- Key exceeds 256 characters
- Value exceeds 1 MB
- Run exceeds 100 entries
- Run exceeds 10 MB total
- TTL exceeds 30 days

---

#### `pipeline_state_delete`

Delete a state entry.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pipeline_id` | string | Yes | Pipeline ID |
| `run_id` | string | Yes | Run ID |
| `key` | string | Yes | State key |

**Returns:** Confirmation message.

---

## State Store Limits

| Limit | Value |
|-------|-------|
| Max key length | 256 characters |
| Max value size | 1 MB |
| Max entries per run | 100 |
| Max total size per run | 10 MB |
| Default TTL | 7 days |
| Max TTL | 30 days |

## Example Conversations

### Creating and Using a Sandbox

```
User: Create a Node.js sandbox and install express

AI: I'll create a sandbox and install express for you.

[Calls sandbox_create with template: "node-20"]
[Calls sandbox_exec with command: "npm install express"]

Done! I created sandbox cage_abc123 with Node.js 20 and installed express.
The sandbox is ready for development.
```

### Running a Pipeline and Checking State

```
User: Run the code-review pipeline and show me what the security agent found

AI: I'll start the pipeline and check the security review findings.

[Calls pipeline_run with pipeline_id: "code-review"]
[Waits for run to complete]
[Calls pipeline_state_get with key: "security_findings"]

The security review found:
- 2 low-severity issues in src/api.ts (missing input validation)
- 1 medium-severity issue in src/auth.ts (weak password policy)

The agent marked the review as "approved" with recommendations.
```

### Multi-Agent State Handoff

```
User: What did each agent in run-xyz789 contribute?

AI: Let me check the state store for that run.

[Calls pipeline_state_list with run_id: "run-xyz789"]

Three agents contributed to this run:

1. **implement** stage wrote:
   - Key: `implementation` — files changed, approach taken, test coverage

2. **security-review** stage wrote:
   - Key: `security_findings` — 0 critical, 2 low severity issues

3. **perf-review** stage wrote:
   - Key: `perf_findings` — 1 N+1 query identified

The final report is at key `final_report` combining all findings.
```

## Troubleshooting

### "CAGED_API_KEY not set"

Set the environment variable in your MCP client config:

```json
{
  "env": {
    "CAGED_API_KEY": "caged_sk_your_key_here"
  }
}
```

### "Sandbox not found"

The sandbox may have been destroyed or doesn't exist. List available sandboxes:

```
[Calls sandbox_list]
```

### "Rate limit exceeded"

The MCP server respects API rate limits. Wait a moment and retry, or contact support for higher limits.

### State Entry Not Found

The key may have expired (check TTL) or never been written. List all state to see available keys:

```
[Calls pipeline_state_list]
```

## Related

- [Pipeline State Store Guide](/guides/state-store) — Detailed patterns and best practices
- [Pipelines API Reference](/api-reference/pipelines) — Full endpoint documentation
- [CLI Commands](/cli/commands) — CLI reference for pipelines and state
- [Config-as-Code Pipelines](/recipes/config-pipelines) — Declarative pipeline definitions
