CLI commands
The full anyray-connect reference. Anyray Connect explains what a run changes.
Install it
- macOS / Linux
- Windows PowerShell
curl -fsSL https://app.anyray.ai/connect.sh | sh -s
& ([scriptblock]::Create((irm https://app.anyray.ai/connect.ps1)))
Downloads a SHA-256-checked standalone binary to ~/.anyray/bin (override with $ANYRAY_HOME)
and runs it once. No Node needed.
- macOS / Linux
- Windows PowerShell
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- --enroll https://app.anyray.ai/enroll/enl_example --yes
& ([scriptblock]::Create((irm https://app.anyray.ai/connect.ps1))) "--enroll" "https://app.anyray.ai/enroll/enl_example" --yes
A flag placed on the curl side goes to curl, not the CLI.
Prompts read from your terminal. With no terminal (CI, a sandbox, an MDM run) the script adds
--yes.
npx anyray-connect@latest also works: npm only bootstraps the same standalone binary, and every
hook, MCP registration, and service points at ~/.anyray/bin/anyray-connect.
Running it
anyray-connect <command> [options]
| Setting | Resolution order |
|---|---|
| Gateway URL | --gateway, then $ANYRAY_GATEWAY_URL, then the ~/.anyray cache, then http://localhost:8787. Cached after the first run. |
| Help | anyray-connect --help (everyday), --help --all or --help-all (everything), <command> --help (one command). |
Managed Claude profiles get source hooks on either credential lane: --bin picks the command hook,
otherwise the env lane uses HTTP. doctor and status --json report both under sourceHook
(source trims).
Set up
| Command | What it does |
|---|---|
anyray-connect | Point installed tools at the gateway. Wizard on a terminal, flags in a script. |
anyray-connect wizard | Force the guided setup, even with flags. |
anyray-connect login | Browser SSO, pick a team, mint your personal gateway key. |
anyray-connect enroll --agent <name> | Mint a key for a CI job or service account, attributed to that name. |
anyray-connect --revert | Undo a previous run and clear the stored enrollment. |
anyray-connect fallback | Gateway outage: route Claude Code and Codex straight to the provider. Needs your own provider key or subscription. |
anyray-connect fallback status | Show whether fallback is on. |
anyray-connect fallback --revert | Gateway back: restore the Anyray route and hooks. Keeps enrollment. |
anyray-connect uninstall --json | Two-layer desktop uninstall: restore managed tools and remove user state, then ask the OS to remove the app/package. |
What each tool gets: What Connect changes.
Choose a Claude session route
After Connect configures Claude Code, open a new terminal:
claude bedrock: "fix the failing tests"
claude subscription: "review this change"
| Prefix | Billing |
|---|---|
bedrock: | Your organization's Bedrock connection through Anyray. Requires a configured Bedrock provider. |
subscription: | Your own native Claude Code subscription login through Anyray. Existing organization subscription fallback still applies. |
Omit the prompt for an interactive session. Ordinary claude commands keep your default.
Choose the prefix again when resuming with --resume or --continue; the launcher does not
save a route in conversation history.
The shortcuts install with Claude Code in both the CLI and desktop tray app. Bash, zsh and
PowerShell profiles receive them. Windows route shortcuts require PowerShell 7.3 or newer.
Existing aliases or functions named claude are kept.
Profiles that cannot be read safely as UTF-8 are left unchanged.
For other shells, or an existing alias, use the explicit command:
anyray-connect claude bedrock: "fix the failing tests"
anyray-connect claude subscription:
Use native Claude Code on Windows. Session routing does not run npm's .cmd launcher.
Sign into your Claude subscription with Claude Code's own login flow. Anyray never asks for
your subscription token. Managed settings that conflict with the selected route cause a refusal;
ask your administrator to change them. Each launch uses private temporary settings and leaves your
saved default alone. A custom Claude settings file selected in Connect is loaded for the session,
including its model, permissions and hooks. --settings is reserved by the launcher; other Claude
arguments pass through.
The startup line names the requested route. Confirm the actual provider on the session's request rows in the Anyray console. If a subscription runs out, the organization's subscription fallback decides whether paid API usage takes over.
Gateway outage fallback
anyray-connect fallback points Claude Code and Codex straight at the provider. fallback --revert
puts the Anyray route and hooks back. Enrollment is kept, and nothing runs in the background.
| Rule | Detail |
|---|---|
| Tools | Works only when every managed tool is Claude Code or Codex |
| Credential | Each tool needs its own provider key or subscription. The org key on the gateway does not work. A token you had before enrolling counts |
| Codex | Unset OPENAI_API_KEY first if it holds an Anyray key. Saved threads keep opening during the fallback and go back through Anyray after fallback --revert |
| After each switch | Restart editors and terminals. Start a new conversation if it has ctx_ handles |
| While on | No Anyray attribution, optimization, or governance. Track the spend in the provider's records |
| Machine policy | A policy that forces the gateway blocks success |
If a switch fails, run anyray-connect fallback status and check the tool settings before you send requests.
Reverting
| Case | Result |
|---|---|
--revert | Removes tool configs, services, and enrollment. The binary stays in ~/.anyray/bin. Removes what it can now and names what is left; nothing waits in the background. |
--tools <id> --revert | Queues work until that app closes. With Cursor open, only its saved OpenAI BYOK settings wait. Records your choice, so sync leaves the tool off unless your admin has locked it. |
| Desktop app | anyray-connect uninstall --json, or Uninstall Anyray Connect… in the tray. Restores tools, deletes user state, unregisters the login item, then removes the app via Apple's Installer, Windows Installer, or PackageKit. |
| Standard (non-admin) user | User layer finishes; result residue: "needs_admin". IT runs the platform package uninstall. |
| Fleet script | anyray-connect uninstall --user --json per logged-in user, then remove the machine package. Never prompts; reports residue: "skipped_no_gui". |
Reconnect with anyray-connect --sso or a fresh enrollment link. Restart editors and terminals that
were already open; they loaded hooks at startup.
Reverting on a fleet-managed machine
A full --revert holds: with no enrollment certificate the machine cannot mint a key, so refresh
and drift passes find nothing, and it stops counting against routing checks. It does not reach:
- A
managed-settings.jsonyour IT pushed. Remove it withsudo anyray-connect managed --revert. - The fleet agent itself, which
anyray-connectnever installed.
An admin can also revert a seat from the person's Machine status tab on Users: about two minutes on the desktop app, 30 minutes on CLI-only machines. The seat shows as offboarded.
Claude Desktop is the one tool with an organization-level effect
Gateway mode signs Claude Desktop out of claude.ai
(the trade). If your org
manages it from the claude.ai admin console, name tools explicitly (--tools claude-code,codex).
Undo with anyray-connect desktop disconnect.
Admin commands
Follow the admin guide to sign in and change config.
| Command | What it does |
|---|---|
anyray-connect admin login [--json] | Browser sign-in for admin access. --json streams the sign-in code and terminal result as NDJSON. --token-stdin reads a credential instead. |
anyray-connect admin status [--json] | Read local admin sign-in, expiry and per-client MCP registration without a network request. --json prints one status object. |
anyray-connect admin whoami [--json] | Show the verified admin identity and scopes. |
anyray-connect admin ops [filter] [--json] | List v1 API operations and whether you hold their scopes. |
anyray-connect admin describe <operationId>|<METHOD> <path> [--json] | Show an operation's scope, parameters and body fields, with types, required flags and allowed values. |
anyray-connect admin api <METHOD> <path> [--json] | Call an admin v1 operation. --body @file or --body - reads JSON; repeat --query k=v for query parameters. --all pages a list; --output <file> [--force] saves the response. |
anyray-connect admin secret set <target> [--stdin] [--json] | Enter a credential in a private browser page, or read it from stdin, then verify the saved configuration. Targets and flags. |
anyray-connect admin secret open <sso_portal [sso|dsync]|enrollment_link> [--json] | Open a page whose Open link button creates a sensitive link and goes there, without printing it. |
anyray-connect admin mcp | Run the separate anyray-admin stdio server. |
anyray-connect admin mcp install [--client claude-code|claude-desktop|codex|cursor]... [--json] | Register in the Claude clients present, or each repeated --client. --json reports installed state and outcomes for all four clients. |
anyray-connect admin logout | Remove local admin access and connect's admin MCP registrations for this gateway in all four clients; revoke a session. |
All accept --gateway <url>. Credentials, flags and exit codes.
Check your setup
To choose the Claude Code settings file, run
anyray-connect claude-settings --path ~/.claude/anyray-settings.json. When Claude Code is on,
Connect moves its setup to the new file. Read the saved target with
anyray-connect claude-settings --json. Set the path back to ~/.claude/settings.json to restore
the default.
| Command | What it does |
|---|---|
anyray-connect status | Each installed tool as on or off, plus gateway, name, team, savings. Tool lines. |
anyray-connect status --json | Write and print the content-free seat status document used by machine policy checks. |
anyray-connect usage | Tokens saved, saving, value created and extra capacity for your seat. --window 7d, 30d (default) or 90d. --json prints the gateway's usage document alone. Exits 1 when not signed in or the gateway cannot answer. |
anyray-connect doctor | Diagnose gateway reachability and each tool's config. Non-zero exit on a problem. |
anyray-connect models | List Copilot models your seat can run on the Anyray lane (--json for scripts). models <id> sets the Copilot CLI startup model after a live one-token check. Use this instead of the Copilot CLI's /models, which cannot list a custom provider. |
anyray-connect copilot-login | GitHub device-flow sign-in so the Copilot CLI lane can run current models. Run it when Connect reports no current models or you see 400 The requested model is not supported. |
anyray-connect connectors authorize <name> | Connect an org OAuth connector to your account. Over SSH, rerun with --claim <code>. Flags and fallbacks. |
doctor prints one health line per tool (what the summaries mean). Run doctor when a tool stops working. For scripts, repair is the stable form of --repair.
For Claude Code and Claude Desktop, doctor also reports each organization plugin's
install state. doctor --json and status --json
include the same ids, versions and states.
doctor also says whether you can share artifacts from Claude:
artifactSharing in doctor --json, artifacts.sharing in status --json. The value is on,
off (your admin has not turned it on), gateway_too_old, or unavailable (the check failed).
The field is absent under --quick or without a key. Whether Claude can read pages shared with you
is reported the same way: artifactReading in doctor --json, artifacts.reading in
status --json, and a Shared pages line in doctor.
An MDM-managed Claude Desktop gets two more verdicts of its own, because it shares through Connect's
anyray-share connector and reads through the gateway's managed anyray server
(states):
| Where | Publishing connector | Shared pages |
|---|---|---|
doctor and status | Claude desktop publishing connector: … | Claude desktop shared pages: … |
doctor --json | share on the claude-desktop row | sharedPages on the same row |
status --json | claudeDesktopManaged.share | claudeDesktopManaged.sharedPages |
claudeDesktopManaged and sharedPages are absent when Claude Desktop is not MDM-managed on the
machine, and without a key. doctor --quick leaves sharedPages out.
status --json also carries claudeDesktopArtifactsPage, the last
Artifacts page sync as status and reason. It is
absent until that sync has run on the machine.
| Flag | What it does |
|---|---|
| (none) | Report what is broken. |
--verify | Also send two tiny live requests: an auth smoke probe and a retrieval-loop probe. |
--repair | Repair managed routing and a missing Anyray skill. Reverted tools stay reverted. |
--json | Shareable report for support, no prompt content. |
--quick | Skip gateway, auth, and fleet-health probes. Skipped legs read null in --json. With --repair, repairs can still fetch gateway policy. Not with --verify. |
--security-review | Service names, unit-file paths, outbound hosts, and self-update footprint for your EDR allow-list. |
Tool states in status
status prints one line per installed tool and a single line for the rest.
Tools
Codex: on
Cursor: off (turned off by you)
Claude Code: on (locked by your admin)
Claude Desktop: pending (quit Claude Desktop to finish)
Not installed: Windsurf, Pi, OMP
The state is on, off, pending (an app has to quit first), or unverifiable (Connect cannot read
the tool's routing on this machine). A reason in parentheses appears only when the state is not plain.
status --json lists the managed tools in a tools array.
| Field | Value |
|---|---|
id | The tool id, as in --tools. |
tier | locked when the admin requires the tool, otherwise recommended. |
routed | Whether the tool's config points at your gateway. |
desktopSkill | Claude Desktop only: the Anyray skill as Desktop holds it, as kind plus version when installed (states). Absent from an older Connect. |
orgPlugins | Claude Code and Claude Desktop: an array of {id, version, state} for organization plugins (states). version is null when unknown. Absent from an older Connect. |
Automate seat maintenance
For fleet scripts, launch agents, systemd units, and scheduled tasks. Never prompts or reads a TTY. Each prints one JSON document on stdout, diagnostics on stderr.
| Command | What it does |
|---|---|
anyray-connect reconcile | Pull org tool policy, apply the Required and Available settings, repair routing drift. |
anyray-connect refresh | Renew the personal key and enrollment certificate when due, re-assert managed config. |
anyray-connect directives [--desktop-channel <staging|stable> --desktop-current <version>] | Run one pending console admin directive. The desktop app passes both flags so an update targets its channel and version. |
anyray-connect repair | doctor --repair without prompts. Prefer it in new automation: stable JSON and exit codes. |
anyray-connect status --json | Local status checks; same document as ~/.anyray/status.json. |
anyray-connect offboard | Revert managed tools, remove background units, clear enrollment. |
anyray-connect uninstall --json | User teardown, unregister the login item, remove ~/.anyray, request package removal. --user = user layer only, for MDM. |
anyray-connect desktop-update --channel <staging|stable> --current <version> | Stage a desktop update for the tray: download, verify checksum and signature, print its path. |
| Exit code | Meaning |
|---|---|
0 | Success: healthy seat, offboard done, or uninstall accepted as complete. |
1 | Unexpected error. |
2 | Usage error (unknown flag or argument). |
3 | Authentication broken. Re-enroll; remediation cannot fix it. |
4 | Partial: work remains, such as an incomplete setup or maintenance write, uninstall needs_admin, a partial user step, or a refused named tool. |
Which copy of the engine runs
A writing command forwards to the installed engine (same arguments, streams, exit code) when invoked via npm, npx, or a secondary CLI. If the recorded app is gone, CLI setup can run again. Releases older than engine forwarding must update first.
Never forwarded: doctor --json and status --json, uninstall (the tray menu spawns its
packaged engine directly), and credential helpers such as print-key.
What the seat maintenance JSON holds
Metadata only: Connect version, enrollment state, refresh timestamps, managed tool ids and whether each is
Required or Available, routing booleans, the last verb's exit code, and uninstall availability and last result.
Never a gateway key, device private key, SSO token, authorization header, or credential-bearing
URL. ~/.anyray/status.json is written atomically, owner-only.
On fleet-managed machines these commands skip self-update and relaunch; stale seats update via
the per-seat directive lane. Off the fleet, refresh still self-updates (the only unattended
path). Directive pulls run on every enrolled seat, report any staged desktop update, and let
other admin commands (offboard, credential repair) jump ahead of a waiting update.
Uninstall result
uninstall --json prints uninstall.user, uninstall.residue, uninstall.loginItem, and
uninstall.at, plus uninstall.leftovers and uninstall.restart when they are not empty:
| Field | Values |
|---|---|
user | complete, or partial(<step>) with <step> one of tray_exit, offboard, credentials, tools, managed_tools, org_content, offboard_marker, login_item, user_state, result_record, leftovers, processes. |
residue | removed, needs_admin, skipped_no_gui |
loginItem | unregistered, stale_entry, error |
leftovers | org_mcp:<tool>, claude_desktop:third_party, credential, file:<kind> (a desktop app folder such as file:tray_webkit), process:engine (an engine still running from the removed install), or unverifiable:<check> (a check that could not run). |
restart | Apps that still send requests to the gateway: vscode, cursor, windsurf, terminal, iterm, warp, ghostty, other, or unverified (could not check, which is always the case on Windows). |
After the user layer finishes, uninstall stops any anyray-connect process still running from the
install (such as an MCP server a coding tool started earlier). If one will not stop, or the check
fails, the result is partial(processes) and ~/.anyray stays for the retry. Otherwise it deletes
~/.anyray and the desktop app's caches, WebKit data, and logs, then re-reads the tool configs
without writing. Anything it still finds, or cannot check, is listed in leftovers, the result is
partial(leftovers), and the exit code is nonzero.
A running app keeps the ANTHROPIC_BASE_URL and OPENAI_BASE_URL it started with, so removing them
from your shell profile does not reach it. VS Code reads your shell environment once at launch, so
new integrated terminals keep routing until it restarts. Uninstall lists those apps in restart
without changing the exit code. The desktop app shows a dialog naming them; the CLI prints the same
line to stderr.
On a partial, run it again. Except for leftovers, ~/.anyray is kept so the retry knows what was ours; a rerun finds leftovers entries by their shape. org_content
means an anyray-connectors entry and key, a marketplace registration, or skill copies may remain.
The receipt lives outside ~/.anyray (no paths, credentials, or content), so doctor --json and
status --json can still explain a leftover app.
Keep the CLI current
| Command | What it does |
|---|---|
anyray-connect --version | Selected engine version. Update notices and conflicts go to stderr. |
anyray-connect --version --local | Invoked executable's version only; no discovery or update check. |
anyray-connect update | Install the published standalone version now. A desktop-bundled engine says the app owns updates and exits 0. |
anyray-connect update --check | Show the published version. Changes nothing. |
anyray-connect update --auto off | Stop automatic updates on this machine. |
anyray-connect update --auto on | Resume automatic updates and update now. |
anyray-connect update --json | JSON result for scripts. |
| Install | How it updates |
|---|---|
Standalone binary (connect.sh or npm) | Itself, about every 30 minutes. |
Binary your MDM placed and managed --bin names | On a newer release the seat moves to a self-updating copy under ~/.anyray; your binary is never changed. Under the Off fleet update policy the seat stays on it. |
| Desktop app | On macOS, for a Mac admin, updates itself in the background and restarts. Turn off Update automatically in the tray (or run update --auto off) to install from Update now instead; a required release installs either way. For a standard user, Update now opens the macOS Installer, or your MDM updates it. Windows asks you to confirm in the tray. The bundled engine never self-updates. |
| Container | Never self-updates. |
When Connect updates itself, or an admin sends an update from Machines, it reapplies its
configuration to your tools and pulls the Anyray skill.
anyray-connect update waits for that step and says whether it finished. An installer or MDM update
reaches your tools the next time one of them runs, within 30 minutes. Open sessions switch to the new
retrieval server code and keep the tools they were shown. New tools appear in your next session.
--auto off still takes mandatory releasesA release marked mandatory (a security or correctness fix) installs anyway, unless the machine is in a container or a fleet update policy says otherwise.
Conflicting installations
Different terminals report different versions? Run anyray-connect doctor --repair. It fixes
user-owned launchers and lists copies needing admin or package-manager action. Repoint any tools
that use a copy before removing it.
Fleet update policy
Admins set it for every machine with updates.mode on PUT /admin/v1/policies/teams
(fields); seats pick it up on their next policy pull. It only restricts: it never re-enables a developer's --auto off.
| Policy | What machines do |
|---|---|
| Automatic Default | Each seat checks about every 30 minutes and installs itself. |
| Administrator-directed | No machine downloads on its own; the gateway stops queuing updates. A version lands only when an admin sends it from Machines. |
| Off | No Anyray process fetches a binary. Ship versions with your own MDM. anyray-connect update reports the policy and does nothing; the console refuses to queue updates. |
The restricted modes exist for behavioral endpoint security (Bitdefender GravityZone ATC,
SentinelOne), which flags download-mark-executable-run regardless of code signature. Stale seats stay
visible in Machines and anyray-connect doctor, which reports the posture instead of advising
--auto on.
Migrating an npx-enrolled seat
A seat still pointing at a version-pinned npm runtime migrates on its next setup change.
anyray-connect update migrates now; update --check previews it. The new binary must pass
its signature check on macOS, or its published checksum elsewhere, before any registration is
repointed.
Platforms without a standalone binary, and containers
No standalone asset for this OS/arch: Connect keeps the npm runtime and reports self-update as
unavailable in --version, update, and doctor. Stay current with npx anyray-connect@latest.
In a devcontainer or Codespace, self-update and the npm-to-binary migration are skipped; rebuild the image instead (Remote and ephemeral machines). SSH remotes are unaffected.
Sync team content
anyray-connect sync
The background service and every successful apply already do this; sync is "apply it now".
| Tool | Where the skills land |
|---|---|
| Codex, Cursor, Copilot, OpenCode, OpenClaw, pi, omp | The shared ~/.agents/skills |
| Claude Code | Plugins. Connect registers the gateway marketplace in ~/.claude/settings.json (extraKnownMarketplaces, enabledPlugins); Claude Code fetches the hash-pinned archives on next launch. Over a plain-http gateway it gets file copies instead. |
| JetBrains, Devin Desktop | Both ~/.claude/skills and ~/.agents/skills (Claude and Codex agents) |
| Claude Desktop | Nothing on disk. Desktop installs from the gateway marketplace on relaunch. Managed machines get it from the bootstrap policy |
Removed skills disappear everywhere. ~/.anyray tracks per-skill versions, so re-runs touch only what
changed or went missing.
The same pull places org connectors: when the policy includes the
organization MCP endpoint, each managed tool gets one anyray-connectors
remote MCP server (Claude Desktop in its Anyray profile, not claude_desktop_config.json, which takes
local commands only). It is removed when no longer advertised. The older anyray-org name is replaced
on the next pull.
Find past context
Anyray moves large tool outputs out of context and leaves a · retrieve ctx_… marker.
| Command | What it does |
|---|---|
anyray-connect retrieve <ctx_…> | Print the original content, byte-for-byte on stdout. |
anyray-connect recall <query> | Semantic search over externalized outputs. Prints handle<TAB>score<TAB>preview; exits 1 on no match, like grep. |
anyray-connect migrate [--export <file.zip>] | Copy portable Claude Desktop local data; optionally restore a claude.ai export. |
anyray-connect history import <file> | Load a Claude export (conversations.json) so past conversations stay searchable. |
anyray-connect history restore <file> | Put them back in Claude Desktop's sidebar (the .zip, with Desktop quit). |
anyray-connect history status | Where the archive lives and its size. |
retrieve and recall take --source auto|claude|profile (which config resolves the gateway;
auto is the default).
anyray-connect retrieve ctx_example123 > output.txt
anyray-connect retrieve ctx_example123 | jq .
anyray-connect recall "migration rollback plan"
anyray-connect recall "failing auth test" --k 5
history and migrate --export take the export from claude.ai → Settings → Privacy → Export data (Anyray cannot fetch it).
Running both import and restore is fine. Full flows:
Bring your claude.ai chats.
Roll out to a fleet
For admins packaging Anyray through MDM.
| Command | What it does |
|---|---|
anyray-connect managed | Emit or install the fleet-wide Claude Code managed-settings.json. |
anyray-connect desktop | Desktop-app routing (Claude desktop app, Codex on managed devices). |
anyray-connect print-key | Print the enrolled developer's short-lived gateway key for helper integrations. |
managed
managed-settings.json outranks the user's ~/.claude/settings.json, so it survives edits. It holds
no credential; each user still enrolls once for attribution.
# Emit for MDM packaging (Jamf, Ansible…)
anyray-connect managed --print --gateway https://gateway.example.com
# Write to the OS system path: merges, preserves non-Anyray keys
sudo anyray-connect managed --write --gateway https://gateway.example.com
# Remove only the Anyray-owned keys
sudo anyray-connect managed --revert
--tool | What it emits |
|---|---|
claude-code | The managed-settings.json above. The default. |
jetbrains | acp.json registering the Anyray ACP agents. Needs --bin and --npx. |
shell | A /etc/profile.d snippet exporting the gateway base URLs. Never a key. |
bootstrap | A bootstrap file carrying the org SSO link. Needs --sso. |
| Flag | What it does |
|---|---|
--print / --write / --revert | Pick one mode. Everything but claude-code is --print only. |
--gateway <url> | Your real gateway. The localhost default is almost never right for a fleet. |
--bin <path> | Fleet-stable absolute path, e.g. /usr/local/bin/anyray-connect. Seats move off it to update: how. |
--team, --intent, --session | Static attribution metadata on the artifact. |
--out | Write UTF-8 with no BOM. Use it on Windows instead of > (PowerShell 5.1 writes UTF-16LE, which no JSON reader accepts): anyray-connect managed --print --out managed-settings.json. |
--lock-skills | Make org Skills and Guidance the only skills Claude Code loads: registers the marketplace with auto-update on and sets strictPluginOnlyCustomization.skills, so loose ~/.claude/skills stops loading. Without it, machines still register the marketplace at user scope. A file generated before connect wrote auto-update never picks up skills added later: generate it again and redeploy. |
--scrub-direct-mode | Pin CLAUDE_CODE_USE_BEDROCK and CLAUDE_CODE_USE_VERTEX to "". Off by default. |
With CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX set, Claude Code never reads
ANTHROPIC_BASE_URL, and no per-user config can override the managed file. Add --scrub-direct-mode
to pin both to "" (Claude Code's documented unset):
sudo anyray-connect managed --write --gateway https://gateway.example.com --scrub-direct-mode
It is off by default because those switches are usually org policy, and the gateway reaches the same
Bedrock or Vertex once its provider is configured. --revert removes only Anyray's empty pin.
desktop
Covers what settings.json cannot: the Claude desktop app, and the Codex app, IDE, and CLI on
managed devices.
# Connect through the normal enrollment/update/healing lifecycle
anyray-connect desktop
# Undo: removes only Anyray-owned config
anyray-connect desktop disconnect
| Subcommand | What it does |
|---|---|
desktop fleet bootstrap <os> <url> <out> | Emit Claude's stable MDM trust anchor for a centrally refreshed policy. --oidc for an existing IdP. |
desktop fleet static <os> <helper-path> <out> | Emit a complete static policy artifact (macOS profile, Windows registry, or Linux JSON). |
desktop helper --write | Install the credential and bootstrap-headers helper wrappers (--print for MDM packaging). |
desktop codex | Emit the Codex MDM artifact (--mobileconfig, or a Windows managed TOML). |
--helper-path must be the same on every deviceUse an absolute path that exists on every machine, or the artifact breaks all machines but yours.
Local setup queues migration of eligible user-owned profile data. On MDM-managed Desktop, Connect may copy that data but never writes the managed policy (the boundary). Artifact commands and flows: Claude Desktop on managed devices, Desktop reference.
print-key
anyray-connect print-key # the ark_ key alone
anyray-connect print-key --json # {"token":"ark_…","headers":{…}}
anyray-connect print-key --passthrough-headers # header object only
The short-lived client key, never a seat OAuth token. Automate with print-key --json, not by
scraping desktop output.
test-key
anyray-connect test-key --json
Uses the gateway and personal key in your stored profile to mint a seven-day test key.
Each run revokes your previous test key and atomically replaces ~/.anyray/test-kit.env
(mode 0600) with ANYRAY_GATEWAY_URL, ANYRAY_BENCH_CLIENT_KEY, and
ANYRAY_TEST_KEY_EXPIRES_AT. Your personal routing key stays in the profile.
The key is never printed. --json returns { ok, path, gateway, expiresAt } on success
or { ok: false, code } on failure. A gateway_refused from a 403, 409 or 503 also
carries the gateway's error type as gatewayType: test_key_personal_only, sso_required,
sso_policy_unavailable, or test_key_unavailable_multi_tenant (a multi-tenant gateway
cannot mint self-serve test keys). Without --json the common ones come with a plain
sentence. Errors exit non-zero: not_enrolled, gateway_refused,
gateway_unreachable, gateway_invalid_response, write_failed, or
invalid_arguments. --help makes no request.
Common flags
For the apply flow: anyray-connect with no subcommand, and wizard.
Identity and attribution
| Flag | What it does |
|---|---|
--gateway <url> | Gateway origin. Cached after the first run. |
--user <id> | Attribute spend to this user. Default: cached name, then git user.name or user.email, then the OS user. '' clears it. |
--team <id> | Attribute spend to this team. '' clears it. |
--intent <id> | Tag traffic, filterable as intent:<id> in the console. |
--intent-label <s> | Human-readable label for that intent. |
--session <id> | Group requests under a session id in the console. |
Enrollment
| Flag | What it does |
|---|---|
--enroll <link> | Passwordless enrollment from an …/enroll/<token> or …/i/<token> link. Sets the gateway from the link. |
--sso <link> | Enterprise SSO from an …/sso/<tenantId> or …/i/<tenantId> link: device sign-in against your IdP. |
--sign-in | Browser sign-in to the deployment mapped to your verified company email. Uses $ANYRAY_CP_ORIGIN, then the default Billing App origin. |
--machine | Machine-mode provisioning token: enroll by machine id, not email. |
--json | NDJSON enrollment events on stdout, human output on stderr. Requires --yes; opens no browser. |
Enrollment saves an Ed25519 keypair and signed cert (~/.anyray/dev-key.pem, mode 600) and mints a
gateway key from it. A device-proof heartbeat extends the key before expiry, with no re-enrollment.
On Windows, a machine Connect install can still win PATH after enrollment. Connect finishes
enrolling, then warns on stderr; the --enroll exit code is unchanged. anyray-connect update
exits non-zero while the machine copy wins PATH. An administrator removes "Anyray" in Settings >
Apps > Installed apps, then the user re-runs the Anyray enroll link.
Billing lane
| Flag | What it does |
|---|---|
| (default) | AUTO: your own subscription where supported, org API billing otherwise. |
--subscription | Always your own seat; your tool's OAuth token rides through the gateway. Honored by Claude Code, Codex, and Claude Desktop on verified macOS builds. |
--org | Always org API billing; your ark_ key still identifies you. Cursor stays on native Team mode unless you pass this. |
--upstream <url> | Route to your org's OpenAI- or Anthropic-compatible endpoint (e.g. a LiteLLM proxy). Both lanes forward your key. Needs a key. Optional when your organization sets a personal LiteLLM URL. |
--upstream-key <key> | Your personal key for that endpoint, stored locally. Shows in the process list, so prefer --upstream-key-stdin. |
--upstream-key-stdin | Read that key from one stdin line, or from a hidden prompt on a terminal. It never appears in argv or output. Cannot be combined with --upstream-key or --key-stdin. |
When your organization sets a personal LiteLLM URL, or you already saved one with --upstream, the
key alone is enough:
printf '%s' "$LITELLM_KEY" | anyray-connect --upstream-key-stdin
A run in a terminal asks for the key once, with the input hidden, checks it, and only then changes
anything. Press Enter to skip. A scripted run (--yes, or no terminal) never asks: it prints one
line on stderr, and with --json it emits {"event":"upstream_key_required","url":"…"}.
The lane is per enrollment, so one gateway serves both. Console per-user and per-team assignments override these flags (mixing both lanes).
Run behavior
| Flag | What it does |
|---|---|
--tools <ids> | Comma-separated subset of the ids in What Connect changes. |
--with-tools <ids> | Add ids to a normal run instead of narrowing it. Today: claude-desktop, which a bare run skips because routing it turns off claude.ai Enterprise org settings; naming it is consent. Users → Add people → Add users with CLI tool emits this. |
--project | Write committable, credential-free routing into the repo (.claude/settings.json, .codex/config.toml) instead of user config. Org API lane only. With --revert, removes it. Remote and ephemeral machines. |
--dry-run | Show what would change. Writes nothing. |
--yes, -y | Skip prompts. |
--quit-apps | Close and reopen editors with a stale environment. The only way a scripted run closes anything. |
--no-quit-apps | Never close anything, whatever else is passed. |
--force | Skip the pre-write gateway reachability check. |
--skip-verify | Skip the post-apply smoke test. |
--no-key-refresh | Turn off the default-on device-proof heartbeat. Leave it on unless you must. |
--revert | Undo a run and clear enrollment. Reverted tools are tombstoned: fleet policy and a later bare run (the enrollment one-liner) leave them off. Unticking a tool in the setup checklist does the same. A Required tool refuses --tools <id> --revert; --tools <id> or --with-tools <id> clears the tombstone. Not with --sso or --enroll. |
--verbose | After apply, show the masked curl re-test recipe and revert hint. |
--help, -h | Everyday help. --all or --help-all for everything. |
doctor and status --json include the verified key's sourceTrim.state
(state vocabulary and grace period). sdk-agent is a metadata ID for
hand-integrated tool loops, not a --tools adapter.
Batch search
The anyray_search batch form is a Default-off prototype.
See enablement, limits, and verification.
Search with source context
anyray_search_context is a Claude Code Default-off prototype.
Combines search with complete TS/JS declarations and labels partial window fallbacks.
See setup and source limits.
Batch reads
anyray_read_batch, on the local MCP server, reads several workspace files in one call.
On by default on Linux, macOS, and Windows.
| Detail | Value |
|---|---|
| Approval | Pre-approved by Connect for Claude Code, Codex, OpenCode, and the JetBrains and Devin Codex agents. Other MCP hosts ask on first use. |
| Call shape | For two or more known ranges: {"reads":[{"path":"src/setup.ts","offset":20,"limit":40},{"path":"src/config.ts","offset":10,"limit":30}]} (1-based lines). Exact relative paths use forward slashes on every OS; on Linux and macOS an absolute path inside the server's directory works too. Request a complete file as a range from line 1; each range may hold up to 16 KB of source, and a larger one is skipped. The older paths form is not advertised with ranged reads on; the server still answers it for a client that listed the complete-file definition before the switch took effect. The server also accepts ranges in place of reads, the name Codex guesses because its scripts never see the schema. |
| Response | Range results carry physical line numbers; complete files carry a path header, starting line, and byte count. |
| Limits | 32 entries, 16 KiB each, 64 KiB total, 4 MiB per ranged source file, 40,000 result characters incl. headers. A range over 16 KiB, or a ranged source over 4 MiB, is skipped, and a PARTIAL line names it by entry number and path; if every entry is too large, the batch fails. Any other bad entry rejects the batch, and so does any file over 16 KiB in the complete-file form; use Read for a single range or exploring. A ranged batch over 64 KiB or 40,000 characters returns its leading entries whole and ends with a PARTIAL line naming the entries it left out. The complete-file form rejects it. |
| Refused | Paths outside the server's directory, symlinks, hardlinks, parent traversal, binary and special files. Windows also: junctions, alternate data streams, device names. Open directory handles anchor each read. |
| Consistency | Sequential reads, not an atomic snapshot. |
| Status | doctor --json and status --json report clientTools.readBatch: off, invalid_policy, enabled_ranged (default), enabled (complete-file switch), unsupported_platform, unsupported_architecture, or native_binding_unavailable. |
| Usage | Heartbeats report attempts and completed batch outcomes separately. Anyray operators can inspect per-agent counts; unreported outcomes remain unknown. See heartbeat reporting. |
| Savings | Messages, Chat Completions and Responses requests must carry both the call and its result; on a Codex WebSocket, a turn that sends only the result is matched to the call in the response it continues. A call returning K files of 2 or more earns ceil(K / 1.19) - 1 avoided round trips on Claude Code, capped at 26 per request, because Claude Code reads 1.19 files per turn on its own; Codex earns ceil(K / 2.63) - 1, capped at 12, because Codex reads 2.63 ranges per turn on its own; other tools earn ceil(K / 1.5) - 1, capped at 21. Each is credited under Batch read (batch_read) as one re-read of that request's cached prompt at the cache-read price. Each call counts once. Calls returning one file, failed requests and requests with no cache reads earn nothing. On Claude Code, a call earns only after the agent has read ranges on its own at least twice in the same conversation (Read with an offset or limit, or a sed -n, cat -n, head, tail or nl command that prints a file). A session that hands work to a sub-agent earns nothing (delegated_session). |
Claude Code loads this tool on its main agent and subagents by default. Restart the client after
changing any clientToolPolicies field below.
| Field | Effect |
|---|---|
readBatchAlwaysLoad: false | Defer the tool behind ToolSearch. |
readBatchInstructions: false | Drop the startup line a Claude Agent SDK app's sdk server gives the model about this tool (SDKs). doctor --json and status --json show it as clientTools.readBatchInstructions. |
readBatchRanges: false | Restore the complete-file definition. |
readBatchNudge: false | Turn off the Claude Code hook reminders (after two consecutive single-range reads, repeating after six further reads, up to three times per agent; and after a search that lists 2 to 300 line-numbered hits in the workspace, up to twice per agent, after which a single-range read is reminded at once) and the startup hint for Explore and general-purpose subagents. doctor --json and status --json show it as clientTools.readBatchNudge. Needs the local stdio MCP server. |
readBatchMainHint: false | On by default Turn off the main agent's startup hint (trace the workspace in batched reads instead of spawning Explore subagents, and never re-read a range a subagent reported). Every agent type always runs. The hint is not sent when Claude Code runs with --max-turns below 80. |
readBatchCodexNudge: false | On by default Turn off Codex's reminder to batch its reads (Codex source trims). |
searchContextHints: false | On by default Keep Symbol context but drop its mention from these hints. doctor --json and status --json show it as clientTools.searchContextHints. |
webFetchRefusalNote: false | On by default Turn off the note Claude Code gets after WebFetch's summarizer declines to quote a page verbatim (answer from the facts, section names and paraphrase it returned instead of fetching the page again). Once per page per agent. doctor --json and status --json show it as clientTools.webFetchRefusalNote. |
constantContext: true | Off by default After each Claude Code compaction, name the transcript from before it so the agent can grep it back with anyray_retrieve, and show back the working state it recorded with anyray_record_state (constant context). The transcript stays on this machine; only the slices the agent reads back are sent, like any other tool output. doctor --json and status --json show it as clientTools.constantContext. |
Failures return a fixed reason and the 1-based entry number when one entry failed. They never return partial file contents or a path.
Batch reads are a separate MCP permission. A path you denied to your client's Read is still reachable through this tool.
To turn it off, set clientToolPolicies.readBatch to false in ~/.anyray/connect.json (merge, keep other fields) and restart the client. No env var or flag
controls it; one switch covers every client.
{
"clientToolPolicies": {
"readBatch": false
}
}
Heartbeat, framing, and the old launch argument
The MCP server sends that state and per-tool call counts on its heartbeat: Anyray tool names and
integers, no paths, arguments, or results (What admins see).
clientTools.readBatch reports the switch, not a running session; an open client keeps its old
answer until restarted.
The source hook leaves the tool's framing unchanged; results enter the conversation under existing routing and content policy. This experimental tool has no established production cost guarantee.
Do not pass --experimental-read-batch as an MCP launch argument. It made Connect treat its own
registration as foreign. It is now ignored, and re-running anyray-connect for that tool repairs it.