Cloud Computer AI

API reference

These are the console endpoints the agent view calls. Shapes match the Express handlers in server/index.js and server/computer-lifecycle.js. No secrets are included.

Send Authorization: Bearer and the Clerk session token on /api routes that are not public. The browser helper is window.OpenPCAuth.getToken(). Create API keys with POST /api/api-keys while that session is valid. The secret is returned once. Later lists omit it. Session checks verify the Clerk token.

Public

Routes that do not require a session
MethodPathResponse
GET/api/flags{ agentView, a11yFocusSafe, mcp, ownerLock, desktopFrameA11y, a11yP2CanvasAlt, desktopOcr, canvasListView, composeServices }. Each is true only when its env var is 1: AGENT_VIEW_ENABLED, A11Y_P3_FOCUS_SAFE, MCP_ENABLED, OWNER_LOCK_ENABLED, DESKTOP_FRAME_A11Y, A11Y_P2_CANVAS_ALT, DESKTOP_OCR_ENABLED, CANVAS_LIST_VIEW, COMPOSE_SERVICES_ENABLED.
GET/api/configClerk publishable configuration for the sign-in gate
GET/api/healthProcess health
GET/llms.txtShort agent map
GET/llms-full.txtRequest and response notes
GET/.well-known/ccai-actions.jsonAgent-view action catalog
GET/openapi.jsonOpenAPI 3.1 for the REST endpoints the MCP tools call
GET/.well-known/oauth-protected-resourceProtected-resource metadata when MCP_ENABLED=1

GET /agent serves the agent view when the flag is on, and redirects 302 to /app when it is off.

Computers

Computer lifecycle
MethodPathBodyResponse
GET/api/computers—{ computers }
POST/api/computersname, templateId, provider, size, vcpu, memoryMb, diskGb, ttlHours, x, y, disclosureAck, optional services201 { computer }. services is queued after the computer is running when COMPOSE_SERVICES_ENABLED=1.
GET/api/computers/:id—{ computer }
PATCH/api/computers/:idname, x, y{ computer }. x and y are the canvas position on the shared computer record. There is no move_computer MCP tool.
POST/api/computers/:id/start—{ computer }
POST/api/computers/:id/stop—{ computer }
DELETE/api/computers/:id—{ ok, id }
GET/api/computers/:id/screenshot—{ pngBase64 }
GET/api/computers/:id/screen-text—{ text, cachedAt, engine: "tesseract" } when DESKTOP_OCR_ENABLED=1. 404 when the flag is off. 501 ocr_unavailable when tesseract is missing. Same visibility as screenshot.
GET/api/services—{ services } catalog when COMPOSE_SERVICES_ENABLED=1. 404 { error: "services disabled" } when the flag is off.
GET/api/computers/:id/services—{ services } on that computer. 404 { error: "services disabled" } when the flag is off.
POST/api/computers/:id/servicesserviceId202 { computer, services }. Dependencies queue first. 400 unknown service. 409 when the computer is not running.
POST/api/computers/:id/services/:sid/health—{ services }. 409 when the computer is not running. 404 when the service was not added.
POST/api/computers/:id/clickx, y, button (left, middle, right). Optional nx, ny, double, move{ success, action }
POST/api/computers/:id/typetext{ success, action: "type" }
POST/api/computers/:id/keykey (example ctrl+c){ success, action: "key" }
POST/api/computers/:id/scrolldirection up or down, amount 1–20{ success, action: "scroll" }
POST/api/computers/:id/bashcommand or cmd, optional timeoutMs{ exitCode, stdout, stderr }
GET/api/computers/:id/backup-status—{ id, name, host, backup }
POST/api/computers/:id/stream—{ streamUrl, password? }

Template ids come from GET /api/workspace field templates. A Railway template also needs disclosureAck: true. size: "small" is 1 vCPU and 4096 MB. size: "medium" is 2 vCPU and 8192 MB. Template t_docker is a fresh Ubuntu desktop with Docker Engine, Docker Compose plugin (v2.24+), git, curl, jq and a terminal. Docker starts at boot. It uses at least 2 vCPU and 4096 MB.

