GrowthOS
GrowthOS is an open-source MCP analytics server that connects your AI assistant
Ask AI about GrowthOS
Powered by Claude Β· Grounded in docs
I know everything about GrowthOS. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
GrowthOS
Answer growth questions in plain English. No SQL required.
Project status
Experimental beta. Snapshot date: 2025-12-15. The strongest current evaluation path is weekly growth review, funnel diagnosis, and channel efficiency review. See STATUS.md and KNOWN_LIMITATIONS.md.
GrowthOS is an open-source MCP analytics server that connects your AI assistant (Claude, Cursor, or any MCP-compatible client) directly to your marketing and product data. Ask questions about funnels, retention, CAC, churn, anomalies, channel performance, forecasts, Shapley attribution, and narrative summaries β and get structured, benchmark-referenced answers in seconds.
Screenshots
| CAC & LTV by Channel | Funnel Analysis |
|---|---|
![]() | ![]() |
| Churn Segmentation | Weekly Growth Summary |
|---|---|
![]() | ![]() |
REST API (Swagger UI)

What GrowthOS Does
Claude / Cursor / any MCP client
β
βΌ
ββββββββββββββββββββββββββββββββ
β GrowthOS MCP Server β GrowthOS sits between your AI assistant and your data
β 49 tools Β· DuckDB Β· SQL β It exposes **49 MCP tools** that your AI can call to run real analysis β funnel breakdowns, CAC/LTV calculations, cohort retention matrices,
β Semantic layer Β· Benchmarks β anomaly detection, SQL queries, and more β then formats results with benchmark comparisons so you get context,
ββββββββββββββ¬ββββββββββββββββββ not just numbers.
β
ββββββββββββββββββββββββ
β Your data sources β
β CSV Β· PostgreSQL β
β Stripe Β· Meta Ads β
β Google Ads Β· HubSpotβ
β Mixpanel Β· Amplitudeβ
ββββββββββββββββββββββββ
5 Questions GrowthOS Answers Reliably
-
"Why did CAC increase last week and is it sustainable?" Channel-level CAC, LTV, and ROAS with automated invest/cut/watch classification.
-
"Where is our funnel breaking and what should we test first?" Step-by-step conversion rates with the biggest drop-off identified automatically.
-
"How bad is our retention and how does it compare to benchmarks?" Cohort retention matrix vs. B2B SaaS medians with Good / Average / Poor rating.
-
"Which users are at risk of churning and how do we bring them back?" Active / At-Risk / Churned segmentation using configurable inactivity thresholds.
-
"What will our spend and signups look like in the next 30 days?" Linear regression and exponential smoothing forecasts with confidence bands.
Who It's For
- Growth teams who want fast, repeatable answers without waiting for a data analyst
- Founders and PMs reviewing weekly metrics in Claude, Cursor, or any AI
- Marketing ops managing multi-channel attribution across Google, Meta, Stripe, HubSpot, Mixpanel, Amplitude, and CSV exports
Who It's Not For
- Teams that need dashboards or BI charts (use Metabase, Looker, etc.)
- Real-time streaming data (GrowthOS reads CSV/DuckDB snapshots)
- Enterprise RBAC or multi-tenant data isolation
Quick Start
Install
pip install growth-os
Claude Desktop
Add to ~/.claude/claude_desktop_config.json:
{
"mcpServers": {
"growth-os": {
"command": "uvx",
"args": ["growth-os"],
"env": {
"GROWTH_DATA_DIR": "/path/to/your/csv/folder"
}
}
}
}
Cursor / Windsurf / any MCP client
{
"mcpServers": {
"growth-os": {
"command": "uvx",
"args": ["growth-os"],
"env": {
"GROWTH_DATA_DIR": "./data"
}
}
}
}
From source
git clone https://github.com/Astoriel/GrowthOS.git
cd GrowthOS
pip install -e ".[dev]"
python -m growth_os.server
Demo Mode β No Data Required
Skip GROWTH_DATA_DIR entirely. GrowthOS auto-generates realistic sample marketing data on startup β useful for exploring all 49 tools before connecting real data. Every connector (HubSpot, Mixpanel, Amplitude, Stripe, Meta, Google Ads) also runs in demo mode with synthetic mock data when credentials are absent.
Try it immediately:
pip install growth-os
# In Claude: "Give me a weekly growth summary"
# GrowthOS responds with real analysis on auto-generated sample data
Data Sources and Connectors
CSV Mode
Point GROWTH_DATA_DIR at a folder containing CSV files. GrowthOS loads all CSVs as queryable DuckDB tables.
export GROWTH_DATA_DIR=/path/to/csv/folder
Recommended file names (auto-detected schema):
| File | Key Columns |
|---|---|
marketing_spend.csv | date, channel, spend, impressions, clicks |
user_events.csv | user_id, event_type, event_date, utm_source |
campaigns.csv | campaign_id, channel, name, start_date, spend |
Column names are flexible β use suggest_attribution_mappings to auto-map aliases.
PostgreSQL Mode
export POSTGRES_URL=postgresql://user:pass@host:5432/dbname
GrowthOS attaches PostgreSQL as a read-only DuckDB extension. All queries are read-only; write/DDL operations are blocked at the AST level.
Stripe
export STRIPE_API_KEY=sk_live_...
Syncs invoices, subscriptions, charges, and events. Call sync_stripe_billing from your AI assistant.
Meta Ads
export META_ACCESS_TOKEN=...
export META_AD_ACCOUNT_ID=act_...
export META_API_VERSION=v21.0 # optional, default v21.0
Syncs campaigns and daily ad insights. Call sync_meta_ads.
Google Ads
export GOOGLE_ADS_DEVELOPER_TOKEN=...
export GOOGLE_ADS_CUSTOMER_ID=...
export GOOGLE_ADS_LOGIN_CUSTOMER_ID=... # manager account ID, if applicable
export GOOGLE_ADS_ACCESS_TOKEN=...
export GOOGLE_ADS_REFRESH_TOKEN=...
export GOOGLE_ADS_CLIENT_ID=...
export GOOGLE_ADS_CLIENT_SECRET=...
export GOOGLE_ADS_API_VERSION=v19 # optional, default v19
Syncs campaigns and click performance. Call sync_google_ads.
HubSpot
Uses a Private App access token (not an API key). Create a Private App in HubSpot Settings β Integrations β Private Apps, and grant these scopes:
crm.objects.contacts.readcrm.objects.deals.read
export HUBSPOT_ACCESS_TOKEN=pat-eu1-... # Private App token
export HUBSPOT_BASE_URL=https://api.hubapi.com # optional
Call sync_hubspot to pull contacts and deals. Falls back to demo mode (100β200 mock rows) when HUBSPOT_ACCESS_TOKEN is unset.
Mixpanel
Uses the API Secret from Project Settings (not the project token).
export MIXPANEL_API_SECRET=... # Project API Secret
export MIXPANEL_PROJECT_ID=... # Project numeric ID (optional)
export MIXPANEL_EU=true # true = EU data residency (default)
Call sync_mixpanel to pull event streams and funnel data. Funnel data falls back to mock if the account is on the free plan (HTTP 402). Falls back to demo mode (up to 500 mock events + 3 funnel templates) when MIXPANEL_API_SECRET is unset.
Amplitude
Requires both the API Key and Secret Key from the Amplitude project settings (under General β API Keys). Note: the JavaScript SDK snippet key is a different key and will not work here.
export AMPLITUDE_API_KEY=... # From Project Settings β API Keys
export AMPLITUDE_SECRET_KEY=... # Secret key (required alongside API key)
export AMPLITUDE_EU=true # true = EU data residency (default)
Call sync_amplitude to pull events and user cohorts. Falls back to demo mode (500 mock events + 8 mock cohorts) when either key is missing.
REST API Server
Run GrowthOS as a standalone HTTP API alongside the MCP server:
pip install "growth-os[api]"
growth-os-api
The API server starts at http://localhost:8000. Swagger docs at http://localhost:8000/docs.
| Method | Path | Description |
|---|---|---|
GET | /health | Server health, loaded tables, timestamp |
POST | /query | Execute a read-only SQL query |
GET | /tables | List all loaded tables |
GET | /tables/{name} | Schema and stats for a specific table |
GET | /analysis/funnel | Funnel conversion rates |
GET | /analysis/cac-ltv | CAC / LTV / ROAS by channel |
GET | /analysis/churn | User churn segmentation |
GET | /analysis/anomalies | Anomaly detection in any metric |
GET | /reports/growth-summary | Weekly growth KPI summary |
Sample Prompts
All prompts work in demo mode or with real data.
Weekly review:
"Give me a weekly growth summary comparing this week to last week."
Funnel diagnosis:
"Analyze the signup β activation β purchase funnel and tell me where we're losing users."
CAC/LTV:
"What's our CAC and LTV by channel? Which channels should we scale up?"
Retention check:
"How is our month-1 retention trending and how does it compare to SaaS benchmarks?"
Churn investigation:
"How many users churned last month and how many are at risk right now?"
Anomaly investigation:
"Something looks off in our spend last Tuesday. Detect any anomalies in marketing_spend."
Shapley attribution:
"Compute Shapley-value attribution across all channels for the last 90 days."
Forecasting:
"Forecast our daily signups for the next 30 days using linear trend and exponential smoothing."
Narrative review:
"Write a plain-English growth narrative with headline findings and a recommendation."
Data drift alert:
"Alert me via webhook if spend drifts more than 15% compared to last week."
HubSpot contacts:
"Sync our HubSpot contacts and show a breakdown by lifecycle stage."
Profile setup:
"Save my current setup as a profile called 'production' for next session."
Tool Reference
All 49 registered MCP tools:
Discovery
| Tool | Description |
|---|---|
health_check | Server status, loaded tables, DuckDB version, timestamp |
list_tables | List all available data tables |
describe_table | Schema, sample rows, and column statistics for any table |
run_query | Execute a read-only SQL query (DuckDB dialect); supports offset/limit pagination |
Analysis
| Tool | Description |
|---|---|
analyze_funnel | Step-by-step funnel conversion rates |
compute_cac_ltv | CAC, LTV, and ROAS by channel with benchmark comparison |
cohort_retention | Cohort retention matrix (weekly or monthly) vs. B2B SaaS medians |
channel_attribution | Attributed revenue and ROAS per channel |
analyze_churn | User segmentation: Active / At-Risk / Churned |
detect_anomalies | Spike/drop detection in any metric time series |
Workflow Tools (Combined Multi-Step Analysis)
| Tool | Description |
|---|---|
funnel_diagnosis | Funnel + churn in one response with prioritized next-step recommendations |
channel_efficiency_review | CAC + LTV + ROAS with automated invest / cut / watch classification |
anomaly_explanation | Anomalies + likely cause hypotheses + investigation actions |
detect_data_drift | Compare current vs. previous period; flags shifts >20% |
funnel_ab_comparison | Side-by-side funnel conversion for two time periods with Ξ (pp) column |
drift_alert | Detect metric drift and optionally fire a webhook notification |
scheduled_report_preview | Preview weekly growth report and optionally deliver it via webhook |
Forecasting
| Tool | Description |
|---|---|
forecast_metric | Forecast any metric column using linear regression or exponential smoothing, with confidence bands |
forecast_growth_kpis | Forecast spend and daily active users for the next N days |
Reports
| Tool | Description |
|---|---|
growth_summary | Weekly growth KPI summary with period-over-period comparison |
weekly_growth_review | Full weekly growth review workflow |
executive_summary | Board-level executive summary |
paid_growth_review | Paid spend vs. Stripe revenue comparison |
campaign_performance_review | Campaign ranking by spend, efficiency, and risk |
attribution_bridge_review | Campaign-to-revenue attribution bridge |
narrative_growth_review | Plain-English prose narrative with headline, findings, and recommendation |
Data Quality
| Tool | Description |
|---|---|
validate_data | Validate tables against GrowthOS schema contracts |
inspect_freshness | Check data freshness across all loaded tables |
list_connectors | List configured connectors and their readiness status |
Attribution Mapping
| Tool | Description |
|---|---|
attribution_mapping_diagnostics | Coverage gaps, unmapped keys, alias rule usage |
suggest_attribution_mappings | Auto-suggest high-confidence alias rules from your data |
attribution_mapping_review_pack | Read-only review: coverage deltas, risk flags, audit trail |
preview_apply_attribution_mappings | Preview coverage lift before applying any changes |
apply_suggested_attribution_mappings | Apply approved aliases (high-risk rules blocked unless force=true) |
review_attribution_mappings | Inspect active rules and full audit history |
rollback_attribution_mappings | Undo specific alias changes by ID |
Integrations
| Tool | Description |
|---|---|
sync_stripe_billing | Sync Stripe invoices, subscriptions, and events to local CSV |
stripe_revenue_summary | Revenue summary from synced Stripe data |
sync_meta_ads | Sync Meta Ads campaigns and daily insights |
meta_ads_summary | Spend, clicks, impressions from synced Meta data |
sync_google_ads | Sync Google Ads campaigns and click performance |
google_ads_summary | Spend, clicks, conversions from synced Google Ads data |
sync_hubspot | Sync HubSpot contacts and deals (demo mode when no token) |
hubspot_contacts_summary | Contacts breakdown by lifecycle stage |
sync_mixpanel | Sync Mixpanel events and funnels (demo mode when no secret) |
sync_amplitude | Sync Amplitude events and user cohorts (demo mode when no keys) |
Workspace Profiles
| Tool | Description |
|---|---|
save_workspace_profile | Save named configuration (data dir, Postgres URL, custom metrics) |
load_workspace_profile | Load and apply a saved profile |
list_workspace_profiles | List all saved profiles |
Workspace Profiles and Custom Metrics
Save any combination of data directory, Postgres URL, and business mode as a named profile:
> "Save my current setup as a profile called 'production'."
> "Load the 'production' profile."
Profiles support custom metric definitions β define SQL-based KPIs with benchmark thresholds and units that GrowthOS evaluates alongside built-in metrics:
> "Add a custom metric: 'avg_order_value' = revenue / orders, benchmark 45, unit USD."
Architecture
src/growth_os/
βββ app/
β βββ server.py # FastMCP server factory
β βββ registry.py # 49 MCP tool registrations
β βββ lifespan.py # Startup sample data provisioning
βββ api/
β βββ server.py # FastAPI REST API (optional)
βββ config/
β βββ settings.py # Pydantic-settings env config
β βββ profiles.py # Workspace profiles + custom metrics
βββ connectors/
β βββ duckdb.py # DuckDB engine + query cache
β βββ csv.py # CSV ingestion
β βββ postgres.py # PostgreSQL attach (read-only)
β βββ stripe.py # Stripe Billing API
β βββ meta_ads.py # Meta Marketing API
β βββ google_ads.py # Google Ads API
β βββ hubspot.py # HubSpot CRM v3 (contacts + deals)
β βββ mixpanel.py # Mixpanel Export + Funnels API
β βββ amplitude.py # Amplitude Export + Cohorts API
β βββ webhook.py # Outbound webhook dispatcher
βββ domain/
β βββ models.py # ToolEnvelope, shared models
β βββ exceptions.py # ConnectorError, QueryError
β βββ enums.py # FreshnessStatus, Severity, ChurnMode
β βββ contracts.py # Schema contracts for validation
βββ ingestion/
β βββ catalog.py # Table catalog
β βββ freshness.py # Freshness detection
β βββ validators.py # Data quality validators
β βββ mapping.py # Attribution mapping engine
β βββ loaders.py # Data loading orchestration
βββ observability/
β βββ logging.py # Structured JSON logging
β βββ tracing.py # @trace decorator
β βββ audit.py # Append-only audit log
βββ presentation/
β βββ markdown.py # ToolEnvelope formatter + narrative builder
βββ query/
β βββ safety.py # AST-based SQL validator (sqlglot)
β βββ builder.py # Query builder
βββ semantic/
β βββ metrics.py # CAC, LTV, churn (3 modes), ROAS
β βββ benchmarks.py # B2B SaaS benchmark data
β βββ funnels.py # Funnel step definitions
β βββ retention.py # Retention cohort logic
β βββ attribution.py # UTM attribution + Shapley values
β βββ forecasting.py # Linear OLS + exponential smoothing
βββ services/
β βββ analysis_service.py
β βββ catalog_service.py
β βββ diagnostics_service.py
β βββ reporting_service.py
β βββ integration_service.py
β βββ notification_service.py
β βββ forecasting_service.py
βββ demo/
β βββ sample_generator.py # Synthetic marketing data
β βββ scenarios.py # 4 curated demo scenarios
βββ tools/
βββ discovery/ # health_check, list_tables, describe_table, run_query
βββ analysis/ # funnel, cac_ltv, retention, churn, anomalies
βββ reports/ # growth_summary, executive, narrative, forecasting
βββ admin/ # profiles, connectors, attribution mapping
Key design decisions:
- Read-only enforcement β All SQL is validated by an AST parser (sqlglot) before execution. Any write, DDL, multi-statement, or PRAGMA operation is rejected.
- Demo-first β Every connector and every analysis runs on synthetic data with no configuration. Real credentials are optional.
- Benchmark context β Metrics are always compared to B2B SaaS median benchmarks (A16Z, OpenView) so raw numbers come with meaning.
- Structured output β All tools return
ToolEnvelopeobjects rendered as clean markdown tables, not raw JSON blobs.
Test Suite
219 tests across 14 test files, covering unit tests, integration tests, and smoke tests.
pytest tests/ -q --tb=short
# 219 passed in ~8s
Test files
| File | What it covers |
|---|---|
test_app_smoke.py | Server creation, tool registration, FastMCP integration |
test_connector.py | HubSpot, Mixpanel, Amplitude β demo mode, real API mock, error paths |
test_demo_runtime.py | Full demo scenario execution end-to-end |
test_formatters.py | ToolEnvelope markdown rendering, narrative formatting, business mode |
test_google_ads_connector.py | Google Ads mock API, pagination, error handling |
test_guardrails.py | Attribution guardrails: high-risk rule blocking, force override |
test_ingestion.py | CSV loading, freshness detection, schema validation, mapping engine |
test_meta_ads_connector.py | Meta Ads API mock, rate limits, data normalization |
test_metrics.py | CAC/LTV/ROAS computation, churn modes, Shapley attribution |
test_profiles.py | Save/load/list/delete profiles, custom metric definitions |
test_schema.py | Schema contracts, data validation, column type inference |
test_sql_safety.py | SQL AST validator β 40+ blocked patterns, allowed queries |
test_stripe_connector.py | Stripe invoice/subscription sync, pagination, normalization |
test_workflow_tools.py | funnel_diagnosis, channel_efficiency_review, anomaly_explanation |
Real API connectivity tests
Connectors were tested against live APIs in development. Results:
| Connector | Auth | Data | Notes |
|---|---|---|---|
HubSpot (pat-eu1-...) | β Token accepted | Requires CRM scopes | Add crm.objects.contacts.read + crm.objects.deals.read to Private App |
| Mixpanel | β Auth confirmed | 0 events (empty project) | Funnels fallback to mock on free plan (HTTP 402) |
| Amplitude | β Auth confirmed | 6 real cohorts fetched | Export 404 = no events tracked yet |
| Stripe | β (mock) | Full invoice/subscription sync | Tested against Stripe test mode |
| Meta Ads | β (mock) | Campaign + insights sync | Tested against Graph API mock |
| Google Ads | β (mock) | Campaign + click sync | Full OAuth flow tested |
Configuration Reference
All settings are environment variables (case-insensitive):
Core
| Variable | Default | Description |
|---|---|---|
GROWTH_DATA_DIR | (none) | Path to folder with CSV files |
POSTGRES_URL | (none) | PostgreSQL connection URL (read-only) |
DB_PATH | (in-memory) | DuckDB file path (set to persist between runs) |
SERVER_NAME | growth-os | MCP server display name |
MAX_QUERY_ROWS | 10000 | Maximum rows returned per query |
QUERY_TIMEOUT_SECONDS | 30 | Query execution timeout |
DEFAULT_TRANSPORT | stdio | MCP transport: stdio or sse |
BUSINESS_MODE | false | Enable business-friendly output mode |
SEMANTIC_PROFILE_PATH | (none) | Path to semantic profile JSON |
Stripe
| Variable | Default | Description |
|---|---|---|
STRIPE_API_KEY | (none) | Stripe secret key (sk_live_... or sk_test_...) |
STRIPE_BASE_URL | https://api.stripe.com/v1 | Override for testing |
Meta Ads
| Variable | Default | Description |
|---|---|---|
META_ACCESS_TOKEN | (none) | User access token |
META_AD_ACCOUNT_ID | (none) | Ad account ID (act_...) |
META_API_VERSION | v21.0 | Graph API version |
META_BASE_URL | https://graph.facebook.com | Override for testing |
Google Ads
| Variable | Default | Description |
|---|---|---|
GOOGLE_ADS_DEVELOPER_TOKEN | (none) | Developer token |
GOOGLE_ADS_CUSTOMER_ID | (none) | Customer (CID) without dashes |
GOOGLE_ADS_LOGIN_CUSTOMER_ID | (none) | Manager account CID (if applicable) |
GOOGLE_ADS_ACCESS_TOKEN | (none) | OAuth access token |
GOOGLE_ADS_REFRESH_TOKEN | (none) | OAuth refresh token |
GOOGLE_ADS_CLIENT_ID | (none) | OAuth client ID |
GOOGLE_ADS_CLIENT_SECRET | (none) | OAuth client secret |
GOOGLE_ADS_API_VERSION | v19 | Ads API version |
HubSpot
| Variable | Default | Description |
|---|---|---|
HUBSPOT_ACCESS_TOKEN | (none) | Private App token (pat-eu1-...). Omit = demo mode |
HUBSPOT_BASE_URL | https://api.hubapi.com | Override for testing |
Mixpanel
| Variable | Default | Description |
|---|---|---|
MIXPANEL_API_SECRET | (none) | Project API Secret. Omit = demo mode |
MIXPANEL_PROJECT_ID | (none) | Project numeric ID (optional) |
MIXPANEL_EU | true | Use EU data residency endpoints |
Amplitude
| Variable | Default | Description |
|---|---|---|
AMPLITUDE_API_KEY | (none) | Project API key. Both keys required for live mode |
AMPLITUDE_SECRET_KEY | (none) | Project Secret key |
AMPLITUDE_EU | true | Use EU data residency endpoints |
Docker
# Build
docker build -t growth-os .
# Demo mode (no credentials)
docker run -p 8000:8000 growth-os
# With CSV data
docker run -e GROWTH_DATA_DIR=/data -v /local/csv:/data growth-os
# With PostgreSQL
docker run -e POSTGRES_URL=postgresql://user:pass@host:5432/db growth-os
# With Stripe and HubSpot
docker run \
-e STRIPE_API_KEY=sk_live_... \
-e HUBSPOT_ACCESS_TOKEN=pat-eu1-... \
growth-os
Limitations
- Read-only enforcement. GrowthOS enforces an AST-based SQL sandbox (sqlglot) that blocks any write, DDL, or multi-statement operation. You cannot accidentally modify data.
- Attribution is approximate. UTM-based attribution has known gaps: direct traffic, cross-device, and offline conversions are not captured.
- Forecasts are statistical, not causal. Linear and exponential smoothing forecasts extrapolate historical trends β they do not account for seasonality, planned campaigns, or market shocks. Use for directional guidance only.
- Benchmarks are medians. Industry benchmarks (B2B SaaS, A16Z, OpenView) reflect median-performing companies. Valid reasons to be above or below exist for every metric.
- Data freshness matters. Stale CSVs produce stale answers. Always run
inspect_freshnessbefore drawing conclusions from time-sensitive analyses. - Connector demo mode produces synthetic data. Mock rows use fixed random seeds so output is deterministic and will not match your actual business metrics.
- HubSpot scope requirement. The Private App must have
crm.objects.contacts.readandcrm.objects.deals.readscopes. Without these scopes the connector returns HTTP 403 even with a valid token. - Mixpanel free plan. The Funnels API returns HTTP 402 on free-tier projects. GrowthOS automatically falls back to synthetic funnel data in this case.
- Amplitude key types. Only the server-side API Key + Secret Key pair works for the Export API. The JavaScript SDK snippet key will not authenticate.
Development
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -q --tb=short
# Lint
python -m ruff check src/ tests/
# Verify server starts cleanly
python -c "from growth_os.app.server import create_mcp_server; create_mcp_server()"
Running the REST API in development
pip install -e ".[api]"
growth-os-api
# Swagger: http://localhost:8000/docs
Docs
License
MIT β see LICENSE.




