Self-hosting

Run the copilot on infrastructure you control.

Cyrano’s free tier stays on your device and needs no backend. When you want the copilot, you can deploy its Worker to your own Cloudflare account and connect your own Anthropic key.

What stays on your device

Live transcription, diarization, the semantic map, session review and history, whisper text-to-speech, and redaction work without a backend or API key.

The copilot adds commitments, open asks, subtext, next moves, custom watch categories, and generated whispers. Those features send transcript text to the backend you configure.

Three things before you begin

  • A Cloudflare account. For one user, the Worker and its SQLite-backed Durable Objects fit within the free plan’s included limits.
  • An Anthropic API key with available credit.
  • Node.js 20 or newer on the machine you deploy from.

You will also need the public Cyrano backend repository: github.com/F-RND/cyrano-backend.

Put the Worker in your Cloudflare account

Clone the repository, install the locked dependencies, authenticate Wrangler, and deploy:

git clone https://github.com/F-RND/cyrano-backend.git
cd cyrano-backend
npm ci

# Opens a browser to authenticate your Cloudflare account
npx wrangler login

# Creates the Worker and its Durable Objects
npx wrangler deploy

Wrangler prints the deployed URL, usually in the form https://cyrano-backend.<your-subdomain>.workers.dev. Keep that URL for the app setup.

Set the bearer token and Anthropic key

Generate a strong token for Cyrano, then store both values with Cloudflare. Wrangler writes them to the Worker’s encrypted secret store rather than the repository.

# Generate the token you will paste into Cyrano settings
openssl rand -hex 32

# Paste the generated token when prompted
npx wrangler secret put AUTH_TOKEN

# Paste your Anthropic API key when prompted
npx wrangler secret put LLM_API_KEY

Secrets take effect immediately. Do not commit tokens, API keys, .env, or .dev.vars files.

Point Cyrano at your Worker

  1. Open Cyrano → Settings → Backend.
  2. Paste the Worker URL into Backend URL.
  3. Paste the value stored as AUTH_TOKEN into Bearer token.
  4. Select Test connection.
Connection-test results and the corresponding checks
ResultWhat to check
Couldn’t reach the backendCheck that the URL uses HTTPS and contains no typos or trailing characters.
Doesn’t look like a Cyrano backendThe URL answered, but it points to a different service.
Bearer token rejected (HTTP 401)The value in Cyrano must exactly match the Worker’s AUTH_TOKEN.
Anthropic rejected the API keyRun npx wrangler secret put LLM_API_KEY again with a valid key.
ConnectedThe Worker, bearer token, and Anthropic key are ready.

If access changes during a session—because a key is revoked or a spending ceiling is reached—Cyrano shows the failure instead of silently returning empty analysis.

The account is yours; so is the bill

All model spend goes to your Anthropic key. The backend reduces unnecessary calls by requiring a useful word window, batching analysis, caching the instruction prefix, capping output, and enforcing a hard per-session ceiling.

  • Filler such as “yeah” and “mm-hm” accumulates without triggering a pass.
  • Commitments, asks, subtext, and next moves share one model call per pass.
  • Custom watch categories or smart detection may add a second call.
  • Prompt caching lowers the cost of consecutive passes.

You can change LLM_MODEL in the Worker configuration and redeploy. The backend omits the thinking parameter; model compatibility still varies, so test a changed model before relying on it.

Updates, rotation, and logs

  • Update: pull the latest release, run npm ci, and run npx wrangler deploy.
  • Rotate the bearer token: run npx wrangler secret put AUTH_TOKEN, then update each device. The old token cannot authenticate new requests or reconnects, but an existing WebSocket can remain active until disconnected. Terminate active sessions when rotating after suspected exposure.
  • Rotate the Anthropic key: run npx wrangler secret put LLM_API_KEY. The next analysis pass uses it.
  • Watch operations: npx wrangler tail streams operational logs. Transcript content is not logged by default. Keep TRANSCRIPT_CONTENT_LOGGING unset or false in real deployments; enabling it deliberately emits transcript-derived diagnostics.
  • Connect an agent: use Settings → Backend → Connect an Agent to mint a separate, revocable key with limited context and result scopes.

Host for a handful of people

The default setup is single-tenant: one operator token with full access. You can mint a separate scoped token for another person without sharing that operator token:

POST /tenant-users HTTP/1.1
Host: your-worker.workers.dev
Authorization: Bearer <AUTH_TOKEN>
Content-Type: application/json

{"label":"alice"}

Send the request with a trusted API client, configuring its Bearer-auth field with the operator credential so the value stays out of shell history and process arguments.

Give the returned cyrano_user_... token—not your AUTH_TOKEN—to that user. Sessions are isolated by tenant, while the operator token remains an administrative escape hatch.

Each user should enter their own Anthropic API key in Cyrano settings. That key passes through the operator-controlled Worker and is serialized into the active WebSocket attachment so it can survive Durable Object hibernation for the life of that connection. A user should provide it only when they trust the operator and the exact deployed code. If they leave it blank, their sessions use and bill your Worker-level key.

Know exactly where the transcript goes

  • Transcript segments travel over TLS to your Worker and are stored under the session retention mode you choose: ephemeral, 24-hour, or pinned.
  • The Worker sends analysis windows to Anthropic using your key and account.
  • Redaction and purge remain available. Transcript text is not logged by default; operators must leave TRANSCRIPT_CONTENT_LOGGING disabled to preserve that property.
  • LLM_API_KEY remains a Cloudflare secret. Cyrano stores the bearer token in the device Keychain; neither value belongs in the repository or app bundle.

Self-hosted and hosted are different routes

With your own deployment, transcript text reaches your Worker and your LLM account; Cyrano does not receive it. With Hosted Copilot, transcript text transits Cyrano’s Worker to generate the copilot. Raw audio remains local in both routes unless you separately opt into a cloud transcription mode.

Read the privacy documentation and use Settings → Plan & Privacy → Where your data goes to inspect the route active on your device.

See every route before you open one.