Skip to main content

Connect reference

What Connect writes and runs on a machine, for security review and fleet operations. Connect runs per user, without privilege, and installs nothing system-wide: no CA certificates, no machine-wide proxy, no DNS changes, no kernel extension, no system daemon, no root (outside the managed --write fleet command). Nothing sits in the request path: tools call the gateway directly, so Connect never sees their method, path, body, or response.

What lands on the machine

Everything Connect owns lives in one directory, ~/.anyray/ (override the root with $ANYRAY_HOME), created mode 0700; the two files holding credentials are written 0600.

PathWhat it is
bin/anyray-connectThe managed standalone binary. Every hook, MCP registration, and service points at this one stable launcher.
versions/<version>/Previously installed versions, kept so an update can roll back.
connect.jsonThis machine's profile: gateway address, your name and team, which tools are configured. Mode 0600.
dev-key.pemThe device private key that proves this machine's identity when renewing your gateway key. Mode 0600, never logged or printed.
logs/connect-refresh.logCaptured output from scheduled key renewal, where installed. Error names only, no request data. macOS only; Linux logs to journald.
vscode-extension/, vscode-receipts/The bundled Anyray VS Code extension and a receipt per applied install.
openclaw-plugin/The OpenClaw plugin. The Anyray repository is private, so Connect is its distribution channel.
hook-tee/Untrimmed copies of tool output the PostToolUse hook trimmed, so the full output: Read … footer it wrote still resolves. Owner-only, never uploaded, kept 30 days after the last reference, 90 days at the outside, and 128 MiB in total. ANYRAY_HOOK_TEE=off disables it.
hook-cache.jsonOptimization verdicts for outputs already seen, so a repeat skips a second round trip. 24 hours, 200 entries. ANYRAY_HOOK_CACHE=off disables it.

Seams inside your tools

Beyond each tool's base URL and key, these are the named seams Connect writes. Each carries an ownership marker, so a re-run is idempotent and --revert removes exactly what Connect added, leaving anything it doesn't own untouched.

SeamWhereWhat it does
PostToolUse hook~/.claude/settings.jsonTrims oversized tool output at the source, before it enters the transcript. Size-gated inside the hook.
UserPromptSubmit hook~/.claude/settings.jsonRecords a paste beacon for attribution.
SessionStart hook~/.claude/settings.jsonSubscription mode only: re-mints a short-lived key at session start, so it can't lapse mid-session. Runs async, never delaying startup.
anyray MCP server~/.claude.json under mcpServersThe retrieval server, described below. Re-invokes the same binary over stdio.
Cursor hooks and MCP~/.cursor/hooks.json, ~/.cursor/mcp.jsonCursor's native Team mode: the local Shell, Read, and MCP optimization seams, plus the same anyray retrieval server.
Managed shell block~/.zshrc, ~/.bashrc, or ~/.profileBase-URL environment variables, fenced by # >>> anyray connect >>> and # <<< anyray connect <<< so the rest of your profile is never rewritten.
VS Code extensionVS Code's own extension storeInstalled from the bundled VSIX through the VS Code CLI; its credential goes to VS Code SecretStorage, not to a file.

The retrieval MCP server

The retrieval server is what makes an optimizer trim reversible: where a strategy replaces bulk with an opaque ctx_… handle, these are the read paths that fetch the detail back. Every client gets anyray_retrieve and anyray_recall, plus anyray_history where that archive has content. Clients whose native search and read output cannot use Anyray's replacement hook also get anyray_search and anyray_read. Claude Code does not advertise those two context tools: its native Grep and Read already pass through the PostToolUse optimizer, so a fresh session does not duplicate its first-turn exploration through MCP.

After initialization, the stdio server sends a content-free liveness heartbeat every 5 minutes until the transport closes. The gateway expires that evidence after 6 hours without verified activity, so a stopped server automatically disables fresh handle-producing strategies.

