Clarity MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Clarity MCP ServerShow me traffic to the blog page for the last 2 days."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Clarity MCP Server
A Model Context Protocol (MCP) server that bridges Microsoft Clarity's analytics API with Claude, adding custom date ranges and page-level filtering on top of Clarity's native limitations.
Why This Exists
Microsoft Clarity's public API exposes only a rolling 1–3 day lookback window and lacks page-level filtering — requesting URL breakdowns across an entire site can return thousands of rows and crash on size limits. This server solves both problems:
Custom date ranges: Capture daily snapshots automatically (or manually trigger them), then query any historical range you've captured. Past data before captures began is unrecoverable (Clarity itself doesn't store it), but from the day you start using this, your full historical record accumulates.
Page-level filtering: Filter results by URL substring after Clarity returns data (post-processing), avoiding the oversized-response crashes and letting you focus on specific pages without re-querying.
Related MCP server: mcp-marketing-analytics
What You Get
Three tools accessible from Claude:
get_clarity_insights— fetch live Clarity data (last 1–3 days) with optional URL filteringcapture_clarity_snapshot— manually save today's data locally so it survives past Clarity's 3-day windowget_clarity_historical_insights— query any date range you've captured, with optional URL filtering
Hard Limits (Microsoft's, Not Ours)
Constraint | Value |
Requests per project per day | 10 |
Date range | Rolling 1, 2, or 3 days (no arbitrary historical windows) |
Dimensions per request | Max 3 |
Response size | Max 1,000 rows, no pagination |
These are baked into Clarity's public API and aren't configurable. Plan your queries accordingly.
Prerequisites
Node.js v18+
An active Microsoft Clarity project with admin access (only admins can generate API tokens)
Claude Desktop (for MCP integration)
Setup
1. Generate an API Token
Go to your Clarity project → Settings → Data Export
Click Generate new API token (requires project admin)
Name it (4–32 alphanumeric chars, plus
-,_,.)Copy immediately — shown once
2. Install This Server
git clone https://github.com/mad7droid/clarity-mcp-server.git
cd clarity-mcp-server
npm install
npm run build3. Configure
Create .env in the project root:
CLARITY_API_TOKEN=your_jwt_token_here4. Wire Into Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"clarity": {
"command": "node",
"args": ["/path/to/clarity-mcp-server/dist/index.js"],
"env": {
"CLARITY_API_TOKEN": "your_jwt_token"
}
}
}
}Replace /path/to/clarity-mcp-server with the actual path.
5. Restart Claude Desktop
Fully quit and reopen Claude Desktop. The Clarity tools should now appear.
Usage
Live Insights (Last 1–3 Days)
Ask Claude:
"What's my site traffic for the last 2 days, broken down by device and OS?"
Claude will call get_clarity_insights with numOfDays: 2, dimension1: "Device", dimension2: "OS".
Page-Level Filtering
Ask Claude:
"Show me traffic to /dashboard for the last day."
Claude will call get_clarity_insights with urlFilter: "/dashboard". The URL dimension is auto-added if needed, and results are filtered post-fetch to avoid oversized responses.
Capture Today's Data
Ask Claude:
"Save today's analytics snapshot."
Claude will call capture_clarity_snapshot, writing data/YYYY-MM-DD.json locally. This uses 1 of your 10 daily requests.
Query Historical Ranges
Ask Claude:
"Show me traffic from July 15 to July 20."
Claude will call get_clarity_historical_insights with your requested dates. It returns:
Found dates: snapshots available locally
Missing dates: days you didn't capture (permanently unrecoverable — Clarity never stores them)
Data: per-day snapshots with optional URL filtering applied
Important Notes
Daily Capture Strategy
To build a useful historical archive, run capture_clarity_snapshot roughly daily. A few tips:
One call per day is enough: Each call captures the full URL breakdown. Calling multiple times same day just overwrites.
Historical depth: After 3 days without a capture, that date is lost forever (Clarity's API won't return it).
Fire and forget: Set a daily reminder in your calendar, or ask Claude each morning. No background daemon needed.
URL Filtering Behavior
Filtering happens after Clarity returns data (post-processing).
Results are still bound by Clarity's 1,000-row upstream limit — if Clarity already dropped rows before your filter sees them, they're gone.
Case-insensitive substring matching:
urlFilter: "/admin"matches/admin,/Admin/Users, etc.
Historical Query Limitations
get_clarity_historical_insights only returns data for days you've captured. There is no way to backfill older dates after the fact; only days you explicitly captured with capture_clarity_snapshot are available.
If you started using this server on July 20, you cannot later retrieve data from July 10–19, even if Clarity still has it in the live window — the data was never captured locally.
Examples
Example 1: Diagnose a High-Traffic Day
You: "Show me the top 20 pages from yesterday by traffic volume."
Claude: Calls get_clarity_insights { numOfDays: 1, dimension1: "URL" }Example 2: Track a Page's Performance Over Time
You: "What was the traffic to /checkout over the last 7 days?"
Claude: Calls get_clarity_historical_insights { startDate: "2026-07-14", endDate: "2026-07-20", urlFilter: "/checkout" }
Returns data from whichever days you captured, lists missing dates.Example 3: Compare Devices Across a Week
You: "How does mobile traffic compare to desktop for the last 7 days?"
Claude: Calls get_clarity_historical_insights for the range, but notes that Device breakdown is not available historically (only live data via get_clarity_insights has Device dimension).
Suggests querying the last 3 days live instead for an accurate comparison.Architecture
See docs/ARCHITECTURE.md for a deep dive into the code structure and module responsibilities.
Integration with Claude
See docs/CLAUDE_DESKTOP_SETUP.md for detailed Claude Desktop integration steps and troubleshooting.
Error Handling
HTTP Code | Meaning | Fix |
401 | Missing/invalid/expired token | Regenerate in Data Export settings |
403 | Token not authorized for this project | Verify token is from the correct project |
400 | Invalid parameters |
|
429 | Daily limit (10/project) exceeded | Wait for daily reset (~24h) |
Supported Dimensions
When requesting breakdowns, use one or more of:
Browser, Device, Country/Region, OS, Source, Medium, Campaign, Channel, URL
Note: Historical snapshots are captured with URL dimension only. Other dimensions are only available for live queries (last 1–3 days).
License
MIT. See LICENSE for details.
Contributing
Contributions are welcome. Please open an issue or pull request on GitHub.
References
Available Tools
3 toolscapture_clarity_snapshotA
Capture today's Clarity insights (numOfDays=1, broken down by URL) and save them to a local file (data/YYYY-MM-DD.json, UTC calendar day) so a future get_clarity_historical_insights call can retrieve this day even after it ages out of Clarity's 3-day live window. This must be triggered manually — there is no background schedule — so run it yourself whenever you want today preserved. Uses 1 of your 10 daily Clarity API requests. Safe to re-run any time today: re-running overwrites today's saved file rather than erroring or creating duplicates.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description fully discloses key behaviors: fixed numOfDays=1, output file path and naming with UTC date, overwrite semantics, daily request consumption, and manual trigger requirement. This goes well beyond a simple verb+object description and provides the agent with complete operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise but information-dense, covering purpose, file path, trigger, cost, and safety in two sentences. Every sentence contributes operational context with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool with no annotations, this description is remarkably complete: it states the exact file output, preservation rationale, manual trigger, API usage cost, and idempotent re-run behavior. The only potential gap is the lack of an explicit return value, but given no output schema and the nature of a file-writing tool, it is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is empty (100% coverage). The description explains the fixed configuration (numOfDays=1, URL breakdown) and output side effects, which adds context beyond the empty schema. With no parameters to document, the description meets the baseline and provides no unnecessary detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it captures today's Clarity insights and saves to a local file, with the purpose of enabling future historical retrieval. Distinguishes itself from siblings by describing its snapshot/preservation role versus live/current retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states this must be triggered manually with no background schedule, telling the agent when to run it. Also clarifies it uses 1 of 10 daily API requests and is safe to re-run (overwrites rather than errors). However, it doesn't explicitly name alternatives for current data access or provide 'when not to use' scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_clarity_historical_insightsA
Return locally-captured Clarity snapshots for each day from startDate to endDate (inclusive, YYYY-MM-DD, UTC). This reads ONLY local files previously written by capture_clarity_snapshot — it never calls the Clarity API and cannot retrieve any day that wasn't explicitly captured, because Clarity's own API has no historical endpoint and only ever exposes the last 1-3 days. The result explicitly lists which requested dates were found locally and which are missing, so gaps are visible rather than silently dropped. There is no way to backfill a missing date after the fact. Optional urlFilter post-filters each found day's rows by URL substring, same as on get_clarity_insights. For wide date ranges, passing urlFilter is recommended to avoid returning many uncompressed days at once.
| Name | Required | Description | Default |
|---|---|---|---|
| endDate | Yes | Inclusive end date, YYYY-MM-DD (UTC). | |
| startDate | Yes | Inclusive start date, YYYY-MM-DD (UTC). | |
| urlFilter | No | Optional case-insensitive URL substring filter, same semantics as get_clarity_insights. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavioral traits: it reads only local files, never calls the API, explicitly lists found/missing dates so gaps are visible, and states there is no backfill possibility. It also mentions the performance consideration of uncompressed days for wide ranges, which is beyond what any structured field could convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purpose and each subsequent sentence adds critical constraint or usage detail. Despite being six sentences long, there is no filler; every sentence reveals a non-obvious aspect of the tool's behavior or a practical tip.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity—historical local data, API limitations, and gap reporting—the description covers all necessary context: it clarifies the source (local snapshots), the constraint (no API access), the gap behavior, the optional filter, and performance advice. Even without an output schema, it explains what the result will include (found/missing dates), making the tool fully understandable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description reinforces inclusive date handling and UTC, but its added value comes from clarifying that urlFilter 'post-filters each found day's rows' and advising its use for wide date ranges to avoid oversized responses. This goes beyond the schema's brief descriptions, though much of the core meaning is already in the structured definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return locally-captured Clarity snapshots for each day from startDate to endDate.' It clearly distinguishes itself from siblings by emphasizing it reads local files only and never calls the Clarity API, contrasting with get_clarity_insights and capture_clarity_snapshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use this tool versus alternatives: it can only retrieve previously captured days, cannot use the Clarity API due to its 1-3 day limitation, and cannot backfill missing dates. It also references get_clarity_insights for urlFilter semantics and recommends passing urlFilter for wide date ranges to reduce data volume.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_clarity_insightsA
Fetch Microsoft Clarity dashboard insights (traffic, scroll depth, engagement time, rage/dead clicks, script errors, etc.) for the last 1-3 days, optionally broken down by up to 3 dimensions. IMPORTANT: Clarity's API only supports a rolling 1-3 day lookback (no custom date ranges), and this project is limited to 10 requests per day total, so batch dimensions thoughtfully rather than making repeated calls. Optional urlFilter applies a case-insensitive substring match on the URL field AFTER Clarity returns its response (post-processing only) — results are still capped at Clarity's 1,000-row response limit, so a very broad urlFilter on a large site can still be affected by rows Clarity already dropped before filtering ever sees them. If urlFilter is set and none of dimension1-3 is 'URL', it's auto-added to the first open slot; if all 3 are already used by other dimensions, the call fails with an error asking you to free a slot.
| Name | Required | Description | Default |
|---|---|---|---|
| numOfDays | Yes | How many days back to pull data for: 1 = last 24h, 2 = last 48h, 3 = last 72h. | |
| urlFilter | No | Case-insensitive substring match on the URL field, applied AFTER Clarity returns data (post-processing only). | |
| dimension1 | No | Optional first breakdown dimension. | |
| dimension2 | No | Optional second breakdown dimension. | |
| dimension3 | No | Optional third breakdown dimension. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description bears full responsibility for behavioral disclosure. It extensively discloses rate limits, API lookback restrictions, urlFilter being post-processing only, the 1,000-row cap, auto-adding a URL dimension, and the failure mode when dimension slots are full. This is highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place, covering purpose, constraints, rate limits, and edge cases in a logical order (purpose → important limitations → urlFilter specifics). It is dense but not verbose, and front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description gives a reasonable sense of return content ('traffic, scroll depth, ...') and thoroughly covers operational caveats (rate limits, filtering, dimension slots). It does not detail response structure, but for a dashboard insights fetch, the provided context is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all 5 parameters documented), so the baseline is 3. The description adds significant value by explaining urlFilter's post-processing behavior and the auto-add/failure interplay with dimensions, which the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Fetch') and a named resource ('Microsoft Clarity dashboard insights'), enumerating sample metrics (traffic, scroll depth, etc.) and explicitly scoping to 'last 1-3 days' with 'up to 3 dimensions'. This clearly distinguishes the tool's function from sibling tools like get_clarity_historical_insights.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: rolling 1-3 day lookback, a 10-requests/day project limit, and explicit advice to 'batch dimensions thoughtfully rather than making repeated calls'. It implies the tool is for recent data only but does not explicitly name sibling tools as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.0.0- First observed
capture_clarity_snapshot - First observed
get_clarity_historical_insights - First observed
get_clarity_insights
TDQS
Scored across 3 tools
Each tool has a clearly distinct role: live API retrieval, historical local retrieval, and snapshot capture. The contexts (live vs. historical vs. capture) are unambiguously described, and despite some overlap in 'insights' wording, the source and behavior are distinctly defined.
The naming follows a consistent pattern: 'get_clarity_*' for retrieval variants and 'capture_clarity_snapshot' for the write operation. The verb-noun structure is uniform and intuitive, with the only variation being the descriptor between 'insights' and 'historical_insights'.
Three tools fully cover the intended workflow: live query, snapshot capture, and historical retrieval. This is a well-scoped set for a specialized server, with no unnecessary extras and no missing core functions.
The tool set forms a complete lifecycle for Clarity data access: capture today's data, retrieve live insights, and retrieve previously captured historical data. The known limitations (API lookback and manual capture) are explicitly documented, and there are no operational dead ends within the server's stated role.
Maintenance
Related MCP Connectors
GA4, Google Ads and Search Console in Claude. Read-only OAuth, multi-account for agencies.
Connect Claude to Fathom meeting recordings, transcripts, and summaries
GA4 conversion analyst inside Claude — funnel drops, traffic anomalies, device gaps, with numbers.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Related MCP Servers
- AlicenseAqualityFmaintenanceA Model Context Protocol server that lets you fetch Microsoft Clarity analytics data through Claude for Desktop or other MCP-compatible clients, with support for filtering by dimensions and retrieving various metrics.36,742 npm115MIT
- FlicenseAqualityDmaintenanceEnables natural language querying of Google Analytics 4, Google Search Console, Meta Ads, and Google Ads data through Claude.23-
- FlicenseNot gradedqualityCmaintenanceRead-only MCP server exposing Microsoft Clarity analytics data as tools for ChatGPT Agent Builder.-
- FlicenseNot gradedqualityCmaintenanceEnables Claude to query Microsoft Clarity analytics remotely via HTTP, with bearer token authentication and caching to manage API quotas.-