Navigation

Quick Start

Three commands. One question. First dashboard.

1. Install

curl -fsSL https://rack.dev/install.sh | sh

2. Create a rack and open Claude

rack init @econ && cd @econ && claude

3. Ask

"Why did everyone stop working in 2020 and are we back to normal yet?
https://fred.stlouisfed.org/series/EMRATIO"

That's it. Claude fetches the employment-to-population ratio from FRED, loads it into DuckDB, and generates a Markdown dashboard with trend analysis, historical context, and economic implications.

No API keys. No configuration. Just a question about public data.

What happened under the hood? Claude wrote scripts in scripts/fetch/, scripts/ingest/, and scripts/derive/. It ran them via rack refresh. The dashboard appeared in dashboards/. All plain text, all readable, all yours to modify.

The Works

The quick start showed the simplest case. Here's what a real session looks like — building a startup metrics rack over a few conversations with Claude.

Adding Data Sources

You just describe what you want to track. Claude figures out how to get it.

APIs with CLIs

Many services have official CLIs that handle auth and pagination. Claude will use these when available.

"I want to track all PRs from our GitHub org acme-corp. Show me weekly velocity - how many merged, how long they took, who's shipping the most. Break it down by repo too."
I'll use the gh CLI to fetch PR data. Let me create the fetch script...

[creates scripts/fetch/github-prs.sh]
[creates scripts/ingest/github-prs.py]
[creates scripts/derive/pr-velocity.py]
[runs rack refresh]

Done. Your dashboard is at dashboards/pr-velocity.md. It shows:
- Weekly merge count with sparkline trend
- Median time-to-merge by week
- Top contributors ranked by merged PRs
- Breakdown by repository
"Add Stripe data too. I want to see MRR, new subscriptions, and churn. Connect it to the GitHub data so I can see if shipping more correlates with revenue."
I'll use the stripe CLI. Do you have it installed?

[checks for stripe CLI]

Found it. Creating fetch scripts for subscriptions and charges...

[creates scripts/fetch/stripe-subs.sh]
[creates scripts/derive/mrr-dashboard.py]
[updates dashboards/index.md with revenue section]

Dashboard now shows MRR trend alongside PR velocity. Added a correlation chart at the bottom.

APIs without CLIs

For services without CLIs, Claude writes scripts that call the REST or GraphQL API directly.

"Add our Linear tickets. I want to see cycle time from ticket creation to PR merge. Which tickets are blocking? Which have been open longest?"
Linear uses GraphQL. I'll need an API key - you can create one at linear.app/settings/api.

What's the key?
"lin_api_xxxxx"
[stores key in .env as LINEAR_API_KEY]
[creates scripts/fetch/linear-issues.sh with GraphQL query]
[creates scripts/derive/cycle-time.py]

I joined Linear tickets to GitHub PRs by matching ticket IDs in branch names (like "feat/ENG-123-add-login").

Dashboard shows:
- Cycle time distribution (ticket created → PR merged)
- Blocked tickets with blocker reason
- Oldest open tickets by assignee

Browser Automation

Some data isn't available via API - competitor pricing, internal dashboards behind SSO, pages that require JavaScript. For these, Claude uses Playwriter to automate a real browser.

"Track competitor.com/pricing - I want to know immediately when they change their prices or plans."
That page requires JavaScript to render. I'll use Playwriter to load it in a real browser.

[creates scripts/fetch/competitor-pricing.py]

The script:
1. Opens headless Chrome
2. Navigates to competitor.com/pricing
3. Waits for the pricing table to render
4. Extracts plan names, prices, and features
5. Saves a screenshot to data/screenshots/ for audit

I'll set up a signal to alert you when any price changes.
"I need to pull data from our internal Metabase dashboard. It's behind Okta SSO."
Playwriter can handle SSO flows. I'll create a script that:
1. Opens the Metabase URL
2. Detects the Okta redirect
3. Waits for you to complete login (first run only)
4. Saves the session cookies for future runs
5. Navigates to your dashboard and extracts the data

[creates scripts/fetch/metabase-dashboard.py]

Run rack refresh once manually - it'll open a browser window for you to log in. After that, it runs headless.
"Scrape job postings from 5 competitors on LinkedIn. I want to track if they're hiring for specific roles."
LinkedIn is aggressive about blocking scrapers, but Playwriter can handle it with some care.

