App-server API
The app-server hosts the same kernel the desktop app embeds and exposes it as a local-first JSON-RPC 2.0 control plane. Use it to drive runs from scripts, integrations, or a remote box over SSH.
Transports
| Transport | Flag | Notes |
|---|---|---|
| stdio | --stdio | Default; intended for direct child-process embedding |
| Unix socket | --unix-socket <path> | Linux and macOS; requires the session token during initialize |
| Loopback WebSocket | --websocket <addr> | Must bind to 127.0.0.1, ::1, or localhost; non-loopback binds are rejected; the handshake requires ?token=... or Authorization: Bearer, and browser-like requests with an Origin header are rejected |
The server never exposes an unauthenticated non-loopback listener.
anymo app-server --workspace anymo-demo --websocket 127.0.0.1:9300 --token devtoken
Session flow
Every client starts with an initialize request carrying the session token, then an initialized notification. All other requests are rejected until both complete.
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"sessionToken":"...","clientInfo":{"name":"my-integration"}}}
{"jsonrpc":"2.0","method":"initialized","params":{}}
The initialize response returns serverInfo, transport capabilities, payload and queue limits, the platform family, and whether the server is a remote runner.
Methods
| Area | Methods |
|---|---|
| Health | server/health |
| Runs | run/start · run/resume · run/cancel · run/list · run/read · run/events/subscribe |
| Approvals | approval/respond |
| Artifacts | artifact/list · artifact/read |
| Memory | memory/list · memory/propose · memory/approve · memory/reject |
| Skills | skill/list · skill/run |
| Automations | automation/list · automation/create · automation/pause · automation/resume · automation/delete |
| Providers | provider/list · provider/check |
| Diagnostics | debug/bundle (sanitized support bundle) |
Event subscriptions
Run events stream as JSON-RPC notifications:
{"jsonrpc":"2.0","method":"run/events/event","params":{"subscriptionId":"sub-...","event":{}}}
Subscriptions keep per-run cursors, so subscribing across all runs cannot lose events when two runs share a sequence number. Replay and live queues are bounded; overload returns a retryable error rather than silently dropping:
{"code":-32080,"message":"event replay has 129 events, queue limit is 128","data":{"retryable":true}}
Ready-made clients
The CLI ships client verbs for the common operations, so scripts rarely need to speak JSON-RPC directly:
anymo connect --websocket 127.0.0.1:9300 --token devtoken # health check
anymo run --websocket 127.0.0.1:9300 --token devtoken --goal "..." --permission manual
anymo approvals --websocket 127.0.0.1:9300 --token devtoken
anymo approve --websocket 127.0.0.1:9300 --token devtoken --approval-id <id>
anymo tail-events --websocket 127.0.0.1:9300 --token devtoken --run-id <id>
See the CLI reference for flags. The token can also come from ANYMO_APP_SERVER_TOKEN.
Remote runner over SSH
Run the kernel on a Linux box and drive it from anywhere, with SSH as the only network boundary. The WebSocket stays loopback on the remote host; the SSH tunnel supplies remote access:
anymo app-server --workspace /srv/anymo --unix-socket /run/anymo/app-server.sock \
--token "$TOKEN" --remote-runner
ssh -L 32145:127.0.0.1:32145 user@vps
anymo app-server --workspace /srv/anymo --websocket 127.0.0.1:32145 --token "$TOKEN" --remote-runner
anymo health-check --websocket ws://127.0.0.1:32145/app-server --token "$TOKEN"
--remote-runner also hosts the automation scheduler, so scheduled runs fire while the server is up.
Security posture
- Tokens are per app-server process and redacted in responses.
- Sensitive JSON keys (
token,secret,password,api_key,authorization) are redacted recursively from every response. - Provider secrets are never serialized; provider summaries expose only
has_api_key. - Home paths are redacted before debug or event responses are serialized.
- Payload size defaults to 1 MiB; the event queue defaults to 128 entries.
- Approvals work identically over the API: a
manualrun parks untilapproval/respondarrives, and permission modes cannot be bypassed remotely.