Skip to content

Astoriel/GrowthOS

Repository files navigation

GrowthOS

Answer growth questions in plain English. No SQL required.

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.

Python 3.10+ License: MIT Tests: 219 passing MCP tools: 49 DuckDB


Screenshots

CAC & LTV by Channel Funnel Analysis
CAC/LTV Funnel
Churn Segmentation Weekly Growth Summary
Churn Growth Summary

REST API (Swagger UI) Swagger


What GrowthOS Does

GrowthOS sits between your AI assistant and your data. It exposes 49 MCP tools that your AI can call to run real analysis — funnel breakdowns, CAC/LTV calculations, cohort retention matrices, anomaly detection, SQL queries, and more — then formats results with benchmark comparisons so you get context, not just numbers.

Claude / Cursor / any MCP client
        │
        ▼
┌──────────────────────────────┐
│        GrowthOS MCP Server   │
│  49 tools · DuckDB · SQL     │
│  Semantic layer · Benchmarks │
└────────────┬─────────────────┘
             │
   ┌──────────────────────┐
   │   Your data sources  │
   │  CSV · PostgreSQL     │
   │  Stripe · Meta Ads   │
   │  Google Ads · HubSpot│
   │  Mixpanel · Amplitude│
   └──────────────────────┘

5 Questions GrowthOS Answers Reliably

  1. "Why did CAC increase last week and is it sustainable?" Channel-level CAC, LTV, and ROAS with automated invest/cut/watch classification.

  2. "Where is our funnel breaking and what should we test first?" Step-by-step conversion rates with the biggest drop-off identified automatically.

  3. "How bad is our retention and how does it compare to benchmarks?" Cohort retention matrix vs. B2B SaaS medians with Good / Average / Poor rating.

  4. "Which users are at risk of churning and how do we bring them back?" Active / At-Risk / Churned segmentation using configurable inactivity thresholds.

  5. "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.read
  • crm.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 ToolEnvelope objects 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_freshness before 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.read and crm.objects.deals.read scopes. 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.

About

GrowthOS is an open-source MCP analytics server that connects your AI assistant

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages