Docs
MCP server
Ask your analytics from Claude Code, Codex or any MCP client. ClickClacks runs a read-only, remote MCP server with nine tools, scoped by an API key, with provenance on every result.
Want the overview first? The MCP feature page shows what it’s like to use. This guide covers the details.
Endpoint
POST https://app.clickclacks.io/api/v1/mcp
Authorization: Bearer cka_live_... The server uses Streamable HTTP in stateless, tools-only mode. Clients send JSON-RPC requests with POST. It doesn’t create sessions or need an Mcp-Session-Id, and GET and SSE streaming aren’t supported.
Authentication
Create an Analytics API key in Settings → Analytics API keys in the app, then send it as a Bearer token on every request. Settings → MCP shows the server URL, whether you have an active key, and setup snippets ready to copy.
- The key decides the organization and project. Tool arguments never take an organization or project id, and a request that includes one is rejected.
- Missing, invalid or revoked keys get HTTP
401. Revoke a key in Settings to disconnect every client that uses it. - Each key has its own rate limit, and responses are sent with
Cache-Control: private, no-store.
Connect a client
Claude Code
Run this in a terminal, then replace cka_... with your key.
claude mcp add --transport http clickclacks https://app.clickclacks.io/api/v1/mcp --header "Authorization: Bearer cka_..."Codex and other clients
For clients configured with JSON. Key names vary a little between clients, but the URL, the HTTP transport and the Authorization header are the same.
{
"mcpServers": {
"clickclacks": {
"type": "http",
"url": "https://app.clickclacks.io/api/v1/mcp",
"headers": {
"Authorization": "Bearer cka_..."
}
}
}
}Dates and filters
Every tool takes optional start and end dates in YYYY-MM-DD form. Send both or neither. The range is inclusive, end can’t be before start, and a window can’t be longer than 3,660 days. Without dates, a tool reads the last 30 calendar days in UTC, including today.
overview, retention, list_events and event_breakdowns also take report filters: a source, a saved segment, and up to 20 event-property filters, each with up to 100 values. applyTo is matching-events or people-ever-matched. Every id is resolved inside the key’s project.
{
"start": "2026-08-01",
"end": "2026-08-31",
"sourceId": "src_...",
"segmentId": "seg_...",
"propertyFilters": [
{
"property": "plan",
"values": ["pro"],
"applyTo": "matching-events"
}
]
}Tools
All nine are read-only. Schemas are strict: a field that isn’t listed is rejected.
| Tool | Arguments besides dates | Returns |
|---|---|---|
overview | report filters | Overview KPIs and the visitors series. |
list_funnels | none | Saved funnel definitions: steps, ordering and count modes, and summary metrics when available. |
funnel_results | funnelId (required), breakdown | Results for one saved funnel, in its saved ordered/unordered and people/events mode, optionally split by an event property. |
retention | interval: daily, weekly (default) or monthly, plus report filters | The saved retention definition and its cohort grid. |
list_events | search, cursor, plus report filters | Event rows with keyset paging. Search matches an exact event name. |
event_breakdowns | dimension: pages, referrers, countries or events, plus report filters | Page, referrer, country and event-name breakdowns, optionally one dimension. Event rows include event and distinct-people counts. |
list_segments | none | Saved segment definitions, with people counts when available (otherwise null). |
list_sources | none | Sources, their event counts for the window, and health from each source’s last received event. |
friction_findings | state: happening (default), stopped or muted | Findings in that state last seen inside the window. people7d stays the finding’s rolling seven-day count. |
Provenance
Every successful call returns the same information twice: structuredContent with data and provenance for programs, and a text version, with the same provenance embedded, for the model or person reading it.
{
"data": { … },
"provenance": {
"window": { "start": "2026-08-25", "end": "2026-08-31" },
"filters": {},
"scope": {
"organizationId": "org_...",
"projectId": "prj_...",
"label": "organization org_... / project prj_..."
},
"freshness": { "dataAsOf": null, "cache": "not-exposed" },
"degraded": false,
"reason": null,
"definitionHash": "…"
}
}scopealways comes from the verified key.filtersrecords the non-date filters that were accepted.freshness.cacheisnot-exposed: the analytics stores don’t say whether a result came from a cache, so ClickClacks doesn’t guess.definitionHashis included for tools backed by a saved definition, when available.
When a report can’t be read from the warehouse, degraded is true, reason says what’s unavailable, and the report data comes back as null. Saved definitions, such as a funnel’s steps, can still be returned while their results are null. Treat a degraded response as unknown, never as a measurement.
Things to ask
- “Which funnel step loses the most people this week? Show the calculation and cite the ClickClacks provenance.”
- “Compare weekly retention for the last eight weeks and tell me whether any cohort is materially weaker. Stop if the response is degraded.”
- “What are the top pages and referrers this month, and which happening friction findings overlap those paths? Keep unavailable values as unknown.”