{"title":"Consequential MCP Server","format":"markdown","content":"# Consequential MCP Server\n\nQuery your governed revenue metrics from Claude, ChatGPT, Cursor or any\nMCP-compatible client. Read-only.\n\nhttps://mcp.consequential.io/mcp · OAuth 2.1 · Updated 10 September 2026\n\n## Overview\n\nThe Consequential MCP Server is a Model Context Protocol server that lets AI agents and\ncoding assistants query the same governed metric layer that powers your dashboard, your alerts\nand your 8am report.\n\nIt does not query Meta, Google or TikTok directly. It queries the reconciled layer\nunderneath them — where every platform-claimed conversion has already been matched against\norders that actually settled in your store. This is the reason a number you get here matches\nthe number in your weekly report, and the reason both differ from what the ad platforms say\nabout themselves.\n\nCoverage is full-funnel, not ads-only. Profit and contribution margin, new-customer\nacquisition cost, checkout conversion, repeat-purchase behaviour and lifetime value are all\nqueryable, across the same dimensions the product governs: channel, campaign, creative,\nlanding page, device, geo, product and cohort.\n\n**A Consequential account is required.** The server resolves your tenant from\nthe authorised session; there is no anonymous or trial mode. If you don't have an account, the\n[free audit](https://www.consequential.io/audit) connects a store and produces a\nfirst report in about 30 minutes.\n\n**Availability.** MCP access depends on your plan. If the connection fails with\n`403 plan_not_entitled`, your workspace does not have it enabled yet —\n[see plans](https://consequential.io/pricing) or talk to your account contact.\n\n## Compatible clients\n\nAny client that supports remote MCP servers over streamable HTTP. Verified:\n\nClaude Desktop · Claude Code · Claude.ai · ChatGPT · Cursor · Windsurf · Cline · Zed ·\nGitHub Copilot · n8n · Continue · Goose\n\nClients that only support local stdio servers cannot connect. If yours rejects the URL,\nthat is usually why — check for a \"remote\", \"custom connector\" or \"HTTP transport\" option\nbefore assuming a fault.\n\n## Setup\n\n### Prerequisites\n\n- A Consequential account with at least one connected store\n- An MCP-compatible client (see above)\n- Nothing else — no API key to generate, no config secrets to manage\n\n### Endpoint\n\n```\nhttps://mcp.consequential.io/mcp\n```\n\n### Claude Desktop, Claude.ai\n\nSettings → Connectors → Add custom connector. Paste the endpoint. A browser window opens\nfor sign-in and consent; approve the `mcp:read` scope for the brand you want to\nquery. If you belong to more than one brand, you choose at this point.\n\n### Claude Code\n\n```\nclaude mcp add --transport http consequential https://mcp.consequential.io/mcp\n```\n\nThen run `/mcp` inside Claude Code to complete the OAuth flow.\n\n### Cursor, Windsurf, Cline and other config-file clients\n\n```\n{\n  \"mcpServers\": {\n    \"consequential\": {\n      \"url\": \"https://mcp.consequential.io/mcp\"\n    }\n  }\n}\n```\n\nSome clients require an explicit transport declaration:\n\n```\n{\n  \"mcpServers\": {\n    \"consequential\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.consequential.io/mcp\"\n    }\n  }\n}\n```\n\n### Verify\n\nAsk your client: *\"Using Consequential, what's our net revenue for the last 7 days?\"*\nA correct setup returns a figure and names the date range it used. If it returns nothing, call\n`status` first — that tool reports connection health and data freshness without\ntouching your metrics.\n\n## Authentication\n\nOAuth 2.1 with PKCE. There are no API keys, no bearer tokens to paste into a config file,\nand no long-lived credentials sitting on disk.\n\n| Property | Value |\n| --- | --- |\n| Endpoint | https://mcp.consequential.io/mcp |\n| Transport | Streamable HTTP |\n| Auth flow | OAuth 2.1 + PKCE, discovered automatically by the client |\n| Scope | mcp:read |\n| Write scope | None. Does not exist. |\n| Tenant | Resolved per request from the authorised session |\n| Compliance | SOC 2. Data remains within your tenant boundary. |\n\nYour client discovers the authorisation server from the endpoint, opens a consent screen,\nreceives a token and stores it. Tokens are scoped to a single tenant. To switch brands,\ndisconnect and reconnect, choosing the other brand at consent.\n\nThere is no write path\n\nNo tool changes a budget, pauses a campaign, edits a target or writes to an ad account.\nThe scope is `mcp:read` and no write scope exists to request. Decisions still go\nthrough approval inside the product.\n\nThis is a deliberate boundary, not a roadmap gap. An assistant that can both read your\nnumbers and move your money is a different risk profile than most teams want to accept.\n\n## Tools\n\nNine tools. Your client selects among them; you don't need to name one in your question.\n\n#### `search`\n\nFree-text search across metrics, campaigns, creatives, landing pages, products and cohorts.\nThe usual entry point when a question doesn't name a specific metric — \"how did the Father's Day\nstuff do\" resolves through here before anything is queried.\n\n#### `list_metrics`\n\nReturns the governed metric catalogue for your tenant: every available metric with its\ndefinition, formula, unit and pillar. Use it to find out what is measurable before asking for a\nnumber, and to see how a metric is defined when two teams disagree about what \"MER\" means.\n\n#### `query_metrics`\n\nThe primary query tool. Any governed metric, across any date range, broken by any supported\ndimension — channel, campaign, ad set, creative, landing page, device, geo, product, cohort.\nSupports comparison periods, including same weekday last year on the NRF 4-5-4 retail calendar.\n\n#### `query_acquisition`\n\nAcquisition-specific queries with new-customer logic applied: new-customer CAC and MER,\nblended CAC, channel mix, spend efficiency by source. Separate from `query_metrics`\nbecause new-versus-returning classification depends on order history rather than on the ad\nplatform's own view of the user.\n\n#### `get_entity_timeseries`\n\nA time series for a single entity — one campaign, creative, product, landing page or cohort\n— at the granularity you specify. This is what answers \"show me how that ad performed over the\nlast six weeks\" without pulling the whole account.\n\n#### `get_tenant_context`\n\nYour brand's operating context: connected sources, committed targets by pillar, retail\ncalendar, reporting currency, and which parts of the funnel have coverage. Clients typically\ncall this first so answers arrive shaped for your business rather than generically.\n\n#### `validate_response`\n\nChecks a generated answer back against source data before it reaches you. It is the guard\nagainst a confident number that isn't in the warehouse — the failure mode that makes people\ndistrust AI over data in the first place.\n\n#### `fetch`\n\nRetrieves a specific record by identifier: a report, an alert, a campaign, a creative. Used\nwhen the conversation already knows what it wants and doesn't need a search.\n\n#### `status`\n\nServer health, connection state, and data freshness per source — when each platform last\nsynced and when reconciliation last ran. Call this first when numbers look unexpected.\n\n## Business context\n\n`get_tenant_context` matters more than it sounds. Without it, an assistant\nanswering \"are we doing well\" has no idea what \"well\" means for your brand.\n\nThe context includes the targets you committed to, the retail calendar you report on, your\nreporting currency, and which pillars have coverage. An answer that knows your Q3 target is\n$2.4M at 1.9 new-customer MER is a different answer from one that just reports a number.\n\nCoverage is also visible: if a pillar has no committed target, that shows as a gap rather\nthan being silently reported as healthy. A metric with no target can be grouped but not\ngoverned, and the context makes that explicit.\n\n## Data sources\n\n160+ connectors feed the reconciled layer. The MCP server queries the layer, not the\nplatforms, so its answers are consistent with everything else in the product.\n\n| Category | Includes |\n| --- | --- |\n| Commerce | Shopify, Shopify Plus, Amazon, WooCommerce, order and OMS data |\n| Advertising | Meta, Google Ads, TikTok, Microsoft, Pinterest, Snap |\n| Analytics | GA4, Adobe Analytics, first-party server-side collection |\n| Lifecycle | Klaviyo, Attentive, Recharge, Gorgias |\n| Warehouse | Snowflake, BigQuery, Databricks, Segment |\n\n## Examples\n\nQuestion shapes that work well, and what they exercise.\n\n### Diagnosing a drop\n\n*\"Our blended MER fell last week. Where did it go?\"* — resolves through\n`query_metrics` for the movement, then `get_entity_timeseries` on the\nchannels or campaigns that carry it. Expect an answer that names a dimension rather than\nrestating the decline.\n\n### Checking incrementality of a channel\n\n*\"How much of our retargeting spend is buying customers we already had?\"* — uses\n`query_acquisition`, where new-versus-returning is decided by order history rather\nthan platform classification.\n\n### Margin by product\n\n*\"What's contribution margin on our top ten SKUs this month?\"* —\n`list_metrics` to confirm how margin is defined for your tenant, then\n`query_metrics` broken by product.\n\n### Cohort health\n\n*\"Is the March cohort behind January at the same age?\"* —\n`get_entity_timeseries` on both cohorts, aligned by weeks since first order rather\nthan calendar date.\n\n### Reconciling against a platform\n\n*\"Why does your revenue number differ from Meta's?\"* — `query_metrics`\nreturns both the platform-claimed figure and the settled-order figure, and\n`validate_response` confirms the answer against source before it is returned.\n\n### Pacing\n\n*\"Are we going to hit the quarter?\"* — `get_tenant_context` for the\ncommitted target, then `query_metrics` for actuals and forecast landing point.\n\n## Limits and behaviour\n\n### Read-only\n\nEvery tool is a read. Nothing mutates state in Consequential or in any connected platform.\n\n### Data freshness\n\nAnswers reflect the last completed reconciliation, not the live platform APIs. A campaign\nlaunched an hour ago may not appear until the next run. `status` reports when each\nsource last synced.\n\n### Governed definitions only\n\nThe server will not invent a metric. If you ask for something outside the catalogue, it\nsays so rather than approximating — a deliberate choice, because a plausible-sounding\napproximation is worse than a refusal when the number is going into a board deck.\n\n### Tenant isolation\n\nA token is scoped to one tenant. There is no cross-tenant query path, and no way to widen\nscope from inside a session.\n\n## Troubleshooting\n\n### Client rejects the URL\n\nThe client likely supports only local stdio servers. Check for a \"remote server\", \"custom\nconnector\" or \"HTTP transport\" option, or update to a build that supports remote MCP.\n\n### No consent screen appears\n\nA stale token is usually the cause. Remove the connector, add it again, and the OAuth flow\nrestarts from the beginning.\n\n### \"No tenant found\"\n\nThe signed-in account isn't attached to a Consequential tenant. Sign in with the address you\nuse for the product. If you were invited to a brand recently, confirm the invitation was\naccepted.\n\n### Numbers differ from yesterday\n\nCall `status`. Reconciliation runs on a schedule; a source that synced an hour\nago and one that synced last night will not agree until the next run completes.\n\n### Numbers differ from Meta or Google\n\nExpected, and the point. Platform figures count conversions the platform believes it caused;\nours count orders that settled. Ask the assistant to show both — it can.\n\n### A metric is missing\n\nCall `list_metrics` to see the catalogue for your tenant. If the metric genuinely\nisn't there, it hasn't been assigned to a pillar yet, which is a configuration change rather\nthan a server issue.\n\n## Support\n\n[support@consequential.io](mailto:support@consequential.io) ·\n[docs.consequential.io](https://docs.consequential.io) ·\n[consequential.io](https://www.consequential.io)\n\nWhen reporting a problem, include the output of `status`, your client and its\nversion, and the question you asked. That is almost always enough to reproduce it.\n"}