# Clients (/docs/gateway/clients)

Connect VS Code, GitHub Copilot CLI, Cursor, Continue, Claude Code and any MCP client to the gateway.

The gateway publishes ready-to-paste configuration for the tools people actually use. Nothing on these endpoints is secret — your key is always a placeholder you fill in locally — so they are public and CORS-open.

Step-by-step guides per tool — Cursor, Claude Code, GitHub Copilot, Cline, Continue and Zed — are in [Integrations](../integrations/index.mdx).

## VS Code (Copilot Chat, Custom Endpoint) [#vs-code-copilot-chat-custom-endpoint]

VS Code's **Custom Endpoint** language-model provider takes a JSON object describing the models to add to the picker. The gateway serves it prebuilt:

```text
GET https://ai.codai.ro/vscode/chatLanguageModels.json
```

<Steps>
<Step>
In VS Code (Insiders recommended), run **Chat: Manage Language Models** → **Add Models** → **Custom Endpoint**. This creates a user-level `chatLanguageModels.json`.
</Step>
<Step>
Fetch the provider object and paste it into the array in that file:

```powershell tab="PowerShell"
curl.exe -s https://ai.codai.ro/vscode/chatLanguageModels.json | Set-Clipboard
```

```bash tab="bash"
curl -s https://ai.codai.ro/vscode/chatLanguageModels.json | pbcopy
```

</Step>
<Step>
VS Code prompts for `${input:chat.lm.secret.codai}` — paste your `codai_…` key. It is stored in the OS keychain. Restart VS Code if the models do not appear.
</Step>
</Steps>

The picker gets three entries, each a fixed model identity:

| Picker entry         | Alias            | Why it exists                                                                                                                  |
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Codai**            | `codai`          | Today Anthropic's current Claude models (see [models](./models.mdx)), with the effort dial (`low` → `max`) exposed in VS Code's _Thinking Effort_ menu. |
| **Codai (fast)**     | `codai-fast`     | A small, fast model for `chat.utilitySmallModel` — titles, intent detection, commit messages. Task-free.                                 |
| **Codai (explorer)** | `codai-explorer` | A mid-size model for the Explore agent — many short read/search turns.                                                                 |

The served config sets headers that keep the gateway a **transparent transport**: `X-Codai-Disable-Subagents: 1`, `X-Codai-No-Recall: 1`, `X-Codai-Compact: off`, plus `X-Codai-Thinking: 1` with a per-alias budget and `X-Codai-Cache: 1`. Copilot owns orchestration and the transcript; the gateway never runs a second agent loop behind it.

<Callout type="info">
  The config deliberately omits `X-Codai-Session-Id`. VS Code does not interpolate `$
  {workspaceFolder}` in `requestHeaders`, so a templated value would bucket every workspace into one
  session. The gateway derives a per-conversation key instead, which keeps prompt caches warm.
</Callout>

Two companion endpoints publish a curated settings baseline: `GET /vscode/settings.json` (VS Code user settings) and `GET /vscode/.copilot/settings.json` (Copilot CLI `~/.copilot/settings.json`).

## GitHub Copilot CLI (BYOK) [#github-copilot-cli-byok]

Copilot CLI runs in **bring-your-own-key** mode when `COPILOT_PROVIDER_BASE_URL` is set — GitHub sign-in is not required. codai is a drop-in provider.

<Tabs items={['PowerShell', 'bash', 'Manual']}>
<Tab value="PowerShell">

```powershell
$env:COPILOT_PROVIDER_API_KEY = 'codai_xxxxxxxx'
Invoke-RestMethod https://ai.codai.ro/copilot/env.ps1 | Out-File env.ps1
. .\env.ps1   # dot-source: sets the vars and launches copilot
```

</Tab>
<Tab value="bash">

```bash
export COPILOT_PROVIDER_API_KEY='codai_xxxxxxxx'
curl -fsSL https://ai.codai.ro/copilot/env.sh -o env.sh
source ./env.sh   # sets the vars and execs copilot
```

</Tab>
<Tab value="Manual">

```bash
export COPILOT_PROVIDER_BASE_URL='https://ai.codai.ro/v1'
export COPILOT_PROVIDER_TYPE='openai'
export COPILOT_PROVIDER_WIRE_MODEL='codai'
export COPILOT_PROVIDER_API_KEY='codai_xxxxxxxx'
copilot
```

</Tab>
</Tabs>

