Discourse × Metabase

How to build Discourse community dashboards in Metabase

Discourse is the open-source discussion platform that runs a large share of developer and product communities — topics, posts, categories, tags, trust levels, and badges, all in a PostgreSQL database you can host yourself. Metabase is where you turn that activity into shared, trustworthy community dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls a scoped slice with the Discourse MCP server and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands Discourse data in a database so you can build dashboards anyone can read.

Heads up: Metabase connects to databases and warehouses — it does not ship a native Discourse connector, and it never calls a SaaS API directly. The good news: members, posts, and registrations are ordinary tabular data. Land them in a database, define "active member" and "attended" once, and every dashboard downstream inherits the same definitions.

How do you connect Discourse to Metabase?

Most teams combine both routes: quick answers through MCP and CLI uploads first, then recurring community reporting on a warehouse-backed model.

Discourse is the one tool in this category where you may already own the database. Self-hosted forums put PostgreSQL right there — and the bundled Data Explorer plugin lets you run SQL through the API without touching the server at all.

1 · MCP + CLI route (AI-assisted)

Live community answers in, quick analysis out

Pair the Discourse MCP server with the Metabase CLI. Use MCP for live lookups, write a scoped result to CSV, then load it into Metabase as a ready-to-query table and model.

Best for
  • Quick questions such as "show me member growth and activation of new signups"
  • Loading Discourse exports into Metabase in seconds
  • Spot-checks and one-off questions without pipeline work
Trade-offs
  • Great for exploration, not the weekly community or event report
  • Use read-only credentials or scoped API keys wherever supported
  • CSV uploads are snapshots — refresh or move to the pipeline for history
2 · Pipeline route (warehouse-backed)

Durable community dashboards with history

Land Discourse data in a database or warehouse — via connector, scheduled API pulls, or a replica of the underlying database — then point Metabase at it.

Best for
  • Discourse dashboards the community, marketing, and support teams all trust
  • Joining community activity with product, support, and CRM data
  • Long-run trends for member growth and activation of new signups and engagement: posts, replies, and reactions over time
Trade-offs
  • You own the refresh schedule and the grain
  • Define "active member" once, in the model layer, and state the window
  • Identity matching across tools caps how far member-level analysis goes

What can you analyze from Discourse data in Metabase?

These all come from the same core objects — topics and posts, plus the users and trust levels, categories and tags, likes and reactions your sync exposes:

  • Member growth and activation of new signups
  • Engagement: posts, replies, and reactions over time
  • Community health: answered questions and response times
  • Category and tag activity, including quiet corners
  • Top contributors and contributor concentration

Which Discourse community dashboards should you build in Metabase?

For: Community managers

Membership

Who joins, and who stays.

  • New members by month (line)
  • Members who posted in the last 30 days (number + trend)
  • Activation: new members posting within 7 days (number)
  • Members by trust level (bar)
For: Community team

Engagement

Where the conversation actually happens.

  • Topics and posts per month (combo)
  • Posts by category, top 10 (bar)
  • Replies per topic distribution (bar)
  • Likes and reactions per post (line)
For: Support and docs teams

Answer quality

Whether questions get answered, and how fast.

  • Median time to first reply (line)
  • Share of topics with no reply (number + trend)
  • Topics with an accepted answer (number + trend)
  • Oldest unanswered topics (table)
For: Leadership

Contribution health

How concentrated the community is.

  • Top contributors by posts (table)
  • Share of posts from the top 10 members (number + trend)
  • First-time posters per month (line)
  • Categories with no new topic in 30 days (table)

How do you use the Discourse MCP server with the Metabase CLI?

Pair the Discourse MCP server with the Metabase CLI for fast, hands-on analysis. MCP is useful for scoped lookups and summarized exports; the Metabase CLI's upload command loads CSV data into Metabase and creates a ready-to-query table and model.

Example workflow

  • Ask the MCP server for last quarter's topics and posts summarized by category and month, with reply counts and first-reply timestamps — not raw post bodies.
  • Export the result as CSV, keeping stable IDs, timestamps, and the category, space, channel, or event keys you group by.
  • Run mb upload csv to load it into Metabase as a table and model, then build questions and dashboards on top.

Be honest about the limits

  • MCP lookups are excellent for exploration, not scheduled reporting.
  • A CSV upload is a snapshot; refresh it with mb upload replace or move to the pipeline for real history.
  • Growth and response-time trends need complete months of topics and posts — and deleted or anonymized accounts quietly rewrite historical member counts, so snapshot member totals daily instead of recomputing them from the current user table.
  • mb upload csv needs an uploads database configured under Admin → Settings → Uploads.

How do you set up Discourse MCP and the Metabase CLI?

Discourse MCP serverofficial

Transport
Local server (npx) over stdio, or `--transport http`
Auth
Anonymous read-only by default; admin or user API key for scoped access
Best for
Live scoped lookups and summarized exports

Metabase CLIofficial

