{"slug": "opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere", "title": "Opendray – run Claude Code/Codex agents on your own box, drive from anywhere", "summary": "Opendray, a self-hosted gateway for AI coding agents like Claude Code and Codex, allows users to run agent sessions on their own infrastructure and control them from web, mobile, or chat. The open-source tool prevents agent sessions from dying when a laptop closes and supports multiple accounts with load balancing and local-first memory.", "body_md": "**Self-hosted gateway for Claude Code, Codex, Antigravity, Grok Build, and OpenCode. Run agent sessions on your own infrastructure. Drive from web, mobile, or chat.**\n\n🌐 **English** · [简体中文](/Opendray/opendray/blob/main/README.zh.md) · [فارسی](/Opendray/opendray/blob/main/README.fa.md) · [Español](/Opendray/opendray/blob/main/README.es.md) · [Português](/Opendray/opendray/blob/main/README.pt-BR.md) · [日本語](/Opendray/opendray/blob/main/README.ja.md) · [한국어](/Opendray/opendray/blob/main/README.ko.md) · [Français](/Opendray/opendray/blob/main/README.fr.md) · [Deutsch](/Opendray/opendray/blob/main/README.de.md) · [Русский](/Opendray/opendray/blob/main/README.ru.md)\n\n```\nflowchart LR\n    subgraph before [\"❌ SSH direct\"]\n        laptop1[Your laptop] -.->|ssh, dies on sleep| host1[Server + CLI]\n    end\n\n    subgraph after [\"✅ opendray gateway\"]\n        web[Web] --> gw[opendray]\n        phone[Phone] --> gw\n        chat[Telegram / Slack / Discord] --> gw\n        gw -->|survives disconnect| cli[Claude Code · Codex · Antigravity · Grok Build · OpenCode · shell]\n    end\n```\n\nRunning Claude Code or Codex over SSH means the agent dies the moment your laptop closes. opendray runs it on a host that stays awake (a Mac mini under your desk, a NAS, a VPS) and lets you reattach from a web admin, a mobile app, or a chat message. Sessions keep executing whether or not anyone is connected. Multiple accounts get pooled with per-tier balancing and live account-switch. A local-first memory layer keeps every embedding on your network.\n\n**opendray** wraps the AI coding CLIs you already use (Claude Code, Codex, Antigravity, Grok Build, OpenCode, plus any shell) and turns them into something you can drive from anywhere. Run sessions on your home server, NAS, or VPS. Get notified on Telegram when a session goes idle. Reply from your phone to feed the next prompt back in. All over a self-hosted gateway you control end to end.\n\n- 🛰\n**One backend, three surfaces.** Single Go binary serving a React web admin and a Flutter mobile app, with every action also exposed over a REST + WebSocket API for third-party integrations. - 💬\n**Six bidirectional channels, no walled gardens.** Telegram, Slack, Discord, Feishu (飞书), DingTalk (钉钉), WeCom (企业微信), plus a Bridge adapter for anything custom. Replies on any channel route back into the right session. - 🧠\n**Local-first memory.** ONNX / Ollama / LM Studio embeddings with three-scope retrieval (user, project, session), smart ranking, and cross-layer conflict detection. No vector data leaves your network. - 🔌\n**Integration-grade API.** Scoped API keys, per-call audit log, reverse-proxy mounts. Treat opendray as the gateway behind your own product or just as a personal command centre. - 🔑\n**Multi-account fleet for Claude, Codex, Antigravity.** Drop multiple logged-in credential directories onto the host; opendray auto-discovers them via a filesystem watcher, balances new sessions across enabled accounts, and lets you switch a live session between accounts**without losing the conversation**(transcript migrates under the hood). Each account row shows live capacity (subscription tier, rate-limit tier, active sessions, last-used, current login email). - 🔒\n**Self-hosted, licence-clear.** Apache 2.0, one static binary, cosign-signed releases with SPDX SBOM. No telemetry, no cloud account, no subscription.\n\nopendray is a Go binary that serves a web admin at `/admin/`\n\nand a REST + WebSocket API at `/api/v1/*`\n\n. Here is what it does, in the shapes you would actually see.\n\n``` bash\n$ opendray sessions ls\nID        PROVIDER      PROJECT              STATE     STARTED\nses_a1f   claude-code   app/web              running   2h ago\nses_b2c   codex         internal/session     idle      5m ago\nses_c9d   grok-build    docs/                running   14m ago\nses_d34   shell         misc/deploy-logs     idle      1h ago\nbash\n$ opendray providers list\nPROVIDER      VERSION     ACCOUNTS   ACTIVE   NOTES\nclaude-code   1.4.11      3          1        auto-discovered via CLAUDE_CONFIG_DIR\ncodex         0.29.0      2          1        openai login\nantigravity   0.7.2       1          0        agy, HOME-isolated\ngrok-build    2.5.1       1          1        xai\nopencode      0.6.3       -          0        local endpoint required\nshell         -           -          1        arbitrary\n```\n\nThe web admin embeds xterm.js. You see the same PTY the CLI wrote to. Close the browser tab and the session keeps running on the host. Reopen it hours later and the transcript is where you left it.\n\n```\n[claude-code ses_a1f · app/web · 2h 14m]\n\n> refactor the router to lazy-load the mobile view\n\nI'll look at the current router and figure out the cleanest split.\n\n● Read(app/web/src/router.tsx)\n  ⎿ 342 lines\n● Grep(pattern: \"loadable\", path: \"app/web/src\")\n  ⎿ found 3 uses\n...\nsequenceDiagram\n    participant U as You (Telegram)\n    participant TG as Telegram Bot\n    participant OD as opendray\n    participant S as Session ses_a1f\n\n    S->>OD: session emits \"review needed on line 42\"\n    OD->>TG: send message + session tag\n    TG->>U: notification with quick-reply\n    U->>TG: \"yes, ship it\"\n    TG->>OD: webhook incoming\n    OD->>S: inject \"yes, ship it\" as next PTY input\n    S->>OD: agent continues\n```\n\nSame shape for Slack, Discord, Feishu, DingTalk, WeCom, and any Bridge-adapter transport.\n\n``` php\nflowchart LR\n    prompt[Agent asks for context] --> ret[memory retrieve]\n    ret --> user[USER scope<br/>preferences, workflows]\n    ret --> proj[PROJECT scope<br/>architecture, decisions]\n    ret --> sess[SESSION scope<br/>this conversation]\n    user --> rank[cross-scope rank]\n    proj --> rank\n    sess --> rank\n    rank --> ctx[injected context]\n```\n\nEvery scope stores embeddings from your own provider (ONNX bundled, Ollama, or LM Studio). Nothing leaves your network.\n\n``` php\nflowchart LR\n    a[Claude account A<br/>rate-limited] -->|switch| b[Claude account B<br/>fresh quota]\n    a -.->|transcript migrates| b\n    b --> cont[Session continues<br/>same conversation]\n```\n\nSame for Codex accounts and Antigravity accounts. `Carry-context`\n\nis on by default; untick to start clean on the new identity.\n\nSessions |\nAttach to a running Claude Code, Codex, Antigravity, Grok Build, OpenCode, or shell session from web, mobile, or chat. Sessions survive client disconnect and host reboot. Live transcript overlay for TUIs that skip wheel input. |\nProviders |\n5 first-class AI coding CLIs plus arbitrary shell. Adding a new CLI is a JSON descriptor drop-in under `internal/catalog/builtin/` . Per-provider MCP-server injection (Vault, memory, integrations). |\nMemory |\nThree-scope retrieval (user, project, session). Local-first embeddings via ONNX, Ollama, or LM Studio. Cross-layer conflict detection. Global knowledge pages injected at spawn. Compiler flywheel distils episodes into reusable playbooks. |\nChannels |\nTelegram, Slack, Discord, Feishu, DingTalk, WeCom. Bridge adapter for custom transports. Bidirectional: sessions notify, replies feed back. |\nIntegrations |\nREST + WebSocket API with scoped API keys, per-call audit log, reverse-proxy mounts. HashiCorp Vault MCP for secret access. Public\n`docs/integration-guide.md` |\n\n**Ops**`opendray update / start / stop / providers update`\n\n). Encrypted PostgreSQL backups + data exports. Goreleaser pipeline with cosign-signed releases + SPDX SBOM.**Security**`ProtectSystem=strict`\n\nsystemd hardening. Multi-tenant-safe scoped tokens.A single Go binary on your host runs the show. Clients drive sessions through HTTP/WebSocket, the session manager spawns each AI CLI in its own PTY, and the memory layer keeps shared state in Postgres with vector embeddings from your own provider.\n\n```\nflowchart LR\n    subgraph clients [Clients]\n        web[Web admin<br/>React SPA]\n        mob[Mobile app<br/>Flutter]\n        chat[Chat<br/>Telegram, Slack,<br/>Discord, Feishu,<br/>DingTalk, WeCom]\n        api[Third-party apps<br/>REST + WS]\n    end\n\n    subgraph gw [opendray gateway · single Go binary on your host]\n        direction TB\n        http[HTTP + WS<br/>chi · auth · audit]\n        sess[Session manager<br/>PTY · ring buffer]\n        mem[Memory layer<br/>three-domain retrieval]\n    end\n\n    subgraph cli [AI CLIs · spawned via PTY]\n        cc[Claude Code]\n        co[Codex]\n        ag[Antigravity]\n        gb[Grok Build]\n        oc[OpenCode]\n        sh[Shell]\n    end\n\n    subgraph data [Persistence · stays on your network]\n        pg[(PostgreSQL<br/>+ pgvector)]\n        em[ONNX · Ollama<br/>LM Studio embeddings]\n    end\n\n    clients --> http\n    http --> sess\n    http --> mem\n    sess --> cc\n    sess --> co\n    sess --> ag\n    sess --> gb\n    sess --> oc\n    sess --> sh\n    sess -.-> mem\n    mem --> pg\n    mem --> em\n```\n\nEverything in the diagram runs on your network. No cloud dependencies, no inference outside your control.\n\n| opendray | Claude Desktop | Cursor | CLI over SSH | ChatGPT Desktop | |\n|---|---|---|---|---|---|\n| Session survives client disconnect | ✅ | ❌ | ❌ | ❌ | |\n| Multi-account pool with live switch | ✅ | ❌ | ❌ | ❌ | ❌ |\n| Cross-session memory layer | ✅ | ❌ | Partial | ❌ | Partial |\n| Host filesystem + tool use | ✅ | Limited | ✅ | ✅ | Limited |\n| Mobile client with feature parity | ✅ | ❌ | ❌ | Partial | |\n| Chat channel adaptors | ✅ (6) | ❌ | ❌ | ❌ | ❌ |\n| Self-hosted | ✅ | ❌ | ❌ | ✅ | ❌ |\n| Licence | Apache 2.0 | Proprietary | Proprietary | (varies) | Proprietary |\n\n| opendray | Open WebUI | LibreChat | Dify | |\n|---|---|---|---|---|\n| Runs actual agent CLI (not just chat) | ✅ | ❌ | ❌ | Partial |\n| Tool use + file writes on host | ✅ | ❌ | ❌ | Sandboxed |\n| Multiple AI coding CLIs in one gateway | ✅ (5) | ❌ | ❌ | ❌ |\n| Cross-session memory | ✅ | Basic | Basic | ✅ |\n| PTY session with terminal reattach | ✅ | ❌ | ❌ | ❌ |\n| Chat channel adaptors | ✅ (6) | Partial | Partial | ✅ |\n| Licence | Apache 2.0 | MIT | MIT | Apache 2.0 |\n\n**Solo dev running a homelab.** You already have a Mac mini, NAS, or Proxmox box running 24/7. You've been running Claude Code over SSH but the session dies every time your laptop sleeps. You want the CLI to keep going, and you want to reattach from your phone on the train. opendray is the gateway that puts your host between you and the CLI.\n\n**Small-team lead standing up shared AI infrastructure.** Your team has 3-5 Anthropic accounts spread across work and personal plans. You want to pool them, watch usage per account, and let anyone on the team drive a session from the browser. opendray gives you multi-account pooling, per-account observability, scoped API keys per teammate, and a mobile app they can install without an App Store submission.\n\n**Integrator building on top of a session-runner.** You are building a product that needs to spawn Claude Code, Codex, or Grok Build sessions with tool use, and you don't want to reimplement session lifecycle, PTY handling, memory, or channel routing. opendray exposes every action over REST + WebSocket with scoped keys, per-call audit logs, and reverse-proxy mounts. Treat it as your agent runtime.\n\n**Linux / macOS / WSL2**\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Opendray/opendray/main/scripts/install.sh | bash\n```\n\n**Windows** sets up WSL2 first, then runs the Linux installer inside it. [details →](/Opendray/opendray/blob/main/scripts/README.md#windows)\n\n```\nirm https://raw.githubusercontent.com/Opendray/opendray/main/scripts/install-windows.ps1 | iex\n```\n\nWalks through Postgres setup, AI-CLI install, admin credentials, and service registration, landing a running gateway in ~5 to 10 minutes. See for what the wizard does, the file layout it creates, options, and troubleshooting.\n\n`scripts/README.md`\n\nWant the manual walkthrough?Read[, a 15-minute end-to-end guide that mirrors what the wizard does so you can verify each step yourself.]docs/getting-started.md\n\nInstall globally and put `opendray`\n\non `PATH`\n\n:\n\n```\nnpm install -g opendray\n```\n\nOr run on demand without installing:\n\n```\nnpx opendray\n```\n\nThis installs **just the binary**, no wizard, no service, no Postgres. The package pulls the matching `opendray-{linux,darwin}-{x64,arm64}`\n\nplatform binary via `optionalDependencies`\n\n(the esbuild / Biome pattern, no `postinstall`\n\n, no network call at install time). Good for scripted environments, ephemeral runners, or when you already run your own Postgres and process supervisor.\n\nYou still bring a database and start the gateway yourself:\n\n```\n# 1. PostgreSQL 15+ with pgvector. Point a DSN at it, set an admin password.\nexport OPENDRAY_DATABASE_URL=\"postgres://opendray:pw@127.0.0.1:5432/opendray?sslmode=disable\"\nexport OPENDRAY_ADMIN_PASSWORD=\"$(openssl rand -base64 24)\"\n# 2. Apply the schema, then run (foreground).\nopendray migrate\nopendray serve        # → http://127.0.0.1:8770/admin/\n```\n\nFull walkthrough (pgvector setup, `config.toml`\n\n, running as a systemd / launchd service, and updating) in [ docs/install-binary.md](/Opendray/opendray/blob/main/docs/install-binary.md).\n\n**Default.** Stops the gateway and removes the binary, but **keeps** your `config.toml`\n\n, data directory (bcrypt keyfile, sessions, notes, vault), logs, and the PostgreSQL database so a re-install resumes where you left off:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Opendray/opendray/main/scripts/uninstall.sh | bash\n```\n\n**Full purge.** Also drops the PG database + role, deletes config / data / logs, removes the service user. Includes a post-delete verification step that bails loudly if anything survived:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Opendray/opendray/main/scripts/uninstall.sh | OPENDRAY_PURGE=1 bash\n```\n\nAfter install, the `opendray`\n\nbinary handles its own lifecycle, with no need to remember `systemctl`\n\n/ `launchctl`\n\nincantations:\n\n```\nsudo opendray update --restart   # download latest release, verify SHA, atomic replace + restart\nsudo opendray providers update   # bump installed AI CLIs (claude / codex / antigravity) to npm-latest\nopendray providers list          # see which AI CLIs are installed + their versions\nsudo opendray start              # start | stop | restart | status, wraps systemd / launchd\n```\n\n`opendray --help`\n\nlists the full subcommand set.\n\nEvery supported path includes session spawn, AI-CLI access, encrypted backups, and the full integration API. opendray is a host-resident gateway; it spawns AI CLIs via PTYs and shares process state (`~/.claude`\n\n, ssh-agent, project files) with them. That model is incompatible with the container isolation that production Docker would impose, so Docker is not a supported deployment path for v2.x.\n\n| Path | Best for | Jump to |\n|---|---|---|\n📦 Pre-built binary |\n\"Just run it\", Linux / macOS, any supervisor |\n|\n\n**systemd unit**[Production deploy §A](#option-a-systemd-bare-metal--vm--lxc)** macOS LaunchDaemon**[Production deploy §C](#option-c-macos-launchd-mac-mini--studio-as-home-server)** Build from source**[Quickstart](#quickstart-5-minute-dev-path)belowFor a full walkthrough with prereqs and troubleshooting, see [ docs/quickstart.md](/Opendray/opendray/blob/main/docs/quickstart.md). The condensed dev path:\n\n```\n# 1. Have a Postgres 15+ running on 127.0.0.1:5432 with pgvector enabled\n#    (apt install postgresql-16 postgresql-16-pgvector / brew install postgresql@16 pgvector).\n#    Point [database].url at any other DSN if you'd rather use a remote PG.\n\n# 2. Local config, already gitignored.\ncp config.example.toml config.toml\n$EDITOR config.toml          # set [database].url, [admin].password\n\n# 3. Build the web bundle into the embed tree.\ncd app/web && pnpm install && pnpm build && cd ../..\n\n# 4. Apply schema.\ngo run ./cmd/opendray migrate -config config.toml\n\n# 5. Run.\ngo run ./cmd/opendray serve -config config.toml\n# → REST + WS:  http://127.0.0.1:8770/api/v1/...\n# → Web admin:  http://127.0.0.1:8770/admin/\n```\n\nThis runs OpenDray in the foreground; Ctrl-C kills it. For a long-running\ndaemon, see **Production deploy** below.\n\nFour supported deploy paths, pick whichever fits your environment. Each one gives you auto-restart on crash, persistent state, and separation of secrets from config.\n\nThe recommended Linux deploy path. Ships a hardened unit at\n[ deploy/systemd/opendray.service](/Opendray/opendray/blob/main/deploy/systemd/opendray.service)\nwith sandboxing (\n\n`ProtectSystem=strict`\n\n, `NoNewPrivileges`\n\n,\n`MemoryDenyWriteExecute`\n\n, capability scrub), `migrate`\n\n-then-`serve`\n\nboot, and a 20s graceful-stop window.**Get a binary first.** Either grab a pre-built archive from the\n[Releases page](https://github.com/Opendray/opendray/releases)\n(`opendray_*_linux_<arch>.tar.gz`\n\n, which unpacks to a single `opendray`\n\nbinary), or build from source via the [Quickstart](#quickstart-5-minute-dev-path)\nabove (`go build ./cmd/opendray`\n\n).\n\n```\n# 1. Install the binary you just grabbed (or built).\nsudo install -m 0755 /path/to/opendray /usr/local/bin/opendray\n\n# 2. Create the service user + state dir.\nsudo useradd -r -s /usr/sbin/nologin -d /var/lib/opendray opendray\nsudo install -d -o opendray -g opendray -m 0700 /var/lib/opendray\n\n# 3. Drop config + secrets (root-owned; mode 0640).\nsudo install -D -m 0640 config.example.toml /etc/opendray/config.toml\nsudo $EDITOR /etc/opendray/config.toml             # set [database].url etc.\nsudo install -D -m 0640 -o root -g opendray /dev/null /etc/opendray/env.d/secrets\nsudo $EDITOR /etc/opendray/env.d/secrets           # OPENDRAY_ADMIN_PASSWORD=…\n\n# 4. Install + enable the unit.\nsudo cp deploy/systemd/opendray.service /etc/systemd/system/\nsudo systemctl daemon-reload\nsudo systemctl enable --now opendray\n\n# 5. Verify.\nsudo systemctl status opendray\nsudo journalctl -u opendray -f --no-pager\n```\n\nThe unit runs `opendray migrate`\n\nas `ExecStartPre`\n\n, so the first boot\napplies all migrations before `serve`\n\never starts. Restarts are\n`on-failure`\n\nwith a 5s back-off and a 5-burst limit per minute.\n\nFor LXC without systemd, FreeBSD `rc.d`\n\n, OpenRC, or anything else.\nBuild once, run with whatever supervisor you already use:\n\n```\n# Cross-compile a release archive locally:\ngoreleaser release --clean --snapshot\nls dist/                  # opendray_*_linux_amd64.tar.gz etc.\n\n# Or grab a published release artefact:\n# https://github.com/Opendray/opendray/releases\n```\n\nThen point your supervisor (s6, runit, supervisord, runwhen) at:\n\n```\n/usr/local/bin/opendray serve -config /etc/opendray/config.toml\n```\n\nPre-flight: run `opendray migrate -config /etc/opendray/config.toml`\n\nonce before the first `serve`\n\n, or as a pre-start hook in your\nsupervisor of choice.\n\nFor Apple Silicon Mac mini / Mac Studio running 24/7. Ships a\nLaunchDaemon at\n[ deploy/launchd/com.opendray.opendray.plist](/Opendray/opendray/blob/main/deploy/launchd/com.opendray.opendray.plist)\nthat starts at boot before any user login, restarts on crash with\na 5s throttle, and logs to\n\n`/usr/local/var/log/opendray/`\n\n.\n\n```\n# 1. Install the darwin binary + config + state dirs.\nsudo install -m 0755 ./opendray /usr/local/bin/opendray\nsudo install -d -m 0755 \\\n  /usr/local/etc/opendray \\\n  /usr/local/var/lib/opendray \\\n  /usr/local/var/log/opendray\nsudo install -m 0640 config.example.toml /usr/local/etc/opendray/config.toml\nsudo $EDITOR /usr/local/etc/opendray/config.toml    # set [database].url etc.\n\n# 2. Apply migrations once.\nsudo /usr/local/bin/opendray migrate \\\n  -config /usr/local/etc/opendray/config.toml\n\n# 3. Install + load the LaunchDaemon.\nsudo cp deploy/launchd/com.opendray.opendray.plist /Library/LaunchDaemons/\nsudo chown root:wheel /Library/LaunchDaemons/com.opendray.opendray.plist\nsudo chmod 0644 /Library/LaunchDaemons/com.opendray.opendray.plist\nsudo launchctl bootstrap system /Library/LaunchDaemons/com.opendray.opendray.plist\n\n# 4. Verify.\nsudo launchctl print system/com.opendray.opendray\ntail -f /usr/local/var/log/opendray/opendray.log\n```\n\nRestart with `sudo launchctl kickstart -k system/com.opendray.opendray`\n\n;\nunload entirely with `sudo launchctl bootout system/com.opendray.opendray`\n\n.\n\nPostgres on macOS: install via Homebrew (`brew install postgresql@17 && brew services start postgresql@17`\n\n) and point `[database].url`\n\nat\n`postgres://$USER@127.0.0.1:5432/opendray`\n\n. Add `pgvector`\n\nwith\n`brew install pgvector`\n\nand `CREATE EXTENSION vector`\n\ninside the\nopendray database.\n\nFor Proxmox-specific LXC notes (PTY in unprivileged containers,\nnetworking, cgroup tweaks), see [ deploy/lxc/proxmox-pty-notes.md](/Opendray/opendray/blob/main/deploy/lxc/proxmox-pty-notes.md).\n\nFor reverse-proxy / TLS termination (nginx, Caddy, Traefik, Cloudflare\nTunnel), see [ docs/operator-guide.md](/Opendray/opendray/blob/main/docs/operator-guide.md) §Topology.\n\n```\n# Master passphrase (env-only, never write into config.toml).\nexport OPENDRAY_BACKUP_KEY=\"$(openssl rand -base64 32)\"\nexport OPENDRAY_BACKUP_ENABLED=1\n\n# pg_dump / pg_restore must match the server's major version. On\n# Apple Silicon dev machines pointing at a PG17 server:\nexport OPENDRAY_BACKUP_PG_DUMP_PATH=/opt/homebrew/opt/postgresql@17/bin/pg_dump\nexport OPENDRAY_BACKUP_PG_RESTORE_PATH=/opt/homebrew/opt/postgresql@17/bin/pg_restore\n```\n\nRestart opendray; the sidebar grows a Backups page (`/backups`\n\n)\nfor encrypted PostgreSQL dumps + restore, and `/export`\n\nfor\nzip-bundle data exports + import. See [ docs/operator-guide.md](/Opendray/opendray/blob/main/docs/operator-guide.md) §Backup for the full lifecycle.\n\nA single Go binary carries the whole web bundle, so no Node runtime\nis required at runtime, no separate static-file server, no Caddy/nginx\nneeded. Cloudflare Tunnel terminates TLS in front of `:8770`\n\n.\n\n```\ncmd/opendray/   binary entry point\ninternal/       Go backend (gateway, sessions, memory, channels,\n                integrations, git, search, one package per domain)\napp/web/        React + Vite admin SPA (embedded in the binary)\napp/mobile/     Flutter app (iOS + Android)\napp/shared*/    cross-surface shared UI + i18n strings\ndocs/           guides: install, getting-started, integration, ops\ndeploy/         systemd / launchd / LXC units + install scripts\n```\n\n`app/web/`\n\nbuilds a single SPA into `internal/web/dist/`\n\n, which the Go\nbinary embeds and serves at `/admin/*`\n\n. The Vite dev server at `:5173`\n\nproxies `/api`\n\nto `:8770`\n\nfor HMR-driven development.\n\n```\n# dev (hot reload on the React side, separate Go server for the API)\ncd app/web && pnpm dev               # http://localhost:5173\ngo run ./cmd/opendray serve -config ../../config.toml   # other terminal\n\n# prod (one binary delivers everything)\ncd app/web && pnpm build              # writes ../../internal/web/dist\ncd ../..\ngo build ./cmd/opendray               # bakes dist into the binary\n./opendray serve -config config.toml\n```\n\nSee [ app/web/README.md](/Opendray/opendray/blob/main/app/web/README.md) for the frontend stack\n(React + Vite + Tailwind v4 + shadcn/ui + TanStack Router/Query +\nZustand + xterm.js) and per-W milestone notes.\n\n`app/mobile/`\n\nis a Flutter app for **iOS and Android** with feature\nparity with the web admin. It attaches to a running gateway over HTTPS.\nEnter the **Gateway URL** + admin login on first launch and you get the\nsame Sessions / Channels / Integrations / Memory / Git surfaces. There is\nno App Store / Play Store build by design (self-hosted, single-tenant):\nyou build it yourself and sign it with your own identity.\n\n** → Build & install guide.** Make the gateway\nreachable from the phone, then sideload an Android APK or install on\niPhone via Xcode. (\n\n[all 10 languages](/Opendray/opendray/blob/main/docs/mobile-app.md); switch at the top of the guide.)\n\nopendray is a self-hosted gateway that wraps the AI coding CLIs you already use (Claude Code, Codex, Antigravity, Grok Build, OpenCode, and shell) and turns them into sessions you can drive from a web admin, a Flutter mobile app, or six chat channels (Telegram, Slack, Discord, Feishu, DingTalk, WeCom). One Go binary. Apache 2.0. Your infra, your data, your tokens.\n\nFive first-class providers as of v2.10.x: **Claude Code** (Anthropic), **Codex** (OpenAI), **Antigravity** (Google `agy`\n\n), **Grok Build** (xAI), and **OpenCode**. Plus arbitrary shell for anything else. Adding a new CLI is a JSON descriptor under `internal/catalog/builtin/`\n\n; no adapter code required for common cases.\n\nClaude Desktop and ChatGPT Desktop are chat clients that run on your laptop and die when the laptop closes. opendray runs the actual agentic CLI on a host that stays awake and lets you reattach from anywhere. Sessions survive client disconnect, laptop sleep, and network drops. Multiple accounts get pooled with live switch between them.\n\nFour things SSH does not give you: (1) session survives when you disconnect (no `tmux`\n\ngymnastics required, though you can still use tmux inside), (2) attach from a phone or a chat channel, not just a terminal, (3) shared memory layer across every session on the host, (4) multi-account pool with per-tier balancing and live account-switch mid-conversation.\n\nThose are chat frontends against a model API. They send prompts to `api.openai.com`\n\n(or similar) and render the response. opendray runs the actual agent CLI process on your host, complete with tool use, file writes, memory, and MCP servers. If a task needs `Read`\n\n/ `Edit`\n\n/ `Bash`\n\non your host filesystem, opendray does it; chat frontends do not.\n\nYes. Drop the logged-in credential directories on the host (Claude uses `CLAUDE_CONFIG_DIR`\n\n, Antigravity uses `$HOME`\n\nisolation) and opendray auto-discovers them via a filesystem watcher. New sessions balance across enabled accounts by tier + capacity. You can switch a live session between accounts without losing the conversation (transcript migrates under the hood). Rate-limit auto-failover carries context by default.\n\nPostgreSQL on your host (bring your own instance, or use the one the installer bootstraps). Embeddings come from your own provider (ONNX bundled, Ollama, or LM Studio). No vector data, transcripts, or memory entries leave your network. No telemetry. No cloud account. `opendray`\n\nnever phones home.\n\nNot currently (v2.x). opendray spawns AI CLIs via PTYs and shares host process state (credential directories, ssh-agent, project files) with them. That is incompatible with the container isolation production Docker imposes. Use the pre-built binary and systemd or launchd (Linux + macOS both have one-line installers). See [Production deploy](#production-deploy).\n\nNAS: yes on Synology / QNAP / TrueNAS-Scale (anything with Linux + Postgres). Mac mini: yes, this is a common deploy (LaunchDaemon shipped). Raspberry Pi: works on Pi 4 / Pi 5 but underpowered for concurrent sessions; single-user hobby use only.\n\nApache 2.0. Free forever. No paid tier, no telemetry, no phone-home. Sponsors welcomed (see [ .github/FUNDING.yml](/Opendray/opendray/blob/main/.github/FUNDING.yml)).\n\nRead [ CONTRIBUTING.md](/Opendray/opendray/blob/main/CONTRIBUTING.md) and\n\n[. Concrete ways in: (1) translate a README or docs page into a language we already ship, (2) add a provider descriptor for a new AI coding CLI under](/Opendray/opendray/blob/main/CODE_OF_CONDUCT.md)\n\n`CODE_OF_CONDUCT.md`\n\n`internal/catalog/builtin/`\n\n, (3) write a channel adaptor for a chat platform we do not cover, (4) contribute screenshots for the docs, (5) file a bug or a feature request. PRs need CI green; translations are advisory-only; no CLA.:`docs/getting-started.md`\n\n**start here** if you're new. Zero to first session in 15 minutes, including installing the wrapped CLIs and bootstrapping Postgres.: install from the npm package or a release binary (bring your own Postgres) and run it as a systemd / launchd service.`docs/install-binary.md`\n\n: 5-minute dev environment (assumes you already know the moving parts).`docs/quickstart.md`\n\n: build & install the Flutter mobile app; sideload an Android APK or install on iPhone via Xcode, then point it at your gateway.`docs/mobile-app.md`\n\n: deploy + ops reference for production-ish setups.`docs/operator-guide.md`\n\n: how to write an external integration in any language.`docs/integration-guide.md`\n\n: versioning strategy (major-as-generation).`VERSIONING.md`\n\n: release history.`CHANGELOG.md`\n\nCurrent generation: **v2.10.x**. See [ CHANGELOG.md](/Opendray/opendray/blob/main/CHANGELOG.md) for release history and\n\n[for the major-as-generation policy (major = product generation, not strict SemVer \"breaking change\").](/Opendray/opendray/blob/main/VERSIONING.md)\n\n`VERSIONING.md`\n\nThis generation ships:\n\n**One-line installer + uninstaller wizards**(Linux + macOS; Windows funnels through WSL2). Walks the operator through Postgres bootstrap, AI-CLI install, admin credentials, listen address, binary install, schema migration, and service registration.**Self-managing binary.**`opendray update / start / stop / restart / status / providers list / providers update`\n\nso operators don't touch`systemctl`\n\n/`launchctl`\n\nfor routine ops.**Goreleaser release pipeline.** Cross-compiled binaries (linux/darwin × amd64/arm64), cosign keyless signing (Sigstore), SPDX SBOM, atomically verified self-update.\n\n```\ngo test -race ./...        # backend\ncd app/web && pnpm build   # web (TS strict + vite production build)\n```\n\nEnd-to-end smoke flows are tracked in commit messages per milestone. A Playwright harness is a planned follow-up.\n\nv1 (`Opendray/opendray`\n\n) is the legacy codebase, now archived. v2 is\nthe current and active generation, feature-complete and the only\nbranch receiving development. Of the 16 v1 builtins, four migrated\ninto the v2 backend; the rest became client-side features, channel\nadaptors, or integration-API consumers.\n\nApache 2.0. See [ LICENSE](/Opendray/opendray/blob/main/LICENSE). (v1 was MIT; v2 is licensed\nindependently.)", "url": "https://wpnews.pro/news/opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere", "canonical_source": "https://github.com/Opendray/opendray", "published_at": "2026-07-09 09:28:56+00:00", "updated_at": "2026-07-09 09:42:22.494372+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-infrastructure", "developer-tools", "ai-products"], "entities": ["Opendray", "Claude Code", "Codex", "Antigravity", "Grok Build", "OpenCode", "Telegram", "Slack"], "alternates": {"html": "https://wpnews.pro/news/opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere", "markdown": "https://wpnews.pro/news/opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere.md", "text": "https://wpnews.pro/news/opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere.txt", "jsonld": "https://wpnews.pro/news/opendray-run-claude-code-codex-agents-on-your-own-box-drive-from-anywhere.jsonld"}}