npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-metabase-experimental

v0.3.0

Published

Experimental agent-oriented CLI for driving a Metabase instance.

Readme

agent-metabase-experimental

Experimental. CLI for driving a Metabase instance.

agent-metabase is an agent-oriented command-line interface to the Metabase HTTP API. It's designed to be called by scripts, LLM agents, and CI jobs:

  • JSON by default when stdout is piped; human-readable tables in a TTY.
  • Deterministic — no interactive prompts. All inputs come from flags, files, or stdin.
  • Scriptable — stdin/stdout chain cleanly with pipes, and http/batch provide escape hatches to any endpoint that doesn't have a dedicated command.
  • Two independent auth contexts — a TARGET instance you read and write against, and an optional SOURCE instance you mirror from.

Install

npm install -g agent-metabase-experimental
agent-metabase --version

Requires Bun ≥ 1.0. The installed binary is agent-metabase (not the package name).

Auth

The CLI talks to up to two independent Metabase instances:

  • TARGET — what every command reads from and writes to by default.
  • SOURCE — a separate instance (often production) you mirror from into a workspace. Used by workspace download …, workspace list/get/create/update/delete, workspace provision/unprovision, and workspace bootstrap. Credentials never cross-fall-back: a missing SOURCE cred hard-errors rather than silently reusing TARGET.

Create API keys at Admin → Settings → Authentication → API Keys.

Environment variables

Read from .env in the working directory or the shell environment:

| Variable | Alias | Role | Required for | |-------------------------------|--------------------|-------------------------------------------|--------------| | METABASE_URL | MB_URL | TARGET URL | all commands | | METABASE_API_KEY | MB_API_KEY | TARGET API key | all commands | | METABASE_SESSION | MB_SESSION | TARGET session (alternative to API key) | optional | | METABASE_SOURCE_URL | MB_SOURCE_URL | SOURCE URL | workspace SOURCE commands | | METABASE_SOURCE_API_KEY | MB_SOURCE_API_KEY| SOURCE API key | workspace SOURCE commands | | METABASE_SOURCE_SESSION | MB_SOURCE_SESSION| SOURCE session (alternative to API key) | optional |

Example .env:

METABASE_URL="http://localhost:3000"
METABASE_API_KEY="mb_your_target_key"

METABASE_SOURCE_URL="https://prod.metabase.example.com"
METABASE_SOURCE_API_KEY="mb_source_read_only_key"

Flag overrides

Every command accepts:

  • --url, --api-key — override TARGET creds
  • --source-url, --source-api-key — override SOURCE creds (on SOURCE commands)

Resolution order: flags → environment variables → .env in the working directory. Missing TARGET creds fail with a clear error; missing SOURCE creds hard-error without falling back to TARGET.

Verify:

agent-metabase ping
# ok  user=Alice <[email protected]> id=1 admin=true

Output format

Every command supports:

  • --format [auto|json|text] — default auto.
  • --json — shorthand for --format json.

In auto, output is JSON when stdout is piped and a human-readable table when it's a TTY (for list-style commands). Exit codes are consistent:

  • 0 — success
  • 1 — API error (network, HTTP 4xx/5xx, validation, task failure, polling timeout)
  • 2 — config or usage error (missing creds, bad flag)

Commands that accept a body or SQL (query, http, batch, license set) read from stdin when it isn't a TTY, so piping in files just works:

cat my-query.sql | agent-metabase query --db-id 2

Command reference

Every group has --help:

agent-metabase --help
agent-metabase <group> --help
agent-metabase <group> <command> --help

Connectivity & discovery

agent-metabase ping                                  # verify auth
agent-metabase search "revenue" --models card,dashboard --limit 20
agent-metabase activity recents --limit 10
agent-metabase activity popular

Collections

agent-metabase collection list
agent-metabase collection get 42                     # or 'root' / 'trash'
agent-metabase collection items 42 --models card,dashboard --pinned-state is_pinned
agent-metabase collection tree
agent-metabase collection create "New folder" --parent-id 42

Alias: coll.

Cards (questions & models)

agent-metabase card list --f mine
agent-metabase card get 57
agent-metabase card query 57 --limit 20                       # preview rows
agent-metabase card query 57 --format csv > export.csv        # raw CSV
agent-metabase card query 57 --format xlsx > export.xlsx      # raw XLSX
agent-metabase card query 57 --parameters '[{"type":"category","value":"A","target":["variable",["template-tag","c"]]}]'
agent-metabase card create --body '{"name":"x","dataset_query":{...},"display":"table","visualization_settings":{}}'
agent-metabase card archive 57

card query supports --format rows|json|csv|xlsx. rows gives a table preview capped at --limit; json returns the full /api/dataset payload with metadata; csv/xlsx stream raw bytes to stdout.