Install
npm install -g @metabase/cli
Auth
mb auth login
Load data
mb upload csv --file data.csv
Requires
An uploads database (Admin → Settings → Uploads)
MCPExample MCP client config
{
  "mcpServers": {
    "discourse": {
      "command": "npx",
      "args": [
        "-y",
        "@discourse/mcp@latest",
        "--site",
        "https://forum.example.com"
      ]
    }
  }
}

Published by the Discourse team itself (@discourse/mcp, requires Node 24+). It defaults to anonymous, read-only access — writes need both --allow_writes and --read_only=false, which analytics work never does. Pass --api_key and --api_username for admin-scoped reads. There is no vendor-hosted remote endpoint: the server runs on your machine and talks to your forum over HTTPS.

TerminalLoad a Discourse CSV with the Metabase CLI
# Install the Metabase CLI
npm install -g @metabase/cli

# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com

# Load a topics-and-posts export — creates a table AND a model
mb upload csv --file discourse-topics-and-posts.csv --collection root

# Refresh that same table later from a new export
mb upload replace <table-id> --file discourse-topics-and-posts.csv

Can you generate a Discourse dashboard with AI?

Yes. Use the prompt below with any assistant that can run the Discourse MCP server and the Metabase CLI. It works end to end: if Discourse tables already exist in Metabase it analyzes those; otherwise it pulls scoped, summarized data, loads it with mb upload csv, then builds the dashboard and caveats any metric that needs missing history.

Prompt for creating a Discourse Community Overview dashboard
Create a polished Metabase dashboard for Discourse community analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.

Goal: Help community, marketing, and support leaders understand member growth, posting activity, time to first reply, unanswered topics, and contributor concentration from Discourse data.

Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for discourse tables and
  models). If durable Discourse data is already present — a warehouse sync, a
  database replica, or an earlier upload — use it and skip to Step 2.
- If nothing is there, pull a scoped, summarized export with the Discourse MCP server:
  topics and posts, plus users and trust levels, categories and tags, likes and reactions.
  Prefer summarized rollups by month, category, space, channel, or event over raw
  message and post bodies. Write each result to a CSV, then load it with the
  Metabase CLI — run "mb upload csv --file <export>.csv" so each upload creates a
  table and a ready-to-query model. Use "mb upload replace <table-id> --file
  <export>.csv" to refresh an existing table instead of creating duplicates.

Step 2 — Inspect before querying:
Do not assume exact table or column names. Inspect available fields, categories,
spaces or channels, events, and date ranges before creating trend cards.

Important:
- Build on whatever data is present; don't claim Metabase connects natively to
  Discourse — it reads a database or CLI-uploaded tables.
- Every "active member" card must state its window and its action (posted?
  logged in?) in the card title or description. There is no standard definition.
- Deleted and anonymized accounts disappear from the current member list, which
  silently rewrites historical member counts. Prefer daily snapshots over
  recomputing history.
- Attendance is unknowable without check-in data. Exclude events where nobody
  checked anyone in rather than scoring them as 0% attendance.
- A single CSV is a point-in-time snapshot: only build trend cards if there is
  a usable date column or multiple periods have been uploaded.

Dashboard title: Discourse Community Overview

Sections:
1. Executive summary: New members this month; Active members (30 days,
   stated on the card); Median time to first reply; No-reply share;
   Posts per month.
2. Membership: New members by month; activation within 7 days; trust levels.
3. Engagement: Topics and posts by month; posts by category; replies per topic.
4. Answer quality: Time to first reply; no-reply share; oldest unanswered.
5. Contribution: Top contributors; top-10 share of posts; first-time posters.

Filters: Date range, Category or Space or Channel, Event, Member segment,
Ticket type.

Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data.

How do you sync Discourse data into a database or warehouse?

For dashboards that need history and reliability, land Discourse data in a database first, then connect Metabase to that database.

Connector options

  • Managed connector or database replica — use a connector when one genuinely covers the objects you need, or replicate the underlying database when you host it yourself.
  • Custom pipeline — use the Discourse API for control over grain, fields, and refresh cadence.
  • MCP + CSV — use this for quick exploration and one-off slices.

Three real options, in rough order of preference. Self-hosting? Replicate the forum's PostgreSQL database into your warehouse and you have every table. Otherwise, run Data Explorer queries through the API on a schedule — it's bundled into Discourse core and returns query results as JSON or CSV, though CSV exports cap at 10,000 rows, so page by date. Fivetran also offers a Discourse connector, but it's an Application Lite connector: check its schema covers the objects your dashboards need before committing to it. Airbyte has no Discourse source.

Notes

  • Decide the grain first (one row per post, message, or registration; daily rollups on top) — it drives every trend card.
  • Land raw tables first, then build clean Metabase models on top of them.
  • Normalize user, topic, category, tag, created-at, and reply-to fields.

How should you model Discourse data in Metabase?

Core tables

TableGrainKey columns
community_membersone row per forum useruser_id, username, created_at, trust_level, last_seen_at, post_count, is_staff
community_postsone row per post (topic starters and replies)post_id, topic_id, user_id, category_id, created_at, is_first_post, reply_to_post_id, like_count
community_topicsone row per topictopic_id, category_id, created_by, created_at, reply_count, views, has_accepted_answer, first_reply_at