Screenshot bytes are raw base64 PNG, without a data: prefix. Scroll does not take pixel dx/dy. The agent view converts dy (negative up, positive down) into direction and amount.

When OWNER_LOCK_ENABLED=1, stop, start, click, type, key, scroll, exec, bash, ensure-template, railway, backup-restore, PATCH, and DELETE return 403 { error: "Only the owner or an admin can control this computer", code: "not_owner" } unless the caller is the owner, a platform admin, or auth bypass. Shared Grok Bot, Ask Grok, and pinned computers stay listable and screenshot-able. A layout-only PATCH { x, y } is owner-locked because those fields live on the shared computer record. HTTP 429 responses set Retry-After in seconds and the same number as retryAfter in the JSON. railway_daily_cap is 3600, railway_active_cap is 300, and any other 429 is 60.

Workspace, credits, legacy MCP

MCP server

When MCP_ENABLED=1, the streamable HTTP MCP server is https://app.cloudcomputerai.com/mcp. Protocol versions: 2025-06-18, 2025-03-26, 2024-11-05. POST accepts a JSON-RPC request or batch and responds application/json. GET and DELETE return 405. The server is stateless.

Create a personal access token while signed in with Clerk: human canvas Settings → Personal access tokens, or /agent → API & tokens. POST /api/tokens with { name, expiresDays } returns the plaintext ccai_pat_… token once. GET /api/tokens lists prefix and dates. DELETE /api/tokens/:id revokes. Those routes reject a token used as the caller (403). The server stores only the sha256 hash.

Send Authorization: Bearer ccai_pat_…. A Clerk session JWT is also accepted on /mcp. Missing or invalid credentials return 401 with WWW-Authenticate: Bearer realm="cloudcomputerai", resource_metadata="https://app.cloudcomputerai.com/.well-known/oauth-protected-resource".

Tools, each implemented by calling the matching REST route: list_computers, get_computer, list_templates (GET /api/workspace), launch_computer, start_computer, stop_computer, screenshot_computer, delete_computer, click_computer, type_text, press_key, scroll. When DESKTOP_OCR_ENABLED=1, screen_text { id } (readOnlyHint) calls GET /api/computers/:id/screen-text. It is omitted from tools/list when the flag is off. When COMPOSE_SERVICES_ENABLED=1, list_services { id? } (readOnlyHint) calls GET /api/services or GET /api/computers/:id/services, and add_service { id, serviceId } calls POST /api/computers/:id/services. Both are omitted from tools/list when the flag is off. There is no move_computer tool. delete_computer requires confirm to equal exactly DELETE <id>. Any other value returns an error and does not call DELETE. A REST 403 is returned as MCP isError text, including not_owner.

Claude Code

claude mcp add --transport http cloudcomputerai https://app.cloudcomputerai.com/mcp --header "Authorization: Bearer ccai_pat_..."

Claude Desktop

claude_desktop_config.json

{"mcpServers":{"cloudcomputerai":{"command":"npx","args":["-y","mcp-remote","https://app.cloudcomputerai.com/mcp","--header","Authorization:${CCAI_TOKEN}"],"env":{"CCAI_TOKEN":"Bearer ccai_pat_..."}}}}

Cursor

~/.cursor/mcp.json

{"mcpServers":{"cloudcomputerai":{"url":"https://app.cloudcomputerai.com/mcp","headers":{"Authorization":"Bearer ccai_pat_..."}}}}

Grok and other streamable HTTP clients

Use the same URL and Authorization header.

Machine-readable REST shapes: openapi.json.

Safety

DELETE /api/computers/:id removes the computer. Confirm with the user, naming that computer, before calling it. The agent view uses a dialog whose Cancel button is focused first and returns focus to the triggering control. Do not place session tokens or API key secrets in pages, logs, or prompts.

Errors look like { error, code? } with an HTTP error status. 403 not_owner means the owner lock blocked control. 429 includes Retry-After and retryAfter. 501 ocr_unavailable means screen text was requested and tesseract is not installed.

See also llms.txt and llms-full.txt.