Open source- https://github.com/developeron29/agentlytics-mcp
I kept doing the same loop: open an analytics dashboard, stare at a chart, then paste numbers into my coding agent and ask "so what should I do next?". The agent was the part doing the thinking, and the dashboard was just a slow way to feed it data.
So I built agentlytics-mcp: cookieless analytics for one website, with an MCP server built in. Claude Code, Cursor or Codex connect to it and query the traffic directly. It runs on your own Cloudflare account (one Worker plus a D1 database), and it's MIT licensed.
What it looks like in practice
You ask questions in plain words:
- "Why did traffic jump yesterday?"
- "Where do people drop off between the homepage and signup?"
- "What's working, and what should I post next?"
- "Make a tracked link for my Reddit post, and check how it did next week."
The agent picks from 20 tools (get_overview, find_traffic_spikes, explain_spike, query_visits, create_funnel, create_tracked_link, get_campaign_results and more) and answers with real numbers.
The architecture: one Worker, four jobs
-
/t.js: a tracker of about 1 KB. It counts pageviews (including SPA navigation) and custom events fromagentlytics.track("signup")or adata-agentlytics-eventattribute. -
/collect: takes the hit, drops bots, derives the visitor id, and writes a row to D1. -
/mcp: MCP as JSON-RPC over HTTP, behind a bearer key. I wrote it by hand, so the project has no runtime dependencies. - An hourly cron: rolls events up into hourly totals, runs spike detection, and deletes raw events after 400 days.
Cookieless visitor counting
There are no cookies and nothing is stored in the browser. To count unique visitors without tracking anyone, the visitor id is a two-step HMAC:
const salt = await hmacHex(env.HASH_SECRET, String(Math.floor(now / DAY_MS)));
const visitor = (await hmacHex(salt, `${site.id}|${ip}|${ua}`)).slice(0, 32);
The salt changes every day, so the same person gets a new id tomorrow, and the IP and user agent themselves are never stored. Only the browser and OS names and the country Cloudflare reports are kept.
Spike detection an agent can explain
"Traffic is up" isn't useful. "Traffic is up because of a Hacker News link to /blog/foo" is. Every hour, the cron:
- Compares each hour's pageviews with the median of the same hour-of-week over the previous 4 weeks (or the same hour-of-day over the last 7 days for young sites).
- Uses the median absolute deviation as the scale and flags hours with z ≥ 4 and a minimum absolute lift, so tiny sites don't get alerts for 3 extra visits.
- Merges consecutive flagged hours into one spike, then attributes the excess by comparing every source, page and event against its own baseline. Each cause gets a lift, a lift % and a share of the spike.
Annotations ("deployed v2", "posted on Reddit") made in the 24 hours before a spike show up next to it. When the agent publishes something through a tracked link and logs an annotation, the next spike explains itself.
Setup
There's a Deploy to Cloudflare button that asks for three settings (your domain and two random keys). Or do it by hand:
npx wrangler d1 create agentlytics-mcp
npx wrangler secret put SITE_DOMAIN
npx wrangler secret put HASH_SECRET
npx wrangler secret put MCP_READ_KEY
npm run deploy
Then connect your agent:
claude mcp add --scope user --transport http agentlytics https://YOUR-WORKER/mcp \
--header "Authorization: Bearer YOUR_MCP_READ_KEY"
Or point your coding agent at the repo's AGENTS.md and let it do all of the above.
Limits
One site per deploy, no dashboard (by design), and spike detection needs a few days of data before it's useful.
If you'd rather not run it, I also run a hosted version, measuremy.site, with a dashboard, alerts and multi-site support. The repo has the same MCP tools.
I'd love feedback, especially on the tool design: what would you want to ask your analytics that this can't answer?
Top comments (1)
Github link- github.com/developeron29/agentlyti...