# How to Integrate Cua with Claude Code or Cursor Using the MCP Server

> Integrate Cua with Claude Code or Cursor using the MCP server. Start the MCP server with `cua serve-mcp` and register it with `claude mcp add cua` for seamless sandbox management and computer control.

- Repository: [Cua/cua](https://github.com/trycua/cua)
- Tags: how-to-guide
- Published: 2026-04-27

---

**Run `cua serve-mcp` to start a Model Context Protocol (MCP) server that exposes Cua's sandbox management and computer control tools to Claude Code or Cursor via STDIO, then register it using `claude mcp add cua -- cua serve-mcp`.**

You can integrate Cua with Claude Code or Cursor to let these AI assistants directly control sandboxes, take screenshots, execute commands, and manage skills. The `trycua/cua` repository provides a dedicated MCP server implementation that bridges the TypeScript-based CLI with Python-based FastMCP tooling, enabling seamless communication over standard input/output streams.

## MCP Server Architecture Overview

The integration relies on a hybrid TypeScript/Python architecture. The **TypeScript CLI** handles command parsing and permission validation, while the **Python FastMCP server** registers available tools and manages the STDIO transport connection.

### CLI Command Registration (TypeScript)

The `serve-mcp` command is defined in [`libs/typescript/cua-cli/src/commands/serve-mcp.ts`](https://github.com/trycua/cua/blob/main/libs/typescript/cua-cli/src/commands/serve-mcp.ts). The `registerServeMcpCommands` function attaches the sub-command to the root `cua` CLI:

```typescript
// libs/typescript/cua-cli/src/commands/serve-mcp.ts
export function registerServeMcpCommands(y: Argv) {
  y.command(
    'serve-mcp',
    'Start an MCP server for Claude Code integration',
    (yargs) => yargs
      .option('permissions', {
        alias: 'p',
        type: 'string',
        description: 'Comma-separated list of allowed permissions (default: all)'
      })
      .example('claude mcp add cua -- cua serve-mcp',
               'Add CUA as an MCP server to Claude Code'),
    serveMcpHandler
  );
}

```

The `serveMcpHandler` processes the `--permissions` flag (or reads from the `CUA_MCP_PERMISSIONS` environment variable) and launches the Python backend. This command is registered in [`libs/typescript/cua-cli/src/cli.ts`](https://github.com/trycua/cua/blob/main/libs/typescript/cua-cli/src/cli.ts) at line 66.

### FastMCP Server Implementation (Python)

The actual MCP server runs in Python via [`libs/python/mcp-server/mcp_server/server.py`](https://github.com/trycua/cua/blob/main/libs/python/mcp-server/mcp_server/server.py). It creates a `FastMCP` instance named `"cua-agent"` and registers tools based on the permission set:

```python

# libs/python/mcp-server/mcp_server/server.py

server = FastMCP(name="cua-agent")

if permissions.has('computer_screenshot'):
    server.tool(
        'computer_screenshot',
        'Take a screenshot of the sandbox screen. Returns a base64-encoded image.',
        {'sandbox': z.string().describe('Name of the sandbox to screenshot')},
        async ({ sandbox }) => {
            const result = await sendCommand(sandbox, 'screenshot', {}, token);
            # ...

        }
    )

```

The server communicates with AI clients using `StdioServerTransport`:

```python
transport = StdioServerTransport()
await server.connect(transport)

```

### Permission Model

The permission system restricts which tools the AI assistant can access. Valid permissions include `list_sandboxes`, `computer_click`, `computer_screenshot`, `skill_record`, and others defined in the `Permission` union type (lines 12-36 of [`serve-mcp.ts`](https://github.com/trycua/cua/blob/main/serve-mcp.ts)). You can specify permissions via:

- The `--permissions` CLI flag (overrides environment variables)
- The `CUA_MCP_PERMISSIONS` environment variable
- The default `ALL_PERMISSIONS` set (full access)

## Step-by-Step Integration Guide

### Install the CLI with MCP Support

First, install the Cua CLI with MCP dependencies:

```bash
pip install "cua-cli[mcp]"

# Alternative: pip install "cua-cli[all]"

```

This installs the Python MCP server component alongside the TypeScript CLI.

### Start the MCP Server

Launch the server with your desired permission level:

```bash

# Full access (default) - exposes all sandbox and computer tools

cua serve-mcp

# Limited permissions - only screenshots and sandbox listing

cua serve-mcp --permissions sandbox:list,computer:screenshot

```

When starting, the server initializes the FastMCP instance and begins listening on STDIO for incoming tool requests from Claude Code or Cursor.

### Register with Claude Code or Cursor

Add the server to Claude Code's MCP configuration:

```bash

# Basic registration with full permissions

claude mcp add cua -- cua serve-mcp

# Registration with explicit environment-based permissions

claude mcp add cua \
  -- -e CUA_MCP_PERMISSIONS=sandbox:list,computer:screenshot \
  -- cua serve-mcp

```

The `--` separator distinguishes Claude Code's arguments from the server launch command. Cursor follows a similar registration pattern using its MCP settings interface or configuration files.

### Using Tools from the Assistant

Once registered, Claude Code or Cursor can invoke Cua tools through standard MCP tool calls. For example, to take a screenshot:

```json
{
  "name": "computer_screenshot",
  "arguments": { "sandbox": "my-sandbox" }
}

```

The MCP server forwards this request to the Cua HTTP API (`/v1/vms` and `/cmd` endpoints), captures the base64-encoded PNG response, and returns it to the AI assistant for analysis.

## Practical Code Examples

### Full-Featured vs. Read-Only Server

**Full-featured server** (all tools available):

```bash
cua serve-mcp

```

**Read-only server** (screenshots only):

```bash

# Using environment variable

export CUA_MCP_PERMISSIONS=computer:screenshot
cua serve-mcp

# Or using CLI flag

cua serve-mcp --permissions computer:screenshot

```

### Example Tool Calls

**Computer interaction** - Clicking at specific coordinates:

```json
{
  "name": "computer_click",
  "arguments": {
    "sandbox": "demo-sandbox",
    "x": 340,
    "y": 210,
    "button": "left"
  }
}

```

The handler in [`serve-mcp.ts`](https://github.com/trycua/cua/blob/main/serve-mcp.ts) translates this into an HTTP POST to the sandbox's `/cmd` endpoint:

```http
POST https://demo-sandbox.sandbox.cua.ai:8443/cmd
Headers:
  X-API-Key: <your-api-key>
  X-Container-Name: demo-sandbox
Body:
{
  "command": "left_click",
  "params": { "x": 340, "y": 210 }
}

```

**Skill management** - Reading a stored skill:

```json
{
  "name": "skill_read",
  "arguments": { "name": "open-browser" }
}

```

This reads from `~/.cua/skills/open-browser`, bundling trajectory files and [`SKILL.md`](https://github.com/trycua/cua/blob/main/SKILL.md) content for the assistant to reference.

## Key Source Files Reference

When customizing or debugging your MCP integration, reference these files from the `trycua/cua` repository:

- **[`libs/typescript/cua-cli/src/commands/serve-mcp.ts`](https://github.com/trycua/cua/blob/main/libs/typescript/cua-cli/src/commands/serve-mcp.ts)** - Defines permission types, CLI argument parsing, and the `registerServeMcpCommands` function
- **[`libs/typescript/cua-cli/src/cli.ts`](https://github.com/trycua/cua/blob/main/libs/typescript/cua-cli/src/cli.ts)** - Bootstraps the `serve-mcp` command into the main `cua` CLI
- **[`libs/python/mcp-server/mcp_server/server.py`](https://github.com/trycua/cua/blob/main/libs/python/mcp-server/mcp_server/server.py)** - Implements the FastMCP server, tool registration logic, and STDIO transport
- **[`libs/python/mcp-server/mcp_server/__main__.py`](https://github.com/trycua/cua/blob/main/libs/python/mcp-server/mcp_server/__main__.py)** - Python entry point executed by the TypeScript wrapper
- **[`libs/python/cua-cli/README.md`](https://github.com/trycua/cua/blob/main/libs/python/cua-cli/README.md)** - User-facing documentation with integration examples

## Summary

- **Run `cua serve-mcp`** to expose Cua sandbox tools through an MCP-compatible server
- **Register via `claude mcp add`** to connect Claude Code or Cursor to the running server
- **Control access** using the `--permissions` flag or `CUA_MCP_PERMISSIONS` environment variable to limit available tools
- **Architecture** splits responsibilities between TypeScript CLI (parsing) and Python FastMCP (tool execution and transport)
- **Communication** occurs over STDIO using the Model Context Protocol, forwarding requests to the Cua HTTP API

## Frequently Asked Questions

### How do I restrict which tools Claude Code can use with Cua?

Pass a comma-separated permission list via the `--permissions` flag when starting the server: `cua serve-mcp --permissions computer:screenshot,sandbox:list`. Alternatively, set the `CUA_MCP_PERMISSIONS` environment variable before launching. Valid permissions include tool names like `computer_click`, `file_write`, and `skill_record` as defined in the `Permission` type.

### Can I use this MCP server with Cursor instead of Claude Code?

Yes. The MCP server in [`libs/python/mcp-server/mcp_server/server.py`](https://github.com/trycua/cua/blob/main/libs/python/mcp-server/mcp_server/server.py) uses standard STDIO transport compatible with any MCP client. Configure Cursor's MCP settings to launch `cua serve-mcp` as the command, following the same pattern used for Claude Code registration.

### Why does the MCP server require both TypeScript and Python components?

The TypeScript CLI ([`libs/typescript/cua-cli/src/commands/serve-mcp.ts`](https://github.com/trycua/cua/blob/main/libs/typescript/cua-cli/src/commands/serve-mcp.ts)) handles argument parsing, permission validation, and environment setup, then delegates to the Python FastMCP implementation ([`libs/python/mcp-server/mcp_server/server.py`](https://github.com/trycua/cua/blob/main/libs/python/mcp-server/mcp_server/server.py)) which provides the actual MCP protocol handling and tool registration. This separation leverages the FastMCP library's Python-native support while maintaining a unified CLI entry point.

### What happens if I don't specify permissions when starting the server?

If no `--permissions` flag is provided and `CUA_MCP_PERMISSIONS` is not set, the server defaults to `ALL_PERMISSIONS`, exposing every available tool including sandbox management, computer control, file operations, and skill management. This is suitable for trusted environments but should be restricted for security-sensitive deployments.