A barebones autonomous SaaS development team powered by OpenClaw. Four AI agents — Lead, Dev, Designer, Marketer — run in Docker, share a product codebase, and coordinate through a JSON dashboard and a bash CLI.
No Convex. No Next.js dashboard. Just files, jq, and agents that ship.
┌─────────────────────────────────────────────────────┐
│ Host │
│ claw CLI ──────────────────────────────────────┐ │
│ (reads/writes data/shared/dashboard.json) │ │
└──────────────────────────────────┬──────────────┘ │
│ HTTP :18789 │
┌──────────────────────────────────▼──────────────────┤
│ Docker │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ gateway (OpenClaw) │ │
│ │ │ │
│ │ lead (Lead 🦞) │ │
│ │ ├─ subagent: Dev 💻 │ │
│ │ ├─ subagent: Designer 🎨 │ │
│ │ └─ subagent: Marketer 📈 │ │
│ │ │ │
│ │ dev │ │
│ │ designer │ │
│ │ marketer │ │
│ └────────────────────────────┬────────────────┘ │
│ │ HTTP :8080 │
│ ┌────────────────────────────▼────────────────┐ │
│ │ searxng (local search engine) │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Volumes: │
│ /data/shared/ ← dashboard.json, memory │
│ /data/product/ ← the actual SaaS code │
│ /data/workspace-lead/ │
│ /data/workspace-dev/ │
│ /data/workspace-designer/ │
│ /data/workspace-marketer/ │
└─────────────────────────────────────────────────────┘
| Component | What it does |
|---|---|
| OpenClaw gateway | Runs agent sessions, fires heartbeats on cron, routes messages between agents |
| dashboard.json | Single source of truth — tasks, agent status, activity feed, deliverables |
claw CLI |
Bash script; reads/writes dashboard.json with jq, triggers agents via OpenClaw CLI |
| SearXNG | Local, privacy-respecting search engine available to all agents as a skill |
shared/WORKING.md |
Soft file-lock table agents use to coordinate edits on /data/product/ |
| Agent | Role | Owns |
|---|---|---|
| Lead 🦞 | Coordinator. Breaks user requests into tasks, assigns work, reviews deliverables. Spawns Dev/Designer/Marketer as subagents. | Everything at a high level |
| Dev 💻 | Full-stack engineer. Writes features, routes, APIs, tests. | product/src/, product/api/ |
| Designer 🎨 | UI/UX. Produces Tailwind components, wireframes, design tokens. | product/src/components/, product/public/, product/src/styles/ |
| Marketer 📈 | Growth. Writes landing copy, blog posts, email sequences, SEO strategy. | product/content/, product/public/copy/ |
Every agent runs on a 15-minute heartbeat — they check the task board, pick up assigned work, update their status, and write results back to /data/product/.
Lead can spawn Dev, Designer, and Marketer as parallel subagents for complex tasks (max depth 2).
/data/product/ ← all agents read/write here
├── src/ ← Dev (logic, features, routes)
│ ├── components/ ← Designer (UI components)
│ ├── app/ ← Dev + Designer
│ └── styles/ ← Designer
├── api/ ← Dev
├── public/ ← Designer (images, icons, fonts)
│ └── copy/ ← Marketer (landing page copy)
└── content/ ← Marketer (blog posts, docs, email sequences)
Each agent workspace has a product/ symlink pointing to /data/product/ for convenience.
Agents use shared/WORKING.md as a soft lock registry. Before editing any file in /data/product/, an agent adds a row to the lock table. Other agents check this table before touching the same files. The claw notify command lets agents ping each other when they need a file that's claimed.
- Docker + Docker Compose v2
jq(brew install jq/apt install jq)- An OpenRouter API key
# 1. Clone
git clone <your-repo> claw && cd claw
# 2. First-run setup — creates .env, data dirs, SearXNG config, generates tokens
bash scripts/setup.sh
# → exits after creating .env. Open it and set your API key:
nano .env # OPENROUTER_API_KEY=sk-or-...
# 3. Finish setup
bash scripts/setup.sh
# 4. Build and launch
docker compose up -d
# 5. Check everything is running
docker compose ps
docker compose logs gateway # watch for init errors
claw squad # shows agent status
docker exec claw-gateway openclaw agents listOr with Make:
make setup # runs setup.sh (run twice: first to create .env, then to finish)
make up # docker compose up -d
make status # docker ps + claw squadIf the host claw command says Gateway ... unreachable but container logs show OpenClaw listening, verify directly with:
docker exec claw-gateway openclaw agents list| Variable | Required | Default | Description |
|---|---|---|---|
OPENROUTER_API_KEY |
Yes | — | Your OpenRouter API key (sk-or-...) |
GATEWAY_TOKEN |
Yes | auto-generated | Secret token for CLI → gateway communication. Auto-set by setup.sh. |
OPENROUTER_BASE_URL |
No | https://openrouter.ai/api/v1 |
OpenRouter API base URL |
OPENROUTER_MODEL |
No | openrouter/auto |
Default model for all agents. Any OpenRouter model works. |
SEARXNG_URL |
No | http://localhost:8080 |
SearXNG endpoint (host-side). Inside containers it's always http://searxng:8080. |
GATEWAY_URL |
No | http://localhost:18789 |
OpenClaw gateway URL for the CLI on the host |
The claw binary is symlinked to /usr/local/bin/claw by setup.sh (host-side). Inside containers it's at /usr/local/bin/claw.
claw init # Initialize a fresh dashboard.jsonclaw dashboard # Pretty-print the full dashboard
claw feed # Recent activity feed (last 20 events)
claw squad # Agent status tableclaw task:create "Title" "Description" [--priority critical|high|medium|low] [--assign lead|dev|designer|marketer]
claw task:view <taskId> # Full task detail with comments and subtasks
claw task:status <taskId> <status> # Update status: todo|pending|in_progress|review|done|blocked
claw task:assign <taskId> <agent> # Reassign task
claw task:comment <taskId> "text" # Add a comment
claw tasks [--agent <name>] [--status <status>] # List tasks with optional filtersclaw subtask:add <taskId> "Subtask title"
claw subtask:progress <taskId> <subtaskId>
claw subtask:check <taskId> <subtaskId> # Toggle completeclaw deliver <taskId> <path> "Description" [--by <agent>]
claw deliverables [<taskId>] # List deliverables (task-specific or all)claw heartbeat <agent> # Trigger an immediate heartbeat for an agent
claw notify <agent> "message" [--from <sender>] # Send a message to an agentclaw business:set "Your SaaS description and ICP" # Set business context for agents
claw business:get # Show current business contextclaw check [<agent>] # No arg: health check. With agent: poll tasks + notificationsclaw check does an HTTP check first; OpenClaw is WS-first. If this reports unreachable, use docker exec claw-gateway openclaw agents list as the authoritative check.
make setup # Run setup.sh
make up # Start containers
make down # Stop containers
make restart # Restart gateway only
make build # Rebuild images (--no-cache)
make logs # Follow gateway logs
make logs-all # Follow all service logs
make status # docker ps + claw squad
make squad # claw squad
make tasks # claw tasks
make feed # claw feed
make hb-lead # Trigger lead heartbeat
make hb-dev # Trigger dev heartbeat
make hb-designer # Trigger designer heartbeat
make hb-marketer # Trigger marketer heartbeatclaw/
├── cli/
│ └── claw # Bash CLI (symlinked to /usr/local/bin/claw)
├── docker/
│ └── gateway/
│ ├── Dockerfile
│ └── entrypoint.sh # First-run init, workspace setup, skill install
├── scripts/
│ ├── setup.sh # Bootstrap: .env, data dirs, SearXNG config
│ └── init-workspaces.sh # Create agent workspaces from committed definitions
├── config/
│ ├── config.json # OpenClaw config copied to /data/config/config.json
│ └── dashboard.json # Dashboard seed copied to /data/shared/dashboard.json
├── workspaces/
│ ├── shared/
│ │ └── WORKING.md # File lock table + agent status
│ ├── lead/
│ │ ├── SOUL.md # Lead identity and principles
│ │ ├── HEARTBEAT.md # What Lead does every 15 minutes
│ │ ├── AGENTS.md # How to use claw CLI and subagents
│ │ ├── MEMORY.md # Persistent memory seed
│ │ └── .claude/agents/ # Subagent definitions (dev, designer, marketer)
│ ├── dev/
│ │ ├── SOUL.md
│ │ ├── HEARTBEAT.md
│ │ └── MEMORY.md
│ ├── designer/
│ │ ├── SOUL.md
│ │ ├── HEARTBEAT.md
│ │ └── MEMORY.md
│ └── marketer/
│ ├── SOUL.md
│ ├── HEARTBEAT.md
│ └── MEMORY.md
├── skills/
│ └── searxng/
│ └── SKILL.md # SearXNG search skill (installed into all agents)
├── agent-management.md # Step-by-step add/remove agent guide
├── data/ # Git-ignored; created by setup.sh
│ ├── config/ # OpenClaw state + runtime config.json
│ ├── shared/ # dashboard.json, memory, deliverables
│ ├── product/ # The actual SaaS codebase
│ ├── workspace-lead/
│ ├── workspace-dev/
│ ├── workspace-designer/
│ └── workspace-marketer/
├── docker-compose.yml
├── Makefile
├── .env.example
└── .gitignore
Each agent wakes up on schedule, reads HEARTBEAT.md for instructions, then:
- Checks
claw tasks --agent <self>for assigned work - Picks up
in_progressortodotasks - Works on the task (writes to
/data/product/or their workspace) - Registers deliverables with
claw deliver - Updates task status with
claw task:status - Updates
shared/WORKING.mdwith their current status
Lead reads the task board, creates subtasks, and uses its .claude/agents/ subagent definitions to spawn Dev, Designer, or Marketer as parallel Claude subagents. Each subagent gets the full task context, works in the shared product volume, and returns results to Lead for review.
All agents have the SearXNG skill available. They call it to research competitors, find design inspiration, look up SEO data, or fetch technical documentation — all through the local SearXNG instance with no external tracking.
- Both ports (
18789,8080) are bound to127.0.0.1— not exposed to the internet. Use a reverse proxy (nginx, Caddy) with auth if you need remote access. GATEWAY_TOKENis generated bysetup.shvia/dev/urandomand stored in.env(git-ignored).- SearXNG runs with
cap_drop: ALLand only the minimum capabilities re-added. - The
.envfile and alldata/directories are git-ignored.