`GET /copilot/config` returns the same values as JSON, including the alternative aliases you may use as the wire model (`codai-fast`, `codai-deep`, `codai-agent`, `codai-max`, `codai-explorer`, `codai-vision`) and the capability flags (streaming, tool calling, vision and prompt caching are on; GitHub-hosted memory and remote delegation stay GitHub-routed and are unavailable in BYOK mode).

<Callout type="warn">
  **Base URL differs by wire type.** With `COPILOT_PROVIDER_TYPE=openai` the CLI appends
  `/chat/completions`, so the base must be `https://ai.codai.ro/v1`. With `anthropic` it appends
  `/v1/messages`, so the base must be the root `https://ai.codai.ro`. Getting this wrong yields a
  `404` that looks like an auth failure.
</Callout>

### Persistent memory for BYOK sessions [#persistent-memory-for-byok-sessions]

BYOK mode loses GitHub's memory. Add the codai MCP server instead:

```bash
mkdir -p ~/.codai
curl -fsSL -o ~/.codai/mcp-codai.mjs https://ai.codai.ro/copilot/mcp-bridge.mjs
curl -s https://ai.codai.ro/copilot/mcp.json   # paste `mcpServers` into ~/.copilot/mcp-config.json
```

The snippet registers a **local stdio bridge**, not an `http` server: the CLI does not expand `${ENV}` placeholders in `http` headers, so a remote server with a templated `Authorization` header sends the literal placeholder and hangs the 60 s handshake. The bridge reads `CODAI_API_KEY` or `COPILOT_PROVIDER_API_KEY` from the environment and forwards JSON-RPC to `/mcp`. Replace `~` in `args` with your absolute home directory — the CLI does not expand it. The server id is `codai` (it used to be `codai-memory`; the bridge URL is unchanged). Set `CODAI_MCP_TOOLSETS` (for example `cards,web` or `all`) to add tool groups to the default set.

## Cursor, Continue, Cline, Zed and other OpenAI-compatible tools [#cursor-continue-cline-zed-and-other-openai-compatible-tools]

Any client with an _OpenAI-compatible_ provider option works. Set:

| Setting  | Value                                              |
| -------- | -------------------------------------------------- |
| Base URL | `https://ai.codai.ro/v1`                           |
| API key  | `codai_xxxxxxxx`                                   |
| Model    | `codai` (or any alias from [models](./models.mdx)) |

If the tool lets you set custom headers, `X-Codai-Effort: high` or `max` is the one worth adding. If it offers a model list, it can read `GET /v1/models` with your key.

Exact settings, file paths and known limits for each tool are in [Integrations](../integrations/index.mdx).

## Claude Code and Anthropic-native tools [#claude-code-and-anthropic-native-tools]

Set the Anthropic base URL to the **root** and the key to your codai key:

```bash
export ANTHROPIC_BASE_URL='https://ai.codai.ro'
export ANTHROPIC_API_KEY='codai_xxxxxxxx'
export ANTHROPIC_MODEL='codai'
```

`POST /v1/messages` accepts both `Authorization: Bearer` and `x-api-key`, so the SDK's default header works unchanged.

## MCP server [#mcp-server]

The gateway is itself a remote **MCP server** (Streamable HTTP, spec 2025-11-25, wire-compatible with 2025-06-18):

```text
POST https://ai.codai.ro/mcp
```

By default `tools/list` returns the **core** toolset: `memory_search`, `memory_store`, `memory_list`, `memory_graph`, `memory_forget`, `chat`, `list_models`, `account_get` and `usage_get` (about 9 KB of tool definitions instead of 90 KB). Every other group below is opt-in per connection, so a client only pays context for what it uses:

| Toolset         | Tools                                                                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`       | settings, devices, hosts, tasks, profile, feedback, orgs                                                                                          |
| `environments`  | projects, environments, environment tasks                                                                                                         |
| `resolve`       | `resolve_*`                                                                                                                                       |
| `transcripts`   | transcripts list/get/search/ask/export/share                                                                                                      |
| `schedules`     | schedules and heartbeat monitors                                                                                                                  |
| `sessions`      | `sessions_*`                                                                                                                                      |
| `notifications` | notifications and triggers                                                                                                                        |
| `cards`         | `cards_*`                                                                                                                                         |
| `lists`         | lists and items                                                                                                                                   |
| `prompts`       | `prompts_list`, `prompts_get`                                                                                                                     |
| `studio`        | codai Studio: `creative_*`, `music_*`, `studio_*` generation and media ops, `studio_job_status`, plus `studio_renders_list`, `studio_assets_list` |
| `sandbox`       | `sandbox_*`                                                                                                                                       |
| `vault`         | `vault_*`                                                                                                                                         |
| `web`           | `web_search`, `web_fetch`, `deep_research`                                                                                                        |

Select groups with `?toolsets=cards,web` on the server URL or the `X-MCP-Toolsets` header; `all` lists everything. A tool outside the selection can still be called by name — the selection only trims the list. List tools return a compact page (for example 20 rows, internal fields dropped) unless you pass `limit`; full detail comes from the matching `*_get` tool. It also exposes prompts (slash commands), resources (`codai://models`, `codai://memory/recent`) and prompt-argument completion.