ToolWhat it does
anyray_retrieveFetch the full original behind a known ctx_… handle.
anyray_recallSearch the durable stash semantically when the handle has scrolled out of view, returning ranked handles.
anyray_searchSearch the local workspace and return file:line candidates, ranked and trimmed against the query.
anyray_readRead a workspace file, returned as a relevant slice the model can top back up rather than a lossy cut.
anyray_historySearch your own past context. Advertised only where that archive has content.

Every result is capped before it leaves the MCP server. If a read reaches the limit, it stops at a line boundary and names the next startLine; a search drops the lowest-ranked tail and reports how many matches were omitted. This prevents an MCP host from rejecting the entire result before the gateway hook can optimize it.

Background services

On a default seat, Connect installs no background service at all: a gateway key lives 90 days, so nothing can expire under a running tool. A small unprivileged service appears only where your organization issues fast-rotating keys, or on a seat used solely for SDK and shell work. It sends credential data only, and never your prompts or replies. Per-platform service labels, unit-file paths, and how to opt out: Key renewal.

The authoritative inventory is generated, not written by hand

anyray-connect doctor --security-review prints the service names, unit-file paths, outbound hosts, and the self-updater's full footprint (the release URLs it fetches, the paths it writes, and the two commands it runs on a freshly downloaded binary) that your security or endpoint team needs to allow-list. It is derived from the installers themselves, works offline, needs no key, and says nothing about your traffic. Where that sheet and this page disagree, trust the sheet.

curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- doctor --security-review

Service keys

An agent host (a CI runner, a bot, a scheduled SDK job) has no person to sign in, so the console mints it a service key instead. Connect runs on that host with the key in the environment and the same headless apply a developer uses:

export ANYRAY_CLIENT_KEY=ark_svc_… # from the host's secret store
curl -fsSL https://app.anyray.ai/connect.sh | sh -s -- --gateway <origin> --yes

Detection picks the installed tools; add --tools shell-env to write only the SDK environment. What changes on this lane:

  • Identity and team come from the key. --user and --team are ignored, with a note saying so.
  • There is no enrollment cert, so nothing refreshes: no background service, no LaunchAgent or scheduled task, and the key is never re-minted on the host. Rotate or revoke it from the console.
  • No remote-environment offer, and --project is refused: a committed repo config gets its key through print-key, which mints from a cert the host does not have.
  • Tool configs, the retrieval MCP server, and the profile are written as usual, so doctor, status, and the MCP server all find the key.

doctor titles the credential section Service key (agent), doctor --json and status --json carry keyKind: "service", and the host sends no seat health report: an agent is not a seat. A --json apply marks its applied event with the same keyKind.

Connector grants

anyray-connect connectors authorize <name> connects one of the organization's OAuth connectors (see the org MCP hub) to the developer's own account. It binds a listener on 127.0.0.1 (a random port, for this run only), asks the gateway to start the vendor flow with that port and a per-run nonce, opens the consent page, and redeems the claim code the gateway redirects back with. The redirect carries the nonce's digest and the listener accepts a code only under it, so a code from someone else's consent pushed at that port is ignored and the run keeps waiting. stdout carries one line naming the connector and the account. The claim code, the nonce, the client key, and the authorization URL's query string never reach either stream; the URL is printed only when no browser could be opened, so the developer can open it by hand.

FlagWhat it does
--claim <code>Redeem a claim code the consent page showed. No listener, no browser.
--gateway <origin>Gateway origin, resolved like every other verb.

In an SSH session, a dev container, or a Codespace the browser cannot reach that listener, so the command sends no port, prints the URL to open, and asks for a rerun with --claim once the page shows the code. The same fallback runs when no local port can be bound. A gateway that predates loopbackPort drops it and shows the code in the browser; Connect sees that in the reply, says so, and hands over to --claim without waiting. Consent has five minutes; after a timeout the redirect lands on a closed port, so the hint says to copy the claim= value from the browser's address bar. Each gateway call has a 30 second budget. Exit codes: 0 connected, 1 not connected (a failure, or any hand-over to --claim that leaves a step to do), 2 usage.

Machine maintenance commands

Fleet and local supervisors call a stable, non-interactive command surface. These commands accept no prompts, print one content-free JSON document to stdout, and write the identical evidence to ~/.anyray/status.json with mode 0600.

