Skip to main content

CLI commands

The full anyray-connect reference. Anyray Connect explains what a run changes.

Install it​

1
Run the installer
macOS / Linux
curl -fsSL https://app.anyray.ai/connect.sh | sh -s

Downloads a SHA-256-checked standalone binary to ~/.anyray/bin (override with $ANYRAY_HOME) and runs it once. No Node needed.

2
Pass CLI flags after `sh -s --`
macOS / Linux
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- --enroll https://app.anyray.ai/enroll/enl_example --yes

A flag placed on the curl side goes to curl, not the CLI.

3
Answer the prompts

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​

Usage
anyray-connect <command> [options]
SettingResolution order
Gateway URL--gateway, then $ANYRAY_GATEWAY_URL, then the ~/.anyray cache, then http://localhost:8787. Cached after the first run.
Helpanyray-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​

CommandWhat it does
anyray-connectPoint installed tools at the gateway. Wizard on a terminal, flags in a script.
anyray-connect wizardForce the guided setup, even with flags.
anyray-connect loginBrowser 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 --revertUndo a previous run and clear the stored enrollment.
anyray-connect fallbackGateway outage: route Claude Code and Codex straight to the provider. Needs your own provider key or subscription.
anyray-connect fallback statusShow whether fallback is on.
anyray-connect fallback --revertGateway back: restore the Anyray route and hooks. Keeps enrollment.
anyray-connect uninstall --jsonTwo-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:

One session
claude bedrock: "fix the failing tests"
claude subscription: "review this change"
PrefixBilling
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:

Explicit launcher
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.

RuleDetail
ToolsWorks only when every managed tool is Claude Code or Codex
CredentialEach tool needs its own provider key or subscription. The org key on the gateway does not work. A token you had before enrolling counts
CodexUnset 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 switchRestart editors and terminals. Start a new conversation if it has ctx_ handles
While onNo Anyray attribution, optimization, or governance. Track the spend in the provider's records
Machine policyA 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​

CaseResult
--revertRemoves 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> --revertQueues 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 appanyray-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) userUser layer finishes; result residue: "needs_admin". IT runs the platform package uninstall.
Fleet scriptanyray-connect uninstall --user --json per logged-in user, then remove the machine package. Never prompts; reports residue: "skipped_no_gui".
A revert spends the enrollment

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.json your IT pushed. Remove it with sudo anyray-connect managed --revert.
  • The fleet agent itself, which anyray-connect never 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.

CommandWhat 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 mcpRun 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 logoutRemove 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.

CommandWhat it does
anyray-connect statusEach installed tool as on or off, plus gateway, name, team, savings. Tool lines.
anyray-connect status --jsonWrite and print the content-free seat status document used by machine policy checks.
anyray-connect usageTokens 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 doctorDiagnose gateway reachability and each tool's config. Non-zero exit on a problem.
anyray-connect modelsList 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-loginGitHub 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):

WherePublishing connectorShared pages
doctor and statusClaude desktop publishing connector: …Claude desktop shared pages: …
doctor --jsonshare on the claude-desktop rowsharedPages on the same row
status --jsonclaudeDesktopManaged.shareclaudeDesktopManaged.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.

FlagWhat it does
(none)Report what is broken.
--verifyAlso send two tiny live requests: an auth smoke probe and a retrieval-loop probe.
--repairRepair managed routing and a missing Anyray skill. Reverted tools stay reverted.
--jsonShareable report for support, no prompt content.
--quickSkip gateway, auth, and fleet-health probes. Skipped legs read null in --json. With --repair, repairs can still fetch gateway policy. Not with --verify.
--security-reviewService 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.

FieldValue
idThe tool id, as in --tools.
tierlocked when the admin requires the tool, otherwise recommended.
routedWhether the tool's config points at your gateway.
desktopSkillClaude Desktop only: the Anyray skill as Desktop holds it, as kind plus version when installed (states). Absent from an older Connect.
orgPluginsClaude 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.

CommandWhat it does
anyray-connect reconcilePull org tool policy, apply the Required and Available settings, repair routing drift.
anyray-connect refreshRenew 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 repairdoctor --repair without prompts. Prefer it in new automation: stable JSON and exit codes.
anyray-connect status --jsonLocal status checks; same document as ~/.anyray/status.json.
anyray-connect offboardRevert managed tools, remove background units, clear enrollment.
anyray-connect uninstall --jsonUser 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 codeMeaning
0Success: healthy seat, offboard done, or uninstall accepted as complete.
1Unexpected error.
2Usage error (unknown flag or argument).
3Authentication broken. Re-enroll; remediation cannot fix it.
4Partial: 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:

FieldValues
usercomplete, 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.
residueremoved, needs_admin, skipped_no_gui
loginItemunregistered, stale_entry, error
leftoversorg_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).
restartApps 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​

CommandWhat it does
anyray-connect --versionSelected engine version. Update notices and conflicts go to stderr.
anyray-connect --version --localInvoked executable's version only; no discovery or update check.
anyray-connect updateInstall the published standalone version now. A desktop-bundled engine says the app owns updates and exits 0.
anyray-connect update --checkShow the published version. Changes nothing.
anyray-connect update --auto offStop automatic updates on this machine.
anyray-connect update --auto onResume automatic updates and update now.
anyray-connect update --jsonJSON result for scripts.
InstallHow it updates
Standalone binary (connect.sh or npm)Itself, about every 30 minutes.
Binary your MDM placed and managed --bin namesOn 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 appOn 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.
ContainerNever 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 releases

A 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.

PolicyWhat machines do
Automatic DefaultEach seat checks about every 30 minutes and installs itself.
Administrator-directedNo machine downloads on its own; the gateway stops queuing updates. A version lands only when an admin sends it from Machines.
OffNo 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​

Pull org Skills and Guidance now
anyray-connect sync

The background service and every successful apply already do this; sync is "apply it now".

ToolWhere the skills land
Codex, Cursor, Copilot, OpenCode, OpenClaw, pi, ompThe shared ~/.agents/skills
Claude CodePlugins. 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 DesktopBoth ~/.claude/skills and ~/.agents/skills (Claude and Codex agents)
Claude DesktopNothing 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.

CommandWhat 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 statusWhere the archive lives and its size.

retrieve and recall take --source auto|claude|profile (which config resolves the gateway; auto is the default).

Examples
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.

CommandWhat it does
anyray-connect managedEmit or install the fleet-wide Claude Code managed-settings.json.
anyray-connect desktopDesktop-app routing (Claude desktop app, Codex on managed devices).
anyray-connect print-keyPrint 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.

managed modes
# 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
--toolWhat it emits
claude-codeThe managed-settings.json above. The default.
jetbrainsacp.json registering the Anyray ACP agents. Needs --bin and --npx.
shellA /etc/profile.d snippet exporting the gateway base URLs. Never a key.
bootstrapA bootstrap file carrying the org SSO link. Needs --sso.
FlagWhat it does
--print / --write / --revertPick 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, --sessionStatic attribution metadata on the artifact.
--outWrite 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-skillsMake 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-modePin CLAUDE_CODE_USE_BEDROCK and CLAUDE_CODE_USE_VERTEX to "". Off by default.
A host already pinned to Bedrock or Vertex ignores the routing keys

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):

Clear a Bedrock/Vertex pin
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.

This machine
# Connect through the normal enrollment/update/healing lifecycle
anyray-connect desktop

# Undo: removes only Anyray-owned config
anyray-connect desktop disconnect
SubcommandWhat 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 --writeInstall the credential and bootstrap-headers helper wrappers (--print for MDM packaging).
desktop codexEmit the Codex MDM artifact (--mobileconfig, or a Windows managed TOML).
--helper-path must be the same on every device

Use 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​

Mint a client-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​

FlagWhat 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​

FlagWhat 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-inBrowser sign-in to the deployment mapped to your verified company email. Uses $ANYRAY_CP_ORIGIN, then the default Billing App origin.
--machineMachine-mode provisioning token: enroll by machine id, not email.
--jsonNDJSON 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​

FlagWhat it does
(default)AUTO: your own subscription where supported, org API billing otherwise.
--subscriptionAlways your own seat; your tool's OAuth token rides through the gateway. Honored by Claude Code, Codex, and Claude Desktop on verified macOS builds.
--orgAlways 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-stdinRead 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​

FlagWhat 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.
--projectWrite 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-runShow what would change. Writes nothing.
--yes, -ySkip prompts.
--quit-appsClose and reopen editors with a stale environment. The only way a scripted run closes anything.
--no-quit-appsNever close anything, whatever else is passed.
--forceSkip the pre-write gateway reachability check.
--skip-verifySkip the post-apply smoke test.
--no-key-refreshTurn off the default-on device-proof heartbeat. Leave it on unless you must.
--revertUndo 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.
--verboseAfter apply, show the masked curl re-test recipe and revert hint.
--help, -hEveryday 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.

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.

DetailValue
ApprovalPre-approved by Connect for Claude Code, Codex, OpenCode, and the JetBrains and Devin Codex agents. Other MCP hosts ask on first use.
Call shapeFor 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.
ResponseRange results carry physical line numbers; complete files carry a path header, starting line, and byte count.
Limits32 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.
RefusedPaths 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.
ConsistencySequential reads, not an atomic snapshot.
Statusdoctor --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.
UsageHeartbeats report attempts and completed batch outcomes separately. Anyray operators can inspect per-agent counts; unreported outcomes remain unknown. See heartbeat reporting.
SavingsMessages, 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.

FieldEffect
readBatchAlwaysLoad: falseDefer the tool behind ToolSearch.
readBatchInstructions: falseDrop 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: falseRestore the complete-file definition.
readBatchNudge: falseTurn 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: falseOn 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: falseOn by default Turn off Codex's reminder to batch its reads (Codex source trims).
searchContextHints: falseOn by default Keep Symbol context but drop its mention from these hints. doctor --json and status --json show it as clientTools.searchContextHints.
webFetchRefusalNote: falseOn 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: trueOff 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.

Read deny rules do not apply

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.

Connect profile fields
{
"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.