Self-hosting

Earshot runs on Vercel (dashboard / MCP / docs / site) + Supabase (Postgres / Storage / Auth) + the host customer's chosen LLM/transcription providers (Anthropic + Groq today). Self-hosting is a fork-and-deploy.

Local development

git clone https://github.com/earshot/earshot
cd earshot
pnpm install
supabase start         # Postgres on :54322, Storage + Auth on :54321

Apply migrations:

supabase db reset

Or apply them ad-hoc (no CLI needed) via a one-off script — see the MEMORY.md snapshot for the pattern.

Boot the apps in parallel:

pnpm -F @earshot/dashboard dev    # :3000
pnpm -F @earshot/mcp dev          # :3001
pnpm -F @earshot/docs dev         # :3002
pnpm -F @earshot/site dev         # :3003
pnpm -F @earshot/widget dev       # :5173 (Vite dev harness)

Or pnpm dev from the root (turbo runs them concurrently).

Required env

Drop these into apps/dashboard/.env.local (the dashboard reads them, plus MCP inherits the few it needs at boot):

# Supabase
SUPABASE_URL=http://host.docker.internal:54321
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:54322/postgres

# LLM / transcription
ANTHROPIC_API_KEY=sk-ant-...       # enrichment LLM (Sonnet) — title + summary per submission
GROQ_API_KEY=gsk_...               # Whisper batch transcription
DEEPGRAM_API_KEY=                   # optional, streaming path (Cloudflare Worker)

# Dashboard client-side
NEXT_PUBLIC_EARSHOT_API_URL=http://localhost:3000
NEXT_PUBLIC_EARSHOT_PROJECT_KEY=pk_dev_test_xxxxxxxxxxxxxxxx

# Encryption + auth
INTEGRATION_ENCRYPTION_KEY=<32 bytes hex>
OAUTH_JWT_SIGNING_KEY=<32 bytes hex>

# Optional
RESEND_API_KEY=re_...               # transactional email; logs + no-ops if unset
RESEND_FROM="Earshot <feedback@your-domain.com>"
INNGEST_EVENT_KEY=                  # background retry layer
SENTRY_DSN=                         # error tracking

Generate the AES + JWT keys:

node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"

OrbStack / Docker note

In dev we run from a Linux container while Supabase runs on the Mac. The container reaches the Mac via host.docker.internal (OrbStack alias for 0.250.250.254). The dashboard's .env.local already uses that host. If you're not on OrbStack, swap to localhost.

Migrations

SQL under supabase/migrations/:

File What
0001_init.sql Core tables (teams, projects, feedback, integrations, oauth) + pgvector + pg_trgm + hnsw index
0002_rls.sql Row-level security policies
0003_audio_bucket.sql audio Storage bucket (private, audio + image MIME whitelist, 50 MiB)
0004_clarify_sessions.sql Per-session async progress row (legacy name; tracks transcribe + enrich + ingest)
0005_project_contexts.sql Project brief + revision audit
0006_integration_events.sql Integration test status + audit log
0007_screenshot_url.sql feedback.screenshot_url
0008_screenshot_session.sql clarify_sessions.screenshot_path
0009_v2_dashboard.sql Saved views + sidebar pinning tables
0010_perf_indexes.sql Hot-path FK indexes (team_members.user_id, projects.team_id, etc.)
0011_feedback_summary_trgm.sql GIN trigram index on feedback.summary for related-feedback similarity
0012_clarify_sessions_async_state.sql Async lifecycle columns (status, feedback_id, error_message, pending_user_text/audio_path)

Applied via supabase db reset or by piping each file through psql.

Production deploy (Sprint 5)

Surface Where
Dashboard Vercel project at dashboard.earshot.dev
API Same Vercel project, /v1/* and /api/*
MCP Vercel project at mcp.earshot.dev (Hono on Edge)
Widget CDN cdn.earshotbot.com/v1/earshot.iife.js — currently the dashboard Vercel project via a host-scoped Next.js rewrite. Future move to Cloudflare R2 + Worker is DNS-only; URL stays.
Docs Vercel project at docs.earshot.dev
Site Vercel project at earshot.dev
Postgres + Storage + Auth Supabase project at supabase.earshot.dev
Email Resend with DKIM-verified sender
Background jobs Inngest cloud

infra/vercel/{dashboard,mcp}.json ship the per-project configs.

Tests

Five suites:

pnpm test:e2e:api         # voice → Groq → DB → federation → tracker
pnpm test:e2e:mcp         # 17 MCP tools incl. integrations
pnpm test:e2e:onboarding  # signup → team → project → submit → patch
pnpm test:e2e:oauth       # DCR → consent → JWT → MCP user tools
pnpm test:e2e:ui          # Playwright UI specs

All five run against the local dev stack and pass green.