CommandPurpose
anyray-connect reconcilePull org tool policy and repair managed drift.
anyray-connect refreshRenew credentials when due and re-assert configuration.
anyray-connect repairRun the complete repair pass.
anyray-connect status --jsonPrint current seat evidence for scripts and policy checks.
anyray-connect offboardRevert managed tools, remove resident units, and clear user state.

Exit codes are stable: 0 healthy or complete, 1 unexpected error, 2 usage error, 3 re-enrollment required, and 4 partial with drift still present. stdout never carries keys, private key material, SSO tokens, authorization values, or URLs with credentials; diagnostics go to stderr.

On a fleet-managed machine these commands never invoke Connect's updater or relaunch path on their own. The gateway compares the seat's reported Connect version with the published release and sends an update directive through the existing per-seat directive lane when it is stale; the seat runs the same checksum-verified, smoke-tested updater as the manual update command, typically within one maintenance cycle of a release. Off the fleet, refresh keeps the scheduled self-update, because that tick is an unmanaged seat's only unattended update path.

Claude Code managed policy

For Claude Code, apply and doctor inspect the machine-wide managed-settings.json. They flag disableAllHooks: true, and flag allowManagedHooksOnly: true when the managed hooks block does not contain Anyray's PostToolUse hook. Connect never edits IT policy: ask the MDM owner to remove the key, or to add the credential-free hook block emitted by anyray-connect managed --print --sso <link> --bin <path>, then restart Claude Code.

Doctor reports this as the separate claude-code / hook_policy fleet check. The failing statuses are disabled and restricted_dropping_ours; it does not reuse the network-liveness hook_lane check.

Claude Desktop configuration carry

Third-party inference gives Claude Desktop a separate profile, so the local MCP servers, user-created skills, and user-installed plugins in the first-party profile are unread until they are copied across. Every apply lane copies them, MDM reconciles included. MCP servers copy right away; skills and plugins wait for the next full quit, because Claude Desktop rewrites those stores on exit. Conversation history moves only through anyray-connect migrate, which reports to the person whose files they are.

Doctor prints the result under Claude Desktop profile and reports it to the fleet as the connect / desktop_config_carry check. It is a diagnostic: no state counts against the compliance score or the failing-check count.

StateMeaning
carriedEvery local entry is in the third-party profile.
pendingSome entries are not there yet. Connect carries them on the next reconcile, or the next time Claude Desktop is fully quit.
nothing_to_carryThe first-party profile holds no local MCP server, user skill, or user plugin.
not_routedThis machine does not route Claude Desktop through Anyray and nothing is queued to, so no carry applies. Normal on a fleet whose policy holds Desktop back.
unreadableThe first-party profile refused access. Allow Connect to read it, then run doctor again.
unsupportedThe host has no third-party profile (Linux).
unknownNo evidence: a status document written before this check existed, or an inspection that failed for a reason other than access. The gateway records the same word for a doctor report from an older Connect.

Update path variants

Updating an npm install

npx anyray-connect@latest bootstraps the same managed standalone install as connect.sh; it does not create a second steady-state npm installation. The first enrollment, apply, repair, or fleet sync that may persist a runtime downloads and verifies the managed binary, then registers every integration against ~/.anyray/bin/anyray-connect. Later npx runs leave that launcher in charge.

Existing seats whose hooks or services point at an older version-pinned npm runtime migrate on their next automatic refresh. Connect smoke-tests the new binary before repointing registrations and keeps the currently running npm copy as rollback until the migration succeeds. Run anyray-connect update to migrate immediately, or anyray-connect update --check to preview it.

Inside a devcontainer or Codespace this migration, and self-update generally, is skipped: the image updates by rebuilding, not by downloading a new binary. See Remote and ephemeral machines.

Platforms without a standalone binary

If Anyray does not publish a standalone asset for the current OS and architecture, Connect keeps the version-pinned durable npm runtime instead. --version, update, and doctor report that self-update is unavailable; use npx anyray-connect@latest to pick up new releases on that platform. A copy placed by your IT team remains externally managed and is still theirs to roll.