Anyray Connect
anyray-connect points a developer's coding tools at your gateway in one command.
Connect edits each detected tool's own config to route through the gateway. Provider keys stay on
the gateway; each developer gets a personal ark_… client key.
/connect/policy follows the person's route:
if its default or any model rule names subscription, the lane is subscription; otherwise it
is org. Without a person route, the existing user or team lane assignment applies.
Agent keys keep their assigned lane.
Run it
An admin creates a passwordless link in Console → Users, or shares the org's SSO command.
- Enrollment link
- Enterprise SSO
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- \
--enroll https://app.anyray.ai/enroll/enl_…
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- \
--sso https://app.anyray.ai/sso/tnt_…
It mints your key, sets your name and team, shows the planned changes, and writes each config.
--dry-runpreviews without writing.anyray-connectwith no setup flags runs interactively.
A running editor keeps its old routing until restarted. An interactive run offers to close and reopen exactly those apps; apps already on the gateway are left alone.
| Flag | Effect |
|---|---|
--quit-apps | Close and reopen without asking. The only way a scripted run closes anything |
--no-quit-apps | Never close anything |
--yes, a non-interactive shell, --dry-run, and the managed and MDM payloads close nothing.
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- status
status shows each installed tool as on or off, plus your gateway, name, and team. Run doctor
the same way to diagnose reachability and each tool's config.
Turn a tool on or off
For Claude Code, open a new terminal after setup to use claude bedrock: or
claude subscription: for one session. This also works after enabling Claude Code in the
desktop app. See session routing.
In the Connect desktop app, open the Tools tab and flip the switch beside a tool. After you
sign in, only the tools your admin locked are on; the rest wait for you. Changes apply
at once. If the tool is a running app, the row says what to restart and offers a Restart
button. A switch your admin controls stays read-only and says why
(who can switch what). From a terminal,
anyray-connect --tools <id> turns a tool on and anyray-connect --tools <id> --revert turns it off.
Each tool you turned on shows one health summary in the app: Working, Ready or Needs attention (with a note on what to do). Connect repairs what it can itself, showing Fixing meanwhile, and notifies you only when you have to act. What each summary means.
First session
After sign-in, open Tools. Turn on the tools you use if your organization permits it, then start a new session and run a normal task. Each row shows that tool's state and next action. Select the tool's name to see its setup and traffic evidence.
Ready means setup checks passed. Working means that tool's required traffic and hook checks passed. Seen traffic can still be Ready while the hook is unproven. The MCP row describes retrieval setup; it does not prove the model read original content.
If a check needs attention, use the action beside the tool. Troubleshoot repairs the connection; Copy report provides the details for your admin. Traffic that cannot be checked stays distinct from no traffic yet. Traffic states.
Your LiteLLM key
When your admin turns on personal LiteLLM keys, the app adds a step after sign-in. Paste your key under Your LiteLLM key and select Save key. A key LiteLLM rejects is not saved: the message stays under the field and you paste it again.
Claude Code and OpenCode then show Your LiteLLM key on the Tools tab. If LiteLLM later rejects the key, both rows read Needs attention with LiteLLM key rejected, and the matching warning offers Update key. Settings, then Change key, opens the same dialog. Quit and reopen the app before saving and the step comes back until a key is saved.
What Connect changes, per tool
Uninstalled tools are skipped. --tools <ids> (comma-separated) configures a subset.
| Tool | What Connect changes | ID |
|---|---|---|
| Claude (API) | the env block in ~/.claude/settings.json, plus an apiKeyHelper that renews the ark_ key on demand | claude-code |
| Claude (Subscription) | same env block; your Claude sign-in stays. A SessionStart hook re-mints the key instead of apiKeyHelper, which would hijack the seat's OAuth sign-in | claude-code |
| Claude Desktop | its third-party gateway mode, plus queued migration of eligible local sessions, MCP entries, plugins, and skills | claude-desktop |
| Codex (app, CLI, IDE) | ~/.codex/config.toml ($CODEX_HOME overrides the directory), with anyray as the default provider | codex |
| Cursor | native Team mode: local Shell/Read/MCP hooks plus a team steering rule (the BYOK OpenAI endpoint only under --org) | cursor |
| VS Code Copilot Chat | an Anyray chat provider (VS Code 1.121+) | copilot |
| GitHub Copilot CLI | COPILOT_PROVIDER_* in your shell profile (macOS/Linux) or user environment (Windows), plus retrieval MCP; seat-billed when a Copilot sign-in is readable, org-billed under --org or with no seat | copilot-cli |
| OpenCode | its direct API providers and its Copilot provider, plus a plugin that routes a ChatGPT Pro/Plus sign-in | opencode |
| OpenClaw | its anthropic and openai providers in ~/.openclaw/openclaw.json, plus the prompt-cache setting its custom-host mode skips | openclaw |
| pi / omp | the built-in anthropic and openai providers in ~/.pi/agent/models.json / ~/.omp/agent/models.yml, plus omp's retrieval MCP entry | pi, omp |
| JetBrains AI Assistant | Anyray Claude and Codex agents in its agent registry | jetbrains |
| Devin Desktop | Anyray Claude and Codex agents in its agent registry | windsurf |
| Shell & SDKs | base-URL env vars in the shell profile | shell-env |
Full on-disk footprint, hooks, MCP seams, and background services: Connect reference. Claude Code source-hook trims (off by default): Claude Code source trims.
Drive enrollment from a program
Add --json to --sign-in, --sso, --enroll, or --claim. Stdout becomes NDJSON events
(sso_grant, enrolled, applied, upstream_key_required, error), human output moves to stderr, --yes is required,
and no browser opens.
Mixing both lanes in one organization
The lane is chosen per enrollment command, so one gateway serves both. Publish one command per group with the same enrollment link:
- Own Claude or ChatGPT plan
- Org's provider account
curl -fsSL https://app.anyray.ai/i/tnt_… | sh -s -- --subscription
curl -fsSL https://app.anyray.ai/i/tnt_… | sh -s -- --org
| Lane | What the tool sends | Who pays |
|---|---|---|
--subscription | The tool's own seat token, forwarded to Anthropic or OpenAI unchanged | The developer's plan |
--org | The personal gateway key; the gateway swaps in the server-held provider credential | The org's provider account |
| neither flag | Whichever fits each tool on that machine | Depends on what is signed in |
With no flag, Connect uses any signed-in Claude or ChatGPT seat, so a developer meant for the org
account bills their own plan. --org is deterministic and remembered for later key refreshes.
Both groups get personal gateway keys, so per-user attribution is the same. Seat traffic skips the org's routing config (routing to Bedrock cannot serve a seat request) but runs its guardrails; org-lane traffic is routed normally.
Assign the lane centrally instead
Set lanes on PUT /admin/v1/policies/teams (fields): org or
subscription per team in lanes.teams, and per user (usually an email) in lanes.users.
-
A user's entry beats their team's, and
autoexempts the user from it. -
Team = the SCIM-mapped team when SCIM manages the roster, otherwise the team set at enrollment. A SCIM group move re-lanes the seat on its next policy pull.
-
Machines apply it on their next policy pull.
anyray-connect syncapplies it now. -
An assignment overrides the developer's flag, and Connect says so.
-
--upstreamBYO passthrough is neither lane and is left alone. -
An older or unreachable gateway, or a not-yet-enrolled developer, resolves to unassigned: the developer's own flag applies.
Staying current
Every install converges on ~/.anyray/bin/anyray-connect, the launcher all hooks and MCP
registrations point at; it checks for a new release about every 30 minutes.
| What is installed | What runs your command |
|---|---|
| A verified desktop app | Its bundled engine, with the same arguments, streams, and exit code |
| No desktop app | An existing standalone CLI. Removing the app does not recreate one or reinstall its scheduler |
| A remote session | Its own existing CLI installation |
| A source checkout | Its own launcher path |
Credential helpers and protocol commands always run locally. npm and npx setup stay supported.
- The desktop app owns updates while it runs: verifies the checksum and the Apple or Microsoft
signature, installs, and restarts. On macOS this is automatic unless you turn off Update
automatically in the tray; Windows asks for confirmation. Its engine never updates on its own.
A failed attempt is retried within minutes, and
doctorshows the last one (desktop app updates). - On CLI-only machines, an old runtime copy is deleted after two safe passes once integrations verify as current; two standalone releases stay for rollback.
doctor --jsonreports the owner, version, schedule, and recent cleanup.- Testing desktop startup needs a dedicated OS account; changing
HOMEdoes not isolate native login registration.
Update commands and the fleet policy (updates.mode in the team policy):
Keep the CLI current,
Fleet update policy,
conflicting installations,
update path variants.
Uninstall
anyray-connect --revert # restore tool configs, clear enrollment
npx anyray-connect@latest --revert # if the CLI is not on PATH
anyray-connect uninstall --json # desktop app: the above, then remove the app
Restart any running editor afterwards. Reconnecting needs a fresh enrollment link or the SSO command.
Desktop app (Uninstall Anyray Connect… in the tray or status window, or uninstall --json).
Before sign-in, open the user menu, then Settings:
- Restores tools, clears enrollment, unregisters the login item, removes
~/.anyray. - Hands package removal to Apple's Installer, Windows Installer, or PackageKit. On macOS that is
/usr/local/lib/anyray-connect/Uninstall Anyray Connect.pkg, which asks for an admin password; the app never elevates itself. - If the user cannot approve or cancels, the result reports
residue: "needs_admin".
Dragging it to the Trash, removing it in Windows Settings, or apt remove leaves per-user tool
configs and the login entry behind. Fleet automation runs uninstall --user --json per active user
before the admin removes the package.