Dashboards

agent-metabase dashboard list --f mine
agent-metabase dashboard get 12
agent-metabase dashboard items 12
agent-metabase dashboard create "Weekly metrics" --collection-id 42

Alias: dash.

Databases, tables, fields

agent-metabase db list
agent-metabase db get 2 --include tables.fields
agent-metabase db metadata 2                         # full schemas/tables/fields
agent-metabase db schemas 2
agent-metabase db schema-tables 2 public
agent-metabase db sync-schema 2                      # trigger schema sync
agent-metabase db rescan-values 2                    # rescan cached field values

agent-metabase table list --db-id 2
agent-metabase table get 101
agent-metabase table metadata 101                    # fields + FKs
agent-metabase table fields 101
agent-metabase table update 101 --body '{"display_name":"Users"}'

agent-metabase field get 9001
agent-metabase field values 9001
agent-metabase field summary 9001
agent-metabase field update 9001 --body '{"description":"Customer tier"}'

Alias: db for database.

Ad-hoc queries

# SQL via flag, file, stdin, or positional
agent-metabase query --db-id 2 --sql "SELECT count(*) FROM orders"
agent-metabase query --db-id 2 --file ./q.sql --format csv > out.csv
cat q.sql | agent-metabase query --db-id 2

# MBQL
agent-metabase query --db-id 2 --mbql '{"type":"query","query":{"source-table":101}}'

# Parameters + template tags (native only)
agent-metabase query --db-id 2 --sql "SELECT * FROM x WHERE y = {{y}}" \
  --template-tags '{"y":{"id":"t","name":"y","display-name":"y","type":"text"}}' \
  --parameters '[{"type":"category","value":"foo","target":["variable",["template-tag","y"]]}]'

--format rows|json|csv|xlsx; --limit caps the rows preview (default 100).

Transforms

agent-metabase transform list
agent-metabase transform get 3
agent-metabase transform run 3                       # auto-polls until done
agent-metabase transform run 3 --no-wait             # fire and return
agent-metabase transform runs --limit 20 --transform-id 3
agent-metabase transform get-run <run-id>
agent-metabase transform cancel 3

transform run polls every 2s (configurable with --interval) up to --timeout ms (default 10 min). Exits non-zero on failed or timeout.

Alias: tx.

Segments, snippets, documents

agent-metabase segment list
agent-metabase segment get 5

agent-metabase snippet list
agent-metabase snippet get 8

agent-metabase document list
agent-metabase document get 17                       # alias: doc

Settings

agent-metabase setting list                          # admin-only
agent-metabase setting get remote-sync-branch
agent-metabase setting set remote-sync-branch '"main"'   # value is parsed as JSON when possible

If --value parses as JSON it's sent as that value; otherwise it's sent as a raw string.

Users & activity

agent-metabase user current
agent-metabase user list --include-deactivated
agent-metabase user get 3

agent-metabase activity recents --limit 10
agent-metabase activity popular

Remote sync

Drives the EE /api/ee/remote-sync endpoints that tie a Metabase instance to a git branch.

agent-metabase sync status                           # rollup: dirty state, current task, branch
agent-metabase sync is-dirty
agent-metabase sync has-remote-changes
agent-metabase sync dirty                            # list dirty objects

agent-metabase sync import --branch main             # repo → Metabase (auto-polls)
agent-metabase sync import --branch main --force     # discard dirty changes (LOSSY)
agent-metabase sync export -m "update dashboards"    # Metabase → repo (auto-polls)
agent-metabase sync stash --new-branch wip           # export to a new branch

agent-metabase sync current-task
agent-metabase sync cancel-task
agent-metabase sync wait --timeout 300000            # poll an in-flight task

agent-metabase sync branches
agent-metabase sync create-branch feat/x

sync import/sync export poll every 2s until the task leaves running. Exits non-zero if the final status is errored, conflict, or timed-out.

Escape hatches: raw HTTP and batched calls

Use these for endpoints that don't have a dedicated command.

agent-metabase http /api/card/57                     # GET (default)
agent-metabase http /api/card -X POST --body '{...}'
agent-metabase http /api/card/57 -X PUT --file patch.json
agent-metabase http /api/search -q '{"q":"revenue","models":["card"]}'
agent-metabase http /api/card/57.csv --raw           # print response as raw text
cat body.json | agent-metabase http /api/card -X POST

batch runs many calls in one invocation, sharing auth and base URL:

cat <<EOF | agent-metabase batch
[
  { "method": "GET",  "path": "/api/card/57", "id": "card" },
  { "method": "GET",  "path": "/api/card/58", "id": "other" },
  { "method": "POST", "path": "/api/card/57/query", "body": {}, "id": "rows" }
]
EOF

