metabase-react-sdk-setup

First-time setup for the Metabase React SDK — instance detection, API key, dashboard discovery, JWT auth, SDK installation, and initial embedding code.

Skill file

Preview skill file
---
name: metabase-react-sdk-setup
description: First-time setup for the Metabase React SDK — instance detection, API key, dashboard discovery, JWT auth, SDK installation, and initial embedding code.
---

Use this skill for any task involving `@metabase/embedding-sdk-react` — whether that's initial setup, embedding dashboards, theming, or plugins.

**Communication style**: Be concise. Do one step at a time. When asking the user for input, output only the question — do not explain upcoming steps, implementation details, or what you plan to do next. The user does not need a roadmap.

> **CRITICAL — YOU MUST GET AN API KEY BEFORE DOING ANYTHING ELSE**
>
> Step 1 asks the user for a Metabase URL and API key. You CANNOT proceed without both.
> Do NOT detect the Metabase version, fetch `llms.txt`, install packages, or write ANY code until the user has given you an API key.
> Do NOT attempt to call any Metabase API endpoint without an API key — it will return 401 and you will be guessing.
> If any Metabase API call returns 401, STOP everything and ask the user for an API key.

## Step 1 — Get the Metabase URL and API key

You need a Metabase instance URL and an admin API key before anything else.

**`.env.metabase` is only for admin tasks within this skill** (API calls to Metabase). It is NOT the app's runtime config. Never import, read, or reference `.env.metabase` from the user's application code or build config. The app's instance URL goes in the user's own `.env` file (e.g., `VITE_METABASE_URL`, `NEXT_PUBLIC_METABASE_URL`) — set that up in Step 4.

Check if `.env.metabase` exists in the project root and already has both `METABASE_INSTANCE_URL` (non-empty) and `METABASE_ADMIN_API_KEY` (non-empty). If so, skip to Step 2.

Otherwise, create the file and gitignore it:

```bash
grep -qxF '.env.metabase' .gitignore 2>/dev/null || echo '.env.metabase' >> .gitignore
printf 'METABASE_INSTANCE_URL=\nMETABASE_ADMIN_API_KEY=\n' > .env.metabase
```

Then output **only this message** — no preamble, no explanation of what comes next, no implementation details:

> I created `.env.metabase` in the project root. Please fill in both values:
>
> 1. Set `METABASE_INSTANCE_URL` to your Metabase URL (e.g. `http://localhost:3000`)
> 2. Open `{your URL}/admin/settings/authentication/api-keys`, create a new API key
> 3. Set `METABASE_ADMIN_API_KEY` to that key
> 4. Let me know when you're done

Do **not** guess or assume the instance URL. Do not pre-fill `localhost:3000`. Do not ask the user to paste the key in the chat — it should only go in `.env.metabase`. Wait for the user to confirm, then proceed to Step 2.

## Step 2 — Detect version and discover dashboards

Now that you have an API key, detect the version and find dashboards.

### 2a — Detect version

```bash
source .env.metabase && \
  curl -s "$METABASE_INSTANCE_URL/api/session/properties" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY" | grep -o '"tag":"[^"]*"'
```

Parse both the **edition** and the **major version** from the tag:

| Tag format | Edition         | Example                     |
| ---------- | --------------- | --------------------------- |
| `v0.X.Y`   | OSS (Community) | `v0.60.1` → major `60`, OSS |
| `v1.X.Y`   | Enterprise (EE) | `v1.60.1` → major `60`, EE  |

If major version < 49, tell the user the Embedding SDK requires Metabase 49+ and stop.

**If the tag starts with `v1.`, the instance is Enterprise Edition — use full JWT SSO embedding.** Do not fall back to guest embedding or any OSS-only auth path.

Remember the major version number — you will need it in Step 3.

### 2b — Enable the Embedding SDK

Automatically enable the SDK so the user doesn't have to toggle it manually in the admin panel:

```bash
source .env.metabase && \
  curl -s -X PUT "$METABASE_INSTANCE_URL/api/setting/enable-embedding-sdk" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"value": true}'
```

If this returns an error (e.g., 403), tell the user to enable it manually at **<INSTANCE_URL>/admin/settings/embedding** and move on.

**Do NOT fetch `llms.txt` yet.** You need dashboard IDs first.

### 2c — Find dashboards and table candidates

Run both of these:

```bash
source .env.metabase && \
  curl -s "$METABASE_INSTANCE_URL/api/search?models=dashboard&archived=false" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY"
```