[Resolve](../resolve/index.mdx) tools: `resolve_submit` (submit a GitHub issue, get a quote), `resolve_get` (poll the job), `resolve_accept` (start the fix — **debits the quoted price from your wallet**, refunded in full if no verified fix; requires `confirm_spend: true`, and a `402` returns the `topup_url`) and `resolve_attestation` (public execution proof). They need an API key; OAuth tokens are refused.

[Transcripts](../api/gateway/transcripts.mdx) tools: `list_transcripts`, `get_transcript`, `search_transcripts`, `ask_transcripts` (answer across your recordings with citations), `export_transcript` (md / txt / srt / vtt / json), `accept_transcript_prompt` (turn a suggested agent prompt into a pending prompt) and `transcript_share_create` (a read-only public link, optional expiry). Deleting, revoking links, re-running and editing a recording are not exposed. API key only.

[Settings](../api/gateway/settings.mdx) tools: `settings_get` (account-level settings with defaults and their `version`) and `settings_update` (deep-merge changes; pass `version` to refuse overwriting a change made meanwhile on another device), plus the read-only `os_gate_policy` (whether your organizations allow overriding the [OS protection gate](../agents/os-protection-gate.mdx)). API key only. `themes_list` lists the curated colour themes ([Themes](../api/gateway/themes.mdx)); read-only, no key needed.

[Scheduler](../api/gateway/schedules.mdx) tools: `schedules_list`, `schedules_runs`, `schedules_preview` (cron or plain words → next runs), `schedules_create`, `schedules_set_enabled`, `schedules_run_now`, `schedules_decide` (approve / skip a run waiting for you), `heartbeats_list`, `heartbeats_create` (the answer holds the secret ping URL, shown once) and `heartbeats_set_paused`. Deleting a schedule or a heartbeat monitor and approving a terminal command for a host are not tools: a person does them. API key only.

[Sessions](../api/gateway/sessions.mdx) tools: `sessions_list`, `sessions_get` (members, presence and lease), `sessions_events`, `sessions_rename`, `sessions_archive` (archive or restore) and `sessions_dispatch` (send a message to, or open the session on, one of your devices). [Notifications](../api/gateway/triggers.mdx) tools: `notifications_list`, `notifications_mark_read` and `notifications_dismiss`. [Triggers](../api/gateway/triggers.mdx) tools: `triggers_list`, `triggers_update` (rename, enable or disable, policy), `triggers_test` and `triggers_events`; creating or deleting a trigger and its signing secret stay with you (desktop, phone or API). Deleting a session is not a tool: a person does it. The same commands exist in the CLI as `codaid sessions`, `codaid notifications` and `codaid triggers`. API key only.

Command line for [memory](../api/gateway/memory.mdx) and lists: `codaid memory list|search|add|rm|clear` (`rm` deletes one memory by id, `clear` deletes all of them; both ask first unless `--yes`) and `codaid lists list|show|add|export` (`add` without a list shares to the Inbox). Deleting a list is not a command. The agent that `codaid run` hosts gets the `lists_list`, `list_items` and `list_add` tools, with no delete. The hub has a Memory page (browse, search, add, forget one); desktop and phone show your API keys (edit tags only; create and revoke keys in the hub) and your verified tasks (read-only).

The MCP server also has [sandbox](../api/gateway/sandboxes.mdx) tools: `sandbox_create` (backend `v2` by default or `v1`, TTL, egress `none`, a `pypi`/`npm` preset or an allowlist), `sandbox_list`, `sandbox_exec` (a bash line or Python/bash code; returns exit code, stdout, stderr and the receipt), `sandbox_files` (`list`, `read` up to 256 KiB, `write` up to 1 MiB, or `artifacts` with sha256 and signed download URLs) and `sandbox_kill`, plus the v2 tools `sandbox_run_code`, `sandbox_pause`, `sandbox_resume`, `sandbox_fork` and `sandbox_preview`. They run with your key, so the `l3_sandbox` tool level, the caps (3 at once per key, 5 running and 10 paused v2 sandboxes per user, 7,200 exec seconds a day) and metering apply exactly as on the REST API. API key only.

