A Flutter app for developers who use AI tools: Codex, Claude Code, etc.
Uses local SQLite (~/.ensemble/ensemble.db) for local persistence. Uses Supabase to find other users who are active now. Logs users in with X.com/GitHub accounts.
Uses MCP protocol and subagents to:
- find other developers who use the same OS, frameworks, versions
- lets them know each other about their X.com handles
- lets them chat using https://github.com/flyerhq/flutter_chat_ui
- lets developers record hard-to-find solutions that were solved by their AI in more than medium effort in order to help developers who are using the same stack
- Flutter 3.x
- Node.js 18+ (development only, for rebuilding MCP runtime)
cp mcp/.env.example mcp/.env
# edit mcp/.env with your real SUPABASE_URL and SUPABASE_ANON_KEYcd mcp && npm ci && npm run buildcd app && flutter run -d macosThe app auto-writes canonical MCP config at ./.mcp.json.
./.mcp.json is portable and secret-free:
- it runs
./mcp/bin/ensemble-mcp - secrets remain in
mcp/.env
Optional: you can still override values via CLI:
--dart-define=SUPABASE_URL=... --dart-define=SUPABASE_ANON_KEY=...
For release distribution (including Mac App Store), prefer compile-time values:
flutter build <platform> --release --dart-define=SUPABASE_URL=... --dart-define=SUPABASE_ANON_KEY=...
Sign in with your X account. Then use the Sync button in the Stack tab to publish your stack to Supabase.
app/ Flutter macOS app
mcp/ MCP server (Node.js/TypeScript)
website/ Static landing page
supabase/ Edge functions + migrations
Static landing page is in website/.
- Run locally:
cd websitecp .env.example .envnpm installnpm run dev
- Configure waitlist frontend with env vars:
- required:
SUPABASE_URL - required:
SUPABASE_ANON_KEY - optional:
WEBSITE_YOLO_URL
- required:
Waitlist backend uses:
- Migration:
supabase/migrations/023_waitlist_subscribers.sql - Edge function:
waitlist-subscribe
GitHub Pages deploy workflow:
.github/workflows/website-pages.yml- build env:
- repo variable:
SUPABASE_URL - repo secret:
SUPABASE_ANON_KEY - repo variable (optional):
WEBSITE_YOLO_URL
- repo variable:
For end users, do not require npm at runtime. Package these artifacts:
mcp/dist/*mcp/bin/ensemble-mcp(andmcp/bin/ensemble-mcp.cmd)mcp/node_modules/*(production-only deps, includingbetter-sqlite3)- optional bundled Node runtime at
mcp/runtime/node/*
At runtime, MCP uses ./mcp/bin/ensemble-mcp, which prefers bundled Node and falls back to system node.
GitHub Actions workflow: .github/workflows/release-builds.yml
It builds release artifacts for:
- macOS
- Linux
- Windows
Each artifact includes:
- packaged Flutter app
- MCP runtime (
mcp/dist,mcp/bin,mcp/node_modules) mcp/.env(from CI secrets if provided, otherwise copied from.env.example)- bundled Node runtime in
mcp/runtime/node - helper scripts to register MCP with Claude/Codex
Set these repository secrets to preconfigure production builds:
SUPABASE_URLSUPABASE_ANON_KEY
These same secrets are injected into Flutter build as --dart-define values,
which is the standard way for sandboxed release apps to access non-secret config.
Minimal-friction path:
- Claude Code: project-level
.mcp.jsonis auto-written by the app. In Claude, run/mcp reload. - Codex: one-time CLI registration is still needed (
codex mcp add ...) unless already configured.
When adding MCP servers via CLI, pass Supabase values as server env (-e/--env),
so MCP does not depend on reading .env from restricted filesystem locations.
Packaged artifacts include helper scripts:
- macOS/Linux:
enable-mcp-claude.sh,enable-mcp-codex.sh - Windows:
enable-mcp-claude.cmd,enable-mcp-codex.cmd
These helper scripts read mcp/.env and pass SUPABASE_URL / SUPABASE_ANON_KEY
to Claude/Codex MCP registration via -e/--env.
codex mcp remove ensemble
claude mcp remove ensemble -s user