```bash
source .env.metabase && \
  curl -s "$METABASE_INSTANCE_URL/api/automagic-dashboards/database/1/candidates" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY"
```

Filter and prioritize the results:

- **Exclude** any dashboards from the "Usage analytics" collection — those are internal Metabase admin dashboards, not user content.
- **Deprioritize** anything from the "Sample Database" — prefer the user's own databases and dashboards.
- Pick the **top 5** most relevant to what the user asked for from each category. Do not dump every result.

Format like this:

> **Existing dashboards:**
>
> 1. Sales Overview (ID 3)
> 2. Customer Analysis (ID 7)
>    ...
>
> **Or I can create a new dashboard from your data:**
> A. Orders table
> B. Products table
> ...
>
> Which ones should I embed? (e.g. "1 and 3" or "A")

Wait for the user to pick. If they choose a table, generate and save the X-ray dashboard:

```bash
source .env.metabase && \
  DASHBOARD=$(curl -s "$METABASE_INSTANCE_URL/api/automagic-dashboards/table/<TABLE_ID>" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY")

source .env.metabase && \
  curl -s "$METABASE_INSTANCE_URL/api/dashboard/save" \
    -H "X-API-Key: $METABASE_ADMIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "$DASHBOARD"
```

The save response contains the persisted dashboard with a real `id` field. Use these IDs going forward.

## Step 3 — Fetch docs, set up auth, and install SDK

You MUST have real dashboard IDs before reaching this step. If you don't, go back to Step 2.

**Now** fetch the versioned docs index using the major version from Step 2a:

```bash
curl -s https://www.metabase.com/docs/v0.<MAJOR>/llms.txt
```

Fall back to `https://www.metabase.com/docs/latest/llms.txt` if empty. This contains correct prop names, auth config shapes, SDK install commands, and breaking changes for this version. Do not fetch `llms-embedding-full.txt` (too large).

### 3a — Set up JWT SSO authentication (skip if already done)

Follow the auth setup instructions in `llms.txt`. In particular:

- Retrieve the JWT signing secret from Metabase: **Settings → Admin → Embedding → Embedding secret key**
- Tell the user to save it as `METABASE_JWT_SECRET` in their server-side environment only (never a browser-accessible env var)
- Ask which backend framework they are using (Next.js API route, Express, Fastify, etc.) and scaffold a minimal JWT signing endpoint following the pattern in `llms.txt`

### 3b — Install the SDK (skip if already installed at correct version)

Check whether `@metabase/embedding-sdk-react` is already in the user's `package.json`.

- If not installed: use the install command from `llms.txt` (the correct dist-tag matches the instance major version).
- If already installed: verify the major version matches. Warn on mismatch and offer to update.

## Step 4 — Generate embedding code

Use `llms.txt` as the authoritative reference for all API shapes. **Write files directly into the user's project** — edit existing files in place rather than creating new ones alongside them.

### Code conventions (override anything in the docs)

- **JWT SSO only**: API keys grant admin-level access and are not safe for end-user embeds. Use a server-side JWT signing endpoint; `MetabaseProvider` receives its URL. Never generate `apiKey`, `METABASE_API_KEY`, `api-key`, or `x-api-key` — not even as a placeholder. Deviate only if the user explicitly asks and acknowledges the security risk.
- **Instance URL from env**: `VITE_METABASE_URL` (Vite), `NEXT_PUBLIC_METABASE_URL` (Next.js), etc. Never hardcode.
- **Dashboard IDs as inline literals**: always hardcode dashboard IDs directly in JSX — e.g. `<InteractiveDashboard dashboardId={7} />`. Dashboard IDs are not secrets. **Never** use `import.meta.env.VITE_METABASE_DASHBOARD_*`, env vars, config objects, `parseDashboardId` helpers, or any indirection for dashboard IDs. The goal is clean, minimal code the user can instantly understand and tweak.
- **Secrets server-side only**: JWT secrets must never appear in browser-accessible env vars or frontend code.

### Theming

After generating the embedding code, inspect the user's app for existing styles — look at CSS variables, Tailwind config, or theme files. Set the `theme` prop on `MetabaseProvider` to match the app's look and feel. At minimum, align:

- `colors.brand` — the app's primary/accent color
- `colors.background` — to match the page background so the embed doesn't look like a white box on a dark page (or vice versa)
- `fontFamily` — to match the app's font

Refer to `llms.txt` for the full theme shape. Keep it minimal — only set values that differ from Metabase defaults.

Source

Creator's repository · metabase/agent-skills

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk