Full activity streaming — thinking, tool calls, and responses in real-time. Self-hosted, open-source.
Quick Start • Why Remo Code • Architecture • Deploy
OpenClaw popularized the idea of talking to an AI agent from your phone. But it requires you to trust a third-party runtime with shell access to your machine, and security researchers have already found real data exfiltration in community-contributed OpenClaw skills.
Remo Code gives you the same "chat with your agent from anywhere" workflow, but with full activity streaming and complete control:
| OpenClaw | Claude Code Remote Control | Remo Code | |
|---|---|---|---|
| Self-hosted | Partial (local agent, cloud relay) | No (Anthropic relay) | Yes, fully |
| Open source | Yes | No | Yes (MIT) |
| Activity streaming | No | No | Yes (thinking, tool calls, text) |
| Web UI | No (messaging apps only) | Yes (claude.ai) | Yes (your own domain) |
| Multi-session | No | No | Yes |
| File attachments | No | No | Yes (images + text files) |
| Auth & data storage | Third-party servers | Anthropic servers | Your Supabase instance |
- Developers who want to check on long-running Claude Code tasks from their phone
- Teams who want a shared dashboard for multiple Claude Code sessions
- Security-conscious users who don't want third-party tools with shell access to their machines
- Self-hosters who want full control over their data and infrastructure
- Bun runtime
- Claude Code CLI installed
- A Supabase project (free tier works)
git clone https://github.com/finedesignz/remo-code.git
cd remo-code
bun installCreate a Supabase project and run the migrations in supabase/migrations/ via the SQL Editor.
cp hub/.env.example hub/.env
# Edit: SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, HUB_ALLOWED_ORIGINS
cp web/.env.example web/.env
# Edit: VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY, VITE_HUB_URL# Terminal 1 — Hub server (port 3040)
bun run dev:hub
# Terminal 2 — Web dev server (port 5173)
bun run dev:webOpen http://localhost:5173 and create your account on the setup form.
Generate an API key in Settings, then install the Remo Code Supervisor desktop app on the Windows machine you want to control:
- Download the latest
.msifrom GitHub Releases. - Run the installer.
- Paste the API key into the first-run wizard. Pick the repo roots the supervisor should scan (typically
C:\Users\you\GitHub).
The supervisor auto-starts at login via a per-user HKCU Run registry entry (no Windows service, no shell alias needed), watches your repo roots, and lets you launch Claude Code (or Codex) sessions remotely from the web UI. One supervisor connects all your repos — sessions auto-register and auto-resume by repo.
The legacy
npx remo-code-agent/claude-remoteshell-alias flow has been retired as of 2026-05-26. The Tauri Supervisor desktop app is the only supported local app.
If you don't want to self-host, use the hosted hub at app.remo-code.com. Sign up, generate an API key in Settings, then install the Remo Code Supervisor desktop app — same flow as above. The supervisor's default hub URL is https://app.remo-code.com.
Browser (React SPA)
↕ WebSocket + REST API
Hub Server (Bun + Hono)
↕ WebSocket /ws/agent
Supervisor desktop app (Tauri MSI — one per host)
↕ subprocess stdin/stdout (stream-json)
Claude Code CLI / Codex CLI (one process per session)
Three packages in a Bun workspace:
- hub/ — Bun + Hono server handling auth (Titanium Licensing magic-link + opaque cookie sessions — see docs/auth.md), message relay, and session management. Broadcasts Claude's activity events (thinking, tool use, text) to subscribed browsers.
- web/ — React 19 + Vite + Tailwind CSS 4 chat UI with activity feed, session switching, file attachments, light/dark theme, and unread badges.
- supervisor/ — Local supervisor source.
supervisor/src/is compiled bybun build --compileinto the sidecar binary thatsupervisor/tauri/bundles into a Windows MSI installer (Rust + WebView2 tray app). Each running host has exactly one supervisor; the supervisor hosts every session for that machine.
GitHub-keyed sessions: as of Phase 08, sessions are identified by their GitHub origin (github://owner/repo) rather than by their local path. All worktrees, clones, and checkouts of the same repo on the same machine — or across machines for the same user — collapse to one session row, one conversation history, one sidebar entry. Folders without a GitHub remote land in a Needs attention section in the sidebar where you can either Create-on-GitHub or Dismiss them. See docs/github-session-keying.md for the resolution algorithm, schema additions, and the REST surface (/api/sessions/pending-prompts, /api/sessions/dismiss-local, /api/sessions/:id/launch, /api/sessions/:id/clone-here, /api/sessions/:id/create-github-repo).
- You install the Remo Code Supervisor MSI on the Windows machine you want to control, paste your API key into the first-run wizard, and pick repo roots.
- The supervisor connects to the hub via WebSocket (
/ws/agent) and registers as an agent for your account. - When you click "Start session" for a repo from the web UI, the supervisor spawns
claude --input-format stream-json --output-format stream-json --verbose(orcodex app-serverfor Codex sessions) in that repo directory. - When you send a message in the web UI, the hub forwards it to the supervisor.
- The supervisor writes the message to the CLI's stdin as JSON.
- The CLI responds — thinking, tool calls, text stream out via stdout.
- The supervisor parses the stream-json events and relays them to the hub.
- The hub broadcasts to all subscribed browsers in real-time.
Session resume: The supervisor reuses existing sessions by matching the repo directory. Restart the supervisor and it reconnects to the same sessions with full message history.
Conversation memory: The supervisor keeps each session's CLI process alive between messages — full conversation context is maintained across messages, just like the terminal.
- Activity streaming — see Claude's thinking, tool calls, and text responses in real-time
- File attachments — paste images (Ctrl+V) or attach text files in the chat
- Multi-session — run agents in multiple project directories, switch between them
- Session resume — restart the agent and reconnect to the same session
- Scheduled tasks — fire prompts, skills, or supervisor commands on a cron cadence against one session, one supervisor, or all of either. Dropdown cron builder (every N min/hour/day/month, daily, weekly multi-select, monthly with "Last day", custom) with plain-English summary + next-3-runs preview. Schedules list has name search + enabled/disabled + task-type filters and last-run cost/duration chips per row. Runs drawer has status filter chips + summary stats (success rate, total cost, avg duration). Every scheduled run ends with a one-line
Summary:from Claude, and the chat shows the trigger as aScheduled: <task name>pill above the prompt. Per-target run history, daily cost cap, offline-grace replay, and post-run actions (chain, email, telegram, web push, webhook). See docs/scheduled-tasks.md. - Error capture — Sentry-style intake at
/api/sentry/:project_id/envelope/that fingerprints + dedupes + rate-limits + caps runtime errors from your deployed apps, then routes them as a structureduser_messageinto the Claude session bound to that repo so Claude can investigate, fix, commit, and push in-session. Includes one-click Sentry SDK auto-install for Node+Express / Node+Next.js / Python+FastAPI / Python+Django (supervisor git-ops + Coolify env PATCH). See docs/error-capture.md. - Grid View — watch up to 12 Claude Code sessions side-by-side at
#/grid. User-named tabs persist per account (chat_tabs+chat_tab_sessions), each with a layout mode (3x3,4x3, orauto-fit). One WebSocket subscribes to many sessions in one frame, message lists are virtualized, and streaming text is RAF-coalesced. On phones the grid auto-swaps to a single-pane accordion (only one chat mounted at a time). See docs/grid-view.md. - Coolify deployment self-heal (Phase 06, partial) — a public HMAC-signed webhook endpoint (
POST /api/coolify/webhook/:user_id) turnsdeployment.failedevents into structuredtriageruns that ask Claude to emit a typedTriageResult(error_type, severity, root_cause, suggested_fix, confidence). Agithub_issuepost-run action then files a labelled issue on the failing repo via the gateway-pair credentials (noGITHUB_TOKENon the hub) with 24-hour idempotency. Webhook ingress, secret rotation, triage schema, and the GitHub-issue action are shipped; the final session-routing wire-up (pickSessionTarget) is pending the Phase 04 self-heal-routing plan landing. See docs/coolify-webhook-migration.md and the "Coolify webhook ingress" / "GitHub-issue post-run action" sections in docs/scheduled-tasks.md. - Codex CLI + rootless ambient sessions — sessions can run either Claude Code or Codex (
cli_kindcolumn). Each agent can also host "ambient" rootless sessions (one Claude + one Codex per host) with no project directory required, lazy-spawned on first message. Global instruction files (~/.claude/CLAUDE.md,~/.codex/AGENTS.md,~/.codex/config.toml) sync from the hub on connect viacreate_if_absent— the agent never overwrites local files. Edit blobs in Settings → Instructions. See docs/codex-and-rootless.md. Requiresnpm i -g @openai/codex+codex login(orOPENAI_API_KEY). - Subscription quota strip — the header shows live Anthropic Claude subscription utilization (5-hour + 7-day windows) reported by the supervisor's poll of
/api/oauth/usage. Hover for exact %, reset countdowns, and Opus / OAuth-app sub-quotas when present. - Unread badges — know when sessions have new messages
- Light/dark theme — toggle in the header
- Mobile-first — responsive design with safe-area support for notched devices
Build and deploy with Docker:
docker build -t remo-code .
docker run -p 3040:3040 \
-e SUPABASE_URL=... \
-e SUPABASE_ANON_KEY=... \
-e SUPABASE_SERVICE_ROLE_KEY=... \
-e HUB_ALLOWED_ORIGINS=https://your-domain.com \
remo-codeThe Docker image builds the web frontend and serves it from the hub — one container, one port. The supervisor runs on your dev machine, not on the server.
├── hub/ # Bun + Hono server (HTTP, WebSocket, auth)
│ └── src/
│ ├── api/ # REST endpoints (sessions, messages, profile, setup)
│ ├── auth/ # JWT + API key verification middleware
│ ├── db/ # Supabase clients and data access layer
│ ├── middleware/ # Rate limiting
│ ├── utils/ # Shared utilities (token generation)
│ └── ws/ # WebSocket handlers (agent, client) + Zod schemas
├── web/ # React 19 + Vite + Tailwind CSS 4 SPA
│ └── src/
│ ├── components/ # Layout, ChatPanel, ActivityFeed, Sidebar, etc.
│ └── hooks/ # useAuth, useWebSocket, useSessions, useChat, useActivity
├── supervisor/ # Local supervisor — Tauri 2 desktop tray app
│ ├── src/ # Bun TypeScript source (compiled to sidecar binary by Tauri)
│ └── tauri/ # Windows tray shell (Rust + WebView2) → MSI installer
├── supabase/ # Database migrations
└── Dockerfile # Multi-stage production build
- Titanium Licensing magic-link auth on all user-facing API and WebSocket endpoints (see docs/auth.md). Agent endpoints (
/ws/agent) use API keys. - Row-Level Security on all database tables — multi-tenant by default
- API keys stored as SHA-256 hashes with timing-safe comparison
- CSP, HSTS, and security headers on all responses
- Rate limiting on API routes, setup endpoints, and WebSocket messages
- Per-IP connection limits on WebSocket endpoints
- Path traversal protection on static file serving
- Non-root Docker user in production
- Setup endpoint mutex preventing race conditions
Your data stays in your Supabase instance. Your Claude Code sessions stay on your machine. The hub is just a relay — and you own it.
The hub exposes its REST surface as an OpenAPI 3.1 spec at /openapi.json and a Scalar-rendered reference UI at /docs (e.g. http://localhost:3040/docs). The committed snapshots live at docs/openapi.json (machine) and docs/api.md (human). Regenerate after touching the OpenAPI sample route:
bun run docs:syncCI fails PRs that drift the snapshots — see .github/workflows/docs-drift.yml. Only /api/profile/cost-today is in the spec today; other routes will be migrated incrementally.
Apache-2.0