[creates scripts/fetch/linkedin-jobs.py]

The script uses realistic timing, rotates user agents, and saves to data/raw/linkedin-jobs.json. I've added rate limiting so you don't get blocked.

Dashboard will show:
- Open roles by competitor
- New postings this week
- Signals when a competitor posts for a role matching keywords you care about (e.g., "ML engineer", "Head of Growth")
Browser automation? playwriter.dev makes it dead simple to automate data fetching through the browser. When Claude needs to scrape pages that require JavaScript, handle logins, or navigate complex UIs, it writes Playwriter scripts.

File Drops

Some data comes as exports. Bank statements, spreadsheets someone emailed you, CSV dumps. Drop them in data/inbox/ and tell Claude what they are.

[drops bank-statement-jan.csv into data/inbox/]
"This is our Chase business checking export. Date, description, amount columns. I want to track monthly burn rate and project runway based on our current balance."
[reads data/inbox/bank-statement-jan.csv]

Got it. 847 transactions from January. I see some categories I can auto-detect:
- Payroll (ADP entries)
- AWS charges
- Gusto payments
- Various SaaS subscriptions

[creates scripts/ingest/chase-statement.py]
[creates scripts/derive/burn-rate.py]

Dashboard shows:
- Monthly burn: $127,400
- Breakdown by category (payroll 68%, infra 12%, SaaS 8%, other 12%)
- Runway: 14.2 months at current burn

Drop future Chase exports in the same folder - they'll auto-ingest and update the dashboard.
[drops customer-survey-q4.xlsx into data/inbox/]
"NPS survey results from Typeform. Can you analyze sentiment and find patterns?"
[reads Excel file, finds 3 sheets: Responses, Metadata, Scores]

Found 234 responses. Analyzing free-text feedback...

[creates scripts/ingest/nps-survey.py]
[creates scripts/derive/nps-analysis.py]

Results:
- NPS: 42 (Promoters: 58%, Passives: 26%, Detractors: 16%)
- Top praise themes: "fast support", "easy to use", "saves time"
- Top complaint themes: "mobile app crashes", "pricing unclear", "missing integrations"

I linked responses to your customer table by email, so you can see NPS by plan tier and usage level.

Signals

Dashboards require you to look. Signals tell you when something needs attention.

"Set up alerts for the important stuff. I want to know if:
- MRR drops more than 10% week-over-week
- Any customer churns who was paying more than $500/mo
- Runway drops below 12 months
- A competitor changes their pricing
- Our shipping velocity drops two weeks in a row"
I'll add threshold checks to your derive scripts. When conditions are met, signals get written to .rack/signals.md with timestamps and context.

[updates scripts/derive/mrr-dashboard.py with MRR drop detection]
[updates scripts/derive/churn-analysis.py with high-value churn alert]
[updates scripts/derive/burn-rate.py with runway threshold]
[updates scripts/derive/competitor-pricing.py with change detection]
[updates scripts/derive/pr-velocity.py with velocity trend check]

Done. Run rack signals anytime to see what's fired. Signals include context so you know why they triggered.

Later that week:

"What signals fired this week?"
[reads .rack/signals.md]

Three signals this week:

Tuesday 2:34am - MRR dropped 12%
→ 3 annual customers churned (Acme Corp, StartupXYZ, TechFlow)
→ Combined loss: $4,200/mo
→ All three had declined usage in past 60 days

Thursday 6:01am - Competitor price change
→ competitor.com dropped Pro tier from $99 → $79/mo
→ Screenshot saved to data/screenshots/competitor-2024-01-18.png

Friday 6:01am - Shipping velocity down
→ 8 PRs merged this week vs 15 avg
→ Second consecutive week of decline
"Tell me more about those churned customers. What happened?"
[queries customer data, usage logs, support tickets]

Pattern: all three were on annual plans that auto-renewed, but they cancelled before renewal.

Acme Corp ($1,800/mo)
- Last login: 45 days ago
- Usage dropped 80% in Q4
- No support tickets
- Likely: found alternative or project ended

StartupXYZ ($1,200/mo)
- Active until last month
- 3 support tickets about missing feature X
- Likely: feature gap

TechFlow ($1,200/mo)
- Sporadic usage throughout
- Never adopted core workflow
- Likely: poor onboarding/fit

