Linear × Metabase

How to build Linear analytics dashboards in Metabase

Linear is where your team plans and ships work. Metabase is where you turn that activity into shared, trustworthy dashboards. This guide covers two complementary paths: a lightweight MCP route for fast, AI-assisted questions, and a durable pipeline route that syncs Linear into a database or warehouse so you can build dashboards anyone can read.

Heads up: Metabase connects to SQL databases and warehouses — it does not ship a native Linear connector. For dashboards that need history and reliability, you'll sync Linear into a database first (covered below).

How do you connect Linear to Metabase?

Most teams combine these: use the MCP route to explore and answer one-off questions, and the pipeline route for the dashboards people depend on.

1 · MCP route (AI-assisted)

Live, conversational analysis

Pair the Linear MCP server with the Metabase MCP server so an AI assistant can pull live issue data and query existing Metabase models on demand.

Best for
  • Ad-hoc questions you don't want to model yet
  • Exploring what's worth tracking before you build
  • Spot checks like "which projects slipped this cycle?"
Trade-offs
  • Not a substitute for governed or scheduled reporting
  • Answers depend on the assistant and API rate limits
  • No history unless your data already lives in Metabase
2 · Pipeline route (warehouse-backed)

Durable dashboards with history

Sync Linear into a database or warehouse with Airbyte, Fivetran, dlt, or the GraphQL API, then point Metabase at it.

Best for
  • Dashboards the whole team relies on
  • Historical trends (velocity over quarters, cycle time drift)
  • Joining Linear with GitHub, deploys, or support data
Trade-offs
  • Requires a destination database and a sync to maintain
  • Some connector sources may be community-maintained — verify
  • You own the data model and refresh schedule

What can you analyze from Linear data in Metabase?

  • Throughput / velocity — issues and points completed per cycle
  • Cycle time and lead time — from start (or created) to done
  • Work-in-progress and flow — how much is open and where it sits
  • Project and initiative health — scope, progress, and slippage
  • Bug vs. feature mix — where engineering time actually goes
  • Estimation accuracy — estimated vs. actual effort over time
  • Team and individual load — open and completed work distribution
  • Backlog age and aging issues — what's getting stale

Which Linear dashboards should you build in Metabase?

For: Eng leads, EMs

Engineering velocity

Track how much the team ships each cycle and whether it's stable.

  • Completed issues per cycle (bar)
  • Completed estimate points per cycle (bar)
  • Rolling 4-cycle average throughput (line)
  • Carryover: started but not finished in-cycle (number + trend)
For: Eng leads, delivery

Cycle time & flow

Understand how long work takes and where it gets stuck.

  • Median cycle time by week (line)
  • Cycle time distribution / p50–p90 (histogram or table)
  • Current WIP by state (bar)
  • Aging WIP: open issues by days-in-progress bucket (table)
For: PMs, leadership

Project & initiative health

See whether projects are on track by scope and progress.

  • Project completion % vs. target date (table)
  • Scope change: issues added after project start (line)
  • Projects at risk: past target with open issues (table)
  • Initiative roll-up: progress across child projects (bar)
For: Eng, QA, support liaison

Quality & bug load

Watch bug inflow vs. resolution and where defects cluster.

  • Bugs created vs. resolved per week (dual line)
  • Open bug count by priority (bar)
  • Median time-to-resolution for bugs (line)
  • Bug share of total completed work (number)

How do you use the Linear and Metabase MCP servers together?

Pair the Linear MCP server with the Metabase MCP server for live, conversational analysis. The Linear MCP pulls current issue/project data; the Metabase MCP queries the models and dashboards you've already built.

Example workflows

  • List issues completed in the current cycle via the Linear MCP, then summarize by team.
  • Pull a project's open issues from Linear and cross-check progress against a Metabase model with the Metabase MCP.
  • Draft a SQL question in Metabase from a natural-language ask, using Linear MCP output to confirm field meanings.
  • Triage: "show high-priority bugs with no assignee created this week" straight from Linear — no dashboard required.

