drobek / docs

Overview

README.md at v0.5.2 · View on GitHub · Markdown

On this page
  1. Choose where to run it
  2. See what people build
  3. Build your first app
  4. The loop
  5. Core concepts
  6. Self-host quickstart
  7. Connect your agent
  8. Develop locally
  9. Versions and upgrades
  10. Extend drobek: write a module
  11. Contributing
  12. Documentation
  13. License

The drobek pixel mascot

CI Release License: AGPL-3.0 Image

Open-source hosting for small web apps your own AI agent builds.

Bring Claude, Claude Code, Cursor or Codex. Your agent connects over MCP, writes the app directly into a workspace and gets compile feedback and a live preview. You decide when to publish. Platform modules supply sign-in, data, forms, e-mail, uploads and external APIs; a dashboard gives you control over the app, its users and its secrets.

Try drobek.app · Self-host · Gallery · Docs

Choose where to run it

Get started
drobek.app The maintainer's hosted instance. Sign in and connect your agent.
Your own server Run the same public image with Postgres, Redis and Caddy. Follow the self-host quickstart, then connect your agent to your server's /mcp endpoint.

The core is AGPL-3.0. Building, testing and self-hosting need no access to the private repository that operates drobek.app. The agent plugins are MIT and can connect to either instance.

See what people build

These are public apps on drobek.app. Browse the gallery for more examples.

Build your first app

  1. Choose an instance above and connect your agent.

  2. Ask for a small app, for example:

    Build a shift planner for our team on drobek.
    Let people sign in and see their own shifts.
    Give me a preview to try before publishing.
    
  3. Open the preview, ask for changes, then ask the agent to publish when ready.

Apps run in the browser. Their backend comes from installed platform modules; arbitrary app server code and per-app npm install are outside the execution model. For your own backend integration, write a platform module.

The loop

  1. Connect drobek to your agent (an MCP server with OAuth — you approve it in the browser).
  2. Ask for an app: "a shift planner for our warehouse". The agent calls create_app and gets a compiling starter plus a briefing of the rules.
  3. It calls write_files. drobek compiles the files in-process with esbuild and returns the compile errors in the same response; the agent fixes them and writes again. Every write is an immutable version.
  4. Each successful compile is live at once on the app's preview host, https://<slug>--preview.<APPS_DOMAIN> — the agent hands you the link.
  5. When you are happy, the agent calls publish and the version goes live on https://<slug>.<APPS_DOMAIN> (or your own domain). Publishing an older version is the rollback.

Why it is built this way:

Core concepts

Agent plugins and platform modules do different jobs. A plugin teaches your agent how to build on drobek. A module runs on the drobek server and adds backend capabilities for apps. Installing a plugin does not install server modules. See the repository and compatibility map.

Self-host quickstart

What you need:

Every command runs as root (or prefix sudo).

1. Docker, git and go-task

curl -fsSL https://get.docker.com | sh
apt-get install -y git openssl
snap install task --classic
docker compose version     # → Docker Compose version v2.x (or newer)
task --version             # → Task version: v3.x

2. The drobek files (the compose file, the scripts, the env template — the image itself comes from GHCR)

git clone https://github.com/freema/drobek /opt/drobek
cd /opt/drobek
git checkout "$(git tag -l 'v*' --sort=-v:refname | head -n 1)"   # the newest release (skip before the first one)

3. Configuration — generates every secret, writes .env.production (mode 600), renders deployments/Caddyfile with the image's own generator (no Node on the host):

DOMAIN=drobek.example.com APPS_DOMAIN=apps.example.net \
TLS_ACME_EMAIL=you@example.com SUPERADMIN_EMAIL=you@example.com \
SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=no-reply@example.com \
EMAIL_FROM=no-reply@example.com \
task selfhost:init

Expected output (abridged):

✓ created .env.production from .env.production.example (mode 600)
✓ generated POSTGRES_PASSWORD
✓ generated DROBEK_MASTER_KEY
✓ generated TLS_ASK_TOKEN
✓ dashboard https://drobek.example.com · apps https://<slug>.apps.example.net
✓ TLS mode for the app hosts: on-demand
✓ rendered deployments/Caddyfile (on-demand)
✓ docker compose config: OK

Then put the SMTP password in (never on the command line):

nano .env.production       # SMTP_PASS='…'   (single quotes if it has $, # or spaces)

