Pulse
Connects Stripe webhooks and checkout metadata to attribute sales, renewals, and refunds to the originating visitor or session. Supports Stripe Payment Links, checkout metadata attribution, and one-click Stripe history import.
Sends Telegram alerts for sales with source attribution, traffic spikes, and daily analytics digests, with optional per-project chat overrides.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Pulse
Open-source, revenue-first analytics that runs on your own Cloudflare.
Pulse tells you which post, search, referrer or AI answer brought the people who paid you, and how AI assistants use your MCP tools. It's a self-hosted, drop-in alternative to DataFast: one Worker, one D1 database, one script tag. Most sites fit in Cloudflare's free plan.
Revenue attribution: Stripe, Polar and Dodo webhooks. Every sale, renewal and refund is credited to the visit that brought the buyer, even weeks later.
Projects home: every site you run on one screen, each with its own pulse line, live visitors, revenue and MCP calls.
MCP usage: see which tools your MCP servers get called with, by which AI client, how fast, and whether they fail.
AI search visibility: checks every page the way Googlebot sees it, where you rank in Brave for real buying queries, and whether Claude (which searches with Brave) cites you, with a verdict on what to fix.
AI crawlers: see when GPTBot, ClaudeBot, PerplexityBot and friends read your pages, which most analytics can't, because crawlers don't run JavaScript.
Ask your AI: Pulse is itself an MCP server, so Claude, ChatGPT or Cursor can answer "where did last week's revenue come from?", and with a write token, add projects and funnels.
Yours: your Cloudflare account, your data, MIT licensed. No cookies needed if you don't want them.
Features
Traffic | Visitors, sessions, pageviews, bounce, engaged time, scroll depth; channels, referrers, UTM campaigns, pages (entry, exit), countries, cities, devices, browsers, OS. Click any row to filter everything. ChatGPT, Claude, Perplexity and Gemini get their own AI channel. |
Revenue | Revenue, sales, average order, share attributed, refunds, revenue per visitor, per source, per page and per country. One-click Stripe history import. |
Readable Direct | No-referrer traffic split into typed/bookmarked, shared links (WhatsApp, iMessage, Slack…), checkout returns and named in-app browsers (Instagram, Facebook, LinkedIn, X, TikTok). |
Lifetime value | Customers grouped by the source that first brought them, with renewals and repeat buyers. |
Funnels | Pages (with |
Page flow | For any page or section ( |
Conversions by source | Visits per referrer, channel, utm_medium or utm_campaign, and how many completed any goal, a chosen goal, or paid. |
Bots & AI crawlers | Hits by category (AI crawlers, search, link previews, SEO tools, monitoring) and by bot and page, from the script and from your server. Real Chrome browsers running inside cloud networks (scanners, agents) are counted as automated browsers, not visitors. |
AI search | Weekly: every sitemap page audited as Googlebot (status, robots.txt, noindex, canonical, links between your sites), Brave index and rank for your buying queries, and Claude's answer with web search (searched? found you? cited you? who instead?). One-click checklist for Brave's submit form. |
Segments | Save any set of filters ("AI traffic from the US on mobile") and switch to it in one click. |
Goals |
|
Realtime | Live map and list of who's on the site, pushed over a WebSocket the moment someone arrives; visitors per minute, sales in the last hour, and the full journey of any visitor. |
Alerts | Telegram: every sale with its source, traffic spikes (a source at 4× its usual hour), daily digest. |
Team | Invite people by link as admins or viewers (email + password, no third-party auth). Viewers see everything but secrets and change nothing. |
API tokens | Named read or write tokens for each AI assistant or script, with last-used dates and one-click revoke. |
Sharing | A read-only public dashboard link per project. |
Workflow | ⌘K command palette, custom date ranges, per-project timezone, CSV export everywhere, light and dark themes, works on phones, and an in-app notice when a new version is out. |
Coming from DataFast?
Swap the script tag and keep your code: window.datafast("signup"), data-fast-goal,
data-fast-scroll, and checkouts that send datafast_visitor_id in metadata all keep working.
Then point your payment webhooks at Pulse.
Related MCP server: flin-shopify-analytics-mcp
Install: one click
Click the button and sign in to Cloudflare (a free account is fine).
Pick two passwords when asked:
ADMIN_TOKEN(your dashboard login) andPULSE_MCP_KEY(for AI assistants).Click Deploy. Cloudflare copies Pulse to your GitHub, creates the database and deploys it.
Open your new
pulse.<you>.workers.devURL, sign in withADMIN_TOKEN, add a project and paste the tag.
To use your own domain, add it under the Worker's Settings → Domains & Routes in Cloudflare. Updates: pull changes from this repo into your copy; Cloudflare redeploys and runs new migrations.
git clone https://github.com/everyai-com/pulse && cd pulse
npm install
npx wrangler login
npm run setup # or: npm run setup -- --domain analytics.example.comsetup creates the database, applies migrations, deploys, and generates ADMIN_TOKEN and
PULSE_MCP_KEY for you (saved in pulse-credentials.txt, which is gitignored).
Upgrade later with git pull && npm run deploy.
Track a site
<script defer data-website-id="my-app" data-domain="example.com" src="https://YOUR-PULSE-URL/js/script.js"></script>Single-page apps need nothing extra. Options:
Attribute | |
| No cookie and no storage. The server derives a visitor hash from a daily-rotating secret + IP + user agent, so visitors can't be linked across days (checkout attribution is off). |
| Carry one visitor across your own domains. |
| Don't track these paths. |
| Track |
| Turn off outbound-click tracking or payment-link tagging. |
| Track localhost while developing. |
In the browser: pulse("goal", props), pulse.identify({ user_id, email, name }),
pulse("payment", { email | payment_id }), pulse.visitorId(), pulse.ignoreMe().
Connect payments
In Settings → Payments, copy the webhook URL for Stripe, Polar or Dodo, add it in the provider, and paste the signing secret back. Then pass the visitor id into checkout:
// Stripe Checkout (server), with visitorId from window.pulse.visitorId() in the browser
await stripe.checkout.sessions.create({
...,
client_reference_id: visitorId,
metadata: { pulse_visitor_id: visitorId },
subscription_data: { metadata: { pulse_visitor_id: visitorId } },
});
// Polar or Dodo: metadata: { pulse_visitor_id: visitorId }Stripe Payment Links, Polar links and Dodo /buy/ links need nothing: the script tags them on click.
Checkouts that can't carry metadata: call pulse("payment", { email }) on the thank-you page.
MCP tool-call analytics
For an MCP server on the same Cloudflare account, add a service binding and log after each response.
The PulseIngest entrypoint is only reachable through bindings, so there's no secret to manage and
nobody can post fake events:
// wrangler.jsonc of your MCP server
"services": [{ "binding": "PULSE", "service": "pulse", "entrypoint": "PulseIngest" }]ctx.waitUntil(env.PULSE.track("my-mcp", {
name: "mcp_call", path: "/mcp",
props: { tool: params.name, client: "claude", status: res.status, ms: Date.now() - t0 },
}));Anywhere else: POST /api/track with Authorization: Bearer <project API key> and
{ "name": "mcp_call", "props": { "tool": "...", "client": "...", "ok": true, "ms": 120 } }. Never send tool arguments.
MCP servers report failures inside HTTP 200 (a JSON-RPC error or isError: true), so send ok: false for those;
the MCP view shows failure rates and average latency per tool.
AI search visibility
Claude's web search retrieves from Brave, and Brave won't crawl a page Googlebot can't, so Pulse checks that chain for every project once a week:
Crawl audit (always on): every sitemap page fetched as Googlebot.
Brave index and rank:
npx wrangler secret put BRAVE_SEARCH_API_KEY(free key at api-dashboard.search.brave.com).Claude citations:
npx wrangler secret put ANTHROPIC_API_KEY. Each check is one Claude Opus 5.5 answer with web search, so it costs money;SEO_AI_WEEKLY_LIMITcaps checks per week (default 60).
Add buying queries per project ("best X 2026", "X vs Y"), or let Pulse suggest them. Brave's submit form has a CAPTCHA, so submission stays a one-click copy-and-open checklist.
If Pulse runs on the same Cloudflare zone as a site it audits, Cloudflare can route its requests differently from public ones; failures seen only from inside the zone are shown as "unverified" rather than as problems.
AI crawler analytics
AI crawlers fetch your pages without running JavaScript, so log them where the page is served.
From a Worker with the PULSE binding:
const ua = request.headers.get("user-agent") || "";
if (/bot|crawl|spider|GPTBot|ClaudeBot|Perplexity|Google-Extended/i.test(ua))
ctx.waitUntil(env.PULSE.crawl("my-app", { ua, path: new URL(request.url).pathname, status: res.status }));Anywhere else: POST /api/crawl with the project API key and { "ua": "...", "path": "/", "status": 200 }.
Pulse classifies the bot (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Googlebot, Bingbot, link previews, SEO tools, uptime monitors…).
Let your AI read your analytics
Pulse serves an MCP server at /mcp. Create a token for each assistant under Team & API tokens
(read, or read + write), or use PULSE_MCP_KEY.
Read tools: list_sites, site_report, breakdown, timeseries, revenue_report, pages_report,
get_paths, get_attribution, get_bot_stats, get_search_visibility, list_goals, realtime, lifetime_value, mcp_usage,
run_funnel, list_funnels, visitor_journey, get_tracking_snippet.
Write tools (write tokens only): create_site, save_funnel, delete_funnel.
claude mcp add --transport http pulse https://YOUR-PULSE-URL/mcp --header "Authorization: Bearer <token>"Cursor, VS Code, Windsurf and Claude Desktop take the same URL and header. Clients that can't send
headers (Claude.ai and ChatGPT custom connectors) can use https://YOUR-PULSE-URL/mcp/<PULSE_MCP_KEY>;
treat that URL like a password.
Alerts
npx wrangler secret put TELEGRAM_BOT_TOKEN # from @BotFather
npx wrangler secret put TELEGRAM_CHAT_ID # default chat; each project can override itHow it works
browser ── /js/script.js ──▶ POST /api/e ─┐
Stripe · Polar · Dodo ── /webhooks/* ─────┤
your Workers ── PULSE binding (track, crawl) ┤
▼
Worker ──┬──▶ D1: projects, visitors, sessions, events, payments (system of record)
└──▶ LiveSite Durable Object per project: last 30 min in SQLite
└── WebSocket push to open dashboards (hibernates when idle)
dashboard (/), share links, /mcp ◀── Worker cron every 15 min: spikes, daily digest → TelegramVisits are classified at ingest (referrer, UTM, in-app user agent, landing page) and stored per session, so filters are cheap.
The live view comes from a per-project Durable Object, so it's instant and doesn't touch D1; reports read D1.
A payment is credited to the visitor's last non-direct session in the 30 days before it (else their first). Refunds and renewals inherit the original sale's credit; webhooks that arrive out of order are back-filled.
Bots never count as visitors; they're stored separately and classified. IPs are never stored.
Money is stored in minor units with its currency and summed as-is (no currency conversion).
Why D1 and not a data lake? Pulse fits in Cloudflare's free plan: one Worker, one D1 database and one Durable Object class. D1 comfortably handles small and mid-size sites (up to tens of millions of events per database). If you outgrow it, the events table is the only thing to move.
Develop
cp .dev.vars.example .dev.vars # local secrets
npm run dev # local D1 + dashboard on http://localhost:8787
npm run check # typecheck + script syntaxSchema changes: add the next migrations/NNNN_name.sql. npm run deploy applies pending migrations before deploying.
Security
Report vulnerabilities privately to support@magicteams.ai. The dashboard escapes every
visitor-supplied string; admin APIs need ADMIN_TOKEN; webhook signatures are verified; public
share links expose only overview, pages and realtime for one project.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only Google Analytics 4 MCP server for AI assistants.
Read-only MCP access to sessions, funnels, campaigns, errors, live visitors, and anomalies.
Read-only Google Search Console MCP server for AI assistants.
Clamp Analytics MCP server: traffic, revenue, funnels, cohorts, errors, and search, for AI agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for Adobe Customer Journey Analytics, enabling AI-powered analytics queries including reports, breakdowns, trends, and dimension searches through Claude and other MCP clients.1628 PyPIMIT
- AlicenseBqualityCmaintenanceRead-only MCP server for querying Shopify analytics data, including orders, customers, products, sales, retention, and attribution.19MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for Umami Analytics that provides read-only tools to query website stats, events, sessions, reports, and more, enabling natural language analytics queries.8 npm3MIT
- AlicenseAqualityDmaintenanceA read-only MCP server for Umami analytics, enabling natural language queries of website stats, traffic trends, events, sessions, and analytics reports.1316 npm1Elastic 2.0