Affinity × Metabase

How to build Affinity deal-flow dashboards in Metabase

Affinity is a relationship-intelligence CRM where your lists, opportunities, and auto-captured interactions live — popular with venture, private equity, and dealmaking teams. Metabase is where you turn that activity into shared, trustworthy deal-flow dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls live data with an Affinity MCP server and loads a CSV into Metabase with the Metabase CLI for quick analysis, and a durable pipeline route that syncs Affinity into a database so you can build deal-flow, pipeline, and sourcing dashboards anyone can read.

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

How do you connect Affinity to Metabase?

Most teams combine both routes: use the Affinity MCP server and Metabase CLI route to pull live data and stand up a quick analysis, and the pipeline route for the deal-flow dashboards the firm depends on.

1 · MCP + CLI route (AI-assisted)

Live data in, quick analysis out

Connect Affinity through a managed MCP server (Gumloop) to read live lists, opportunities, and relationship data, then pair it with the Metabase CLI, whose upload command loads a CSV into Metabase as a ready-to-query table and model.

Best for
  • Quick lookups like "which deals in our sourcing list have gone quiet?"
  • Loading an Affinity CSV export into Metabase in seconds
  • Spot-checks and one-off analyses without a warehouse
Trade-offs
  • Great for exploration, not governed reporting
  • Scope the Affinity MCP connection to read-only where possible
  • CSV uploads are snapshots — refresh or move to the pipeline for history
2 · Pipeline route (warehouse-backed)

Durable dashboards with history

Sync Affinity into a database or warehouse with the Affinity API, dlt, or a managed connector, then point Metabase at it.

Best for
  • Deal-flow, pipeline, and sourcing dashboards the whole firm relies on
  • List and stage conversion trends over quarters
  • Joining relationship data with portfolio, fund, or ops data
Trade-offs
  • Requires a destination database and a sync to maintain
  • You own the stage and status definitions and the refresh schedule
  • Capture list-entry stage changes if you want accurate velocity metrics

What can you analyze from Affinity data in Metabase?

  • Deal flow — new opportunities by source, sector, and week
  • Pipeline — open value by list, stage, and owner
  • Stage conversion — where deals advance and where they stall, per list
  • Win rate — won vs. decided opportunities, by source and sector
  • Relationship coverage — interactions per opportunity and orgs with a recent touch
  • Sourcing quality — which channels and relationship paths produce real deals

Which Affinity dashboards should you build in Metabase?

For: Partners & deal leads

Deal flow

What's coming in and where it sits.

  • New opportunities by source and week (line)
  • Pipeline value by list and stage (bar)
  • Active deals with no interaction in 30 days (table)
  • Deals by owner and stage (matrix)
For: Platform / ops

Conversion

Where deals advance and where they stall.

  • Stage-to-stage conversion by list (funnel)
  • Win rate by source and sector (bar)
  • Passed vs. progressed by reason (bar)
  • Median time-in-stage (bar)
For: Firm leadership

Relationships

Who we know and how warm it is.

  • Interactions per active opportunity (number)
  • Coverage: orgs with a recent touch (number)
  • Introductions by relationship path (table)
  • Response time to inbound (line)
For: Sourcing

Sourcing quality

Which channels produce real deals.

  • Sourced deals by channel (bar)
  • Source → won conversion (funnel)
  • Median deal size by source (bar)
  • Aging of sourcing list entries (table)

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

Connect Affinity through a managed MCP server (Gumloop) and pair it with the Metabase CLI for fast, hands-on analysis. The Affinity MCP looks up current lists, opportunities, and interactions; the Metabase CLI's upload command loads a CSV into Metabase and creates a ready-to-query table and model. Scope the connection to read-only where possible.

Example workflow

  • Ask the Affinity MCP which active deals in the sourcing list have gone quiet, or pull an organization's opportunities and recent interactions.
  • Export the deals or list you want to keep as a CSV.
  • 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

  • The Affinity MCP is great for live lookups — not for scheduled or audited deal-flow reporting.
  • A CSV upload is a point-in-time snapshot; refresh it with mb upload replace or move to the pipeline for real history.
  • Scope the managed connection to read-only where possible; it acts with the permissions of the connected Affinity account.
  • mb upload csv needs an uploads database configured under Admin → Settings → Uploads.

How do you set up the Affinity MCP server and the Metabase CLI?

Affinity MCPmanaged

Provider
Gumloop (managed connector)
Endpoint
Gumloop-generated server URL
Auth
Connect your Affinity account in Gumloop (API key)
Note
No official first-party Affinity MCP server yet

Metabase CLIofficial

