Open source · MIT · no account

Audit your Metabase in one command.

The audit I run for clients, as a script you run yourself. Duplicate questions, dead dashboards, queries pointing at tables that no longer exist, a health grade and a cleanup list. Runs on your laptop. Your API key never leaves it.

Node 18 or newer and an Admin API key from your Metabase. Under a minute for most instances.

METALENS-REPORT.mdsample instance
C
36 / 100
Foundation needs rework.
Northwind Outdoors · 138 questions · 11 dashboards
Duplicate questions12 groups, 11 to archive
Pointing at missing tables4
Unused for 90+ days57 of 138
Dashboards mostly stale4 of 11
Core data model22 of 28 tables
$ npx metabase-audit archive --from duplicates
Dry run: 11 questions would be archived.
34 s
to scan 2,700 questions and 93 dashboards
0
bytes sent anywhere except your Metabase
2
dependencies, both for the MCP server
0.50 to 1.63
Metabase versions tested
The report

One file. Every problem, in the order to fix it.

The scan writes METALENS-REPORT.md next to where you ran it. No dashboard to log into, nothing to export. Below, three excerpts from the sample instance.

Do this first
  1. Fix 4 questions pointing at missing tables. They fail for everyone who opens them, one sits on the Executive Summary (legacy) dashboard.
  2. Archive 11 exact duplicate questions. 7 groups of structurally identical SQL. Keep one, archive the rest.
  3. Review 57 stale questions. Nobody has opened them in 90+ days.
  4. Add descriptions to 83 questions. Start with the most viewed.
  5. Review 5 groups with the same name. Same name, different query. Probably two ways to count one metric.
Duplicates, with the fix
Keep New subscribers by plan (weekly) (860 views, last used 2026-08-22)
Archive New subscribers by plan (copy) (16 views, 2026-04-15)
Archive new_subscribers_by_plan_v2 (1 view, 2025-12-24)
Archive Copy of New subscribers by plan (8 views, never)
These 4 queries are structurally identical. Keep New subscribers by plan (weekly), archive the other 3.
npx metabase-audit archive --ids 368,374,406
Dashboards and owners
DashboardStatusStaleOwner
Board KPIshealthy0/8Dana Whitfield
Support Overviewbroken2/5Jamie Okonkwo
Subscription Healthwarning5/6Marcus Oyelaran
Cohorts 2023warning4/4Priya Natarajan
Priya scratchunknown0/0Priya Natarajan
A second file: DATA-CONTEXT.md
Your schema, relationships, the 15 queries the team actually trusts, and a glossary. Under 5,000 tokens. Paste it into Claude and it knows your data.
See the sample context file
What leaves your machine

Nothing. That was the point.

Last month I offered to audit five Metabase instances for free. Nobody wanted to hand over an instance, which is fair. So the audit now runs where the instance lives.

Talks only to your Metabase
One file makes network calls, and only to the URL you gave it. No telemetry, no phone home, no MetaLens account.
Key from the environment
Read from METABASE_API_KEY, never written to disk, masked in every error message. Basic-auth proxies work too.
Everything stays as plain files
snapshot.json, findings.json and two Markdown files in your folder. Script on top of them, or delete them.
Small enough to read
Plain JavaScript, two dependencies, 240 tests. Read it in one sitting before you run it. MIT license.

The key needs to be in the Administrators group: Metabase only exposes table metadata, user names and the full question list to admins. Everything the kit does is read-only, except the archive command, which you opt into.

Cleanup, safely

Dry run first. Undo file always.

Archiving is the only thing the kit ever writes to your Metabase, and it refuses to do it by accident.

01 · PREVIEW
$ npx metabase-audit archive --from duplicates
Prints the list. Zero requests to Metabase. The question marked “keep” in a group can never be selected.
02 · APPLY
$ npx metabase-audit archive --ids 368,374,406 --apply
Writes .metalens/undo-2026-09-16T10-00-00.json before the first change, then archives. Partial failures stay visible in the file.
03 · UNDO
$ npx metabase-audit unarchive --undo .metalens/undo-… --apply
Restores every question from the undo file. Questions only in v1, never dashboards or collections.
Use it with Claude

Your Claude, your Metabase, your key.

The kit does the counting. The model you already pay for does the reading, the arguing and the writing. Three ways in, pick one.

Claude Code skills
Copy the skills folder into your project. Then say “audit my Metabase”.
metabase-audit runs it, explains it, asks before archiving
metabase-gaps which dashboards are missing
metabase-sql-review reviews a question against your schema
metabase-metric-tree North Star tree as a Mermaid diagram
MCP server
Claude Desktop, Claude Code or Cursor. Six tools, archive stays a preview unless the model passes apply: true.
{
  "mcpServers": {
    "metabase-audit": {
      "command": "npx",
      "args": ["-y", "metabase-audit", "mcp"],
      "env": { "METABASE_URL": "…", "METABASE_API_KEY": "…" }
    }
  }
}
Plain paste
Open DATA-CONTEXT.md, paste it into any chat, ask your questions. Works with any model.
# Data context: Northwind Outdoors

## Data model
#### public.orders (35 questions, ~1,284,000 rows)
- id: BigInteger [PK]
- order_number: Text
- customer_id: Integer [FK] -> customers
- placed_at: DateTime [CreationTimestamp]
…
## Trusted queries
### Net revenue by day, last 90 days
When the report is not enough

The report says what is wrong. It does not decide who is right.

Which of the three revenue definitions is the real one. Who is allowed to archive the CFO’s dashboard. What the board should look at instead of the pages nobody opens. That part is people and decisions, and a script will not do it. The Sprint is two weeks: we run this same kit with you, sit with the owners, sign off the definitions, execute the cleanup with someone accountable, and hand back the context file as a living document.

From $12,000
two weeks, fixed scope
See how the Sprint works
Nothing here is gated. The kit is complete as it is.
Questions

Before you run it

Which Metabase versions?
Tested from 0.50 to 1.63, self-hosted and Metabase Cloud. Older instances lose “last used” dates; the kit falls back to the activity log and otherwise marks those questions unknown rather than stale.
My questions are built in the query builder, not SQL.
Run scan with --compile once. Metabase compiles each GUI question to SQL, one request per question, so duplicates and missing tables are found by query text rather than by name.
How big can the instance be?
2,700 questions, 93 dashboards and 1,462 tables took 34 seconds. Dashboard details are fetched for the 300 most viewed by default.
How is this different from the hosted MetaLens?
Same engine, same score. The hosted version ran it on our servers and asked for your key. This one runs on yours and shows its source.

One command. Your laptop. Your key stays home.