Grips Intelligence MCP server (v2)
A Model Context Protocol (MCP) server that exposes the Grips Intelligence e-commerce data API to any MCP client — Claude Desktop, Cowork, Claude Code, etc.
v2 is a clean rebuild of v1 with defensive data handling baked in from day one. It fixes the ".map is not a function" class of bugs that v1.x needed a runtime patch to address — thin or unknown domains now degrade to a clean "no data" response instead of crashing the tool call.
What's in it
| Tool | What it does |
|---|---|
grips_get_domain_performance | Monthly revenue / transactions / sessions / ad cost / AOV / CR / CPC for one or more domains |
grips_get_daily_performance | Daily revenue / transactions / sessions (limited coverage) |
grips_get_channels | Organic / Paid Search / Direct / Referral / Social breakdown — timeseries + aggregated |
grips_get_adwords | Paid-media spend, clicks, and CPC — timeseries + aggregated |
grips_get_devices | Mobile / desktop / tablet revenue, sessions, CR, AOV |
grips_compare_domains | Parallel per-domain pull with leaderboard ranking; per-domain errors are isolated |
grips_raw_query | Escape hatch — send an arbitrary Grips GraphQL query |
All tools default to markdown output for readability. Pass format: "json" for machine-parseable output.
Installation
npm install
The prepare script auto-builds dist/ when you run npm install.
Configuration
Set your Grips API key in the MCP client's server config. For Claude Desktop, that's ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"grips": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/grips-mcp-server-v2/dist/index.js"
],
"env": {
"GRIPS_API_KEY": "your-api-key-here",
"GRIPS_DEFAULT_COUNTRY": "US"
}
}
}
}
Required env:
GRIPS_API_KEY— your Grips API token (sent as thegrips-api-keyheader).
Optional env:
GRIPS_DEFAULT_COUNTRY—US,GB, orDE. Defaults toUSif unset or invalid.
After editing the config, fully quit Claude Desktop (Cmd+Q — not just closing the window) and reopen.
What's different from v1
v1 crashed on a specific API response shape: when Grips returned a thinly-covered or unknown domain, the timeseries field came back as {} rather than null, undefined, or []. The code used (data.timeseries ?? []).map(...), which only guards against null/undefined — not against {}. Result: "data.timeseries ?? []).map is not a function".
v2 routes every payload field through toArray<T>() (for arrays) or toObject<T>() (for dict-shaped responses like the devices endpoint) before use. Any non-array / non-object value falls through to a safe empty default, and the tool returns a clean "no data" response instead of throwing.
Other changes:
- Date normalisation is consistent (every date becomes
YYYY-MM-DDin UTC) across all tools, so rows don't slip across day boundaries in non-UTC timezones. - Currency / integer / percent formatters render
—for missing values instead of$NaNor0.00%. - Error messages now include actionable hints — 401 → "check your API key", 429 → "rate-limited, narrow your window", etc.
- Per-domain error isolation in
grips_compare_domains— one thin domain in an 8-domain compare no longer breaks the other seven. - Character-budget truncation — responses cap at ~200KB with a visible notice so multi-domain pulls don't blow up the context window.
Development
npm run dev # watch mode, rebuilds on change
npm run build # one-shot build to dist/
Testing from the command line
Test that the server boots without errors (it will exit on EOF from stdin):
GRIPS_API_KEY=your-key node dist/index.js < /dev/null
You should see [grips-mcp] grips-mcp-server v2.0.0 ready (default country: US). on stderr and no crash.
For interactive testing, use @modelcontextprotocol/inspector:
npx @modelcontextprotocol/inspector node dist/index.js
API reference
Grips documents their public schema at https://gripsintelligence.com/knowledge-base/api. The queries this server uses are copied verbatim from that page.
Supported countries today: US, GB, DE. Everything else will error at the API.
Licence
Private — not for external distribution.