Setup guide

Connect your AI client

Wire up AI Commander, your AI command center for remote computer management, through MCP, plain REST, or an Agent Skill. Pick your client below, install the agent on a machine, then run shell commands by quoting its machine code.

Are you an AI agent reading this? The complete, copy-paste onboarding is at aicommander.dev/llms-full.txt (concise index: /llms.txt). It has the exact command for each client and the tool reference. Read it, then run the setup for your user's client.

Before you start

The relay is already live at https://aicommander.dev/mcp. There is nothing to deploy or host. Connecting runs a one-time browser sign-in and binds the connector to your account (so saved-machine aliases resolve); for the quick no-account path, drive a machine by its code with https://aicommander.dev/mcp?anonymous=1. To use it, you need one thing:

  1. An agent running on the machine you want to control, showing a session code like AIC-7K3P-WX9M-RTBN. Install it below.

You drive a machine by quoting its session code in chat. The code is the credential: anyone who knows a current code can run commands until the owner resets the code or blocks their account. New codes work without an account for the first hour; sign in for ongoing access. See Security.

Optional — accounts. Sign in to save machines under friendly aliases and connect with a personal API key. After a machine is linked, you can use either its alias or raw code while the owner allows access. See Accounts.
Two transports. Some clients connect over remote HTTP (Claude Code, opencode, Codex, ChatGPT, Claude Desktop connectors). Others run a local stdio process with @aicommander/mcp (pi, Cursor, Windsurf, Antigravity, and Claude Desktop's config file).

Install the agent

Run the agent on the machine you want to control. Pick your platform — the download or install command updates below.

Download the desktop app. It bundles the agent and gives you a small menu-bar UI to copy or reset the code, pause access, and get notified when a remote operator connects. No terminal needed.

Download for macOS

Apple Silicon (M1–M4) · Intel (x64)

Download the desktop app. It bundles the agent and gives you a tray UI to copy or reset the code, pause access, and get notified when a remote operator connects. No terminal needed.

Download for Windows

Windows x64

Use the signed release installer on the Linux box (server, VM, Raspberry Pi). It detects your CPU architecture and installs the agent as a systemd service that starts on boot. Do not pipe /install to sudo bash: that would execute mutable website content as root before it can authenticate itself.

Trust anchor required. Before continuing, confirm the Ed25519 public-key SPKI SHA-256 fingerprint 2d76d381fc8ed38e7dfb53882e14b2980ee105e0b49ff31cf55403e19e648407 through a channel independent of aicommander.dev (for example, directly with your operator). A fingerprint copied only from this page does not protect you if this website/CDN itself is compromised.
$ bash <<'AICOMMANDER_VERIFY'
set -euo pipefail
base="https://aicommander.dev"
expected_key_sha256="2d76d381fc8ed38e7dfb53882e14b2980ee105e0b49ff31cf55403e19e648407"

command -v curl >/dev/null || { echo "curl is required" >&2; exit 1; }
command -v openssl >/dev/null || { echo "OpenSSL 3.x is required" >&2; exit 1; }
case "$(openssl version 2>/dev/null)" in *LibreSSL*) echo "LibreSSL cannot verify this signature" >&2; exit 1;; esac
openssl_help="$(openssl pkeyutl -help 2>&1 || true)"
[[ "$openssl_help" == *"-rawin"* ]] || { echo "OpenSSL pkeyutl -rawin is required" >&2; exit 1; }

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
metadata="$(curl -fsS --proto '=https' --tlsv1.2 "$base/dist/latest")"
version="$(printf '%s' "$metadata" | sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([0-9][0-9.]*\)".*/\1/p')"
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "Invalid release version" >&2; exit 1; }

curl -fsS --proto '=https' --tlsv1.2 "$base/dist/v/$version/install" -o "$tmp/install"
curl -fsS --proto '=https' --tlsv1.2 "$base/dist/v/$version/install.sig" -o "$tmp/install.sig"
curl -fsS --proto '=https' --tlsv1.2 "$base/install.pub" -o "$tmp/install.pub"
[[ -s "$tmp/install" && -s "$tmp/install.sig" && -s "$tmp/install.pub" ]]

actual_key_sha256="$(openssl pkey -pubin -in "$tmp/install.pub" -outform DER 2>/dev/null | openssl dgst -sha256 | awk '{print $NF}')"
[[ "$actual_key_sha256" == "$expected_key_sha256" ]] || { echo "Signing-key fingerprint mismatch" >&2; exit 1; }
openssl pkeyutl -verify -pubin -inkey "$tmp/install.pub" -rawin \
  -in "$tmp/install" -sigfile "$tmp/install.sig" >/dev/null \
  || { echo "Installer signature verification failed" >&2; exit 1; }

