···1313 "build:docs": "cd docs && bun run build",
1414 "build:cli": "cd packages/cli && bun run build",
1515 "deploy:docs": "cd docs && bun run deploy",
1616- "deploy:cli": "cd packages/cli && bun run deploy"
1616+ "deploy:cli": "cd packages/cli && bun run deploy",
1717+ "dev:server": "cd packages/server && bun run dev",
1818+ "start:server": "cd packages/server && bun run start"
1719 },
1820 "devDependencies": {
1921 "@types/bun": "latest",
+20
packages/server/.env.example
···11+CLIENT_URL=https://your-domain.com
22+CLIENT_NAME=Sequoia
33+PORT=3000
44+REDIS_URL=redis://redis:6379
55+66+# Theme overrides (optional)
77+# THEME_ACCENT_COLOR=#3A5A40
88+# THEME_BG_COLOR=#F5F3EF
99+# THEME_FG_COLOR=#2C2C2C
1010+# THEME_BORDER_COLOR=#D5D1C8
1111+# THEME_ERROR_COLOR=#8B3A3A
1212+# THEME_BORDER_RADIUS=6px
1313+# THEME_FONT_FAMILY=system-ui, sans-serif
1414+# THEME_DARK_BG_COLOR=#1A1A1A
1515+# THEME_DARK_FG_COLOR=#E5E5E5
1616+# THEME_DARK_BORDER_COLOR=#3A3A3A
1717+# THEME_DARK_ERROR_COLOR=#E57373
1818+1919+# Path to a custom CSS file for full theme control (optional)
2020+# THEME_CSS_PATH=/app/theme.css
···11+# Sequoia Server
22+33+Self-hostable AT Protocol OAuth and subscription server. Handles Bluesky login and manages `site.standard.graph.subscription` records on behalf of users. Built with Bun, Hono, and Redis.
44+55+## Quickstart
66+77+### Docker (recommended)
88+99+```bash
1010+cp .env.example .env
1111+# Edit .env — at minimum set CLIENT_URL to your public URL
1212+docker compose up
1313+```
1414+1515+### Local development
1616+1717+Requires [Bun](https://bun.sh) and a running Redis instance.
1818+1919+```bash
2020+bun install
2121+CLIENT_URL=http://localhost:3000 bun run dev
2222+```
2323+2424+## How it works
2525+2626+1. A user visits `/subscribe?publicationUri=at://...` and enters their Bluesky handle
2727+2. The server initiates an AT Protocol OAuth flow — the user authorizes on Bluesky
2828+3. After callback, the server creates a `site.standard.graph.subscription` record in the user's repo
2929+4. The [sequoia-subscribe](https://github.com/standard-schema/sequoia) web component can point to this server for the full flow
3030+3131+### Routes
3232+3333+| Route | Method | Description |
3434+|-------|--------|-------------|
3535+| `/api/health` | GET | Health check |
3636+| `/oauth/client-metadata.json` | GET | OAuth client metadata |
3737+| `/oauth/login?handle=` | GET | Start OAuth flow |
3838+| `/oauth/callback` | GET | OAuth callback |
3939+| `/oauth/logout` | POST | Revoke session |
4040+| `/oauth/status` | GET | Check auth status |
4141+| `/subscribe` | GET | Subscribe page (HTML) |
4242+| `/subscribe` | POST | Subscribe via API (JSON) |
4343+| `/subscribe/check` | GET | Check subscription status |
4444+| `/subscribe/login` | POST | Handle form submission |
4545+4646+## Configuration
4747+4848+| Variable | Required | Default | Description |
4949+|----------|----------|---------|-------------|
5050+| `CLIENT_URL` | Yes | — | Public URL of this server (used for OAuth redirects) |
5151+| `CLIENT_NAME` | No | `Sequoia` | Name shown on Bluesky OAuth consent screen |
5252+| `PORT` | No | `3000` | Server port |
5353+| `REDIS_URL` | No | `redis://localhost:6379` | Redis connection URL |
5454+5555+### Theming
5656+5757+The subscribe pages use CSS custom properties that can be overridden via environment variables:
5858+5959+| Variable | Default |
6060+|----------|---------|
6161+| `THEME_ACCENT_COLOR` | `#3A5A40` |
6262+| `THEME_BG_COLOR` | `#F5F3EF` |
6363+| `THEME_FG_COLOR` | `#2C2C2C` |
6464+| `THEME_BORDER_COLOR` | `#D5D1C8` |
6565+| `THEME_ERROR_COLOR` | `#8B3A3A` |
6666+| `THEME_BORDER_RADIUS` | `6px` |
6767+| `THEME_FONT_FAMILY` | `system-ui, sans-serif` |
6868+| `THEME_DARK_BG_COLOR` | `#1A1A1A` |
6969+| `THEME_DARK_FG_COLOR` | `#E5E5E5` |
7070+| `THEME_DARK_BORDER_COLOR` | `#3A3A3A` |
7171+| `THEME_DARK_ERROR_COLOR` | `#E57373` |
7272+7373+For full control, set `THEME_CSS_PATH` to a CSS file path (e.g. `/app/theme.css` mounted via Docker volume). It will be injected after the default styles.
7474+7575+## Deployment
7676+7777+The included `Dockerfile` produces a minimal image:
7878+7979+```bash
8080+docker build -t sequoia-server .
8181+docker run -p 3000:3000 \
8282+ -e CLIENT_URL=https://your-domain.com \
8383+ -e REDIS_URL=redis://your-redis:6379 \
8484+ sequoia-server
8585+```
8686+8787+Or use `docker-compose.yml` which bundles Redis:
8888+8989+```bash
9090+docker compose up -d
9191+```
9292+9393+Place behind a reverse proxy (Caddy, nginx, Traefik) for TLS.