Agent Native

dashboard-expert

This skill analyzes, builds, modifies, and adds explainer text to Mixpanel dashboards using the mixpanel_headless Python library.

by MixpanelOfficial publisher

Identity proven by GitHub's verified organisation badge (mixpanel)

Agents
Claude Code
License
MIT (permissive)
Pin
fbed0c5pinned Oct 9, 2026
Context cost
about 2,800 tokenswhen the skill loads
GitHub stars
18on mixpanel/mixpanel-headless
Scripts
None found

What it does

“Analyzes, builds, modifies, and adds explainer text cards to Mixpanel dashboards with the mixpanel_headless Python library. It reads a dashboard's layout and runs every report on it, creates dashboards with text cards and a grid layout, edits cells and rows in place, and writes data-driven explainer cards. Use when the user asks to analyze, summarize, explain, build, create, redesign, update, reorganize, or clean up a Mixpanel dashboard; asks about dashboard layout, rows, cell widths, text cards, or which chart type suits a board; or wants to turn queries into reports placed on a dashboard. Do not use for general analytics questions or one-off queries (use mixpanelyst), or for what a specific user did in a session recording (use session-replay).”
The author's description, from SKILL.md

Generated summary from the skill's own text

This skill analyzes, builds, modifies, and adds explainer text to Mixpanel dashboards using the mixpanel_headless Python library. It reads dashboard layouts, runs reports, creates and edits cells and rows in a 12-column grid, and generates data-driven text cards. Use it when the user requests dashboard analysis, creation, redesign, reorganization, or wants to turn queries into dashboard reports.

When to use it

  • Analyze, summarize, or audit an existing Mixpanel dashboard and its reports
  • Build or create a new Mixpanel dashboard from scratch with multiple reports
  • Modify, reorganize, add cells, or update an existing dashboard layout
  • Add explainer text cards with insights below dashboard charts

When not to

  • General analytics questions or one-off ad hoc queries without dashboard context
  • Session recording or user session behavior analysis

Install

These commands install from the publisher's repository and need no account.

skills CLI

npx skills add mixpanel/mixpanel-headless --skill dashboard-expert

Installs from the repository's default branch, which may have changed since the commit we checked.

GitHub CLI 2.90 or later

gh skill install mixpanel/mixpanel-headless dashboard-expert@fbed0c596f6856a705e54ef528c03e943527410d

Installs the commit we checked (fbed0c5).

Copy by hand

Download the folder at fbed0c5 and put it in .claude/skills/dashboard-expert for Claude Code and in .agents/skills/dashboard-expert for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.

Skill folder on GitHub at fbed0c5

Copy for your agent

A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.

Prompt

Install the agent skill "dashboard-expert" by Mixpanel.

Source, pinned to commit fbed0c596f6856a705e54ef528c03e943527410d:
https://github.com/mixpanel/mixpanel-headless/tree/fbed0c596f6856a705e54ef528c03e943527410d/mixpanel-plugin/skills/dashboard-expert

1. Download that folder at exactly this commit. Do not use the default branch.
2. Copy every file unchanged, keeping the folder structure, into .claude/skills/dashboard-expert/ for Claude Code and .agents/skills/dashboard-expert/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist.
3. Do not edit the files, and do not run any script in the folder unless I ask you to.
4. When you are done, list the files you copied and where you put them.

Listing and checks: https://www.agentnative.dev/skills/mixpanel/dashboard-expert

SKILL.md at the pin

---
name: dashboard-expert
description: >-
  Analyzes, builds, modifies, and adds explainer text cards to Mixpanel dashboards with the
  mixpanel_headless Python library. It reads a dashboard's layout and runs
  every report on it, creates dashboards with text cards and a grid layout,
  edits cells and rows in place, and writes data-driven explainer cards. Use
  when the user asks to analyze, summarize, explain, build, create, redesign,
  update, reorganize, or clean up a Mixpanel dashboard; asks about dashboard
  layout, rows, cell widths, text cards, or which chart type suits a board;
  or wants to turn queries into reports placed on a dashboard. Do not use for
  general analytics questions or one-off queries (use mixpanelyst), or for
  what a specific user did in a session recording (use session-replay).
allowed-tools: Bash(${CLAUDE_PLUGIN_DATA}/venv/bin/python *) Bash(${CLAUDE_PLUGIN_DATA}/venv/bin/mp *) Bash(mp --version) Bash(mp help) Bash(mp help *) Bash(uv run *) Read Write Edit WebFetch(domain:mixpanel.github.io)
---

# Dashboard Expert

