Updated September 26, 2026. Editor: Codex.
The AnyRemote CLI runs on a computer you want to control. It receives MCP requests from AnyRemote and uses Node.js file and process APIs on that computer.
Run the published CLI with Node.js >=20.9.0. The repository's development scripts use Bun 1.3.11.
Start the local AnyRemote app, then run this command from the repository root:
bun run src/bin.js --base-url http://localhost:5173With no subcommand, the CLI starts the remote device authorization flow. It opens a browser so you can sign in or create an account, then approve the device. After approval, the CLI saves device credentials and keeps the local agent running until you press Ctrl+C or send SIGTERM. If it cannot open a browser, visit the URL printed in the terminal. Add --no-browser to skip the automatic browser launch. The CLI and app must use the same origin.
The remote flow saves device credentials. It does not save the browser authorization session or enrollment token. Each time you start remote, the CLI asks you to authorize the device again. If the saved device is still active on the selected origin, the CLI keeps its device ID and dashboard name and rotates its device token. If the device was revoked or deleted, the CLI registers a replacement during the same authorization flow. For remote, an explicit --base-url wins; otherwise ANYREMOTE_URL is used, then production. A saved origin is not used to choose a new remote target. When the selected origin differs from the saved origin, the CLI does not send old origin credentials and replaces the local device only after authorization succeeds. The previous server-side device remains on its origin. Use separate ANYREMOTE_CONFIG_DIR values to manage multiple origins at once.
Use connect to connect with saved device credentials. Both commands reconnect after a temporary network failure without asking you to authorize again or replaying a request. Press Ctrl+C, send SIGTERM, or revoke the device to disconnect. The CLI also stops process tasks that it started. It does not install a background service or configure startup at login.
The CLI chooses a device name from the operating system. On macOS it reads ComputerName. On Linux it tries the pretty hostname. On Windows it uses the host name. If a lookup fails, the CLI falls back to the host name and then a platform default.
Pass --name 'Work computer' to choose a name. Names must contain 1 to 120 characters, cannot be blank, and cannot include control characters. Automatic names keep Unicode characters, remove control characters, and stay within the length limit. The remote and pair commands use the same rules.
Reauthorizing an existing device does not change its name, even when you pass a different --name. Rename it in the dashboard.
After you publish the package, run the CLI with no subcommand to connect to the production service:
# Bun
bunx @panda-ai/anyremote@latest
# npm
npx @panda-ai/anyremote@latest
# pnpm
pnpm dlx @panda-ai/anyremote@latest
# Yarn
yarn dlx @panda-ai/anyremote@latestThe CLI handles --help/-h and --version/-v before loading local
configuration or connecting to AnyRemote. The version command is also
available. Use --agent-version <value> to override the version reported by
this device agent; the older value-taking --version <value> form remains
supported.
When Bunx resolves an installed CLI from its package cache, the CLI checks the
npm latest tag on every run. If a newer version exists, it launches that exact
version through Bunx. When the registry cannot be reached, it continues with the
cached CLI. The first run still depends on Bunx selecting a release that includes
this update check; use @latest to request the current tag explicitly. Bunx
can reuse a recent latest tag resolution for up to 24 hours, as described in
the Bun auto-install cache documentation.
bunx @panda-ai/anyremote@latest --version
bunx @panda-ai/anyremote@latest --helpTo connect to a preview, local app, or another AnyRemote origin, keep the explicit URL override:
bunx @panda-ai/anyremote@latest --base-url https://your-anyremote-domainThe equivalent explicit subcommand remains available: bunx @panda-ai/anyremote@latest remote --base-url https://your-anyremote-domain. Both --base-url https://your-anyremote-domain and --base-url=https://your-anyremote-domain are supported. For remote, URL selection uses --base-url, then ANYREMOTE_URL, then https://anyremote.dev; it does not use a saved origin. Other commands keep their saved-origin behavior where applicable.
You can also use these commands with a published package:
bunx @panda-ai/anyremote@latest doctor
bunx @panda-ai/anyremote@latest login --base-url https://your-anyremote-domain --email [email protected] --password 'your-password'
bunx @panda-ai/anyremote@latest pair --base-url https://your-anyremote-domain --token "$ANYREMOTE_TOKEN" --wait
bunx @panda-ai/anyremote@latest connect --base-url https://your-anyremote-domain --token "$ANYREMOTE_TOKEN"
bunx @panda-ai/anyremote@latest logout --base-url https://your-anyremote-domain
bunx @panda-ai/anyremote@latest revoke --base-url https://your-anyremote-domainRun these commands from the root of a standalone clone of this repository. They install the CLI and shared protocol contracts from its Bun workspace. When you work in the submodule inside the AnyRemote parent checkout, use the parent repository's workspace commands. Run the tarball command below from a standalone CLI clone.
bun install --frozen-lockfile
bun run lint
bun run typecheck
bun run test
bun run buildbun run test runs the CLI tests and the contract tests in packages/contracts. The build writes the CLI entry points to dist/.
To run the source version against a local AnyRemote app, use the remote command shown above. To create and install a package tarball, run:
bun pm pack --destination artifacts
bun install --global ./artifacts/panda-ai-anyremote-0.2.6.tgzThe CLI repository includes the shared protocol contracts and uses the MIT License. The parent AnyRemote repository pins its CLI version through a Git submodule.
login also reads ANYREMOTE_EMAIL and ANYREMOTE_PASSWORD. Commands that need an application origin use --base-url, saved configuration, ANYREMOTE_URL, or the production origin. The pair, connect, and account-management commands can also read ANYREMOTE_TOKEN. The CLI stores account sessions in the local config directory. Set ANYREMOTE_CONFIG_DIR to use a separate config directory. ChatGPT uses its own OAuth flow when it connects to /mcp; it does not use the CLI account token.
The logout command ends the account session and keeps the device connection. It clears saved account credentials, including a session that has already expired. It keeps the credentials when a network or server error prevents logout. The revoke command revokes the saved device and clears its local credentials. It requires an account session or ANYREMOTE_TOKEN. The older disconnect command remains an alias for revoke. If no device is saved, revoke succeeds without making a request. The dashboard must approve a pairing code before pair can connect.
The CLI writes request time, request ID, tool name, status, total duration, executor duration, and serialized result size to stderr. Stdout remains available for command output.
process.start, process.read, and process.write return bounded stdout/stderr with the process state and byte cursors. They accept waitMs from 0 to 10000 (default 1000) and maxBytes from 1 to 65536 (default 65536). The wait controls this response; it does not terminate the process. A short command can finish and return its output in one start call. A nonzero exitCode remains a successful tool result.
Start waits for exit or its budget. Read returns immediately when output or exit is already available, otherwise it waits for new output. Write queues stdin/eof once and waits for a response; accepted means queued, not processed by the program. Write defaults its cursor to the output end immediately before the input; pass cursor to include earlier unread output.
Use nextCursor for the next read. outputStartCursor identifies the earliest byte still buffered, and truncated reports output omitted from the page or evicted from the buffer. If a complete UTF-8 character cannot fit into a small page, the result keeps its process handle and reports the required maxBytes in error; read again at the same cursor with that larger page. An incomplete character in a running stream waits for more bytes and does not claim the page is too small. Reads are independent and do not consume shared output. Remote response waits are also bounded by the remaining request deadline. Worker process tools require CLI 0.2.6 or newer.
The process streams use Node's UTF-8 decoder before buffering. A character split across OS chunks enters the output cursor when complete, independently for stdout and stderr. Cursors count the UTF-8 bytes stored in that text buffer; invalid UTF-8 is normalized to Node's replacement characters.
The screen.capture tool captures the primary desktop on the target computer. It returns a text summary and a PNG image in the same MCP response. The CLI scales and compresses the image to no more than 1 MiB. The Worker retains the result in the existing device request record for 60 seconds. The CLI does not upload the image to a third-party image host or include a temporary file path in the response or diagnostic log.
On macOS, allow the terminal app to record the screen the first time you use this tool. On Linux, install grim, gnome-screenshot, or scrot. On Windows, the CLI uses PowerShell to capture the primary display.
The tool returns a structured error if there is no desktop session, the operating system denies permission, or the image cannot be compressed below the size limit. An MCP client may support image blocks without displaying them in its interface. Check the behavior of your MCP client.