haacked/dotfiles/metabase-prod-query

Claude Code and agent skill by haacked/dotfiles

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Query PostHog production Metabase. Use when the user wants prod data such as counts, distributions, customer-report debugging, or region comparisons. Not for local dev investigations; use the `posthog-db` MCP for those.

Install

npx vskill@latest install haacked/dotfiles/metabase-prod-query

SKILL.md

Metabase Prod Query

Run SQL against PostHog production Metabase via hogli metabase:*. Production Metabase sits behind ALB Cognito OAuth, so this is the only path that works (API keys won't pass the ALB).

The four underlying commands:

CommandPurpose
`hogli metabase:login --region us\eu`Opens browser, captures SSO cookies, caches at ~/.config/posthog/metabase/cookie-{region} (mode 0600)
`hogli metabase:databases --region us\eu`Lists database IDs (these change when Metabase metadata is rebuilt — refresh per session)
`hogli metabase:query --region us\eu --database-id N --file F.sql`Runs SQL against /api/dataset; cookie stays internal
`hogli metabase:cookie --region us\eu [--check]`Prints cached cookie header (humans only — NEVER use this; query reads the cookie internally)

Non-negotiables

  • This hits prod. Run a bounded read-only query without asking, and show its SQL with the results. Ask first when a query matches a trigger in step 5.
  • Never run `metabase:cookie`. That command prints credentials to the terminal/logs. The query command reads the cookie internally.
  • Use `--save PATH` for `query`. Results can be large; dumping rows into the conversation transcript bloats context and risks leaking customer data. Save to a file, then read just what you need.
  • Refresh DB IDs every session. They change when Metabase metadata is rebuilt. Run metabase:databases once at the start.
  • Never use this for local dev. Local dev uses the posthog-db MCP. This skill is prod-only.

Steps

1. Confirm scope

Parse args. Determine:

  • Region(s): us, eu, or both. If ambiguous, ask. (both means run sequentially per region.)
  • Question: what is the user trying to learn? If they passed raw SQL, use it. If they passed a question, draft SQL in step 3.

If region or intent is unclear, ask the user before doing anything.

2. Verify session

For each region in scope, check the cookie cache:

bash
test -f ~/.config/posthog/metabase/cookie-<region> && echo cached || echo missing

If missing, OR if a later command returns 301/302/401, run:

bash
hogli metabase:login --region <region>

This opens the user's default browser. Tell the user this will happen before running it.

3. Refresh database IDs

Once per session per region:

bash
hogli metabase:databases --region <region> --format json

Save the output. Note the relevant database IDs (typically posthog Postgres and replica ClickHouse, but verify by name — IDs are not stable across rebuilds). Pick the ID that matches the data the user is asking about (Postgres for app/control-plane data; ClickHouse for events/analytics).

4. Compose SQL

Write the query to a temp file under /tmp/metabase-<short-slug>-<region>.sql. Keep queries:

  • Bounded: include LIMIT (e.g., LIMIT 1000) unless the user explicitly wants a full export.
  • Time-bounded: include WHERE timestamp >= now() - interval ... (or equivalent) on event tables.
  • Read-only: this is SELECT-only. Never write DDL/DML.

For ClickHouse-flavored questions, use ClickHouse SQL (no interval '1 day' Postgres syntax — use INTERVAL 1 DAY). For Postgres, use Postgres syntax.

5. Decide whether to ask first

Ask for approval before running when any of these holds:

  • The query has no LIMIT because the user wants a full export.
  • A ClickHouse query reads events, flag_evaluations, session_replay_events, or another table of similar size, and has no time filter or a window longer than 30 days.
  • The query needs a --timeout above the 120-second default.
  • The user asked to review SQL before it runs.

If none holds, go to step 6.

To ask, display to the user, exactly:

text
Region: <us|eu|both>
Database: <name> (id <N>)
Save to: /tmp/metabase-<slug>-<region>.<tsv|json>
SQL:
<the query, indented 2 spaces>

Then ask: "Run this query against prod? Reply yes to confirm, or describe changes."

Do not proceed until the user replies yes (or equivalent confirmation). If the user requests changes, update and re-show.

6. Run the query
bash
hogli metabase:query \
--region <region> \
--database-id <id> \
--file /tmp/metabase-<slug>-<region>.sql \
--save /tmp/metabase-<slug>-<region>.tsv

For --region both, run once per region with separate --save paths.

Default format is TSV. Pass --format json only when the user needs structured output.

7. Read and summarize results

First, check the file size and shape:

bash
wc -l <file> && head -5 <file>

If the file has 50 rows or fewer, read it in full with Read. Otherwise, work from targeted extracts (head/awk/cut) to get counts, top-N rows, or specific columns rather than loading the whole file into context.

Report to the user:

  • The region, database, and SQL that ran, in the step 5 format
  • Row count
  • Top N rows (or summary stats — sums, distributions — depending on the question)
  • Anomalies worth flagging
8. Clean up (optional)

If the saved files contain potentially sensitive data and the user is done, offer to delete them:

bash
rm /tmp/metabase-<slug>-*.{sql,tsv,json}

Error handling

SymptomCauseFix
301/302 redirectCookie expired or ALB session lostRe-run metabase:login --region <region>
401 UnauthorizedCookie rejectedRe-run metabase:login --region <region>
404 on database-idDB IDs changedRe-run metabase:databases --region <region>
Query failed: ... in bodySQL errorRead the error, fix the SQL, and re-run. Ask first if a step 5 trigger applies
Non-JSON responseUpstream issueShow the raw response to the user; do not retry blindly

Notes

  • The cookie cache file is mode 0600 and lives at ~/.config/posthog/metabase/cookie-{region}. Do not cat it, copy it elsewhere, or print its contents.
  • The two production hosts are metabase.prod-us.posthog.dev and metabase.prod-eu.posthog.dev. You don't need to use them directly — hogli handles routing.
  • For long-running queries, pass --timeout <seconds> (default 120s).

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
129
Repository forks
22
7-day trend score
24

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/haacked/dotfiles/metabase-prod-query/badge)](https://verified-skill.com/skills/haacked/dotfiles/metabase-prod-query)

Something wrong with this skill or its page? Tell us.