task selfhost:init never asks anything and never overwrites a secret; run it again whenever you like (after changing TLS settings: then task tls:reload). The TLS default for a real domain is on-demand (one Let's Encrypt certificate per app host, gated by drobek); TLS_MODE=wildcard-file or TLS_MODE=dns pick a wildcard certificate instead — see "TLS" in docs/SELF-HOSTING.md.

4. Start

docker compose --env-file .env.production -f docker-compose.production.yaml up -d --wait

The first start pulls the images and drobek applies every database migration. Expected: Container drobek-prod-postgres-1 Healthy, …-redis-1 Healthy, …-drobek-1 Healthy, …-caddy-1 Healthy.

curl -s https://drobek.example.com/healthz      # → {"ok":true,"db":"up","redis":"up"}
curl -s https://drobek.example.com/api/version  # → {"name":"drobek","sha":"<commit>","version":"vX.Y.Z","commitTime":"…","startedAt":"…","modules":[…]}

Tip: alias dc='docker compose --env-file .env.production -f docker-compose.production.yaml' — the rest of this guide spells the command out.

5. Sign in — open https://drobek.example.com, enter your SUPERADMIN_EMAIL, type the 6-digit code from the e-mail. You land on /me with a personal workspace.

6. Connect an agent (Claude Code)

claude mcp add --transport http drobek https://drobek.example.com/mcp

Claude Code discovers drobek's OAuth server, opens the consent page in your browser (read, write, publish) and gets a token bound to you. Without a browser on the agent's machine, mint an API key on the server instead and pass it as a header:

docker compose --env-file .env.production -f docker-compose.production.yaml exec drobek \
  node node_modules/@drobek/oauth/dist/cli/api-key-create.js \
  --email you@example.com --name laptop --scopes read,write,publish
# → drk_…   (shown once)
claude mcp add --transport http drobek https://drobek.example.com/mcp \
  --header "Authorization: Bearer drk_…"

7. Publish an app — ask the agent: "Build a tip calculator on drobek and publish it." It calls create_app → write_files → publish; open the published_url it returns (https://tip-calculator.apps.example.net). With on-demand TLS the very first request to a new app host waits a few seconds for its certificate.

A test box without DNS — the same steps with Caddy's local CA:

DOMAIN=localhost SUPERADMIN_EMAIL=you@example.com SMTP_HOST=… task selfhost:init   # → TLS mode internal
docker compose --env-file .env.production -f docker-compose.production.yaml up -d --wait
docker compose --env-file .env.production -f docker-compose.production.yaml cp \
  caddy:/data/caddy/pki/authorities/local/root.crt ./drobek-root.crt
curl --cacert drobek-root.crt https://localhost/healthz

Trust drobek-root.crt in your browser / OS to use it without warnings (Node clients: NODE_EXTRA_CA_CERTS=drobek-root.crt). App hosts are https://<slug>.apps.localhost, which browsers resolve to the machine itself. HTTPS_PORT=8443 (plus HTTP_PORT=8080) moves Caddy off 443 — every URL then carries the port.

Backups (task backup / task restore), upgrades (task selfhost:upgrade), the three TLS paths, custom domains, abuse handling and every setting: docs/SELF-HOSTING.md.

Connect your agent

The MCP endpoint is <PUBLIC_APP_URL>/mcp (OAuth 2.1; the client discovers, registers and asks for your consent by itself). Scopes: read, write, publish; the token is bound to you and reaches every workspace you belong to, with your role in each.

The agent gets twenty-four tools — list_apps, create_app, duplicate_app, get_app, read_file, write_files, restore_version, publish, set_gallery_listing, skill_info, configure_module, query_data, get_logs, for video, audio, images and fonts create_asset_upload, list_assets, delete_asset (an upload URL — the file never passes through the model), and for custom domains list_domains, add_domain, verify_domain, set_primary_domain, remove_domain, and for the proxy module's external APIs list_upstreams, register_upstream, remove_upstream (a super-admin also gets set_workspace_publishing). The full agent contract (scopes, the briefing, skills, /llms.txt) is docs/AGENT.md; a running server serves it at /llms.txt, /llms-full.txt and /build-with-your-agent. To teach an agent the loop without the plugin: cp -r skills/drobek ~/.claude/skills/drobek.

Develop locally

Prereqs: Docker (compose v2) for the stack; go-task 3, Node 22 and pnpm 10 for the host-side task check / task e2e.

git clone https://github.com/freema/drobek && cd drobek
cp .env.example .env
# Two edits make it yours (the rest have working dev defaults):
#   1. SUPERADMIN_EMAIL  → the email you'll sign in with (becomes super-admin)
#   2. DROBEK_MASTER_KEY → a real key:  openssl rand -hex 32
task dev          # or: docker compose up -d --build
Service Host port Check
drobek (dashboard + OAuth AS + MCP /mcp) 3041 GET /healthz → {ok,db,redis} (503 when a dependency is down); GET /health → {ok:true}
postgres 17 5441 pg_isready
redis 7 6391 redis-cli ping
mailpit (dev SMTP sink) 8025 the login codes land here

The dev stack runs every built-in module plus the example drobek-module-hello. Sign in at localhost:3041 (the code is in Mailpit), then point your agent at http://localhost:3041/mcp.

Opening apps locally. APPS_DOMAIN=apps.localhost:3041, and browsers resolve every *.localhost name to your machine — nothing to add to /etc/hosts:

Host Serves
http://<slug>--preview.apps.localhost:3041 the newest version that compiled
http://<slug>.apps.localhost:3041 the published version ("not published yet" until the first publish)
http://<slug>--v<N>.apps.localhost:3041 exactly version N

curl and Node do not resolve *.localhost everywhere; send the app host in the Host header instead:

curl -i -H 'Host: <slug>--preview.apps.localhost:3041' http://127.0.0.1:3041/

Browsers refuse __Host- cookies on plain http://localhost, so the http dev stack (NODE_ENV ≠ production) uses the unprefixed, still host-only drobek_session / drobek_app_access / drobek_eu; production and every https origin use the __Host- names. task dev:tls runs the dev stack behind Caddy on https://localhost with its local CA. For scripts without an OAuth flow: task api-key:create EMAIL=you@example.com NAME=laptop SCOPES=read,write.

Everyday commands:

task dev          # build + start the stack, wait until healthy
task check        # host-side gate: install, doc-lint, build packages + app bundle, typecheck, lint, knip, unit tests
task logs         # tail the drobek service
task health       # curl the health endpoints
task e2e          # Playwright suite (incl. @local specs) vs the stack
task e2e:image    # what CI runs: the prod image behind Caddy + the whole suite
task e2e:smoke    # @smoke specs only (safe against any target, prod included)
task build        # build the production image ghcr.io/freema/drobek:<sha>
task prod:proof   # build + prove the prod image (size, non-root, fail-closed, live boot)
task dev:tls      # dev stack behind Caddy (tls internal); task dev:tls:down to leave
task db:generate  # drizzle-kit generate (journal __drizzle_migrations_core)
task down         # stop the stack (docker compose down -v also wipes the data)

Contributor rules and the repository map: CLAUDE.md. Public repositories, agent plugins versus server modules, and the external consumer check: docs/ECOSYSTEM.md.

End-to-end tests

tests-e2e is one Playwright suite with two tiers:

mcp-loop.spec.ts is the agent loop end to end: the official MCP SDK client with an OAuth provider (401 → discovery → DCR → PKCE consent driven by Playwright → token), then list_apps → create_app → write_files (compile error → fix) → preview host → publish → production host → restore_version → get_app, asserted under 90 s.

task e2e runs against the dev stack (task dev). task e2e:image is the CI flow (.github/workflows/ci.yml runs the same scripts/e2e-image.sh): build the production image, start it with docker-compose.e2e.yaml (project drobek-e2e, its own loopback ports, so it runs next to the dev stack) behind Caddy with tls internal on https://localhost:8443 and https://<slug>--preview.apps.localhost:8443, let it migrate a fresh DB, then run @smoke + @local and tear everything down. DROBEK_IMAGE=… skips the build, E2E_KEEP=1 keeps the stack, extra args go to Playwright (task e2e:image -- tests/mcp-loop.spec.ts).

Versions and upgrades

drobek follows semantic versioning; while it is at 0.x, a minor release may need an operator step, and its release notes say which. Every release is a git tag vX.Y.Z, an immutable image ghcr.io/freema/drobek:vX.Y.Z, a GitHub release and an entry in CHANGELOG.md; latest and previous move with each release (docs/SELF-HOSTING.md → Image tags). Migrations only go forward and run as their own step of task selfhost:upgrade; a rollback is the previous image plus, when the release migrated the database, the backup taken before it (Upgrades and rollback). Modules declare the contract range they need, and the server refuses to start with a module it cannot satisfy (docs/MODULES.md → Compatibility).

Extend drobek: write a module

An app's backend is a set of platform modules, and anyone can write one: an npm package against the published contract, installed by the operator without building an image.

npm create drobek-module@latest erp   # routes, SDK slice, migration, SKILL.md, tests

The contract is on npm as @freema/drobek-modules; the scaffold installs it under the name module code imports, @drobek/modules ("@drobek/modules": "npm:@freema/drobek-modules@^X.Y.Z").

docs/MODULES.md → Writing a module walks through the contract, publishing and installing; examples/drobek-module-hello is a working one, and Published modules lists the modules others can install.

Contributing

Issues, questions and pull requests are welcome — see CONTRIBUTING.md. Questions and ideas go to Discussions; security issues are reported privately (SECURITY.md).

Documentation

Document What
docs/ARCHITECTURE.md one process, origins, versions, the compiler, serving, modules, TLS, jobs
docs/SELF-HOSTING.md the quickstart, compose, every environment variable, TLS, backups, upgrades, custom domains, abuse
docs/MODULES.md the platform module contract and the built-in modules
docs/AGENT.md connecting agents, the tools and scopes, the briefing, skills, llms.txt
docs/SECURITY.md the threat model and how to report a vulnerability
docs/LICENSING.md AGPL-3.0 §13 and the boundary with the hosted drobek.app
CHANGELOG.md every release

License

AGPL-3.0 — see docs/LICENSING.md.