Install
npm install -g @metabase/cli
Auth
mb auth login (browser OAuth on v62+, or an API key)
Load data
mb upload csv --file data.csv
Requires
An uploads database (Admin → Settings → Uploads)
Cursor~/.cursor/mcp.json or .cursor/mcp.json
{
  "mcpServers": {
    "affinity": {
      "url": "https://your-gumloop-server-url/mcp"
    }
  }
}
TerminalLoad an Affinity 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 an Affinity CSV export — creates a table AND a model
mb upload csv --file affinity-opportunities.csv --collection root

# Refresh that same table later from a new export
mb upload replace <table-id> --file affinity-opportunities.csv

Affinity doesn't publish a first-party MCP server, so the practical path is a managed connector: connect your Affinity account in Gumloop, then use its generated MCP URL. Because a third party brokers access, scope the connection tightly and review what the connector can read and write. The Metabase CLI stores its credentials securely after mb auth login.

Verify before shipping: confirm an uploads database is enabled under Admin → Settings → Uploads (Metabase docs) and the current Affinity connector setup in Gumloop's Affinity MCP page.

Can you generate an Affinity dashboard with AI?

Yes. Use the prompt below with any assistant that can run the Affinity MCP server and the Metabase CLI. It works end to end: if Affinity tables already exist in Metabase it analyzes those; otherwise it pulls the data over the Affinity MCP, loads it with mb upload csv, then builds the dashboard — resolving stage per list and skipping metrics the data can't support instead of faking them.

Prompt for creating an Affinity Deal Flow dashboard
Create a polished Metabase dashboard for Affinity deal-flow and pipeline analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.

Goal: Help partners and platform teams understand deal flow, pipeline, stage
conversion, sourcing quality, and relationship coverage from Affinity data.

Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for Affinity tables and
  models). If durable Affinity data is already present — synced from a warehouse
  or uploaded earlier — use it and skip to Step 2.
- If nothing is there, pull it with the Affinity MCP server (scope the connection
  to read-only where possible): opportunities, organizations, lists and list
  entries, and interactions. 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:
Affinity CSV exports are usually flat and pre-aggregated (one row per opportunity
or list entry, with columns like list, stage, amount, and source), while
warehouse tables are raw and normalized (persons, organizations, list entries,
field-value changes, interactions). Stages and statuses live in list-specific
fields, so inspect the actual tables and column names first; do not assume exact
names or a global stage set.

Important:
- Build on whatever data is present; don't claim Metabase connects natively to
  Affinity — it reads a database or CLI-uploaded tables.
- Affinity is highly customizable: stages and statuses live in list-specific
  fields, so resolve them per list rather than assuming a global stage set.
- For win rate, state the denominator explicitly (won / decided vs. won /
  created) and hold the cohort fixed.
- Report deal size and time-in-stage as medians (p50) and p90, never plain
  averages — both are right-skewed.
- Only compute time-in-stage or stage conversion when list-entry stage-change
  history exists; otherwise use a caveat.
- Convert all amounts to a single reporting currency; caveat any mix.
- Only build a card if its underlying column/metric exists in the data.
- 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: Affinity Deal Flow Overview

Sections:
1. Executive summary (KPI cards): Open pipeline; New deals (last 90 days); Win
   rate; Median deal size; Median time-in-stage; Orgs with a recent interaction.
2. Deal flow: New opportunities by source; pipeline by list and stage; stale
   deals.
3. Conversion: Stage-to-stage conversion by list; win rate by source and sector.
4. Relationships: Interactions per opportunity; coverage; response time.
5. Sourcing: Sourced deals by channel; source-to-won conversion; deal size by
   source.

Filters: List, Stage, Owner, Source, Date range.

Reuse the models Metabase auto-created from uploaded CSVs, or (for a warehouse)
create reusable models: modeled_affinity_opportunities,
modeled_affinity_list_entries, modeled_affinity_stage_history,
modeled_affinity_organizations, and modeled_affinity_interactions.

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. Reconcile totals against
Affinity's own reporting. Keep it practical, dense, and executive-readable.

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

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

Connector options

  • Affinity API (raw) — the source of truth; pull persons, organizations, opportunities, lists, list entries, field values, and interactions.
  • dlt (code) — write a Python pipeline against the Affinity API for full control of schema and incremental loads.
  • Managed ETL (Airbyte / Fivetran) — check the connector catalogs for an Affinity source; where one exists it can land the core objects on a schedule.
  • Reverse-ETL / webhooks — Affinity webhooks can stream field and list-entry changes so you don't lose transitions between syncs.

Notes

  • Land raw tables first, then build clean models on top.
  • Stages and statuses live in list-specific fields, not a global column — resolve them per list.
  • Capture field-value history (webhooks) for time-in-stage and conversion.
  • Convert opportunity amounts to a single reporting currency.

How should you model Affinity data in Metabase?

Core tables

TableGrainKey columns
opportunitiesone row per opportunityid, name, organization_id, amount, status, source, owner_id, created_at
listsone row per listid, name, type
list_entriesone row per entry on a listid, list_id, entity_id, stage, created_at
field_value_changesone row per changeentity_id, field, value, changed_at
organizationsone row per orgid, name, domain, sector
interactionsone row per interactionid, organization_id, type (email/meeting/call),direction, occurred_at

