Analytics for builders
Give Claude Code or Cursor read access to your site's traffic over MCP
By Emily Parker 路 Oct 19, 2026 路 9 min read
You built the site with an agent, so the agent already knows your routes, your copy and your last deploy. What it does not know is what happened afterward. Connecting it to your traffic closes that gap: you ask "which page lost visits after Tuesday's deploy" in the same session where you can fix it.
This post shows the exact config for both tools, how to confirm it works, and what the agent can and cannot reach once it is connected.
What you are connecting
Peeko hosts an MCP server at usepeeko.com/api/mcp. You reach it with a bearer API key. It is read only, with one exception: a single tool creates a site. Every call is scoped by construction to the sites of the teams you belong to, so a key cannot reach a site that belongs to somebody else.
The command line speaks the same endpoint. npx @usepeeko/cli needs no install, and a command and a tool call return the same numbers. That gives you a way to check the agent: when it quotes a figure, run the same question through the CLI and compare.
Source: Cloudflare, The crawl-to-click gap: Cloudflare data on AI bots, training, and referrals, Aug 29, 2025. Retrieved Oct 16, 2026.
The chart above is the reason one section of this post exists. Cloudflare reports that over a 12 month window to Aug 2025, 80% of AI crawling was for training, 18% for search and 2% for user actions. That describes Cloudflare's network, not your site, and a share of requests says nothing about how many companies visit a small site. But it shows why an agent asked "are AI bots reading my site" needs the categories, not one total. Peeko files every recognized crawler hit under AI answers, Search indexing, AI training or Other AI bots, and the agent can only give you a useful answer if it keeps those apart.
Store the key outside the config
Put the key in an environment variable before you touch either tool. The name is yours to choose; this post uses PEEKO_API_KEY.
export PEEKO_API_KEY="paste-your-key-here"
Add that line to your shell profile so it survives a restart. Treat the key as read access to the numbers of every site on your teams. Do not paste it into a file that goes to git.
Connect Claude Code
Claude Code adds a remote server with one command. Its documentation shows the --transport http and --header flags for a bearer token:
claude mcp add --transport http peeko https://usepeeko.com/api/mcp \
--header "Authorization: Bearer $PEEKO_API_KEY"
Your shell expands $PEEKO_API_KEY before Claude Code sees it, so the stored entry holds the literal key. By default the entry has local scope: it loads in the current project only, is not shared with your team, and is stored in ~/.claude.json. Add --scope user to load it in every project, or --scope project to write it to .mcp.json in the project root so it is shared through version control.
If you choose project scope, do not let the literal key land in a committed file. Write the entry by hand and reference the variable instead. Claude Code expands ${VAR} in the url and headers of an HTTP server:
{
"mcpServers": {
"peeko": {
"type": "http",
"url": "https://usepeeko.com/api/mcp",
"headers": {
"Authorization": "Bearer ${PEEKO_API_KEY}"
}
}
}
}
Each teammate sets their own PEEKO_API_KEY, and the file in git holds no secret. One trap from the documentation: if a variable has no value and no default, the config still loads, Claude Code shows a warning, and the literal text ${PEEKO_API_KEY} is sent as the token. The server then rejects it.
The add command does not validate the token. Run /mcp inside Claude Code afterward. A server with bad credentials shows a failure mark with the HTTP status in the detail.
Connect Cursor
Cursor reads .cursor/mcp.json in a project for project-specific tools, or ~/.cursor/mcp.json to make a server available in every project. A remote server uses url and headers instead of command:
{
"mcpServers": {
"peeko": {
"url": "https://usepeeko.com/api/mcp",
"headers": {
"Authorization": "Bearer ${env:PEEKO_API_KEY}"
}
}
}
}
Cursor resolves ${env:NAME} in url and headers, which keeps the key out of the file. For remote servers, set the variable in your shell profile or system environment. Cursor's documentation says envFile works only for STDIO servers, so it will not help here. Start Cursor from a shell that has the variable set, or set it system wide, and restart Cursor after you change it.
Confirm it works before you trust it
Two checks take a minute.
First, ask the agent which tools it received from the peeko server. The list comes from the server, so it is the authoritative statement of what the agent can do. This post does not list tool names because the server, not a blog post, is the source for them.
Second, ask one question with a number you can verify by eye. "How many page views did my site get yesterday?" is enough. Open your dashboard, or run the same question through npx @usepeeko/cli, and compare. They should match, because the CLI and the agent use the same endpoint.
What the agent can reach
Everything Peeko records for the sites on your teams, read only. In concrete terms:
- Page views, outbound clicks and custom events. The five click kinds that need no code (outbound, phone, email, whatsapp and form) are recorded automatically. Anything else comes from a
data-peeko-eventattribute or awindow.peeko.eventcall. - Goals, funnels and revenue. A goal is a definition rather than a counter, so a goal written today counts over months before it was written. A funnel holds two to five steps and follows a person rather than a visit. Revenue from a
window.peeko.revenuecall and revenue from a verified Stripe webhook are separate totals and are never added together. Amounts in different currencies are listed, never converted. - AI crawler hits. Crawlers do not run JavaScript, so these come from a separate server side path, the
@usepeeko/bot-trackmiddleware. Peeko matches user agents against a curated list of 55 agents from 21 companies. - Visits from AI assistants. Visits that arrive from ChatGPT, Claude, Perplexity, Copilot and Gemini are counted from ordinary page views by their referrer. The post on counting visits from AI assistants by referrer covers how.
- Search Console and Bing data, if you connected them. Both connect read only, and their rows are kept for sixteen months.
- History. Page views, events and crawler hits are kept three years by default, and a site owner can set that window anywhere from 30 days to ten years. The agent can ask about a date before it existed in your head.
The one write is a tool that creates a site. If you do not want an agent creating sites, say so in its instructions. The key does not let it change a goal, delete a funnel or alter retention, because those are not tools the server offers.
What the agent cannot reach
This part matters more than the list above, because an agent that cannot find an answer will often produce a plausible one.
Other people's sites. The key is scoped to your teams. A question about a competitor's traffic returns nothing from Peeko, and the agent should say so rather than estimate.
Anyone's IP address. No IP address is ever stored. A visitor is the first part of a one way keyed hash of the address and browser string, and the address is never written to a database or a log. There is nothing to look up.
A person across days in the People number. The hash behind the People number mixes in the date and is re-salted every day. You cannot add daily People figures to get distinct people over a week, and neither can the agent. A second hash without the date is what tells a returning visitor from a new one and builds a journey, and it is the identity behind goals, funnels and revenue. If you want "how many people, over the whole month, finished checkout", ask a funnel question, not a sum of daily counts.
The question a user asked an assistant. An answer fetch says a page was read while an assistant was replying to somebody. The question itself never reaches your server, so nobody can report it. If the agent invents the prompts behind your AI traffic, it is guessing. The post on AI visibility scores versus server side counts explains why a count from your own server and a score from a prompt panel are different things.
Who is behind a crawler hit, beyond the user agent. No address and no visitor hash exist on the crawler path at all. The raw user agent is kept up to 512 characters, so old hits can be reclassified as the crawler list grows. For how an operator can be named without addresses, see naming the operator of an AI agent without IP addresses.
Fresh search data. Google publishes search data about three days late and revises its three most recent days. Bing's query rows are weekly buckets dated to a Friday, which is why a Bing position is derived and can be null. An agent that compares "this week" with "last week" in Search Console will see a drop that is only missing data. Put a line in your agent's instructions file:
Search Console numbers for the last 3 days are provisional. Do not report a
drop or a gain that falls inside that window. A null Bing position means
unknown, not zero.
Keep answers inside the output limit
Large answers hurt agents. Claude Code displays a warning when MCP tool output exceeds 10,000 tokens, and the default maximum is 25,000 tokens. You can raise it with MAX_MCP_OUTPUT_TOKENS, but a better habit is to ask narrower questions: a date range, the top 10 pages, one funnel. A full dump of a year of page paths wastes the context your agent needs for the code.
Questions that fit
Start with questions that tie a number to a change you made:
- "Compare page views for
/pricingin the 7 days before and after my last commit. Ignore the last 3 days of search data." - "Which AI crawlers fetched the site this month? Group them as AI answers, Search indexing, AI training and Other AI bots."
- "How many visits came from ChatGPT, Claude, Perplexity, Copilot and Gemini last week, and which pages did they land on?"
- "Of the people who reached the pricing page, how many finished the checkout funnel within 7 days?"
- "Which outbound links were clicked, and from which pages?"
The third and fourth connect to a longer thread. If AI visits are what you care about, following an AI referral to a signup without cookies shows the path from referrer to goal. If your site is new and the crawler numbers look thin, what AI crawlers do on a new site in its first 30 days sets expectations before you ask the agent to explain a quiet week.
Limits of this setup
The agent reads numbers; it does not judge them. It will tell you a page got 40 visits and it may tell you why, but the why is a guess from the code it can see. Ask it to separate what the numbers show from what it infers, and check anything that would cost you money to get wrong against the dashboard or the CLI.
Key handling is the other limit. A bearer key in an environment variable is only as safe as your shell and your machine. If a key leaks, replace it, and keep it out of any file in git.
That is the whole connection: one key, one entry in one config file, and a short list of things to tell the agent about what the data is and is not.