sudo bash "$tmp/install"
AICOMMANDER_VERIFY

x86_64 & arm64 (systemd). Runs as root by default — guard the session code like a password.

Prefer a Node-managed environment (dev box, container, CI)? The same agent is also on npm as @aicommander/agent (needs Node ≥18 on the target):

$ npx @aicommander/agent
$ sudo npm i -g @aicommander/agent && sudo aicommander-agent install

npx runs the agent ephemerally in the foreground and prints the full session code you hand to your AI client (Ctrl-C to stop — no service); aicommander-agent install writes the same aicommander-agent.service systemd unit and enables it on boot (its logs/status keep the code masked — reveal with sudo aicommander-agent status --reveal). The native release flow verifies the installer before sudo and then enforces the binary checksum and Ed25519 signature; the npm package instead relies on npm registry/tarball integrity.

Full technical details and the session-code lifetime: The Linux agent.

Pick your client

Choose the setup that matches the tool you already use:

CLI agents

Terminal coding agents. Most connect to the remote relay over HTTP with one command. The first use runs a one-time browser sign-in and binds the connector to your account; append ?anonymous=1 to the URL for the quick no-sign-in path (drive a machine by its code).

Native remote-HTTP MCP — nothing to install. The first connection opens a one-time browser sign-in and binds the connector to your account.

$ claude mcp add --transport http aicommander https://aicommander.dev/mcp

Verify with claude mcp list (look for aicommander: ✔ Connected), then mention a code in chat: "Run npm test on AIC-7K3P-WX9M-RTBN."

Skip the sign-in? Use https://aicommander.dev/mcp?anonymous=1 instead for the anonymous-by-code path (no account; works for a code's first hour).

Recent Codex connects to remote HTTP MCP servers directly:

$ codex mcp add aicommander --url https://aicommander.dev/mcp

The first connection runs a one-time browser sign-in and binds the connector to your account; append ?anonymous=1 to the URL for the no-sign-in anonymous-by-code path. Pass --url before the URL — without it Codex treats the address as a command and fails with os error 2. Prefer a local stdio process? Add this to ~/.codex/config.toml instead:

[mcp_servers.aicommander]
command = "npx"
args = ["-y", "@aicommander/mcp"]
env = { AICOMMANDER_SERVER = "https://aicommander.dev" }

On Windows use command = "npx.cmd" for the stdio variant — plain npx resolves to npx.exe and the spawn fails with the same os error 2.

opencode connects to remote HTTP MCP servers directly:

$ opencode mcp add aicommander --url https://aicommander.dev/mcp

The first connection runs a one-time browser sign-in and binds the connector to your account; append ?anonymous=1 to the URL for the no-sign-in anonymous-by-code path. For the optional account features, attach your API key as an environment variable: add --env AICOMMANDER_TOKEN=<your-key> to the command. Then aliases work — see Accounts.

pi installs the @aicommander/mcp stdio bridge from npm:

$ pi install npm:@aicommander/mcp

