A terminal-based product status dashboard for heads of product. Provides a real-time, AI-assisted view of team progress, workload, sprint health, and business metrics — aggregated from GitHub, Notion, Grafana, PostHog, and SigNoz.
Two binaries communicate over a local HTTP API:
cmd/server— REST API server. Manages the SQLite database, syncs data from external sources, runs AI analysis pipelines, and serves all data endpoints.cmd/tui— Bubble Tea terminal UI. Connects to the server and renders the dashboard views.
cmd/server → :8081 (REST API + MCP endpoint)
cmd/tui → connects to localhost:8081
- Org overview — cross-team sprint health, workload, and AI-generated concerns
- Team view — sprint details, goals, workload by member (in work-days), velocity, and business metrics
- On-demand sync — pull latest data from all sources on demand
- Discovery — scan connected sources and tag items to teams/purposes
- AI analysis — sprint concerns, goal alignment, and workload summaries via Claude (cached by input hash)
- Annotations — per-item and per-team notes that persist across sprints
- Config TUI — manage teams, members, sources, annotations, and users from the terminal
- MCP server — expose all dashboard data to Claude Desktop or any MCP client via
/mcp
- Go 1.21+
- GitHub personal access token (for GitHub connector)
- Notion integration token (for Notion connector)
- Anthropic API key or
claudeCLI binary (for AI analysis) - Optional: Grafana, PostHog, SigNoz tokens for metrics
Create a .env file in the project root:
GITHUB_TOKEN=ghp_...
NOTION_TOKEN=secret_...
# Optional metrics sources
GRAFANA_TOKEN=...
GRAFANA_BASE_URL=https://your-grafana.example.com
POSTHOG_API_KEY=phc_...
POSTHOG_HOST=https://app.posthog.com
SIGNOZ_API_KEY=...
SIGNOZ_BASE_URL=https://your-signoz.example.com
Copy and edit the example config:
cp config.example.yaml config.yaml
Edit config.yaml:
server:
port: 8081
storage:
path: ./dashboard.db
auth:
jwt_secret: <random string>
admin_username: admin
admin_password_hash: "" # see below
ai:
provider: anthropic # or: claude-code
model: claude-opus-4-6
api_key: "" # required for anthropic provider
binary_path: claude # required for claude-code provider
mcp:
api_key: "" # static Bearer token for /mcp; leave empty to disable auth
AI providers:
anthropic— direct API calls usingapi_keyclaude-code— invokes theclaudeCLI subprocess (no API key needed)
go run ./cmd/server hash-password
# Enter password at prompt, then paste the output into config.yaml auth.admin_password_hash
# Build both binaries
go build -o bin/dashboard-server ./cmd/server
go build -o bin/dashboard-tui ./cmd/tui
# Start the server
./bin/dashboard-server -config config.yaml
# In another terminal, start the TUI
./bin/dashboard-tui
Or run directly without building:
go run ./cmd/server -config config.yaml
go run ./cmd/tui
- Log in with your admin credentials in the TUI login screen.
- Go to Config > Teams and create your teams and add members.
- Go to Config > Sources and run Discover to scan your GitHub repos and Notion pages.
- Tag discovered sources to teams and purposes.
- Trigger a Sync to pull the latest data.
- Browse the org overview and team dashboards.
The server exposes a Model Context Protocol endpoint at /mcp (Streamable HTTP transport). This lets Claude Desktop — or any MCP-compatible client — query your dashboard data conversationally.
| Tool | Args | Description |
|---|---|---|
list_teams |
— | All teams with IDs and member counts. Start here. |
get_org_snapshot |
— | Cross-team sprint progress, risk levels, workload, and goal alignment. |
get_team_status |
team_id |
Full status for one team: sprint, goals, concerns, workload, velocity, metrics. |
get_team_members |
team_id |
Roster with roles, GitHub usernames, and Notion user IDs. |
search_annotations |
team_id?, query? |
Search manual annotations and flags across the system. |
get_sync_status |
team_id? |
When data was last refreshed per team. |
trigger_sync |
scope, team_id? |
Start a data refresh. Returns a sync_run_id to poll. |
The server must be reachable from the machine running Claude Desktop. On the same machine, use localhost. Over a private network (e.g. Tailscale), use the hostname directly — HTTP is fine since Tailscale encrypts traffic at the network layer.
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"dashboard": {
"command": "npx",
"args": [
"mcp-remote",
"http://<host>:8081/mcp",
"--header",
"Authorization:Bearer <your-mcp-api-key>",
"--allow-http"
]
}
}
}
Replace <host> with localhost or your server's hostname (e.g. a Tailscale name), and <your-mcp-api-key> with the value from config.yaml mcp.api_key. The --allow-http flag is required for non-localhost URLs; omit it if connecting to localhost.
Restart Claude Desktop after editing the config. The tools appear in Settings → Developer.
Set mcp.api_key in config.yaml to a random string. The endpoint requires Authorization: Bearer <key> on every request. Leave the key empty to disable authentication (only appropriate on a fully trusted network).
Users are managed by admins in the Config > Users TUI section. Two roles are available:
view— read-only access to all dashboardsedit— full access including sync, config, and annotations
There is no self-registration.
| Source | What it provides | Env vars |
|---|---|---|
| GitHub | Issues, PRs, sprint workload | GITHUB_TOKEN |
| Notion | Sprint docs, goals, team annotations | NOTION_TOKEN |
| Grafana | Infrastructure/product metrics | GRAFANA_TOKEN, GRAFANA_BASE_URL |
| PostHog | Product analytics | POSTHOG_API_KEY, POSTHOG_HOST |
| SigNoz | Observability metrics | SIGNOZ_API_KEY, SIGNOZ_BASE_URL |
cmd/
server/ main entry point for the API server
tui/ main entry point for the terminal UI
discover/ diagnostic CLI for inspecting discovered sources
internal/
api/ HTTP handlers, router, and MCP server
ai/ AI generator interface (Anthropic + Claude Code providers)
auth/ JWT, bcrypt, bootstrap
config/ YAML config and .env loading
connector/ External source clients (GitHub, Notion, Grafana, PostHog, SigNoz)
pipeline/ AI analysis pipelines (concerns, goals, workload, velocity, alignment, team status)
store/ SQLite store and migrations
sync/ Sync engine, discovery, classification, and homepage extraction
tui/ Bubble Tea app, views, and HTTP client
- JWT access tokens (1-hour expiry) + refresh tokens (30-day expiry)
- Bcrypt password hashing
- All API endpoints except
/auth/loginand/auth/refreshrequire a valid JWT /mcpuses a separate static API key (see above)
# Run tests
go test ./...
# Run with race detector
go test -race ./...