agent-metabase batch --file steps.json --parallel        # fan out
agent-metabase batch --file steps.json --bail            # stop on first error (sequential only)

Each step yields {id?, ok, status, data?, error?}. batch exits non-zero if any step fails.

Provisioning a local Metabase from a source

workspace commands let you stand up a local Metabase jar preloaded with metadata, cached field values, and config from a source instance. There are two modes: end-to-end bootstrap and per-step.

End-to-end

The easiest path. Requires an EE source instance with Workspaces enabled and an absolute path to a metabase.jar.

agent-metabase workspace bootstrap my-workspace \
  --jar "$PWD/metabase.jar" \
  --databases '[{"database_id":2,"input_schemas":["raw_github"]}]' \
  --source-url https://prod.example.com --source-api-key mb_source_key

# open http://localhost:3000

This will, in order:

  1. Create the workspace on the source (or reuse it with --reuse-existing).
  2. Provision every attached database, polling until :provisioned.
  3. Scaffold ./my-workspace/ with agent-metabase.yaml, .env, .gitignore.
  4. Download metadata.json, field-values.json, config.yml into that dir.
  5. Write a .env that points TARGET at http://localhost:<port> using the API key from the config bundle, and preserves your SOURCE creds.
  6. Run a license preflight against the metastore (skip with --skip-license).
  7. Launch the jar detached, then poll /api/health until ready.

Per-step

If you want explicit control:

agent-metabase workspace init ./my-workspace --jar "$PWD/metabase.jar"
cd ./my-workspace
# edit .env with TARGET + SOURCE credentials (see auth table above)

agent-metabase workspace create "my-workspace" \
  --databases '[{"database_id":2,"input_schemas":["raw_github"]}]'
agent-metabase workspace provision <id> --wait

agent-metabase workspace download all --id <id>
# writes metadata.json, config.yml, field-values.json at the workspace root

agent-metabase workspace instance start
# open http://localhost:3000

workspace instance start spawns the jar with MB_TABLE_METADATA_PATH, MB_FIELD_VALUES_PATH, MB_CONFIG_FILE_PATH, and MB_DB_FILE pointed at the downloaded files, so the instance seeds from source on first boot. Use --skip-metadata, --skip-field-values, or --skip-config to omit any one.

Operating the child jar

agent-metabase workspace instance status              # not-started | starting | ready | exited
agent-metabase workspace instance logs -n 200         # tail the jar log
agent-metabase workspace instance stop                # SIGTERM via pid file
agent-metabase workspace instance current             # which workspace is this jar running?
agent-metabase workspace instance remappings          # schema input → output map

Local CLI state lives under the workspace root:

agent-metabase.yaml        # CLI config
.env                       # creds & ports
metadata.json              # MB_TABLE_METADATA_PATH
field-values.json          # MB_FIELD_VALUES_PATH
config.yml                 # MB_CONFIG_FILE_PATH
<prefix>-metabase.db.mv.db # MB_DB_FILE (H2)
.metabase-instance.pid     # jar PID
.metabase-instance.log     # jar stdout/stderr

Inspect what the jar will see:

agent-metabase workspace config show
agent-metabase workspace config paths

Managing workspaces on the source

agent-metabase workspace list
agent-metabase workspace get <id>
agent-metabase workspace status <id>                  # per-database provisioning state
agent-metabase workspace update <id> --name "new name"
agent-metabase workspace unprovision <id> --wait      # must be :unprovisioned before delete
agent-metabase workspace delete <id>

provision/unprovision are async; pass --wait to poll every 3s (up to --timeout, default 10 min) until every database reaches the target state.

Alias: ws.

License token

EE features that the child jar needs (Workspaces, config-text-file, etc.) require a license token. The license group stores it with user-only (0o600) permissions in ~/.agent-metabase/license.json and injects it into the child jar as MB_PREMIUM_EMBEDDING_TOKENthe token value never appears in arguments, flags, or output.

# Set (token from stdin only — avoids shell history)
echo "$MY_TOKEN" | agent-metabase license set

agent-metabase license status                         # is a token stored?
agent-metabase license status --check                 # also validate against metastore
agent-metabase license apply                          # apply to already-running TARGET
agent-metabase license clear                          # remove stored token

license status --check returns plan, features, and expiry without ever printing the token value. workspace instance start runs a preflight against the metastore before spawning the jar and errors if required features are missing; use --skip-preflight or --skip-license to bypass.

license apply is only needed for Metabase instances you didn't launch through workspace instance start — when you did, the token was already injected via env var.

More

  • Full command list: agent-metabase --help
  • Source & issues: https://github.com/metabase/agent-metabase
  • License: Apache 2.0