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 | sh

Sign 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 it

Give 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 prompt

Scripts

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/mcp

Claude 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 cuiar

Other 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>

E-mail

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.tgz
import { 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);