https://github.com/agentserver/agentserver
Run OpenClaw and OpenCode in the browser. Self-hosted, multi-user, Helm-deployable.
https://github.com/agentserver/agentserver
ai claude code-server docker helm kubernetes oidc openclaw self-hosted terminal
Last synced: 2 days ago
JSON representation
Run OpenClaw and OpenCode in the browser. Self-hosted, multi-user, Helm-deployable.
- Host: GitHub
- URL: https://github.com/agentserver/agentserver
- Owner: agentserver
- License: mit
- Created: 2026-02-26T14:45:27.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-02T06:55:45.000Z (20 days ago)
- Last Synced: 2026-05-02T07:26:19.499Z (20 days ago)
- Topics: ai, claude, code-server, docker, helm, kubernetes, oidc, openclaw, self-hosted, terminal
- Language: Go
- Homepage: https://agentserver.dev
- Size: 2.82 MB
- Stars: 22
- Watchers: 1
- Forks: 7
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
agentserver
Personally command and deploy AI agents across every location and device β from one place.
---
> π Read the full vision: [Overview of agentserver](Overview%20of%20agentserver.pdf) (slide deck, Apr 2026)
agentserver is a self-hosted platform for **operating a fleet of coding agents from one console** β cloud sandboxes, your laptop, your desktop, even your phone, all reachable through the same Web UI or an IM channel (WeChat / Weixin, Telegram, β¦).
It is the answer to a question Addy Osmani frames as the path from L1 (no AI) to L8 (build your own orchestrator)*: once you are juggling 10+ agents across machines, you stop being a *conductor* and become an *orchestrator*. agentserver is the orchestration layer.
* Addy Osmani, Director, Google Β· Gemini & Cloud AI β talks.addy.ie/oreilly-codecon-march-2026
### How it differs from what already exists
| Tool | Local agents | Cloud sandboxes | Cross-device peering |
|------|:---:|:---:|:---:|
| OpenClaw / Claude Code Remote | one at a time | β | β |
| Claude Code on the web | β | β
| β |
| Claude Code Agent Teams | β | β
(subagents) | β |
| **agentserver** | **β
many** | **β
** | **β
** |
## Why agentserver?
- **One console, every device** β Operate cloud sandboxes, local laptops/desktops, and IM-bound agents from the same workspace.
- **Local tunneling, zero public IP** β A local opencode/Claude Code/Codex instance dials home over WebSocket and appears as a sandbox in the UI.
- **Sandboxes** β Per-task containers with pause/resume and idle auto-pause; Docker (single node) or Kubernetes with [Agent Sandbox](https://github.com/kubernetes-sigs/agent-sandbox) + gVisor.
- **Multi-tenancy by workspace** β Cloud and local agents register into the *same* workspace registry; role-based access (owner / maintainer / developer / guest).
- **Credential & LLM proxy** β Sandboxes never see real provider keys; per-workspace RPD quotas and usage tracking enforced server-side.
- **IM bridge (WIP)** β Drive agents from WeChat / Weixin or Telegram via `imbridge`; no terminal required.
- **SSO ready** β GitHub OAuth and generic OIDC (Keycloak, Authentik, β¦).
- **Deploy anywhere** β Pre-built binaries, Homebrew, Docker Compose, or Helm for Kubernetes.
## Roadmap: Three Stages
agentserver is being built in three stages. The diagrams and full reasoning live in [Overview of agentserver.pdf](Overview%20of%20agentserver.pdf).
| Stage | Theme | Status | What lands |
|-------|-------|:---:|------------|
| **1** | `code-server` for coding agents | β
shipping | Sandbox provisioner, agent registry, credential / LLM proxy, agent-proxy ingress, Web Console |
| **2** | The emergence of OpenClaw | π§ in progress | NanoClaw (sandboxed Claude Code), `imbridge` (WeChat / Telegram), agent message bus |
| **3** | Centralized agent-loop | π designing | Stateless `cc` worker pool, `cc-broker` provisioner, tool router, durable memory / context store, agent mailboxes |
### Core insights driving Stage 3
- **Stateless harness** β Decouple the *brain* (Claude + harness) from the *hands* (sandboxes and tools). Sessions are append-only event logs that live outside the context window. Workers are *cattle, not pets* β a worker that dies mid-turn loses nothing.
- **Hybrid cloud-local mesh** β Cloud and local agents share one workspace registry. Discovery happens through agent cards; the LLM picks a tool and a tool router decides where the call goes. *Agent discovery, not network mesh.*
- **Async collaboration via mailboxes** β Agents hand off work through inboxes in durable storage. The receiver does not need to be alive when the message is sent. The mailbox is the source of truth.
## Architecture
Today's deployment (Stage 1, with Stage 2 services landing):
```
World (Anthropic, GitHub, β¦)
β²
β egress
βββββββββββββ΄βββββββββββββ
β credentialproxy / β
β llmproxy (:8081) β
β β’ key injection β
β β’ RPD quota / usage β
βββββββββββββ¬βββββββββββββ
β
WeChat / Telegram βββΆ imbridge βββΆ β
Browser ββββββββββββΆ agentserver ββ€ ββββββββββββββββββββ
(:8080) β β sandbox pod / β
β’ REST API βββββΆβ container β
β’ admin UI β β ββ opencode / β
β’ registry β β nanoclaw β
β’ tunnels β ββββββββββββββββββββ
β β
β ββββΆ local laptop / desktop / phone
β ββ agentserver-agent (WS tunnel)
βΌ
PostgreSQL
(users, workspaces,
sandboxes, quotas,
sessions, mailboxes)
Browser βββΆ sandboxproxy (:8082) ββΆ subdomain routing to sandbox services
Browser βββΆ cc-broker ββββΆ stateless cc worker pool (Stage 3)
Sandbox βββΆ executor-registry ββββΆ tool-call dispatch / executor lookup
```
| Service | Default Port | Role |
|---------|-------------|------|
| **agentserver** | `:8080` | Main API, Web UI, agent registry, tunnel endpoints |
| **llmproxy** | `:8081` | LLM API proxy with per-workspace rate limiting and usage tracking |
| **sandboxproxy** | `:8082` | Subdomain-based routing to sandbox services |
| **credentialproxy** | β | Server-side injection of provider credentials |
| **imbridge** | β | IM channel bridge (WeChat / Weixin, Telegram) |
| **cc-broker** | β | Stateless Claude Code / Codex worker pool (Stage 3) |
| **executor-registry** | β | Tool-call dispatch / executor discovery (Stage 3) |
## Code of Conduct
agentserver follows four house rules that shape every change:
- β **No human-authored code.** All production code is generated by AI agents.
- β
**Open source from day 1.** The repository is public from inception; no closed-source phase.
- β
**Fully automated DevOps.** Build, test, release, and deployment are end-to-end automated.
- β
**Dogfooding & bootstrapping.** agentserver is built (partially) *with* agentserver β every feature is used by our own agents before it ships.
## Quick Start
### Docker Compose (recommended for local use)
```bash
git clone https://github.com/agentserver/agentserver.git && cd agentserver
docker build -f Dockerfile.opencode -t agentserver-agent:latest .
export ANTHROPIC_API_KEY="sk-ant-..."
docker compose up -d
```
Open `http://localhost:8080` in your browser.
### Helm (Kubernetes)
```bash
helm install agentserver oci://ghcr.io/agentserver/charts/agentserver \
--namespace agentserver --create-namespace \
--set database.url="postgres://user:pass@postgres:5432/agentserver?sslmode=disable" \
--set anthropicApiKey="sk-ant-..." \
--set ingress.enabled=true \
--set ingress.host="cli.example.com" \
--set baseDomain="cli.example.com"
```
### Pre-built Binaries
Download from [GitHub Releases](https://github.com/agentserver/agentserver/releases), or install via Homebrew:
```bash
brew install agentserver/tap/agentserver
```
## Local Agent Tunneling
Connect a locally-running opencode instance to agentserver β no public IP or third-party tunnel needed.
1. In the Web UI, click the laptop icon next to "Sandboxes" to generate a registration code.
2. On your local machine:
```bash
# First time β register with the server
agentserver connect \
--server https://cli.example.com \
--code \
--name "My MacBook"
# Subsequent runs β auto-reconnect using saved credentials
agentserver connect
```
3. A **local** sandbox appears in the Web UI β click "Open" to access your local opencode through the browser.
### Multi-agent support
Register multiple agents on the same machine, each targeting a different directory and workspace:
```bash
# List all registered agents
agentserver list
# Remove a registration
agentserver remove --workspace
```
Agent credentials are stored in `~/.agentserver/registry.json`.
**Tunnel features:** zero-config networking, auto-reconnect with backoff, binary WebSocket protocol (no base64 overhead), real-time SSE streaming, offline detection with auto-recovery.
## Configuration
See the [API reference](docs/api-reference.md) for full endpoint documentation.
Helm Values
| Parameter | Description | Default |
|-----------|-------------|---------|
| `image.repository` | Server image | `ghcr.io/agentserver/agentserver` |
| `image.tag` | Server image tag | `latest` |
| `opencode.image` | Opencode agent image for sandbox pods | `ghcr.io/agentserver/opencode-agent:latest` |
| `opencode.runtimeClassName` | RuntimeClass for sandbox pods (e.g. `gvisor`) | `""` |
| `openclaw.image` | OpenClaw gateway image | `""` |
| `openclaw.port` | OpenClaw gateway port | `18789` |
| `database.url` | PostgreSQL connection string | (required) |
| `anthropicApiKey` | Anthropic API key | (required) |
| `anthropicBaseUrl` | Custom Anthropic API base URL | `""` |
| `anthropicAuthToken` | Anthropic auth token (alternative to API key) | `""` |
| `backend` | Sandbox backend: `docker` or `k8s` | `docker` |
| `baseDomain` | Base domain for subdomain routing | `""` |
| `baseScheme` | URL scheme for generated URLs | `https` |
| `idleTimeout` | Auto-pause idle sandboxes after | `30m` |
| `persistence.sessionStorageSize` | Per-sandbox ephemeral storage | `5Gi` |
| `persistence.userDriveSize` | Per-workspace shared disk size | `10Gi` |
| `persistence.storageClassName` | Storage class for PVCs | `""` (cluster default) |
| `workspace.resources` | Resource limits/requests for sandbox pods | `1Gi/1cpu` limits |
| `agentSandbox.install` | Install Agent Sandbox controller | `true` |
| `ingress.enabled` | Enable Nginx Ingress | `false` |
| `ingress.host` | Ingress hostname | `agentserver.example.com` |
| `ingress.tls` | Enable TLS (cert-manager) | `false` |
| `gateway.enabled` | Enable Gateway API HTTPRoute | `false` |
Environment Variables (Main Server)
| Variable | Description | Default |
|----------|-------------|---------|
| `DATABASE_URL` | PostgreSQL connection string | (required) |
| `ANTHROPIC_API_KEY` | Anthropic API key | (required) |
| `ANTHROPIC_BASE_URL` | Custom API base URL | `https://api.anthropic.com` |
| `ANTHROPIC_AUTH_TOKEN` | Anthropic auth token (alternative to API key) | - |
| `OPENCODE_CONFIG_CONTENT` | JSON opencode config for sandbox pods | - |
| `BASE_DOMAIN` | Base domain for subdomain routing | - |
| `BASE_SCHEME` | URL scheme (`http` or `https`) | `https` |
| `IDLE_TIMEOUT` | Auto-pause timeout (e.g. `30m`) | `30m` |
| `AGENT_IMAGE` | Container image for sandbox agents | `ghcr.io/agentserver/opencode-agent:latest` |
| `LLMPROXY_URL` | Base URL of the LLM proxy service | - |
| `PASSWORD_AUTH_ENABLED` | Enable password-based auth | `true` |
| `OIDC_REDIRECT_BASE_URL` | External URL for OIDC callbacks | - |
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | - |
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | - |
| `OIDC_ISSUER_URL` | Generic OIDC issuer URL | - |
| `OIDC_CLIENT_ID` | Generic OIDC client ID | - |
| `OIDC_CLIENT_SECRET` | Generic OIDC client secret | - |
| `SANDBOX_NAMESPACE_PREFIX` | K8s namespace prefix | `agent-ws` |
| `NETWORKPOLICY_ENABLED` | Enable K8s NetworkPolicy isolation | `false` |
| `NETWORKPOLICY_DENY_CIDRS` | CIDRs to deny in network policies | - |
| `AGENTSERVER_NAMESPACE` | agentserver's own K8s namespace | - |
| `STORAGE_CLASS` | K8s storage class for PVCs | (cluster default) |
| `USER_DRIVE_SIZE` | Per-workspace storage size | `10Gi` |
| `USER_DRIVE_STORAGE_CLASS` | Storage class for workspace drives | inherits `STORAGE_CLASS` |
| `CC_BROKER_URL` | URL of the cc-broker service (required for TUI flow) | - |
| `EXECUTOR_REGISTRY_URL` | URL of the executor-registry service (required for TUI flow) | - |
| `INTERNAL_API_SECRET` | Shared secret for internal endpoints (recommended) | - |
Environment Variables (LLM Proxy)
| Variable | Description | Default |
|----------|-------------|---------|
| `LLMPROXY_LISTEN_ADDR` | HTTP listen address | `:8081` |
| `LLMPROXY_DATABASE_URL` | Proxy's own PostgreSQL connection URL | - |
| `LLMPROXY_AGENTSERVER_URL` | agentserver internal API URL for token validation | (required) |
| `ANTHROPIC_API_KEY` | Anthropic API key | (required*) |
| `ANTHROPIC_AUTH_TOKEN` | Anthropic auth token (alternative to API key) | (required*) |
| `ANTHROPIC_BASE_URL` | Upstream Anthropic API URL | `https://api.anthropic.com` |
| `LLMPROXY_DEFAULT_MAX_RPD` | Default max requests per day per workspace (0 = unlimited) | `0` |
Environment Variables (Sandbox Proxy)
| Variable | Description | Default |
|----------|-------------|---------|
| `DATABASE_URL` | PostgreSQL connection string | (required) |
| `LISTEN_ADDR` | HTTP listen address | `:8082` |
| `BASE_DOMAIN` | Base domain for subdomain routing | (required) |
| `OPENCODE_SUBDOMAIN_PREFIX` | Subdomain prefix for opencode sandboxes | `code` |
| `OPENCLAW_SUBDOMAIN_PREFIX` | Subdomain prefix for openclaw sandboxes | `claw` |
| `OPENCODE_ASSET_DOMAIN` | Domain for opencode static assets | `opencodeapp.{BASE_DOMAIN}` |
OIDC Authentication
**GitHub OAuth:**
```bash
helm upgrade agentserver oci://ghcr.io/agentserver/charts/agentserver \
--reuse-values \
--set oidc.redirectBaseUrl="https://cli.example.com" \
--set oidc.github.enabled=true \
--set oidc.github.clientId="your-client-id" \
--set oidc.github.clientSecret="your-client-secret"
```
Callback URL: `https://cli.example.com/api/auth/oidc/github/callback`
**Generic OIDC (Keycloak, Authentik, etc.):**
```bash
helm upgrade agentserver oci://ghcr.io/agentserver/charts/agentserver \
--reuse-values \
--set oidc.redirectBaseUrl="https://cli.example.com" \
--set oidc.generic.enabled=true \
--set oidc.generic.issuerUrl="https://idp.example.com/realms/main" \
--set oidc.generic.clientId="agentserver" \
--set oidc.generic.clientSecret="your-secret"
```
Kubernetes Backend
For production multi-tenant deployments with gVisor isolation:
```bash
helm upgrade agentserver oci://ghcr.io/agentserver/charts/agentserver \
--reuse-values \
--set backend=k8s \
--set opencode.runtimeClassName=gvisor \
--set sandbox.namespace=agentserver
```
## Building from Source
```bash
# Prerequisites: Go 1.26, Node.js, pnpm, bun
# Build everything (frontend + backend)
make build
# Build individual components
make backend # Go binary β bin/agentserver
make frontend # React frontend β web/dist/
make agent # Local agent binary β bin/agentserver-agent
make agent-all # Agent for all platforms (linux/darwin/windows, amd64/arm64)
make llmproxy # LLM proxy binary β bin/llmproxy
# Docker images
make docker # Main server image
make docker-agent # Agent container image
make docker-llmproxy # LLM proxy image
make docker-all # All images
```
## Contributing
```bash
# Terminal 1: Start backend
go run . serve --db-url "postgres://..." --backend docker
# Terminal 2: Start frontend dev server
cd web && pnpm install && pnpm dev
```
Per the [Code of Conduct](#code-of-conduct), production code is AI-generated. Pull requests authored by an agent (with a human reviewer) are welcome; the repo is dogfooded against itself.
## License
[MIT](LICENSE)