The MCP server also has **Vault** tools (credentials manager): `vault_list` (the credentials you exposed to agents: handle `{{vault:<slug>}}`, title, bound hosts, env var name, sensitivity — never a value), `vault_request_use` (a policy decision for one use: `t1`/`t2` allowed, `t3`/`t4` returns an `approval_id` you approve on desktop, phone, watch or the hub, `deny` with reasons), `vault_http` (an https call where the handle in a header or the body is replaced on the server, only for items you marked cloud-usable and only to their bound hosts; the response is redacted), `vault_approval_status`, `vault_add_secret` (when a credential is missing: you get a single-use link to a codai page where you type the value; clients that declare `capabilities.elicitation.url` receive it as a `-32042` URL elicitation, others as a normal result), `vault_add_status` (pending, completed with the `{{vault:<slug>}}` handle, cancelled or expired) and `vault_policy_simulate` (read-only: replays your past agent uses under draft rules and reports which tiers would change; grants are not replayed). Agents never receive secret values, and revealing or approving stays with you. API key only. `codaid vault mcp` is a local stdio server with `vault_list`, `vault_run` (runs a command with handles injected by the local broker, output redacted), `vault_add_secret`, `vault_add_status` and `vault_policy_simulate`.

The MCP server also has read-only account tools: `account_get` (plan, credits, task counts), `usage_get` (spend and requests, optional `days` and `group_by`), `devices_list` and `hosts_list` (push tokens are never returned), and `tasks_list`, `tasks_get`, `tasks_stats`. Confirming a task is billing, so it stays in the hub, desktop and phone. There is no MCP tool for API keys. The CLI has the same views: `codaid account`, `codaid usage [--days N]`, `codaid keys list|tag` (tags only; create and revoke keys in the hub), `codaid devices list|hosts`, `codaid tasks list|show|stats` (no confirm) and `codaid chat "<prompt>"`, which streams a reply from `codai`. Desktop has Overview and Usage pages with the same data as the hub.

More MCP tools: `prompts_list` and `prompts_get` (your prompt library, read-only; launching a prompt stays in the apps), `profile_get`, `profile_update` (username only) and `feedback_submit` (thumbs up or down on one of your turns), `orgs_list` and `org_members_list` (read-only), and `studio_renders_list` and `studio_assets_list` (read-only, no signed download URLs; generation is in the `studio` toolset below). The CLI matches them: `codaid prompts list|show`, `codaid transcripts list|show|search`, `codaid profile show|set --username`, `codaid feedback --up|--down`, `codaid projects list`, `codaid team list|members <org-id>`, `codaid referrals` and `codaid studio renders|assets`. Desktop adds Security (a read-only view; passkeys, two-factor and sessions open in the hub), Projects and Team pages; the phone adds Overview, Cloud projects and Team screens; the hub has an agent Chat page that streams replies from `codai` and bills them to your account.

Resolve is on every surface now: desktop and the phone list your jobs, show the quote and the proof, submit new issues and accept a quote after a confirmation that shows the price and what pays for it (a short wallet opens the top-up page in the browser; nothing is paid inside the apps). The phone gets a notification when a job is quoted or finishes; desktop shows one for jobs you are watching. `codaid resolve list`, the MCP tool `resolve_list` and `resolve.list()` / `resolve.iterate()` in both SDKs list your jobs. The SDKs also gain `billing` (plan, wallet, auto top-up settings, invoices and a low-balance watcher; read-only, checkout stays in the browser) and `referrals` (your link, stats and invitees, plus redeeming a code and referral consent).

[Cards](../agents/cards.mdx) tools: `cards_weather`, `cards_places` (billed at Google list price, 200 per day), `cards_fx`, `cards_unfurl`, `cards_product`, `cards_route` (billed like Google Routes), `cards_track` and `cards_efactura`. Each returns `{ block, provenance }` as `structuredContent` — a ready card block — and its markdown twin as text. API key only.

