Outlit MCP Server
Query customer intelligence data through 7 MCP tools covering customer profiles, revenue metrics, activity timelines, and raw SQL analytics access.
Quick Start
digraph quickstart {
rankdir=LR;
node [shape=box];
start [label="What data?" shape=diamond];
customer_list [label="Multiple\ncustomers"];
customer_single [label="Single\ncustomer"];
analytics [label="Custom\nanalytics"];
discover [label="Schema\ndiscovery"];
list_tool [label="outlit_list_customers" shape=ellipse style=filled fillcolor=lightblue];
detail_tool [label="outlit_get_customer" shape=ellipse style=filled fillcolor=lightblue];
query_tool [label="outlit_query" shape=ellipse style=filled fillcolor=lightyellow];
schema_tool [label="outlit_schema" shape=ellipse style=filled fillcolor=lightgray];
start -> customer_list -> list_tool;
start -> customer_single -> detail_tool;
start -> analytics -> query_tool;
start -> discover -> schema_tool;
}
First Call: Schema Discovery
Before writing SQL queries, discover available tables and columns:
// Discover SQL tables and columns
{ "tool": "outlit_schema" }
// Discover available data entities
{ "tool": "outlit_list_entities" }
Common Patterns
Find at-risk customers:
{
"tool": "outlit_list_customers",
"billingStatus": "PAYING",
"noActivityInLast": "30d",
"orderBy": "currentMrr",
"orderDirection": "desc"
}
Revenue breakdown (SQL):
{
"tool": "outlit_query",
"sql": "SELECT billing_status, count(*) as customers, sum(mrr_cents)/100 as mrr_dollars FROM customer_dimensions GROUP BY 1 ORDER BY 3 DESC"
}
Event analytics (SQL):
{
"tool": "outlit_query",
"sql": "SELECT event_type, count(*) FROM events WHERE occurred_at >= now() - INTERVAL 30 DAY GROUP BY 1 ORDER BY 2 DESC LIMIT 10"
}
Tool Selection Guide
digraph tool_selection {
rankdir=TB;
node [shape=box fontsize=10];
edge [fontsize=9];
start [label="What do you need?" shape=diamond];
// First level decisions
list [label="Browse/filter customers"];
single [label="Single customer deep dive"];
aggregate [label="Aggregated metrics"];
discover [label="Explore schema"];
// Tool outcomes
list_customers [label="outlit_list_customers" shape=ellipse style=filled fillcolor=lightblue];
get_customer [label="outlit_get_customer" shape=ellipse style=filled fillcolor=lightblue];
get_timeline [label="outlit_get_timeline" shape=ellipse style=filled fillcolor=lightblue];
get_revenue [label="outlit_get_customer_revenue" shape=ellipse style=filled fillcolor=lightblue];
query [label="outlit_query (SQL)" shape=ellipse style=filled fillcolor=lightyellow];
schema [label="outlit_schema" shape=ellipse style=filled fillcolor=lightgray];
list_entities [label="outlit_list_entities" shape=ellipse style=filled fillcolor=lightgray];
start -> list [label="segments, at-risk lists"];
start -> single [label="specific customer"];
start -> aggregate [label="reports, dashboards, SQL"];
start -> discover [label="what's available?"];
list -> list_customers;
single -> get_customer [label="overview + contacts"];
single -> get_timeline [label="activity history"];
single -> get_revenue [label="billing data"];
aggregate -> query [label="write SQL"];
aggregate -> schema [label="see columns first"];
discover -> list_entities;
discover -> schema;
}
Quick Reference
| Tool | Purpose | Key Params |
|---|---|---|
outlit_list_customers | Filter/paginate customers | billingStatus, noActivityInLast, mrrAbove |
outlit_get_customer | Single customer details | customer, include[], timeframe |
outlit_get_timeline | Activity history | customer, channels[], eventTypes[] |
outlit_get_customer_revenue | Revenue + attribution | customer, includeAttribution |
outlit_query | Raw SQL queries | sql, limit |
outlit_schema | SQL table schemas | table (optional) |
outlit_list_entities | Available entities | (none) |
References
| Reference | When to Read |
|---|---|
| Query Patterns | SQL examples for common analytics: MRR, cohorts, events, churn |
| SQL Guide | Complete table schemas, security model, ClickHouse tips |
| Workflows | Multi-step analysis: churn risk, revenue dashboards, segmentation |
| Troubleshooting | Error codes, common issues, debugging strategies |
| Responses | Full response examples, parsing guidance |
Core Tools
outlit_list_customers
Filter and paginate customers with risk signal indicators.
| Parameter | Type | Values | Default |
|---|---|---|---|
status | enum | PROVISIONAL, ACTIVE, CHURNED, MERGED | (all) |
billingStatus | enum | NONE, TRIALING, PAYING, CHURNED | (all) |
type | enum | COMPANY, INDIVIDUAL | (all) |
hasActivityInLast | enum | 7d, 14d, 30d, 90d | (none) |
noActivityInLast | enum | 7d, 14d, 30d, 90d | (none) |
mrrAbove | number | cents (e.g., 10000 = $100) | (none) |
mrrBelow | number | cents | (none) |
search | string | name or domain | (none) |
orderBy | enum | lastActivityAt, firstSeenAt, name, currentMrr | lastActivityAt |
orderDirection | enum | asc, desc | desc |
limit | number | 1-100 | 20 |
cursor | string | pagination token | (none) |
Risk Signals (returned in response): healthy (≤7d), at_risk (7-30d), critical (30d+)
Example - High-value at-risk:
{
"billingStatus": "PAYING",
"noActivityInLast": "30d",
"mrrAbove": 50000,
"orderBy": "currentMrr",
"orderDirection": "desc",
"limit": 25
}
outlit_get_customer
Get complete customer profile with optional includes.
| Parameter | Type | Description | Required |
|---|---|---|---|
customer | string | Customer ID, domain, or name | Yes |
include | array | Data sections to fetch | No |
timeframe | enum | 7d, 30d, 90d | No (30d) |
Include Options: contacts (journey stages), revenue (MRR, LTV), recentTimeline (activity events), behaviorMetrics (activity counts)
Example - Full profile:
{
"customer": "acme.com",
"include": ["contacts", "revenue", "recentTimeline", "behaviorMetrics"],
"timeframe": "30d"
}
outlit_get_timeline
Get activity timeline for a customer.
| Parameter | Type | Description | Required |
|---|---|---|---|
customer | string | Customer ID or domain | Yes |
channels | array | Filter by channel | No |
eventTypes | array | Filter by event type | No |
startDate | string | ISO 8601 timestamp | No |
endDate | string | ISO 8601 timestamp | No |
limit | number | 1-100 | No (50) |
cursor | string | Pagination token | No |
Channels: EMAIL, SLACK, INTERCOM, CALENDAR, CALL, DOCUMENT
Example - Email and meeting activity:
{
"customer": "cust_123",
"channels": ["EMAIL", "CALENDAR"],
"limit": 50
}
outlit_get_customer_revenue
Get revenue metrics and attribution for a customer.
| Parameter | Type | Description | Required |
|---|---|---|---|
customer | string | Customer ID or domain | Yes |
timeframe | enum | 30d, 90d, 12m, all | No (12m) |
includeAttribution | boolean | Include UTM/channel data | No (true) |
includeBillingHistory | boolean | Include billing events | No (true) |
Example:
{
"customer": "acme.com",
"includeAttribution": true,
"includeBillingHistory": true
}
Raw SQL: outlit_query
Execute custom SQL queries against analytics data with built-in security.
Parameters
| Parameter | Type | Description | Required |
|---|---|---|---|
sql | string | SQL SELECT query | Yes |
limit | number | Max rows (1-10000) | No (1000) |
Available tables: events, customer_dimensions, user_dimensions, mrr_snapshots
Use outlit_schema to discover columns before writing queries.
Security: Only SELECT queries allowed. Organization data isolated via row policies. External access functions blocked.
Quick SQL Examples
MRR by billing status:
{
"tool": "outlit_query",
"sql": "SELECT billing_status, count(*) as customers, sum(mrr_cents)/100 as mrr FROM customer_dimensions GROUP BY 1"
}
Daily event volume:
{
"tool": "outlit_query",
"sql": "SELECT toDate(occurred_at) as day, count(*) as events FROM events WHERE occurred_at >= now() - INTERVAL 30 DAY GROUP BY 1 ORDER BY 1"
}
Top customers by activity:
{
"tool": "outlit_query",
"sql": "SELECT customer_id, customer_domain, count(*) as events FROM events WHERE occurred_at >= now() - INTERVAL 30 DAY GROUP BY 1, 2 ORDER BY 3 DESC LIMIT 25"
}
See Query Patterns for comprehensive SQL examples covering all common analytics use cases.
See SQL Guide for complete table schemas, security model, and error handling.
Schema Discovery
outlit_schema
Get table schemas for SQL queries.
// All tables
{ "tool": "outlit_schema" }
// Specific table with columns
{ "tool": "outlit_schema", "table": "events" }
Response includes: Column names, types, descriptions, and example queries.
outlit_list_entities
List all queryable data entities.
{ "tool": "outlit_list_entities" }
outlit_get_entity_schema
Get detailed schema for a specific entity.
{ "tool": "outlit_get_entity_schema", "entity": "customer" }
Data Model
Customer States
status: PROVISIONAL (new), ACTIVE (active customer), CHURNED (no longer active), MERGED (combined with another)
billingStatus: NONE (no billing), TRIALING (trial period), PAYING (active subscription), CHURNED (cancelled)
Contact Journey Stages
DISCOVERED → SIGNED_UP → ACTIVATED → ENGAGED → INACTIVE
Data Formats
- •Monetary values: Cents (100 = $1.00)
- •Timestamps: ISO 8601 (
2025-01-15T10:30:00Z) - •IDs: String prefixes (
cust_,contact_,evt_)
Pagination
All list endpoints use cursor-based pagination:
// First request
{ "tool": "outlit_list_customers", "limit": 25 }
// Response
{
"items": [...],
"pagination": {
"hasMore": true,
"nextCursor": "eyJsYXN0QWN0aXZpdHlBdCI6Li4ufQ==",
"total": 156
}
}
// Next page
{ "tool": "outlit_list_customers", "limit": 25, "cursor": "eyJsYXN0QWN0aXZpdHlBdCI6Li4ufQ==" }
Always check pagination.hasMore before requesting more pages.
Best Practices
- •Start with schema discovery — Call
outlit_schemabefore writing SQL - •Use filters at the source — Filter in the query, not after fetching
- •Request only needed includes — Omit
includeoptions you don't need - •Prefer customer tools for single lookups — Don't use SQL for single customer queries
- •Add time filters to SQL — Always include
WHERE occurred_at >= ...for event queries - •Convert cents to dollars — Divide monetary values by 100 for display
- •Use LIMIT in SQL — Cap result sets to avoid large data transfers
Known Limitations
- •SQL is read-only: No INSERT, UPDATE, DELETE operations
- •Organization isolation: Cannot query data from other organizations
- •Timeline requires customer: Cannot query timeline across all customers
- •MRR filtering is post-fetch: May be slower on large datasets in list_customers
- •Event queries require time filters: Queries without date ranges scan all data
Troubleshooting
See Troubleshooting Guide for detailed solutions.
Quick fixes:
| Issue | Solution |
|---|---|
| 401 Unauthorized | Check authentication, re-authorize MCP connection |
| 404 Not Found | Verify customer ID/domain exists |
| Empty results | Widen filters, check timeframe |
| Slow queries | Add filters, reduce limit, add time constraints |
| SQL table not found | Use outlit_schema to see available tables |
| SQL syntax error | Check ClickHouse syntax (not MySQL/PostgreSQL) |