Getting Started
This guide walks a new developer from a clean machine to a fully running Made Open hub and web app.
Quick start: If you have Docker, Node.js 20+, and the Supabase CLI installed, you can skip straight to the one-command setup:
make quickstart # Full setup + start dev servers (blocks terminal) make quickstart-bg # Full setup + start in background (non-blocking) make quickstart-infra # Setup infrastructure only, no dev serversThis checks prerequisites (Docker memory, port conflicts), installs dependencies, starts infrastructure, auto-generates the
.envfile with correct Supabase keys, applies all database migrations, and launches the dev servers.After quickstart completes, log in as demo@made-open.dev / demopassword to see pre-loaded contacts, rules, and conversations.
To simulate the call-routing demo:
make up-mock && make mock-call
1. Prerequisites
| Tool | Version | Install |
|---|---|---|
| Node.js | 20+ | nodejs.org |
| pnpm | 9+ | npm install -g pnpm@9 |
| Docker Desktop | latest | docker.com |
| Git | any recent | git-scm.com |
Optional (only needed for specific platforms):
| Tool | When needed |
|---|---|
| Supabase CLI | Required for local database setup |
| Rust + Tauri | Only for apps/windows (browser automation agent) |
| Android Studio | Only for apps/android |
Install the Supabase CLI:
# macOS / Linux
brew install supabase/tap/supabase
# Windows (winget)
winget install Supabase.CLI
# Or via npm
npm install -g supabase
2. Clone and Install
git clone https://github.com/drdropout/made-open.git
cd made-open
pnpm install
pnpm install installs all workspace dependencies for hub, web, and all packages in a single pass.
3. Environment Setup
Copy the example environment file:
cp .env.example .env
The root .env is the single source of truth for all configuration. The hub reads it directly via --env-file, and the web app auto-generates .env.local from NEXT_PUBLIC_* vars when you run pnpm dev. You only need to edit this one file.
The minimum set of variables required to start the hub locally are listed below. The defaults in .env.example are already correct for local development — you only need to supply the Supabase keys (obtained in Step 5).
| Variable | Default | Notes |
|---|---|---|
NATS_URL | nats://localhost:4222 | Already correct for Docker setup |
MEILI_URL | http://localhost:7700 | Already correct for Docker setup |
MEILI_MASTER_KEY | masterKey | Change in production |
SUPABASE_URL | http://localhost:54321 | Already correct for local Supabase |
SUPABASE_SERVICE_ROLE_KEY | (must set) | From supabase status — see Step 5 |
SUPABASE_ANON_KEY | (must set) | From supabase status — see Step 5 |
DATABASE_URL | postgresql://postgres:postgres@localhost:54322/postgres | Already correct |
JWT_SECRET | change-me-in-production-use-at-least-32-chars | Change before any real use |
PORT | 4101 | Hub HTTP port |
HUB_URL | http://localhost:4101 | Used by web app |
The NEXT_PUBLIC_* variables for the web app are also stored in root .env and auto-synced.
4. Start Infrastructure
Start NATS JetStream and Meilisearch via Docker Compose:
docker compose up -d
This starts the default (non-profiled) infrastructure services:
- NATS on port
4222(client connections) and8222(HTTP monitoring) - Meilisearch on port
7700 - Redis on port
6379(used by rate limiter / high-throughput queues) - LightRAG on port
9621(knowledge-graph bridge; requires Ollama)
The hub, web, tools, and mock-api containers are gated behind Docker Compose profiles (full, tools, mock) and are not started by a bare docker compose up -d. Use make up-full, make up-tools, or make up-mock for those.
Verify they are healthy:
# NATS
curl http://localhost:8222/healthz
# Meilisearch
curl http://localhost:7700/health
# Should return: {"status":"available"}
5. Start Supabase
Start the local Supabase stack (PostgreSQL, Auth, Storage, Studio):
supabase start
This downloads and starts all Supabase containers. First run takes a few minutes. Once running, apply all migrations:
supabase db push
To reset and re-seed demo data:
supabase db reset # Drops all data, re-runs migrations + seed.sql
The seed data includes a demo user (demo@made-open.dev / demopassword) with 18 contacts, 2 locations, 2 rules, 3 conversations, and pre-configured Twilio credentials pointing at the mock API.
After supabase start completes, it prints the service URLs and keys. Copy the service_role key and anon key values into your .env:
supabase status
# Output includes:
# API URL: http://localhost:54321
# DB URL: postgresql://postgres:postgres@localhost:54322/postgres
# Studio URL: http://localhost:54323
# anon key: eyJ...
# service_role key: eyJ...
Set SUPABASE_SERVICE_ROLE_KEY, SUPABASE_ANON_KEY, and NEXT_PUBLIC_SUPABASE_ANON_KEY in your root .env from this output. (The make quickstart command does this automatically.)
You can access Supabase Studio (table viewer, SQL editor) at http://localhost:54323.
6. Start the Hub
Run the hub in watch mode (restarts on file changes):
pnpm hub
# Equivalent to:
pnpm -F @made-open/hub dev
The hub boots all services sequentially. A successful startup looks like:
[EventBus] Connected to NATS at nats://localhost:4222
[DataService] Supabase client initialised
[PolicyService] Audit log stream ready
[PluginManager] V8 isolate pool ready
[SearchService] Meilisearch connected — indexes: persons, messages, documents
[RulesService] Rules engine ready
[ConnectorService] 1 connector plugins loaded: com.microsoft.graph
[ChannelService] 1 channel plugins loaded: io.twilio.channel
[JobQueue] pg-boss connected — queues: realtime, interactive, background
[HTTP] Fastify listening on http://0.0.0.0:4101
[Hub] All services online
7. Start the Web App
In a separate terminal:
pnpm web
# Equivalent to:
pnpm -F @made-open/web dev
The web app starts on http://localhost:4100. It connects to the hub at http://localhost:4101.
8. Verify Everything Works
Run these checks to confirm all components are up:
# Hub health check
curl http://localhost:4101/health
# Expected: {"status":"ok","version":"0.0.1"}
# Detailed health (all services)
curl http://localhost:4101/health/detailed
The /health/detailed endpoint probes real service connectivity — NATS, Meilisearch, and the database. Services show connected or disconnected status. If any service shows disconnected, check that its container is running with docker compose ps.
Demo account: Log in at http://localhost:4100 with demo@made-open.dev / demopassword to see the pre-loaded seed data.
In the browser:
- Swagger UI — http://localhost:4101/api/docs — interactive API explorer
- Web app — http://localhost:4100
- Sign up — http://localhost:4100/auth/signup
Create your first account via the sign up page. After signing in, navigate to Settings > Credentials to add integration credentials (Twilio, Microsoft Graph, etc.).
You can also check overall status with the management CLI:
bash scripts/made-open status # Health check all services
bash scripts/made-open doctor # Full environment diagnostics
9. Running Tests
# All tests
pnpm test
# Hub tests only (unit)
pnpm -F @made-open/hub test
# Hub tests in watch mode
pnpm -F @made-open/hub test:watch
# Hub integration tests (requires Docker infrastructure running)
pnpm -F @made-open/hub integration-test
10. Next Steps
Try the demo: Start the mock API and simulate the call-routing flow:
make up-mock # Start mock Twilio + MS Graph server
make mock-call # Simulate incoming call → rules fire → SMS sent
make mock-sms # Simulate incoming SMS
make mock-sync # Simulate 500-contact MS Graph sync
Debug in VS Code: The project includes shared debug configurations. Press F5 to launch the hub or web app with breakpoints. See .vscode/launch.json for all configurations.
Learn the architecture:
- Plugin Development — Build a connector or channel plugin
- SDK Usage — Integrate
@made-open/sdkinto another app - Deployment — Deploy to production
- Architecture Overview — Understand how all services fit together
- Event Catalog — All canonical NATS events and their payloads