Time Travel

Every rack refresh snapshots your data. You can query any point in the past, compare across time, and understand what changed.

"What did our MRR look like on January 1st? And how does that compare to today?"
[queries snapshot from 2024-01-01]

January 1st: $42,100 MRR
Today: $49,700 MRR

Growth: +$7,600 (+18%)

Breakdown of change:
- New customers: +$9,200
- Upgrades: +$1,400
- Churned: -$3,000

Net retention: 107%
"Show me exactly which customers we had on January 1st that we don't have today."
[diffs customer table across snapshots]

5 customers churned since Jan 1:

| Customer | Plan | MRR | Last Active | Reason |
|----------|------|-----|-------------|--------|
| Acme Corp | Pro | $1,800 | Jan 15 | Cancelled |
| StartupXYZ | Team | $1,200 | Jan 22 | Cancelled |
| OldCo | Pro | $600 | Dec 28 | Payment failed |
| TestAccount | Free | $0 | Nov 1 | Inactive |
| ...
"What did competitor.com/pricing look like 3 months ago vs today?"
[queries competitor pricing snapshots]

October 2023 vs Today:

| Plan | Oct Price | Today | Change |
|------|-----------|-------|--------|
| Starter | $29/mo | $29/mo | — |
| Pro | $99/mo | $79/mo | ↓ 20% |
| Enterprise | $299/mo | $249/mo | ↓ 17% |

They've dropped prices twice - once in November, once last week. Screenshots from each change are in data/screenshots/.

Scheduling

Keep your data fresh without thinking about it.

"Refresh this rack every morning at 6am."
Creates launchd plist (macOS) or systemd timer (Linux). Your dashboards update before you wake up.
"Check competitor pricing every hour."
Adds hourly schedule for just that fetch script. Signals you immediately if prices change.

Annotations

Mark what happened so spikes and dips make sense later.

"Mark January 15 as 'Launched v2.0' and January 20 as 'Started paid ads'."
Adds annotations to .rack/annotations.yaml. Dashboards now show these events on the timeline. When you see the traffic spike, you know why.

Cross-Rack Queries

You can have multiple racks for different domains. They can talk to each other.

"I have a @competitors rack with pricing data. Compare our prices to theirs in my main dashboard."
Attaches the other rack's database. Joins your products table to their pricing table. Dashboard shows price delta by product.

MCP Integration

MCP (Model Context Protocol) lets Claude query your rack directly. Install it once:

rack mcp install

Now Claude has access to your data in any conversation - Claude.ai, Claude Code, or any MCP-compatible client.

"What was last week's revenue? Break it down by plan and compare to the week before."
[rack:query SELECT ... FROM stripe_subscriptions]

Last week: $12,400 total revenue

| Plan | Revenue | WoW Change |
|------|---------|------------|
| Pro | $8,200 | +12% |
| Team | $3,100 | -3% |
| Enterprise | $1,100 | — |

Pro tier is growing. Team had 2 downgrades.
"Which customers should I be worried about? Anyone showing signs of churning?"
[rack:query SELECT ... FROM customers JOIN usage_events]

3 accounts showing churn risk signals:

Acme Corp - $1,200/mo - ⚠️ High risk
- Last login: 18 days ago
- Usage down 70% vs prior month
- Annual renewal in 6 weeks

TechFlow - $600/mo - ⚠️ Medium risk
- Active but usage plateaued
- 2 open support tickets (unanswered 5 days)

StartupXYZ - $1,800/mo - 👀 Watch
- Admin account hasn't logged in (but team still active)
- Payment method expires next month
"Draft a check-in email for the Acme Corp account owner."
[rack:query SELECT contact_email, contact_name, ... FROM customers WHERE name = 'Acme Corp']

Here's a draft:

Subject: Quick check-in from [Your Company]

Hi Sarah,

I noticed it's been a few weeks since anyone on your team logged in. Just wanted to check if everything's going well with [Product] or if there's anything we can help with.

Your annual renewal is coming up in March - happy to chat about your plans or answer any questions.

Best,
[You]

Next Steps

You've seen the full tour. Here's where to go from here:

  • Spec — detailed documentation of every command and behavior
  • GitHub — source code and issue tracker

Questions? Open an issue. We read them all.