MCP registry optimization: target real keywords, not a guess - #2
Merged
Merged
Conversation
…ough tools callable from Claude, Cursor, VS Code — create an account, record events, or read reports with your API key. Streamable HTTP at /mcp with 27 tools covering analytics overview, traffic, pages, events, metrics, users, live visitors, page flow, and crawlers. Share ingest logic (Ping module), client IP detection, and account provisioning between REST and MCP endpoints so events mean exactly the same thing either way. 580/581 tests passing; one flaky hash test on OTP 28 CI. - Extract shared ping ingest module (WebAnalytics.Ingest.Ping) used by both /api/ping and MCP track_event tool, so rules never drift between endpoints. - Extract ClientIP helper module for unified x-forwarded-for handling with trust_proxy_headers config in collect, account creation, crawler reporting. - Extract AccountProvisioning module shared between REST endpoint and MCP create_analytics_account tool, same rate limiting and error handling. - Add API keys table, schema and context; authenticate MCP clients with Bearer tokens; max 20 per account, rate-limited to prevent abuse. - Build MCP server module with stateless (2026-07-28) and handshake (2024-11-05 to 2025-11-25) protocol support, server/discover, tool dispatching, resource listing, prompt rendering, and proper error codes. - Implement 27 MCP tools: create_analytics_account and track_event (writing, no key); get_integration_guide; 16 reading tools for account, overview, pages, traffic sources, events, metrics, users, live visitors, flow, crawlers; plus resources (llms.txt) and prompts (add_analytics, analytics_report). - Add /mcp HTTP endpoint with Streamable HTTP transport, CORS for cross-origin, authentication via Authorization: Bearer header, support both JSON requests and JSON-RPC batches. - Add MCP landing page explaining the server, showing copy-paste snippets for Claude Code, Cursor, VS Code, and an overview of all 27 tools in a sortable table. - Add API key creation/revocation UI to Getting Started; keys shown once and stored only as SHA-256 hash; last_used_at updated max once per minute to avoid turning every read into a write. - Update Cors plug to accept configurable methods and headers for MCP's larger header set (mcp-protocol-version, mcp-method, mcp-name, authorization, etc.). - Move landing controller's llms.txt text generation to public method so MCP's resources/read can serve the same document, with deployment-specific URLs filled in both places. - Leverage existing Analytics API (overview, timeseries, pages, users, metrics, etc.) to answer every reading tool; nothing duplicated, same reports as dashboard. Pages affected: - [Analytics MCP Server](https://seriouslysimpleanalytics.com/analytics-mcp-server) -- Connect Claude or ChatGPT to your analytics, create accounts and track events as a tool. - [Getting Started](https://seriouslysimpleanalytics.com/getting-started) -- Create API keys for MCP clients, manage revocation, see integration snippets for website and AI tools. - [Integration Guide](https://seriouslysimpleanalytics.com/llms.txt) -- Full event API contract, now served as MCP resource; unchanged content.
Researched how the official MCP Registry, Smithery, Glama, PulseMCP and mcp.so actually surface servers. Verified fact: the official registry's search only substring-matches the `name` field, not description — so the domain-verified namespace itself is the highest-leverage lever available. - Add server.json at repo root under the domain-verified com.seriouslysimpleanalytics/analytics-mcp-server namespace (the domain already serves /.well-known/mcp-registry-auth), with a remotes entry for the Streamable HTTP endpoint and a 100-char keyword-front-loaded description (the registry's hard limit). - Fix a broken icon reference (icon-512.png never existed) to use the existing logo.svg, in both server.json and the MCP server's serverInfo. - Refresh GitHub topics: drop 9 redundant/low-signal tags, add mcp, mcp-server, model-context-protocol and 5 more — the repo previously had none of the three highest-signal tags in this space (~29k repos use mcp-server alone). - Tighten the MCP landing page hero, page title and meta description, and two tool descriptions, around the researched keyword set. - Add a README section introducing the MCP server. Human-required next steps (need live domain + personal accounts, can't be scripted from here): run `mcp-publisher login http` against the deployed domain to generate the /.well-known/mcp-registry-auth proof and publish server.json; then claim/submit on Smithery, Glama and mcp.so. Pages affected: - [SeriouslySimpleAnalytics](https://seriouslysimpleanalytics.com/) -- free, cookieless web analytics with one script tag. - [Analytics MCP Server](https://seriouslysimpleanalytics.com/analytics-mcp-server) -- the page this work targets, now with tightened keyword copy. - [Getting Started](https://seriouslysimpleanalytics.com/getting-started) -- where an MCP client's API key is created. - [AI Analytics (llms.txt)](https://seriouslysimpleanalytics.com/AI-Analytics-llms-txt) -- usage analytics for AI agents, MCP servers and CLIs. Closes #1 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The tag has to load and run before it can report, so anything that never executes JavaScript is invisible to it. That was unmeasurable until server-side recording existed. Now that the Phoenix plug reports the same pageviews the tag does, the gap between them is a number, and this tab is it. A pageview reported by the server alone carries no viewport height and no heartbeat, because a server has no viewport and does not sit on a page. Both are required before calling one untagged -- a visitor who leaves inside a second is gone before the first heartbeat, and either signal alone would misread them. - Splits misses into automated and not. A crawler missing the tag is expected; a person missing it is a blocked script or an untagged page, and the tab says so plainly - Counts crawlers even with the crawler filter on, since hiding the largest thing the tag misses would defeat the report - Groups by path, never title: a title is one of the things only the tag can supply 619 tests passing, 11 of them new. Closes #3 --- Pages affected: - [Seriously Simple Analytics](https://seriouslysimpleanalytics.com/) -- the dashboard this tab joins. - [AI crawler analytics](https://seriouslysimpleanalytics.com/ai-crawler-analytics) -- the automated half of what the tag misses. - [Analytics MCP server](https://seriouslysimpleanalytics.com/analytics-mcp-server) -- the same numbers, queryable from an agent. - [MCP Harbor](https://ai.mcpharbor.com/) -- a site already feeding this with server-side data. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Show what the browser tag never saw
Owner
Author
|
Heads up: this branch picked up #4 (the Coverage tab) before merging, so promoting it now ships three things rather than one — the MCP server conversion, the registry keyword work, and the tag-coverage report. All four checks pass on the merged result. 619 tests. Worth knowing after this lands: this repo has no deploy job — |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Research-backed keyword optimization for the new MCP server, closing #1.
Verified fact driving the biggest change: the official MCP Registry's own
search only substring-matches the
namefield (not description), sopublishing under a domain-verified namespace is the single highest-leverage
lever available there.
server.jsonat repo root undercom.seriouslysimpleanalytics/analytics-mcp-server(domain-verified, since the domain already serves
/.well-known/mcp-registry-auth),with a
remotesentry and a 100-char description (the registry's hard limit).icon-512.pngnever existed) to the reallogo.svg.mcp,mcp-server,model-context-protocoland 5 more — previously had none of the threehighest-signal tags in this space.
descriptions around the researched keyword set; added a README section.
Remaining steps need a live deployed domain and personal accounts, so they're
not part of this PR: run
mcp-publisher login httpagainst production togenerate the registry-auth proof and publish
server.json, then claim/submiton Smithery, Glama and mcp.so.
Test plan
mix test— 608 passedmix format --check-formatted/analytics-mcp-serverrenders the new copy in a live previewPages affected:
🤖 Generated with Claude Code