Analyze, build, modify, and explain Mixpanel dashboards with `mixpanel_headless`. A dashboard is a list of rows. Each row holds one to four cells on a 12-column grid. A cell is a report (owned by this dashboard), a report link (owned by another dashboard, read-only), or a text card (HTML).

Run code with the plugin's Python environment: `${CLAUDE_PLUGIN_DATA}/venv/bin/python script.py` or `${CLAUDE_PLUGIN_DATA}/venv/bin/python -c "..."`. Always write that full literal path, never a shell variable such as `$CLAUDE_PLUGIN_DATA`, because a variable expands to nothing in the shell and the command is denied.

If that interpreter path fails, the environment is not set up. Do not check again with `ls`, `which`, or shell variables; those checks are denied and prompt the user. Instead:

1. Ask the user to run `/mixpanel-headless:setup` before any analysis code.
2. For look-ups until then, run the bare command `mp --version` on its own (the `mp` on `PATH`, not the plugin path).
3. If it shows 0.4.0 or later, use the bare `mp help <query>` for look-ups only.

A denial of some other command does not mean Bash is blocked, so still try the bare `mp --version`.

Do not run analysis code with a Python or `mp` found on `PATH`, because its library version is unknown. The one other route is the user's own project: if it already has `mixpanel_headless` (for example a uv project), `uv run python` works.

## Pick the mode

| User intent | Mode | Steps |
|---|---|---|
| Analyze, read, understand, audit a dashboard | **Analyze** | Read the layout, run each report, summarize by section |
| Build, create, make a new dashboard | **Build** | Check the data, plan the sections, create with rows in one call, pin |
| Modify, add to, fix, reorganize a dashboard | **Modify** | Read the current state, plan the changes, apply them in the fixed order |
| Explain a dashboard, add insights or explainer cards to it | **Explain** | Analyze, compute key numbers, insert explainer cards |

The reading guide at the end says which reference to read for each mode. Show the user a plan before you create or change a dashboard. A dashboard is shared team state, and a wrong layout is slow to undo.

## Quick start: analyze a dashboard

```python
import datetime
import re
import mixpanel_headless as mp

ws = mp.Workspace()
end = datetime.date.today()
start = end - datetime.timedelta(days=90)
dash = ws.get_dashboard(DASHBOARD_ID)
layout, contents = dash.layout, dash.contents

# Rows -> cells -> content items
for row_id in layout["order"]:
    for cell in layout["rows"][row_id]["cells"]:
        cid, ctype = str(cell["content_id"]), cell["content_type"]
        if ctype in ("report", "report-link"):
            info = contents["report"][cid]
            tag = " [linked]" if ctype == "report-link" else ""
            print(f"[{cell['width']}w] {info['name']} ({info['type']}){tag}")
        elif ctype == "text":
            md = contents["text"][cid].get("markdown", "")
            header = " [SECTION]" if re.search(r"<h2[\s>]", md, re.I) else ""
            print(f"[{cell['width']}w] TEXT{header}: {md[:60]}")

# Run each report -> DataFrame
for cid, info in contents.get("report", {}).items():
    btype, bid = info["type"], info["id"]
    if btype == "flows":
        result = ws.query_saved_flows(bid)
    elif btype == "funnels":
        # Without dates, a saved funnel runs over the last 30 days.
        result = ws.query_saved_report(
            bid, bookmark_type="funnels", from_date=start.isoformat(), to_date=end.isoformat()
        )
    else:
        result = ws.query_saved_report(bid, bookmark_type=btype)
    print(f"{info['name']}: {len(result.df)} rows, columns={list(result.df.columns)}")
```

## Quick start: build a dashboard

```python
import json
import mixpanel_headless as mp
from mixpanel_headless.types import CreateDashboardParams, DashboardRow, DashboardRowContent

ws = mp.Workspace()
dau = ws.query("Login", math="dau", last=90)
signups = ws.query("Sign Up", math="total", last=90)


def text(html):
    return DashboardRowContent(content_type="text", content_params={"markdown": html})


def report(name, btype, result):
    return DashboardRowContent(
        content_type="report",
        content_params={"bookmark": {
            "name": name, "type": btype, "params": json.dumps(result.params),
        }},
    )


dashboard = ws.create_dashboard(CreateDashboardParams(
    title="Product Health",
    description="Core metrics.",
    rows=[
        DashboardRow(contents=[text("<h2>Product Health</h2><p>Core metrics, last 90 days.</p>")]),
        DashboardRow(contents=[
            report("DAU (90d)", "insights", dau),
            report("Signups (90d)", "insights", signups),
        ]),
    ],
))
ws.pin_dashboard(dashboard.id)  # new dashboards are not visible to the team until pinned
```

