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

http
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.

terminal
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.

mcp config
{
  "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.

arguments
{
  "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.

ToolArguments besides datesReturns
overviewreport filtersOverview KPIs and the visitors series.
list_funnelsnoneSaved funnel definitions: steps, ordering and count modes, and summary metrics when available.
funnel_resultsfunnelId (required), breakdownResults for one saved funnel, in its saved ordered/unordered and people/events mode, optionally split by an event property.
retentioninterval: daily, weekly (default) or monthly, plus report filtersThe saved retention definition and its cohort grid.
list_eventssearch, cursor, plus report filtersEvent rows with keyset paging. Search matches an exact event name.
event_breakdownsdimension: pages, referrers, countries or events, plus report filtersPage, referrer, country and event-name breakdowns, optionally one dimension. Event rows include event and distinct-people counts.
list_segmentsnoneSaved segment definitions, with people counts when available (otherwise null).
list_sourcesnoneSources, their event counts for the window, and health from each source’s last received event.
friction_findingsstate: happening (default), stopped or mutedFindings 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.

structuredContent
{
  "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": "…"
  }
}
  • scope always comes from the verified key.
  • filters records the non-date filters that were accepted.
  • freshness.cache is not-exposed: the analytics stores don’t say whether a result came from a cache, so ClickClacks doesn’t guess.
  • definitionHash is 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.”