The Worker doubles as an MCP server. Point a client at https://YOUR-DATAPENNY-URL/mcp with a read-only key and it can see what your dashboard sees, with nothing extra to host.
The quick way
From your clone:
npx datapenny mcp
It makes a read-only key, registers DataPenny with Claude Code when it finds it, and prints what the other clients need. Not near a terminal? Setup → API keys & AI agents makes a key and shows each client’s snippet with your values filled in.
Client by client
Read keys start with dpr_.
Claude Code
claude mcp add --transport http --scope user datapenny https://YOUR-DATAPENNY-URL/mcp \
--header "Authorization: Bearer dpr_YOUR_KEY"
Cursor
For every project use ~/.cursor/mcp.json, and for just one use .cursor/mcp.json inside it:
{
"mcpServers": {
"datapenny": {
"url": "https://YOUR-DATAPENNY-URL/mcp",
"headers": { "Authorization": "Bearer dpr_YOUR_KEY" }
}
}
}
VS Code
Put this in .vscode/mcp.json, or run the MCP: Open User Configuration command:
{
"servers": {
"datapenny": {
"type": "http",
"url": "https://YOUR-DATAPENNY-URL/mcp",
"headers": { "Authorization": "Bearer dpr_YOUR_KEY" }
}
}
}
Codex
~/.codex/config.toml:
[mcp_servers.datapenny]
url = "https://YOUR-DATAPENNY-URL/mcp"
http_headers = { "Authorization" = "Bearer dpr_YOUR_KEY" }
Windsurf
Copy the Cursor block into ~/.codeium/windsurf/mcp_config.json, and rename url to serverUrl.
The tools
None of these can change anything. They all share the same arguments: site (id or domain), then either period (today, yesterday, 24h, 2d, 7d, 30d, 90d, mtd, last_month, 12m or all) or a from and to, plus optional filters, for example {"utm_campaign": "pricing-thread"}.
| Tool | What it answers |
|---|---|
list_sites |
All your sites, with numbers for today and the last week and month. |
get_overview |
The headline numbers against the previous period, with chart notes. |
get_breakdown |
A ranked list for any dimension: referrers, pages, countries, goals and so on. |
compare_periods |
Two periods side by side, with what rose and fell the most. |
list_sales |
Recent sales and the source behind each. |
list_visitors, get_visitor |
Recent visitors, or a single visitor’s full trail. |
get_realtime |
Who’s on the site now. |
get_goals, get_funnels |
Goal completions and funnel steps. |
get_customer_value |
What customers from each first source go on to pay. |
get_peak_hours |
The busiest hours of the week, for traffic and for sales. |
get_engagement |
How much of each page gets read. |
get_purchase_paths |
The route customers took to a first sale. |
From the terminal
From your clone:
npx datapenny sites
npx datapenny stats example.com --period 7d
npx datapenny sources --by revenue
npx datapenny breakdown country --filter referrer=google.com
npx datapenny compare
npx datapenny sales -n 10
npx datapenny visitor 3f2a91c0
npx datapenny live
Add --json for scripts and agents. npx datapenny query get_peak_hours '{"period":"30d"}' calls any tool directly.
Elsewhere, such as in CI, set your address and key:
export DATAPENNY_URL=https://YOUR-DATAPENNY-URL
export DATAPENNY_API_KEY=dpr_YOUR_KEY
npx datapenny stats --json
The read API
The same tools answer over plain HTTP, with the same Authorization header: GET /api/v1/get_overview?site=example.com&period=7d&filter=referrer:x.com. GET /api/v1/tools lists them. MCP itself is JSON-RPC over POST /mcp, so a tool call is {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_overview","arguments":{"period":"7d"}}}.
What a key can see
- A key reads every site in your account and can’t write anything. You see it once, and DataPenny keeps only its hash. To cancel one, use Setup → API keys & AI agents or
npx datapenny key revoke. - Customer names and emails are left out by default. To include them, tick the option when making the key, or run
npx datapenny key create --pii. - Your agent calls your own Worker with nothing in between. Whatever it reads then reaches your AI provider, under that provider’s terms.