# Metaverse — Project Summary

**One-liner**: Claude Code (and other AI agents) talk to Metabase in natural language via an MCP server.

---

## Infrastructure

- **3 Docker services**: Postgres 16 (data) + Metabase (analytics UI) + Python MCP server
- **Seed database** with 4 tables: `customers`, `products`, `orders`, `gift_cards` — 200/30/800/120 rows respectively, spanning 2 years of realistic data
- **`just up`** starts everything; **`just setup`** runs first-time Metabase config (creates admin + API key)

---

## MCP Tools (24 total)

| Group | Tools |
|-------|-------|
| Schema | `list_databases`, `list_tables`, `describe_table` |
| Queries | `run_query`, `list_questions`, `get_question`, `create_question`, `update_question`, `execute_question`, `delete_question` |
| Dashboards | `list_dashboards`, `get_dashboard`, `create_dashboard`, `add_card_to_dashboard`, `remove_card_from_dashboard`, `update_card_on_dashboard` |
| Alerts | `list_alerts`, `create_alert`, `delete_alert` |
| Metrics | `list_metrics`, `get_metric`, `create_metric`, `archive_metric`, `execute_metric` |

All responses are normalized (consistent `{id, name, ...}` shapes) to minimize token usage.

**Visualization support** — `create_question` and `update_question` accept a `display` parameter:
`"table"` (default) · `"scalar"` · `"bar"` · `"line"` · `"area"` · `"pie"` · `"row"` · `"combo"`

Optional `visualization_settings` dict passes through to Metabase for axis labels, colors, column ordering, etc.

**Metrics** — MBQL aggregations (Metabase v0.49+) tied to a specific table and field. `describe_table` returns `id` on each field for use with `create_metric`. Aggregation types: `count`, `sum`, `avg`, `distinct`, `min`, `max`.

---

## Claude Skills (5 total)

| Skill | What it does |
|-------|-------------|
| `/metaask [question]` | Answers a data question → markdown table + one-line summary |
| `/metaquery [description]` | Builds, validates, and saves a reusable SQL question |
| `/metaboard [description]` | Creates 3–6 saved questions and assembles them into a dashboard |
| `/metalert [condition]` | Finds or creates a metric question, then sets up a threshold alert |
| `/metametric [description]` | Creates or explores a reusable MBQL metric on a table field |

Each skill runs in a forked agent context with only the relevant MCP tools allowed.

---

## Python Server

- **FastMCP** over HTTP at `localhost:8000/mcp` — same transport works for local Claude Code, Claude Desktop (via ngrok), and future Slack/GitHub bots
- **`client.py`**: lazy singleton `httpx.AsyncClient`, auth via `X-API-KEY` header, uniform error raising
- **`config.py`**: all settings from env vars / `.env` (`METABASE_URL`, `METABASE_API_KEY`, `MCP_HOST`, `MCP_PORT`)

---