`rows` places every cell in one call, and the cells in a row share the 12 columns evenly. Check each result before you add it: skip a report whose `result.df` is empty, because an empty chart on a shared board looks like a bug.

## Mode steps in short

**Analyze.** Read the structure (quick start above). Group cells into sections: a text card with an `<h2>` starts a section. Run every report and extract the key numbers for its type. Look for links between reports, for example a DAU trend against a retention curve. Present an overview, a section-by-section summary, cross-report findings, and suggestions.

**Build.** Check that each candidate event has volume. Pick a template from `references/templates.md` and map its placeholders to real events. Present the plan. Query each metric, then create the dashboard with `rows` in one call. Pin it. Open it and confirm every report renders.

**Modify.** Read the current state first and show it to the user. Classify each change. Apply the changes in the order in gotcha 3. Read the dashboard again between layout changes, because row and cell IDs change.

**Explain.** Run the analyze steps. For each report, compute the latest value and the change against a baseline from `result.df`. Insert a short explainer card under the chart it explains. The card patterns and the HTML rules are in `references/text-cards.md`.

## Gotchas

These 14 rules come from failures against the live Mixpanel API. The library does not check most of them for you.

1. **Send `content` and `layout` together to place a cell in an existing row.** Put both in one `UpdateDashboardParams`. With `content` alone, the new cell goes to a new full-width row at the bottom.
2. **Redistribute widths when you add to a row.** A row with N cells gets N+1 cells of width `12 // (N + 1)`, because the widths in a row must sum to 12.
3. **Apply updates in this order:** metadata, cell creates, row reorder (`rows_order`), cell updates, cell deletes, row deletes. A reorder before a create fails with an unknown row ID, and an early delete can leave gaps.
4. **`per_user` needs `math_property`.** Without it, the query raises `BookmarkValidationError` before any network call. The same is true for `math="average"`, `"median"`, and the percentiles.
5. **`CreateBookmarkParams.dashboard_id` is required, but it does not place the report on the dashboard.** Mixpanel requires every saved report to belong to a dashboard. Place a report with an inline bookmark content action or with `rows`.
6. **`add_report_to_dashboard()` clones the report.** The copy gets a "Duplicate of ..." name and a new content ID. Prefer `rows` or an inline content action.
7. **The GET layout and the PATCH layout differ.** GET returns `order` and `rows` as a dict keyed by row ID. PATCH takes `rows_order` and `rows` as a list with an `id` on each row. A patch with `order` does not reorder anything.
8. **Leave `version` out of a layout PATCH.** GET returns `"version": "2.0.0"`, and the API rejects a patch that sends it back.
9. **Remove newlines from text card HTML.** Call `.replace("\n", "").strip()` before you send it. With newlines, the editor in Mixpanel parses the HTML as markdown and garbles it.
10. **Stay inside the limits:** title 255 characters, description 400, text card 2,000 (keep it under 500), 4 cells per row, 30 rows per dashboard.
11. **An update cannot change `content_type`.** To turn a text card into a report, delete the cell, then create a new one.
12. **Report-link cells are read-only.** A `report-link` cell shows a report that another dashboard owns. You can run it, but you cannot edit its params from this dashboard.
13. **Pin a new dashboard.** A new dashboard is not visible to the team until you call `ws.pin_dashboard(dashboard.id)`.
14. **The `markdown` field takes HTML only.** Markdown syntax such as `# Heading` or `**bold**` shows as literal text. Use `<h2>` and `<strong>`.

## Look up the API before you write code

When the plugin environment exists, `mp` below means `${CLAUDE_PLUGIN_DATA}/venv/bin/mp`; run it with that full path. When it does not exist, use the bare-`mp` fallback near the top of this file.

The installed library documents itself, so do not guess a method name, a parameter, or a type field. Verify any signature with `mp help Workspace.<method>`, for example `mp help Workspace.update_dashboard`. Other useful look-ups:

- `mp help Workspace --domain dashboards` lists every dashboard method.
- `mp help Workspace --domain reports` lists the saved-report (bookmark) methods.
- `mp help CreateDashboardParams` and `mp help DashboardRow` show the fields and a worked example.

The full look-up loop is in the mixpanelyst skill. The same text is available as `${CLAUDE_PLUGIN_DATA}/venv/bin/python -m mixpanel_headless help <query>`.

## Report links

To read a report URL that the user pasted, call `ws.resolve_report_link(link)`. It returns the params and the report type, and `ws.query_report_link(link)` runs it. To give the user a URL for a report on a dashboard, call `ws.saved_report_link(bookmark_id, report_type="funnels")` with the report's type.