[Web](../agents/tools.mdx#web-tools-one-contract-everywhere) tools: `web_search` (verified search with domain, publish-date and freshness filters; results as `[S1]`..`[Sn]`), `web_fetch` (one page as clean markdown, optional `focus`) and `deep_research` (an async job that returns a cited report; when it is not ready within ~50 s the tool returns the job id, call it again with `job_id` to collect it). Same names, schemas and rendering as the desktop, phone, VS Code and headless agents, from `packages/agent-core/spec/tools-web.json`. Your rules apply as on `/v1/tools/*` (`web_search` and `deep_research` gate as `web_search`, `web_fetch` as `browser_fetch`). Metered like the REST endpoints: $3 / 1,000 fast searches, $8 / 1,000 deep, $0.50 / 1,000 fetches, $0.20 per research job; the first 1,000 calls a month are free, and calls inside a codai agent turn are never charged.

[Studio](./creatives.mdx) tools (`?toolsets=studio`): Claude, ChatGPT, Cursor or VS Code create and edit creatives, run productions, documents, media operations and music with the same tools as the codai desktop, phone and VS Code agents — same names, descriptions and schemas, from `packages/agent-core/spec/tools-studio.json`:

- **Creatives** (free): `creative_list`, `creative_create`, `creative_outline`, `creative_get`, `creative_find`, `creative_edit` (node-id ops against `base_seq`), `creative_lint`, `creative_lint_fix`, `creative_versions`, `creative_revert`, `creative_templates`, `creative_save_template`, `creative_brand_kit_save`, `creative_restyle`, `creative_locale_fork`, `creative_share`, `creative_review`, `creative_review_comment`, `creative_remix`, `creative_export_lottie`, `creative_from_document`, `creative_build`, `creative_batch`, `creative_batch_status`.
- **Paid** (money gate: quote and wallet hold first, `402 insufficient_funds` when the wallet is short, nothing charged): `studio_image`, `studio_music`, `studio_video`, `studio_render`, `studio_document`, `studio_document_preview`, `studio_document_video`, `creative_frame`, `creative_render`, `creative_variants`, `creative_brand_extract`, `creative_captions`, `creative_adapt`, `creative_localize`, `creative_produce` (brief → finished video, image, presentation, document, spreadsheet, song, carousel or print poster), `creative_export_fcpxml`, `studio_media_op`, `music_create`, `music_edit`. `studio_media_ops` and `studio_sfx` list operations and free sound effects.
- **Jobs**: a call waits up to about 45 s. A longer render, video, preview, export, frame, media operation or song returns `status: "pending"` with `next_call`; call `studio_job_status` with those arguments to collect the result (it also places a finished `music_create` / `music_edit` song on the creative). Productions and batches are polled with `creative_produce` (`production_id`) and `creative_batch_status`.

Results carry asset ids and signed download URLs (valid 1 hour); nothing is saved on your machine. Deleting creatives, templates or brand kits is not a tool. API key only (`Authorization: Bearer codai_…`); OAuth tokens are refused by these tools for now.

```json title="VS Code mcp.json (Studio)"
{
  "servers": {
    "codai": {
      "type": "http",
      "url": "https://ai.codai.ro/mcp?toolsets=studio",
      "headers": { "Authorization": "Bearer ${input:codai-key}" }
    }
  }
}
```

Two ways to authenticate:

- **API key** — `Authorization: Bearer codai_…`. Use this from scripts or via the stdio bridge above.
- **OAuth 2.1** — clients that support it (VS Code, Claude Desktop, Claude Code, ChatGPT connectors) need no key at all. Point them at the URL; an unauthenticated request returns `401` with a `WWW-Authenticate: Bearer resource_metadata=…` challenge, and `GET /.well-known/oauth-protected-resource/mcp` points to [auth.codai.ro](https://auth.codai.ro) for self-onboarding.

```json title="VS Code mcp.json"
{
  "servers": {
    "codai": { "type": "http", "url": "https://ai.codai.ro/mcp?toolsets=cards,web" }
  }
}
```

Send `Accept: text/event-stream` and a `chat` tool call streams `notifications/progress` while in flight, then the JSON-RPC result. Every MCP request passes the same rate limiter as `/v1`, and tool calls that reach an upstream write a usage record.

## Which one should I use? [#which-one-should-i-use]

- **You live in VS Code** → the Custom Endpoint config. Effort dial, three roles, keychain-stored key.
- **You live in a terminal** → Copilot CLI BYOK plus the memory bridge.
- **You use another editor** → its OpenAI-compatible provider with the `/v1` base URL.
- **You are wiring an agent framework** → the [SDKs](../sdks/index.mdx), or the OpenAI/Anthropic SDK against the matching base URL.
