Lightweight, self-hostable web analytics with an AI-ready API
NanoAnalytics is a lightweight analytics MCP server with 15 tools covering read analytics queries, beacon recording, health checks, and OpenAPI documentation. Most tools have well-structured input schemas with clear parameter descriptions. However, there are critical gaps: output schemas are not documented anywhere, limiting the LLM's ability to chain results; descriptions, while present, are often brief (averaging ~60 chars) and lack actionability around tool selection criteria; and the server exhibits inconsistent tool naming patterns (verb_noun vs simple nouns like 'pageviews', 'pages', 'devices'). Security is adequate for read-only operations but the 'hit' tool (WRITE) lacks dry-run/confirmation patterns for agents. The Flask HTTP implementation is sound, but MCP protocol integration details are not visible in the provided code snippet.
Active unique sessions in the last N seconds (default 300 = 5 min), with per-country breakdown. Use for real-time visitor map.
Bounce rate by page. Single-page sessions with no onward navigation.
Top countries by pageview count (ISO 3166-1 alpha-2 codes). Detected from visitor IP at collection time.
Pageview breakdown by device type (mobile / tablet / desktop / unknown)
Top entry pages — the first page seen in each session, ranked by how often sessions begin there. Distinct from top pages by total views.
Health check
Record a pageview (beacon). Inserts a hit row and returns a 1×1 GIF.
Output schemas are completely undocumented. The code snippet does not show what fields or data structures each tool returns. LLMs cannot plan downstream tool calls or extract required chaining IDs (e.g., if 'pages' returns a page_url, agents cannot call other tools with that URL without guessing the field name).
Inconsistent tool naming: mix of noun-only names ('pageviews', 'pages', 'devices', 'languages') vs verb_noun ('entry-pages', 'peak-hours', 'bounce-rates'). This inconsistency forces LLMs to parse multiple naming conventions and risks wrong tool selection when many similar tools are available. Naming should consistently follow verb_noun or descriptive_metric pattern.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 53 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 43 | - | v1 |
Pageview breakdown by exact hostname (subdomain breakdown). Accepts root domain or any subdomain — all subdomains are matched automatically.
Top browser languages
OpenAPI 3.1.0 specification — machine-readable API documentation
Top pages by view count
Total pageviews and unique sessions
Top 10 busiest hours of day (UTC, 0–23) by pageview count. Useful for scheduling content or launches at peak audience times.
Top external referrer domains (internal self-referrals from the tracked domain are automatically excluded)
Daily pageviews (grouped by UTC date)
The 'hit' tool is a WRITE operation (records pageviews) but lacks a dry-run parameter or confirmation step. Agents make mistakes, especially with beacon recording where duplicate hits corrupt analytics. Should support an optional 'dry_run' or 'confirm' parameter to prevent irreversible side effects.
Tool descriptions are brief (30-75 chars) and lack depth on selection criteria. E.g., 'pageviews' says 'Total pageviews and unique sessions' but does not explain when to call it vs 'pages' (which is about top pages). Agents lack guidance on tool selection and may choose the wrong one.
Parameter 'limit' has default=10 and maximum=500, but descriptions do not explain the trade-off or when to increase it. LLMs may not realize they can request more results or may over-request and blow context windows. Guidance like 'Request more results only if necessary; default 10 covers most queries' would help.
Error handling and recovery guidance not visible in provided code. If a tool fails (e.g., 'site not found'), it is unclear what the LLM should do next. Should offer actionable recovery suggestions like 'Call openapi to see available analytics endpoints' or 'Check the site domain is registered.'