Be honest about the limits

  • MCP is great for live lookups — not for scheduled or audited reporting.
  • It does not create history; trend analysis still needs synced data in a database.
  • Respect Linear API rate limits and access scopes for the connected workspace.
  • The Metabase MCP server is built in; an admin enables it under Admin → AI → MCP.

How do you set up the Linear and Metabase MCP servers?

Linear MCP official

Endpoint
https://mcp.linear.app/mcp
Transport
Streamable HTTP
Auth
OAuth 2.1 (browser) — no API key, no local install
Note
The /sse endpoint is deprecated.

Metabase MCP built-in

Enable
Admin → AI → MCP
Endpoint
https://<your-metabase>/api/metabase-mcp
Auth
OAuth handled by Metabase
ClaudeClaude Code CLI
# Linear (remote, OAuth in browser)
claude mcp add --transport http linear https://mcp.linear.app/mcp

# Metabase built-in MCP (replace with your instance URL)
claude mcp add --transport http metabase https://your-metabase.example.com/api/metabase-mcp

Claude Desktop: add each as a remote/custom connector (Settings → Connectors) using the same URLs; Claude handles the OAuth pop-up.

CodexOpenAI Codex CLI
codex mcp add linear --url https://mcp.linear.app/mcp
codex mcp add metabase --url https://your-metabase.example.com/api/metabase-mcp

First remote MCP in Codex? Enable the rmcp client in ~/.codex/config.toml:

~/.codex/config.toml
[features]
experimental_use_rmcp_client = true

[mcp_servers.linear]
url = "https://mcp.linear.app/mcp"

[mcp_servers.metabase]
url = "https://your-metabase.example.com/api/metabase-mcp"
Cursor~/.cursor/mcp.json or .cursor/mcp.json
{
  "mcpServers": {
    "linear": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.linear.app/mcp"]
    },
    "metabase": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://your-metabase.example.com/api/metabase-mcp"]
    }
  }
}

Clients with native remote support can use a "url" field instead of the mcp-remote bridge. On first connection each server opens a browser window to authorize.

Verify before shipping: endpoints and flags change — confirm the Metabase MCP URL in Admin → AI → MCP (Metabase docs) and the current Linear MCP URL in the Linear MCP docs.

Can you generate a Linear dashboard with AI?

Yes — and this is the fastest way to a strong first draft. Use the prompt below with the Metabase MCP server, Codex, Claude, Cursor, or any other assistant that can inspect your warehouse schema and create Metabase questions. It assumes Linear data is already synced into a database Metabase can read. It deliberately treats MCP as exploratory and builds the durable dashboard from database tables — and tells the agent to skip metrics the schema can't support instead of faking them.

Prompt for creating a Linear Delivery Health dashboard
Create a polished Metabase dashboard for Linear analytics using the available
Linear tables in this database.

Goal: Help engineering and product leaders understand delivery health, cycle
progress, backlog risk, and bug/support load from Linear data.

First, inspect the schema and identify the available Linear tables. Do not assume
exact table names. Map the available raw tables into these analytical concepts
where possible: Issues, Teams, Projects, Cycles, Workflow states, Labels, Users,
and Issue history / status-change events if available.

Important:
- Treat MCP data access as exploratory only.
- Build the dashboard from durable database/warehouse tables.
- If status history is missing, do not calculate true cycle time, scope change,
  time in status, or reopen rate. Use a caveat instead.
- Do not claim Metabase connects natively to Linear unless that is explicitly
  true in this environment.

Dashboard title: Linear Delivery Health

Sections:
1. Executive summary (KPI cards): Open issues; Issues completed last 7 days;
   Issues created last 7 days; Median cycle time (only if a reliable
   started_at/status-history field exists); High-priority open bugs; Active
   projects at risk (only if project target/status fields exist).