Modeling advice

  • Build a modeled_affinity_opportunities table with clean status, amount (one currency), source, and closed_at.
  • Resolve stage from the relevant list's status field and normalize it into an ordered funnel.
  • Derive modeled_affinity_stage_history from field-value changes for time-in-stage and velocity.
  • Roll auto-captured interactions up to organization and opportunity for coverage metrics.
  • Reconcile modeled pipeline against Affinity's own reports before trusting it.

Which Affinity metrics should you track in Metabase?

MetricDefinitionNotes
Open pipelineSum of amount for active opportunities.Segment by list, stage, owner.
Deal flowNew opportunities created per period.Segment by source and sector.
Win rateWon ÷ decided opportunities in a cohort.Fix the denominator (decided vs. created) first.
Time-in-stageDays an entry spends in each stage.Needs field-value history; report median and p90.
Relationship coverageOrgs with an interaction in the last N days.Uses auto-captured interactions.
Sourcing conversionSourced → won by channel.Read with deal size, not alone.

What SQL powers Affinity dashboards in Metabase?

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

Open pipeline by list and stagePostgreSQL

The current funnel — active deals and value by list and stage.

SELECT
  le.list_name,
  le.stage,
  COUNT(*)                        AS active_deals,
  ROUND(SUM(o.amount), 2)         AS pipeline_value
FROM modeled_affinity_list_entries le
JOIN modeled_affinity_opportunities o ON o.id = le.opportunity_id
WHERE o.status = 'active'
GROUP BY le.list_name, le.stage
ORDER BY pipeline_value DESC;
Win rate by sourcePostgreSQL

Won as a share of decided opportunities, by sourcing channel.

SELECT
  o.source,
  COUNT(*) FILTER (WHERE o.status = 'won')                     AS won,
  COUNT(*) FILTER (WHERE o.status IN ('won', 'passed'))        AS decided,
  ROUND(
    100.0 * COUNT(*) FILTER (WHERE o.status = 'won')
      / NULLIF(COUNT(*) FILTER (WHERE o.status IN ('won', 'passed')), 0),
    1
  ) AS win_rate_pct
FROM modeled_affinity_opportunities o
WHERE o.status IN ('won', 'passed')
GROUP BY o.source
ORDER BY decided DESC;
Active deals going quietPostgreSQL

Active opportunities with no logged interaction in 30 days.

-- Active opportunities with no logged interaction in the last 30 days
SELECT
  o.id,
  o.name,
  o.owner,
  MAX(i.occurred_at) AS last_interaction
FROM modeled_affinity_opportunities o
LEFT JOIN modeled_affinity_interactions i
  ON i.organization_id = o.organization_id
WHERE o.status = 'active'
GROUP BY o.id, o.name, o.owner
HAVING MAX(i.occurred_at) < CURRENT_DATE - INTERVAL '30 days'
    OR MAX(i.occurred_at) IS NULL
ORDER BY last_interaction NULLS FIRST;

What are common mistakes when analyzing Affinity in Metabase?

Assuming a global stage set.→ Affinity stages live in list-specific fields — resolve stage per list, then normalize into a shared funnel.
Treating a live MCP lookup or a one-off CSV as governed reporting.→ Use the Affinity MCP and CSV uploads for live exploration; build warehouse-backed dashboards for anything the firm depends on.
Computing time-in-stage without field history.→ Capture field-value changes — a snapshot can't tell you when a deal entered or left a stage.
Leaving win rate's denominator ambiguous.→ Won ÷ decided and won ÷ created are different metrics — pick one and label it.
Mixing currencies in pipeline value.→ Convert all amounts to a single reporting currency before you total them.

Related analytics

Related metrics

Related integrations

FAQ

Does Metabase connect natively to Affinity?
No. Metabase reads databases and warehouses. Sync Affinity into a database first (the Affinity API, dlt, a managed connector, or webhooks), then connect Metabase to that database.
Is there an official Affinity MCP server?
Not a first-party one. The practical path is a managed connector such as Gumloop: connect your Affinity account, then use its generated MCP URL. Use MCP for live lookups, not governed reporting, and scope the connection tightly.
How do I quickly load Affinity data without a warehouse?
Export a CSV from Affinity and run `mb upload csv --file data.csv` with the Metabase CLI. It creates a table and a model you can build questions on right away. You'll need an uploads database enabled under Admin → Settings → Uploads. Refresh later with `mb upload replace`, or move to the pipeline route when you need history.
How do I track pipeline stages when Affinity is so customizable?
Affinity stores stage and status in list-specific fields rather than one global column. Resolve stage from the relevant list's status field, then normalize the values into an ordered funnel so conversion charts stay stable across lists.