Modeling advice

  • Build a clean community_posts model with common columns across forums, community platforms, chat servers, and event tools, so multi-source dashboards don't fork definitions.
  • Snapshot member counts daily into a table you own. Deleted and anonymized accounts vanish from the live member list, which changes last quarter's numbers every time you refresh.
  • Keep the definition of "active member" — the window and the action — in the model layer, and surface it in card titles. There is no standard.
  • Treat attendance as missing, not zero, when no check-in was recorded. Flag those events explicitly so conversion cards can exclude them.
  • Hash or drop email addresses at the pipeline boundary and join members across tools on a stable ID wherever you have one.

Which Discourse community metrics should you track in Metabase?

MetricDefinitionNotes
Member growth rateNet new members per period over members at the start of it.Deleted accounts rewrite history — snapshot daily.
Engagement rateMembers who posted or reacted over total members.State the window; 30 days is a choice, not a standard.
Reply rateShare of topics that get at least one reply.Its inverse, the no-reply share, is the honest alarm.
Conversion rateNew members who post within their first 7 days.An activation rate: fix the window and never move it.

What SQL powers Discourse community dashboards in Metabase?

These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline — the modeled names above rarely survive a sync unchanged.

New members and growth rate by monthPostgreSQL

Signups per month against the members you already had.

SELECT
  date_trunc('month', created_at) AS month,
  COUNT(*) AS new_members,
  ROUND(
    100.0 * COUNT(*) / NULLIF(
      SUM(COUNT(*)) OVER (
        ORDER BY date_trunc('month', created_at)
        ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
      ), 0
    ), 1
  ) AS growth_rate_pct
FROM community_members
WHERE NOT is_staff
GROUP BY 1
ORDER BY 1;
Median time to first reply by monthPostgreSQL

The percentile answer, not the average one.

-- Median, not average: one topic answered three weeks late
-- drags an average past anything a member would recognize.
SELECT
  date_trunc('month', created_at) AS month,
  COUNT(*) AS topics,
  ROUND(
    PERCENTILE_CONT(0.5) WITHIN GROUP (
      ORDER BY EXTRACT(EPOCH FROM (first_reply_at - created_at)) / 3600
    )::numeric, 1
  ) AS median_hours_to_first_reply
FROM community_topics
WHERE first_reply_at IS NOT NULL
GROUP BY 1
ORDER BY 1;
Share of topics with no replyPostgreSQL

The number that tells you whether the forum is working.

SELECT
  date_trunc('month', t.created_at) AS month,
  COUNT(*) AS topics,
  COUNT(*) FILTER (WHERE t.reply_count = 0) AS unanswered_topics,
  ROUND(
    100.0 * COUNT(*) FILTER (WHERE t.reply_count = 0)
    / NULLIF(COUNT(*), 0), 1
  ) AS no_reply_pct
FROM community_topics t
GROUP BY 1
ORDER BY 1;

What are common mistakes when analyzing Discourse in Metabase?

Reporting an active member count without saying what active means.→ Thirty days or ninety? Posted, reacted, or merely logged in? Each choice produces a different number, and none of them is a standard. Put the window and the action in the card title, and keep the definition in one model.
Recomputing historical member counts from the current user table.→ Deleted and anonymized accounts disappear from it, so last quarter's growth number changes every time the dashboard refreshes. Snapshot member totals daily into a table you control.
Using average time to first reply.→ One topic answered three weeks late drags the average past anything a member would recognize. Use the median, and show the no-reply share next to it — a fast median means little if a fifth of topics never get an answer.
Building dashboards from live MCP lookups only.→ MCP is useful for exploration; durable community dashboards need a database-backed model with history behind them.

Related analytics

Related dashboards

Related integrations

FAQ

Does Metabase connect natively to Discourse?
No. Metabase reads databases and warehouses. Land Discourse data in a database first — via connector, scheduled API pulls, or a replica of the underlying database — or upload a CSV with the Metabase CLI, then build Metabase models and dashboards on top.
Should Metabase replace Discourse?
No — they answer different questions. Discourse is where the community or the event actually happens, and its built-in reporting is fine for a quick look. Metabase is where you build governed, shareable reporting for the whole company, and join community and event activity with product usage, support tickets, and CRM data.
Should I query the Discourse database directly or use Data Explorer?
If you self-host, replicate the forum's PostgreSQL database into your warehouse — you get every table, and it is by far the richest option. If you are on hosted Discourse, run Data Explorer queries through the API on a schedule instead: the plugin is bundled into Discourse core and returns results as JSON or CSV, though CSV exports cap at 10,000 rows, so page by date range.
How should I count active members?
However you like — but say so on the card. "Active" might mean posted in 30 days, reacted in 90, or simply logged in; each produces a different number, and none of them is the industry standard. Pick one definition, model it once, and put the window and the action in the card title. See engagement rate for the pattern.