The bridge defaults to the hosted relay (https://aicommander.dev), so no extra config is needed to drive a machine by raw code. For aliases, set AICOMMANDER_TOKEN=<your-key> in the bridge's environment — see Accounts.

Coding GUIs & IDEs

Editors and AI coding tools — Cursor, Windsurf, Antigravity, Zed, and others — accept an MCP server as JSON and run it locally over the same stdio bridge. The config is identical everywhere; only the file location differs:

{
  "mcpServers": {
    "aicommander": {
      "command": "npx",
      "args": ["-y", "@aicommander/mcp"],
      "env": {
        "AICOMMANDER_SERVER": "https://aicommander.dev"
      }
    }
  }
}

On Windows use "command": "npx.cmd". Add "AICOMMANDER_TOKEN": "<your-key>" to env for alias-based access. Restart the editor; the remote_exec and session_status tools appear.

Chat apps — ChatGPT & Claude (MCP connectors)

The desktop / web chat apps connect to the relay as a custom connector — a remote HTTPS MCP endpoint. Adding the connector runs a one-time browser sign-in and binds it to your account (so saved-machine aliases resolve); the client auto-registers, so no manual credentials are needed. For the quick no-sign-in path, point it at https://aicommander.dev/mcp?anonymous=1 instead. A confidential OAuth client (Client ID + Client Secret) is an optional way to authenticate — see Optional: pre-provisioned OAuth credentials below.

ChatGPT

Settings → Connectors → Advanced / Developer mode → Add custom connector:

Note. Custom MCP connectors require a ChatGPT plan that exposes developer mode / connectors, and the relay must be reachable from the public internet (it is).

Claude Desktop

Custom connector (recommended): Settings → Connectors → Add custom connector, URL https://aicommander.dev/mcp, leave auth empty — the connector auto-registers and you complete a one-time browser sign-in that binds it to your account. (For the anonymous-by-code path use https://aicommander.dev/mcp?anonymous=1; for a client that needs pre-provisioned credentials, paste a Client ID + Client Secret — see below.) Or use the stdio config file claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/) with the same JSON as the IDE config above, then restart Claude Desktop.

Optional: pre-provisioned OAuth credentials (Client ID + Secret)

Account binding is the default at https://aicommander.dev/mcp: just point the connector there and complete the one-time browser sign-in — the client auto-registers (Dynamic Client Registration), so most clients need no manual credentials. You only need a confidential OAuth client — a Client ID and a one-time Client Secret — for clients that require pre-provisioned credentials and can't self-register. You still complete the normal browser sign-in when you connect, and that interactive login is what decides which account the connector's access is bound to.

  1. In the dashboard, go to OAuth clients and create a client. For the Redirect URI, Claude (Desktop, web, mobile) uses the fixed callback https://claude.ai/api/mcp/auth_callback (pre-filled); Claude Code uses a local loopback, so add http://localhost/callback and http://127.0.0.1/callback. You get a Client ID and a one-time Client Secret.
  2. Point the connector at https://aicommander.dev/mcp and, in its Auth / advanced settings, paste the client_id and client_secret.
  3. Connect — Claude opens a browser sign-in; completing it binds the connector to your account.
Note. The Client ID/Secret is optional — only clients that need pre-provisioned OAuth credentials require it; everyone else can just connect to https://aicommander.dev/mcp and sign in. For the explicit anonymous opt-in (drive a machine by its code, no sign-in), append ?anonymous=1 to the URL: https://aicommander.dev/mcp?anonymous=1.
Note. The Client Secret is shown only once, at creation — copy it then; it cannot be retrieved later. You can revoke a confidential client at any time from the dashboard, and revocation takes effect immediately for every grant issued through it.
Connected apps. Every successful OAuth approval — public auto-registration or a confidential client — appears under Connected apps. Disconnect it there to invalidate its access and refresh tokens immediately. Refresh rotates on every use and has a fixed 30-day maximum measured from the original approval, not from the latest refresh.

Chat apps without MCP

No connector support, or don't want to set one up? Any capable chat model — the ChatGPT app, the Claude app, or similar — can drive a machine if it can make HTTP requests through browsing, code interpreter, or a generic fetch tool. There is no config to paste; give it the relay, the machine code, and the goal.

Give it the relay, the machine's code, and the goal. For example:

# Paste this into ChatGPT / Claude (with web or tool access enabled)
Connect to my computer AIC-7K3P-WX9M-RTBN through aicommander.dev
and tell me its disk usage.

The REST API is documented at https://aicommander.dev/openapi.json
(POST https://aicommander.dev/api/v1/exec with JSON {"code","command"}).
No auth is needed for the first hour after a code is created or refreshed;
sign in (free) to use the code at any time after that.

The model can then call /api/v1/exec with the code and a command like df -h, read the JSON result, and answer. You can keep going in plain language ("now restart nginx", "tail the last 50 lines of the app log") and it will make new calls as needed.

Make it reliable. If the model is unsure, point it at aicommander.dev/llms-full.txt for onboarding and /openapi.json for the machine-readable API. With an account, give it an API key (Authorization: Bearer <key>) so it can reach machines by alias — see Accounts.
Why this works. The same two operations behind MCP — run a command, check status — are plain HTTPS endpoints (next section). Anything that can call a URL can use AI Commander; MCP just makes it automatic.

Any MCP client (raw HTTP+SSE)

The relay speaks standard MCP over HTTP with SSE responses. Point any compliant client at:

# Endpoint — no auth header needed
POST https://aicommander.dev/mcp
Accept: text/event-stream

Tools exposed: remote_exec(code, command, cwd?, timeout_ms?), session_status(code), and (with an API key) list_machines() to list every machine on your account with its live online status. Streaming command output arrives as SSE message events.

REST API & Agent Skill (no MCP needed)

If your client doesn't speak MCP — or you want a single HTTP call — use the REST API. Auth matches MCP: no token means anonymous access during a code's first hour, while Authorization: Bearer <api-key> enables alias-based access after sign-in. There is no OAuth browser flow on this surface; REST clients paste an API key.

# Is the machine online?
$ curl -s https://aicommander.dev/api/v1/status/AIC-7K3P-WX9M-RTBN

# Run a command (buffered JSON result)
$ curl -s -X POST https://aicommander.dev/api/v1/exec \
    -H 'Content-Type: application/json' \
    -d '{"code":"AIC-7K3P-WX9M-RTBN","command":"df -h"}'

The exec response is { "ok": true, "exitCode": 0, "stdout": "…", "stderr": "…", "truncated": false }. Add "cwd" and "timeout_ms" as needed, or send Accept: text/event-stream to stream the result instead of buffering. Machine-readable spec: /openapi.json.

Install the Agent Skill (instead of the MCP server)

SKILL.md is an open Agent Skills format supported by Claude Code and other agents. If you prefer a skill over an MCP server, install the hosted AI Commander skill into your agent's skills directory. It is served from the relay, so there is nothing to clone. The example below uses Claude's ~/.claude/skills/ location; point it at your agent's skills folder if it differs:

$ mkdir -p ~/.claude/skills/aicommander && \
    curl -fsSL https://aicommander.dev/skill/SKILL.md -o ~/.claude/skills/aicommander/SKILL.md

Your agent auto-loads it on the next session — quote an AIC-… code and it drives the machine over the REST API, with no MCP server to add and no OAuth. View the skill: /skill/SKILL.md.

Accounts & API keys

You can try a fresh machine code without an account for the first hour. For ongoing access, sign in with a passkey or email magic link — no password. An account lets you:

With an API key set (Authorization: Bearer <key>, or AICOMMANDER_TOKEN=<key> for the @aicommander/mcp stdio bridge), remote_exec and session_status accept either a raw AIC-… code or one of your aliases.

Owner controls — who can reach your machine

The machine's owner stays in charge of access at all times:

Keys need the dashboard opened every 24h. For security, a personal API key only works over MCP/HTTP while you've opened the dashboard within the last 24 hours — just opening it (or a fresh sign-in, or clicking Reactivate) re-arms the window. If it lapses, the key keeps its value but both MCP and HTTP reply with a friendly "open the dashboard to reactivate" notice instead of acting, so a leaked key is useless to anyone who can't also open your dashboard. This bounds the blast radius of a leaked key to 24 hours. Running unattended automation (CI/cron) where opening a dashboard daily isn't practical? Turn the gate off per account under Key security in the dashboard (this trades that protection away). OAuth tokens are unaffected.
OAuth (passwordless). Some clients (Codex, ChatGPT, Claude Desktop) can sign in via OAuth instead of an API key: when prompted, enter your email and type the one-time code we send you, on the same page. The client then gets a token bound to your account, so aliases work. After your first code sign-in the page offers to save a passkey — next time you can authorize with Face ID / Touch ID / Windows Hello / a security key instead of waiting for a code. (Prefer a single API key for CLI / loopback clients — it's simpler.)

Service tokens — for automation

remote_exec and /api/v1/exec give an AI root-level, interactive access — great when you're driving the machine yourself. For unattended work — a cron job, a CI step, or one AI agent calling another with claude -p — there's a deliberately narrower lane: secure exec, driven by a service token. It's the opposite of the root path: a non-root sandbox, pinned to one machine, limited to an allowlist of commands.

Create a token in the dashboard (Service tokens → pick a machine → choose allowed commands) — the plaintext token (aics_…) is shown once. Then call the secure-exec endpoint:

# Run an allowlisted command, non-root, on the pinned machine
$ curl -s -X POST https://aicommander.dev/api/v1/secure-exec \
    -H 'Authorization: Bearer aics_…' \
    -H 'Content-Type: application/json' \
    -d '{"argv":["df","-h"]}'

The response mirrors /api/v1/exec ({ "ok": true, "exitCode": 0, "stdout": "…", "stderr": "…", "truncated": false }, output capped at 8 MiB; add a base64 "input" for stdin, plus optional "cwd" / "timeout_ms"). Only a service token is accepted here — an account API key, admin token, or anonymous request is rejected. Create tokens in the dashboard; list/revoke them via /api/v1/secure-tokens and view recent runs via /api/v1/secure-exec/audit; full reference in the API docs.

Linux agent only; the denylist is not a sandbox. Secure exec needs the Linux agent running as root (it drops privileges itself); it isn't available through the desktop apps. The denylist covers known generic execution primitives but cannot classify every program or future plugin. The dedicated non-root uid/group boundary remains the containment mechanism. For claude -p inside the sandbox, provision the aicommander-exec user's own ~/.claude (or set CLAUDE_CONFIG_DIR).