2. Delivery throughput: Completed issues by week; Created vs completed by week;
   Completed issues by team; Completed issues by priority.
3. Cycle health: Current cycle planned vs completed; Incomplete issues by team
   and cycle; Carryover rate (only if cycle timing/snapshots exist); Scope added
   after cycle start (only if issue-cycle history/snapshots exist).
4. Project health: Active projects by status; Open issues by project and
   workflow state; Projects with target dates in next 30 days; Past-due/blocked
   projects (if fields exist).
5. Backlog and aging: Open backlog by team; Open issues by workflow state;
   Oldest open issues table; Unassigned/untriaged issues.
6. Bug and support load: New bugs by week; Resolved bugs by week; Open
   high-priority bugs by age; Bug/support issues by product area or label
   (use labels to identify bugs/support/customer requests if available).

Filters: Team, Project, Cycle, Label, Priority, Workflow state, Assignee,
Date range.

Before finalizing, create or recommend reusable Metabase models:
modeled_linear_issues, modeled_linear_teams, modeled_linear_projects,
modeled_linear_cycles, modeled_linear_workflow_states, modeled_linear_labels,
and modeled_linear_issue_events (only if history exists).

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 schema. Keep it practical, dense,
and executive-readable. Avoid vanity metrics.

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

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

Connector options

  • Airbyte(managed ETL) — has a Linear source connector. Syncs issues, projects, teams, and related entities; check Airbyte docs for the current stream list.
  • Fivetran(managed ETL) — does not offer a native Linear connector; use Airbyte, dlt, or the GraphQL API instead.
  • dlt(code) — write a small Python pipeline against Linear's GraphQL API; best for full control of streams and schema.
  • Linear GraphQL API(raw) — the source of truth; paginate issues/cycles/projects and upsert on a schedule.

Recommended destinations

Notes

  • Land raw tables first, then build clean models on top — don't report off raw JSON.
  • Schedule syncs to match how fresh dashboards need to be (hourly is usually plenty).
  • Capture state-change history if you want accurate cycle/lead time; raw snapshots lose transitions.

How should you model Linear data in Metabase?

Core tables

TableGrainKey columns
issuesone row per issueid, identifier, team_id, project_id, cycle_id, state_type, priority, estimate, assignee_id, created_at, started_at, completed_at, canceled_at
cyclesone row per cycleid, team_id, number, starts_at, ends_at
projectsone row per projectid, name, state, target_date, started_at, completed_at, lead_id
teamsone row per teamid, name, key
usersone row per memberid, name, email, active

Modeling advice

  • Add derived cycle_time = completed_at - started_at and lead_time = completed_at - created_at in your model layer, not in every question.
  • Normalize state into a small state_type set (backlog/started/completed/canceled) so charts stay stable when workflow states change.
  • If you need historical WIP/flow, model an issue_state_history table from API change events; point-in-time snapshots are unreliable.
  • Treat labels as a bridge table (issue_labels) so an issue can carry many labels without exploding rows.
  • Define "completed" once (state_type = 'completed') and reuse it everywhere to avoid metric drift.

Which Linear metrics should you track in Metabase?

MetricDefinitionNotes
Throughput (issues completed)Count of issues with state_type = 'completed' in a period.Simplest velocity signal; pair with points to avoid gaming by issue-splitting.
Velocity (points completed)Sum of estimate for issues completed in a cycle.Only meaningful if the team estimates consistently.
Cycle timecompleted_at − started_at, usually a median.Use median (p50) and p90; averages are skewed by outliers.
Lead timecompleted_at − created_at.Captures queue/backlog wait, not just active work.
Work in progress (WIP)Count of issues with state_type = 'started' right now.High WIP often correlates with longer cycle time.
Carryover rateShare of issues started in a cycle but completed later.Signals over-commitment or scope churn.
Bug ratioCompleted bug issues ÷ all completed issues.Watch the trend, not a single number.
Estimation accuracyRelationship between estimate and actual cycle time.Look for systematic under/over-estimation, not per-issue noise.