## Reading guide

Read a reference only when its condition is true. Each file stands alone.

| Read | When |
|---|---|
| [references/content-and-layout.md](references/content-and-layout.md) | Before you analyze or modify a dashboard, and before any `update_dashboard` call that adds, moves, resizes, or deletes a cell or row. It covers content actions, the grid, the PATCH format, operation order, report-link semantics, time filters, and duplication. |
| [references/text-cards.md](references/text-cards.md) | Before you write or change a text card, and in Explain mode. It covers the allowed HTML, the whitespace rule, and card patterns. |
| [references/report-pipeline.md](references/report-pipeline.md) | Before you build a dashboard, or when you turn query results from any engine into reports on a dashboard. It covers the build steps and the query-to-report path for insights, funnels, retention, and flows. |
| [references/templates.md](references/templates.md) | When you plan a new dashboard or a new section. It has nine templates with rows, widths, heights, text, and report specifications. Read the selection guide and "How to use these templates", then read only the chosen template's section. |
| [references/chart-types.md](references/chart-types.md) | When you pick or check a chart type, or pick a width for a chart. |

From mixpanel/mixpanel-headless at fbed0c5, shown as plain text under its license: MIT (permissive). The license text is in LICENSE.

View SKILL.md on GitHub at fbed0c5

Files

6 files, 96 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.

Skill folder on GitHub at fbed0c5
All 19 skills from Mixpanel

More from Mixpanel

  • auth

    Manages Mixpanel credentials, authentication, and account configuration for the mixpanel_headless library and mp CLI.

    Contains scripts

    Claude Code · about 3K tokens · pinned 7 days ago

  • mixpanelyst

    The skill analyzes Mixpanel data by running Python code with the mixpanel_headless library and pandas.

    Claude Code · about 4.3K tokens · pinned 7 days ago

  • session-replay

    This skill retrieves and analyzes Mixpanel session replay recordings to show what a specific user did on screen, action by action.

    Claude Code · about 2.6K tokens · pinned 7 days ago

  • setup

    This skill creates an isolated Python environment for Mixpanel analysis, installs mixpanel-headless version 0.4.0 or newer along with data science libraries…

    Contains scripts

    Claude Code · about 1.1K tokens · pinned 7 days ago

  • analyze-report

    Interprets existing Mixpanel reports and charts by re-running queries, identifying patterns, and summarizing what the data shows and what stands out.

    Claude Code, Codex, Cursor +4 · about 1.9K tokens · pinned 7 days ago

  • create-dashboard

    Creates cohesive Mixpanel dashboards by discovering event and property schemas, validating queries with real data, and arranging reports in a top-to-bottom…

    Claude Code, Codex, Cursor +4 · about 1.1K tokens · pinned 7 days ago

  • install

    This skill sets up Mixpanel integration for a project by configuring one of three engines: Mixpanel MCP server, the headless Python SDK, or the user's own…

    by MixpanelOfficial publisher

    Claude Code · about 1.2K tokens · pinned 7 days ago

  • alphagenome-single-variant-analysis

    Analyzes how genetic variants affect gene expression, chromatin accessibility, and splicing using the AlphaGenome API.

    by GoogleOfficial publisher

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 2.8K tokens · pinned 7 days ago

  • alphagenome-variant-impact-score

    Score genetic variants using AlphaGenome Variant Impact models to assess functional impact through 18 biological feature attributions.

    by GoogleOfficial publisher

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 4.1K tokens · pinned 7 days ago

  • chdb-datastore

    This skill enables working with tabular data using a pandas-compatible API backed by ClickHouse for faster execution.

    by ClickHouseOfficial publisher

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 1.2K tokens · pinned 7 days ago

  • chdb-sql

    The skill enables running ClickHouse SQL queries on local files (parquet, csv, json), remote databases (Postgres, MySQL, MongoDB, ClickHouse Cloud), and cloud…

    by ClickHouseOfficial publisher

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 960 tokens · pinned 7 days ago

  • blueprint

    Blueprint enables composing Apache Airflow DAGs from YAML templates using reusable Python task group classes with Pydantic validation.

    by AstronomerOfficial publisher

    Claude Code, Codex, Cursor +4 · about 8.3K tokens · pinned 7 days ago

Open roles at Mixpanel

3 open roles on the jobs board

The skills listed here are third-party software, collected from public GitHub repositories as a catalog of recent skills and provided as is. Agent Native does not write or control them and is not responsible for any harm, loss or damage caused by installing or using them. Labels and checks describe what we saw at one commit and are not a guarantee. Read a skill's files before you run it. Terms of use