Developers
Docs.
The CLI, MCP clients and the REST API all control the Cuiar app on your computer. The app must be open and signed in.
CLI
Install the CLI on macOS or Linux:
curl -fsSL https://cuiar.com/install.sh | shSign in. The CLI works on every plan, and it keeps one session per account.
cuiar login # approve the code on cuiar.com
cuiar login --email you@example.com # approve from your e-mail or the account page
cuiar account list # the signed-in accounts; * is the current one
cuiar account use work@example.com
cuiar --account work@example.com whoami
cuiar account export # all your data as one JSON file
cuiar account email new@example.com # a code to the new address confirms it
cuiar account delete # a code to your address confirms itGive a task. The CLI shows the agent's work until the task ends; when the agent asks a question, answer it in the terminal. Ctrl-C leaves the task running in the app.
cuiar "Find the three cheapest flights from Berlin to Lisbon in November"
cuiar --session <id> "Only direct flights" # a follow-up; --steer changes the current step
cuiar --odyssey --workspace research --permission read-only "Compare five VPN providers and cite sources"
cuiar --folder ~/Downloads "Rename the invoices by date"
cuiar exec -m cuiar/default "Summarize example.com" # only the result, for scripts
cuiar tasks list
cuiar tasks log <id> -f
cuiar tasks cloud <id> # Pro and Team: go on in a cloud browser
cuiar tasks back <id>--permission is read-only, guard (the default: the agent uses the--folder folders and asks before anything else) or full. --incognitokeeps no history and does not use the vault or memory. -m picks the model and --fast a lighter one.
REPL
Run JavaScript in the app with openTab, inspect, screenshot, download and tabs:
cuiar repl "const t = await openTab('https://example.com'); return inspect(t)"
cuiar repl < script.js
cuiar repl # an interactive promptScripts
Every command takes --json; with it, an error is JSON on stderr with its code. CUIAR_API_KEY uses a key instead of a session. CUIAR_CREDENTIALS_PATH keeps the sessions in another file: set it to an absolute path beforecuiar login, and keep it set for every command.
cuiar completion zsh > ~/.zfunc/_cuiar # also bash, fish, powershell, elvish
cuiar update # or cuiar --update
CUIAR_CREDENTIALS_PATH=/abs/path/creds.json cuiar login- 0
- Done.
- 1
- Failed for another reason.
- 2
- The command line is not valid.
- 3
- Not signed in, or the credential cannot do this.
- 4
- The plan or the credits do not cover this.
- 5
- The Cuiar app is not open, is busy, or did not answer.
- 6
- Not found.
- 7
- Too many requests. Try again later.
- 8
- The task failed or was cancelled.
- 9
- Cuiar cannot be reached.
MCP
The Cuiar MCP server is at https://mcp.cuiar.com/mcp. It works on every plan. Your AI plan pays for the model, and Cuiar does the browser work. Connect itto Claude, ChatGPT, Cursor, VS Code and other apps.
Claude Code
claude mcp add --transport http cuiar https://mcp.cuiar.com/mcpClaude Code opens cuiar.com to connect the first time.
Codex
Add the server to ~/.codex/config.toml, then sign in:
[mcp_servers.cuiar]
url = "https://mcp.cuiar.com/mcp"codex mcp login cuiarOther clients
A client that supports remote servers with sign-in needs only the URL. A client that starts local servers can use the CLI:
{
"mcpServers": {
"cuiar": { "command": "cuiar", "args": ["mcp"] }
}
}A client that sends headers can use an API key with the mcp scope:
{
"mcpServers": {
"cuiar": {
"url": "https://mcp.cuiar.com/mcp",
"headers": { "Authorization": "Bearer cuiar_..." }
}
}
}Tools
- list_workspaces
- List the workspaces with their system, proxy and status.
- create_workspace
- Make a workspace with a new device.
- open_workspace / close_workspace
- Open or close a workspace.
- navigate
- Go to a URL.
- snapshot
- Read the page as an accessibility tree with element refs.
- click / type / press_key / scroll
- Act on elements from the last snapshot.
- wait_for
- Wait for text or for a time.
- screenshot
- Take a screenshot.
- tabs
- List, open, switch to or close tabs.
- evaluate
- Run JavaScript in the page.
- sign_in
- Sign in with a saved password. The password stays in the vault.
- run_task
- Give a whole task to the Cuiar agent. It uses credits.
- account / devices
- Show the plan, the credits and the open devices.
REST API
The base URL is https://api.cuiar.com. Send Authorization: Bearer with an API key or a CLI session. Control of the app with an API key is in the Pro and Team plans.
Your account
curl https://api.cuiar.com/v1/me \
-H "Authorization: Bearer $CUIAR_API_KEY"Start a task
A task runs in the app and keeps a transcript. Follow it with GET /v1/tasks/{id}/events?wait=30, send follow-ups to/v1/tasks/{id}/messages, and pause, resume or cancel it. Options: workspaceId (the workspace to work in), mode (odysseyfor long research), permission (read_only, guard, full),folders, incognito, model, speed andmaxCredits (the most credits the task may use; creditsUsed shows what it used).
curl https://api.cuiar.com/v1/tasks \
-H "Authorization: Bearer $CUIAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task": "Find a flight to Lisbon under 300 €", "workspaceId": "travel", "permission": "read_only"}'Cloud hand-off
POST /v1/tasks/{id}/handoff moves a running task and its workspace to a Cuiar cloud browser, so it goes on while your computer sleeps. The app must be open to pack the workspace. A cloud browser takes 1 credit a minute. The task comes back when it ends, when the credits run out, or with POST /v1/handoffs/{id}/return. GET /v1/handoffslists the hand-offs with the time each one ran. Pro and Team.
Call a tool
/v1/rpc sends one JSON-RPC call to the app. The MCP tools are available as tools/call.
curl https://api.cuiar.com/v1/rpc \
-H "Authorization: Bearer $CUIAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"method": "tools/call", "params": {"name": "snapshot", "arguments": {"workspace_id": "travel"}}}'When Cuiar is open on more than one computer, add "device" with a name or an id from GET /v1/devices.
Routines
A routine runs a task on a schedule in the Cuiar app on your computer. The schedule is cron with 5 fields in a time zone, and two runs are 15 minutes apart or more. No plan limits routines. Manage them on theroutines page, with the CLI, with the MCP tools create_routine, list_routines and delete_routine, or with/v1/routines.
cuiar routines create "Morning prices" --schedule "0 9 * * 1-5" --time-zone Europe/Berlin \
"Find the price of a 2 TB SSD on three stores and list the cheapest"
cuiar routines list
cuiar routines run <id>We send each result by email. A routine with a webhook also gets a POST, signed with the routine's secret:
x-cuiar-signature: t=1793000000,v1=<hex HMAC-SHA256(secret, "1793000000." + body)>
{"type": "routine.run", "routine": {"id", "name"}, "run": {"id", "status", "result", "error", "startedAt", "finishedAt"}}Channels
Give tasks by e-mail, Telegram, Slack or iMessage. Set them up on theaccount page or with the CLI. The result comes back to the same place, and a reply continues the task. A question from the agent or a request for approval comes there too: reply to answer, or reply yes or no.
cuiar channels email # your private address for tasks
cuiar channels link telegram # a code for the Telegram bot
cuiar channels # the list
cuiar channels remove <id>Write to your private address from your account's e-mail address. The subject is the name of the task and the text is the task. We take a message only when DKIM or DMARC passes for its sender. Make a new address to stop the old one.
Telegram and Slack
For Telegram, send /start <code> to the bot. For Slack, Add to Slack links you at once; other members of the workspace send link <code> to the app. Write a task in a direct message, and reply to a message about a task to continue it.
iMessage
A bridge on your Mac reads Messages and sends the answers back into the same chat. It needs no approval from Apple. Set it up withcuiar imessage link; see iMessage. Cuiar does not offer RCS.
API keys
Make keys on the account page or with cuiar keys create. We show each key one time only. A key cannot manage keys, sessions, billing or the vault; those need a signed-in session. A key has one or more scopes:
- account:read
- Read the plan, the credits and the open devices.
- routines:read
- List routines and their runs.
- routines:write
- Make, change, run and delete routines.
- app
- Control the Cuiar app: tool calls and tasks. Pro and Team.
- models
- Use the model gateway with credits.
- mcp
- Use the remote MCP server.
- api
- Every scope above except mcp. Keys made before the finer scopes have it.
A request without the scope gets 403 insufficient_scope, and detail.required names the scope.
Model gateway
The Cuiar agent uses this gateway, and you can use it too. It accepts OpenAI-style chat requests. The model iscuiar/default, Cuiar's built-in model. Requests go only to providers with zero data retention: they keep no request data and do not train on it.
Credits
Each plan gives credits each month; Pricing shows how many. One credit is $0.001 of model cost: 3,333 input tokens, 166,666 cached input tokens or 833 output tokens. We count use in millionths of a credit, so a small request does not cost a full credit. The gateway sets max_tokens to what your credits pay for. Work that your own Claude, Codex or other MCP client does uses no credits.
curl https://api.cuiar.com/v1/llm/chat/completions \
-H "Authorization: Bearer $CUIAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "cuiar/default", "messages": [{"role": "user", "content": "Hello"}]}'Errors and limits
An error has the shape {"error": "code", "message": "text", "detail": {...}}. Branch onerror; the message is for people and can change. A code never changes its status or its meaning.
- bad_request
- 400
- The request is not valid. The message says why.
- authorization_pending
- 400
- Device sign-in (RFC 8628): the user has not approved the code yet. Poll again.
- slow_down
- 400
- Device sign-in: poll less often.
- access_denied
- 400
- Device sign-in: the user refused the code.
- expired_token
- 400
- Device sign-in: the code expired or was used.
- invalid_grant
- 400
- Device sign-in: the device code is not known.
- unauthorized
- 401
- No credential, or the credential is not valid.
- invalid_code
- 401
- The sign-in code is wrong or expired.
- forbidden
- 403
- This credential cannot do this.
- insufficient_scope
- 403
- The API key does not have the scope. `detail.required` names it.
- not_found
- 404
- The resource does not exist.
- no_vault
- 404
- The user has no vault yet.
- plan
- 402
- The plan does not include this.
- no_credits
- 402
- The credits do not pay for this.
- task_budget
- 402
- The task used the credits it may use (`maxCredits`).
- conflict
- 409
- The request conflicts with the current state.
- already_subscribed
- 409
- The user already has a card subscription.
- no_billing
- 409
- The user has no payments yet.
- too_many_keys
- 409
- The account has the most API keys it can have.
- too_many_routines
- 409
- The account has the most routines it can have.
- finished
- 409
- The routine run already has a result.
- full
- 409
- The vault has the most items it can have.
- offline
- 409
- The Cuiar app is not open on any device of the account.
- idempotency_key_in_use
- 409
- A request with this `Idempotency-Key` is still running.
- idempotency_key_reused
- 422
- This `Idempotency-Key` was used for a different request.
- too_large
- 413
- The body is too large.
- rate_limited
- 429
- Too many requests. `Retry-After` says when to try again.
- internal
- 500
- A fault on our side.
- model
- 502
- The model provider did not answer.
- closed
- 502
- The app closed the connection before it answered.
- unavailable
- 503
- A service this needs is not available now.
- busy
- 503
- The app has too many requests open.
- timeout
- 504
- The app did not answer in time.
- team_owner
- 409
- The account owns a team. Give the team to another member or delete it first.
Rate limits
A credential can send 600 requests a minute; a caller without one, 120. Every answer hasRateLimit-Limit, RateLimit-Remaining andRateLimit-Reset (seconds). A 429 also has Retry-After.
Retries
Send Idempotency-Key with any unique string on a write. A retry with the same key gets the first answer, withIdempotent-Replayed: true, and does not run again. Keys belong to the credential and live 24 hours. The same key with a different body gets 422 idempotency_key_reused. The model gateway does not take keys.
Lists
Lists answer {"<items>": [...], "nextCursor": "..."}. Send ?cursor= withnextCursor for the next page, and ?limit= for 1 to 200 items (default 50). The last page hasnextCursor: null.
Reference and SDK
The API makes its OpenAPI 3.1 document from its own code:api.cuiar.com/v1/openapi.json. Generate a client in any language from it.
The TypeScript SDK has a type for every path, body and answer:
npm install https://get.cuiar.com/sdk/cuiar-sdk-latest.tgzimport { createCuiar, unwrap, paginate, idempotencyKey } from "@cuiar/sdk";
const cuiar = createCuiar({ token: process.env.CUIAR_API_KEY! });
const me = unwrap(await cuiar.GET("/v1/me"));
const routine = unwrap(await cuiar.POST("/v1/routines", {
body: { name: "Prices", task: "Find the cheapest 2 TB SSD", schedule: "0 9 * * 1-5" },
params: { header: { "idempotency-key": idempotencyKey() } },
}));
for await (const r of paginate(async (cursor) => {
const page = unwrap(await cuiar.GET("/v1/routines", { params: { query: { cursor } } }));
return { items: page.routines, nextCursor: page.nextCursor };
})) console.log(r.name);