What SQL powers Linear dashboards in Metabase?

These assume the modeled tables above (PostgreSQL dialect). Adjust identifiers to match your warehouse.

Throughput per cyclePostgreSQL

Issues completed in each cycle, by team.

SELECT
  t.name        AS team,
  c.number      AS cycle,
  c.starts_at,
  COUNT(*)      AS issues_completed,
  SUM(i.estimate) AS points_completed
FROM issues i
JOIN cycles c ON c.id = i.cycle_id
JOIN teams  t ON t.id = i.team_id
WHERE i.state_type = 'completed'
GROUP BY t.name, c.number, c.starts_at
ORDER BY c.starts_at;
Median cycle time by weekPostgreSQL

Flow trend using the median of completed_at − started_at.

SELECT
  date_trunc('week', i.completed_at)            AS week,
  percentile_cont(0.5) WITHIN GROUP (
    ORDER BY EXTRACT(EPOCH FROM (i.completed_at - i.started_at)) / 86400.0
  )                                             AS median_cycle_days
FROM issues i
WHERE i.state_type = 'completed'
  AND i.started_at IS NOT NULL
GROUP BY 1
ORDER BY 1;
Current WIP by statePostgreSQL

Snapshot of open work right now.

SELECT
  i.state            AS state,
  COUNT(*)           AS open_issues
FROM issues i
WHERE i.state_type = 'started'
GROUP BY i.state
ORDER BY open_issues DESC;
Projects at riskPostgreSQL

Projects past their target date with open issues remaining.

SELECT
  p.name,
  p.target_date,
  COUNT(*) FILTER (WHERE i.state_type <> 'completed') AS open_issues,
  COUNT(*)                                            AS total_issues
FROM projects p
JOIN issues i ON i.project_id = p.id
WHERE p.target_date < CURRENT_DATE
  AND p.state <> 'completed'
GROUP BY p.name, p.target_date
HAVING COUNT(*) FILTER (WHERE i.state_type <> 'completed') > 0
ORDER BY p.target_date;
Bugs created vs. resolved per weekPostgreSQL

Quality trend; assumes a 'Bug' label via an issue_labels bridge table.

WITH bug_issues AS (
  SELECT i.*
  FROM issues i
  JOIN issue_labels il ON il.issue_id = i.id
  WHERE il.label = 'Bug'
)
SELECT
  weeks.week,
  COUNT(created.id)  AS bugs_created,
  COUNT(resolved.id) AS bugs_resolved
FROM (
  SELECT generate_series(
    date_trunc('week', CURRENT_DATE - INTERVAL '12 weeks'),
    date_trunc('week', CURRENT_DATE),
    INTERVAL '1 week'
  ) AS week
) weeks
LEFT JOIN bug_issues created
  ON date_trunc('week', created.created_at) = weeks.week
LEFT JOIN bug_issues resolved
  ON date_trunc('week', resolved.completed_at) = weeks.week
GROUP BY weeks.week
ORDER BY weeks.week;

What are common mistakes when analyzing Linear in Metabase?

Treating MCP answers as governed reporting.→ Use MCP for exploration; build warehouse-backed Metabase dashboards for anything people depend on.
Reporting straight off raw API/JSON tables.→ Add a thin model layer with consistent state_type and derived time metrics.
Measuring cycle time from created_at instead of started_at.→ Separate lead time (from created) and cycle time (from started); label charts clearly.
Using averages for cycle/lead time.→ Report medians and p90 — duration data is heavily right-skewed.
Comparing velocity across teams as if points are equivalent.→ Treat velocity as a within-team trend, not a cross-team leaderboard.
Ignoring canceled issues in completion math.→ Exclude state_type = 'canceled' from throughput and completion-rate denominators where appropriate.
Expecting historical flow from point-in-time snapshots.→ Capture state-change history if you need accurate WIP/aging over time.

Related dashboards

Related integrations

Related metrics