umami-analytics-mcp
Provides tools for interacting with Umami analytics, including retrieving stats, metrics, events, sessions, reports (funnel, retention, journey, attribution, revenue, UTM, web-vitals), managing segments, teams, share links, event ingestion, and self-hosted user administration.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@umami-analytics-mcp Show me today's page views for all websites."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
umami-analytics-mcp
Security-first Model Context Protocol server for Umami analytics β Umami Cloud and self-hosted (v3). Set up, analyze, report on, and (when you allow it) administer your Umami instance from any MCP client.
π Local-first β
npx umami-analytics-mcp, zero build step, ~2 runtime deps.βοΈ Or host it β deploy to Vercel (one Web function) or run the bundled Docker HTTP server. One shared core, three transports.
π Credential-safe β secrets live in env only; never placed in tool arguments, outputs, or logs (two-layer redaction). Remote endpoints are bearer-gated and fail closed.
ποΈ Least privilege β read-only by default;
writeandadmintiers are opt-in; destructive ops (delete/reset) are double-gated.π Comprehensive β full Umami v3 surface: stats, metrics, events, sessions, reports (funnel, retention, journey, attribution, revenue, UTM, web-vitals), segments, teams, share links, event ingestion, and self-hosted user administration.
Contents
Related MCP server: Umami MCP Server
Quickstart (local / npx)
No install required. Point your MCP client at:
npx -y umami-analytics-mcpβ¦with credentials supplied via environment variables. For Umami Cloud, create an API key at Dashboard β Settings β API keys and set UMAMI_API_KEY. For self-hosted, set UMAMI_API_URL + UMAMI_USERNAME + UMAMI_PASSWORD. See MCP client setup for copy-paste configs.
By default the server is read-only (32 analytics tools). Opt into writes/admin explicitly β see Capability tiers.
Configuration
All configuration is via environment variables (secrets) and optional CLI flags (non-secrets).
Variable | Mode | Description |
| Cloud | Umami Cloud API key (selects Cloud mode). |
| Cloud |
|
| self-hosted | Instance base URL, e.g. |
| self-hosted | Login credentials β bearer token (cached, auto-renewed on 401). |
| both | Scope website listings to a team (optional). |
| both | IANA tz for time-series tools (default |
| both |
|
| both |
|
| both |
|
| remote | Shared-secret bearer required by the Vercel/HTTP endpoints. |
Self-hosted instances that issue API keys can use
UMAMI_API_URL+UMAMI_API_KEYinstead of username/password.
Surrounding quotes are stripped from values defensively. For local use you can keep settings in a file and load them with --env-file:
npx umami-analytics-mcp --env-file .env.localRun npx umami-analytics-mcp --help for the full flag list.
Capability tiers
The server exposes only the tools for the tiers you enable, layered on top of Umami's own role-based access (the API still enforces your account's real permissions β tiers just decide which tools are even visible).
Tier | Enable with | Adds | Example tools |
read | (always on) | analytics & reporting |
|
write |
| mutations + ingestion |
|
admin |
| user administration |
|
destructive |
| delete / reset |
|
Tool counts: 32 read β 46 with write β 52 with destructive β 58 at full tier on self-hosted. On Cloud the admin tier is automatically disabled (Umami Cloud has no user-admin API) and the server explains why at startup. Destructive tools carry MCP destructiveHint annotations so clients can warn before running them.
MCP client setup
Claude Desktop / Cursor (claude_desktop_config.json / .cursor/mcp.json)
{
"mcpServers": {
"umami": {
"command": "npx",
"args": ["-y", "umami-analytics-mcp"],
"env": {
"UMAMI_API_KEY": "your_cloud_api_key"
// self-hosted instead:
// "UMAMI_API_URL": "https://stats.example.com",
// "UMAMI_USERNAME": "admin",
// "UMAMI_PASSWORD": "β’β’β’β’β’β’",
// opt into writes:
// "UMAMI_ENABLE_WRITE": "1"
}
}
}
}Claude Code
claude mcp add umami \
-e UMAMI_API_KEY=your_cloud_api_key \
-- npx -y umami-analytics-mcpVS Code (.vscode/mcp.json)
{
"servers": {
"umami": {
"type": "stdio",
"command": "npx",
"args": ["-y", "umami-analytics-mcp"],
"env": { "UMAMI_API_KEY": "your_cloud_api_key" }
}
}
}Remote hosting
Both remote transports require MCP_AUTH_TOKEN; without it they reject every request (fail closed). Clients authenticate with Authorization: Bearer <MCP_AUTH_TOKEN>.
Deploy to Vercel
The repo ships a single Web function at api/mcp.ts (no Next.js required).
Push this repo to GitHub and Import it in Vercel.
Set Environment Variables: your Umami credentials (
UMAMI_API_KEYorUMAMI_API_URL+UMAMI_USERNAME+UMAMI_PASSWORD), optional tier flags, and a strongMCP_AUTH_TOKEN.Deploy. Your endpoint is
https://<deployment>.vercel.app/api/mcp.Harden: enable Vercel Deployment Protection (locks preview URLs) and Firewall.
Connect a Streamable-HTTP-capable client to the URL with the bearer header. stdio-only clients bridge via:
npx mcp-remote https://<deployment>.vercel.app/api/mcp \
--header "Authorization: Bearer $MCP_AUTH_TOKEN"Docker / self-host
Runs the framework-free standalone HTTP server (umami-mcp-http):
docker build -t umami-mcp .
docker run --rm -p 8787:8787 \
-e UMAMI_API_KEY=your_cloud_api_key \
-e MCP_AUTH_TOKEN=$(openssl rand -hex 32) \
umami-mcp
# β endpoint at http://localhost:8787/mcp (health: /health)Or without Docker: MCP_AUTH_TOKEN=β¦ UMAMI_API_KEY=β¦ npx -y umami-analytics-mcp umami-mcp-http (bin umami-mcp-http). Set HOST, PORT, optional MCP_ALLOWED_HOSTS (enables DNS-rebinding protection), or MCP_ALLOW_INSECURE=1 for localhost-only unauthenticated dev.
Security model
Secrets in env only. Never committed, never passed as flags, never persisted. The self-hosted bearer token is cached in memory and re-fetched on 401.
Never logged or echoed. A redaction layer scrubs secrets by key and by literal value from every log line, error, and tool result.
get_meand user/admin responses are sanitized oftoken/authKey/shareToken. stdio diagnostics go to stderr only (stdout is the JSON-RPC channel).Remote endpoints are auth-gated and fail closed β constant-time bearer comparison; no
MCP_AUTH_TOKENβ all requests rejected.Least privilege by default β read-only unless you opt in; destructive operations double-gated and annotated.
No third-party credential collection. Run your own instance of this server. Never point credentials at someone else's hosted MCP endpoint.
See SECURITY.md for the full threat model and disclosure policy.
Tool reference
list_websites Β· get_website Β· get_website_daterange Β· get_active_visitors Β· get_realtime Β· get_stats Β· get_pageviews Β· get_metrics Β· get_website_values Β· get_events Β· get_event_data Β· list_sessions Β· get_session Β· get_session_activity Β· get_session_stats Β· get_session_properties Β· report_funnel Β· report_retention Β· report_journey Β· report_goals Β· report_attribution Β· report_revenue Β· report_utm Β· report_breakdown Β· list_reports Β· get_report Β· list_segments Β· get_segment Β· list_teams Β· get_team Β· get_team_members Β· get_me
create_website Β· update_website Β· manage_website_share Β· transfer_website Β· send_event Β· create_team Β· update_team Β· join_team Β· add_team_member Β· update_team_member Β· create_segment Β· update_segment Β· create_report Β· update_report
Destructive (also needs UMAMI_ALLOW_DESTRUCTIVE): delete_website Β· reset_website Β· delete_team Β· remove_team_member Β· delete_segment Β· delete_report
list_users Β· get_user Β· create_user Β· update_user Β· set_user_role
Destructive: delete_user
Every tool returns a concise text summary plus a typed structuredContent payload, and accepts flexible date ranges (range: "7d" | "today" | "this-month", or explicit startAt/endAt).
Prompts & resources
Prompts (server-side, teach correct tool-chaining): analytics_report, traffic_overview, top_pages, acquisition_channels, realtime_check, funnel_analysis, retention_analysis, audience_insights, compare_periods.
Resources: umami://websites, umami://website/{id}, umami://me (sanitized).
Development
npm install
npm run build # tsup β dist/{cli,http,server}.js
npm test # vitest (58 tests)
npm run typecheck # tsc --noEmit
npm run inspect # MCP Inspector against the stdio CLIArchitecture: a single registerAll(server, ctx) core (src/server.ts) is shared by the stdio CLI (src/bin/cli.ts), the standalone HTTP server (src/http/server.ts), and the Vercel function (api/mcp.ts) β so the tool surface never drifts between local and hosted modes. See the design spec.
License
MIT Β© Mateusz Siatrak
Available Tools
32 toolsget_active_visitorsGet active visitorsARead-only
Current real-time active visitor count for a website (visitors in the last few minutes).
Inputs: websiteId (required). Returns: data, visitors, websiteId
get_event_dataExplore custom event-dataARead-only
Explore custom event properties. select chooses the view: 'events' (event names), 'fields' (all fields), 'properties' (property keys), 'values' (values for a property β pass propertyName), or 'stats' (counts). Optionally scope by eventName.
Inputs: select (required), websiteId (required), endAt, range, +3 more. Returns: data, select, websiteId
get_eventsGet event activityARead-only
Custom-event activity over time for a website, bucketed by unit. Returns a time series of event counts. For a ranked list of event names use get_metrics(type='event').
Inputs: websiteId (required), unit, endAt, range, +2 more. Returns: data, endAt, startAt, websiteId
get_meGet current accountARead-only
Return the authenticated account's profile: id, username, role, isAdmin, and teams. Credentials/tokens are stripped from the response.
Inputs: no named parameters. Returns: user, deployment
get_metricsGet metric breakdownCRead-only
Top-N breakdown of a website by a single dimension (type) over a date range. Returns ranked { x: value, y: count } rows. Use type=event for custom-event counts. url is an alias for path.
Inputs: type (required), websiteId (required), os, tag, +17 more. Returns: data, type, count, websiteId
get_pageviewsGet pageviews time seriesBRead-only
Pageviews and sessions over time, bucketed by unit. Returns { pageviews: [{x,y}], sessions: [{x,y}] } where x is the bucket timestamp and y the count.
Inputs: websiteId (required), os, tag, url, +16 more. Returns: endAt, startAt, sessions, pageviews, +1 more
get_realtimeGet realtime activityARead-only
Richer real-time snapshot for a website (recent events/sessions/series). Availability varies by Umami version; falls back gracefully.
Inputs: websiteId (required). Returns: data, websiteId
get_reportGet saved reportARead-only
Fetch a saved report's full definition (type, parameters) by ID.
Inputs: reportId (required). Returns: data
get_segmentGet segmentARead-only
Fetch a single segment/cohort definition by ID.
Inputs: segmentId (required), websiteId (required). Returns: data
get_sessionGet sessionARead-only
Fetch a single visitor session's details by session ID.
Inputs: sessionId (required), websiteId (required). Returns: data
get_session_activityGet session activityBRead-only
Ordered pageview/event timeline for a single session (createdAt, urlPath, referrer, eventType, eventName) β effectively a data-level session replay.
Inputs: sessionId (required), websiteId (required), endAt, range, +1 more. Returns: data, count, sessionId
get_session_propertiesGet session propertiesARead-only
List the custom properties attached to a single session (set via identify calls).
Inputs: sessionId (required), websiteId (required). Returns: data, sessionId
get_session_statsGet session statsARead-only
Aggregate session totals over a date range: pageviews, visitors, visits, countries, events β a session-centric overview.
Inputs: websiteId (required), os, tag, url, +14 more. Returns: endAt, stats, startAt, websiteId
get_statsGet website statsARead-only
Aggregate metrics for a website over a date range: pageviews, visitors (unique sessions), visits, bounces (single-pageview sessions), and totaltime (seconds). Includes a previous-period comparison by default.
Inputs: websiteId (required), os, tag, url, +15 more. Returns: endAt, stats, startAt, websiteId
get_teamGet teamARead-only
Fetch a single team's metadata by ID.
Inputs: teamId (required). Returns: team
get_team_membersGet team membersARead-only
List members of a team and their roles (team-owner, team-manager, team-member, team-view-only).
Inputs: teamId (required), page, search, pageSize. Returns: data, count
get_websiteGet websiteARead-only
Fetch one website's metadata (name, domain, share settings, createdAt) by ID.
Inputs: websiteId (required). Returns: website
get_website_daterangeGet website data rangeARead-only
Return the earliest and latest timestamps for which a website has analytics data. Use this to choose a valid window before querying stats/metrics.
Inputs: websiteId (required). Returns: data
get_website_valuesGet distinct field valuesARead-only
List the distinct values seen for a column over a date range β useful to discover valid filter values (e.g. all browsers or countries) before filtering other queries.
Inputs: type (required), websiteId (required), endAt, range, +2 more. Returns: data, type, websiteId
list_reportsList saved reportsARead-only
List saved reports (funnels, goals, journeys, etc.), optionally scoped to a website.
Inputs: page, search, pageSize, websiteId. Returns: data, count
list_segmentsList segments & cohortsARead-only
List saved segments and cohorts defined for a website.
Inputs: websiteId (required), page, search, pageSize. Returns: data, count, websiteId
list_sessionsList sessionsBRead-only
Paginated list of individual visitor sessions over a date range (id, browser, os, device, geo, screen, visits, views, firstAt/lastAt). Supports search + filters.
Inputs: websiteId (required), os, tag, url, +17 more. Returns: data, count, websiteId
list_teamsList teamsARead-only
List teams you belong to (id, name, role). Available on both Cloud and self-hosted.
Inputs: page, search, pageSize. Returns: data, count
list_websitesList websitesARead-only
List every website you can access (including team sites). CALL THIS FIRST β every other tool needs a website ID from here. Returns id, name, domain, createdAt.
Inputs: page, search, pageSize, includeTeams. Returns: data, count
report_attributionAttribution reportARead-only
Conversion attribution. model is first-click or last-click; type is the target dimension; step the target value.
Inputs: step (required), type (required), model (required), websiteId (required), +4 more. Returns: data
report_breakdownBreakdown reportCRead-only
Multi-dimensional breakdown across one or more fields (e.g. ['country','browser']).
Inputs: fields (required), websiteId (required), os, tag, +15 more. Returns: data
report_funnelFunnel reportARead-only
Conversion funnel across an ordered list of steps. Each step is { type: 'path' | 'event', value }. window is the conversion window (hours).
Inputs: steps (required), websiteId (required), os, tag, +16 more. Returns: data
report_goalsGoals reportBRead-only
Progress toward one or more goals. Each goal is { type: 'event' | 'path', value }. Computed per goal against Umami's /reports/goal endpoint.
Inputs: goals (required), websiteId (required), os, tag, +15 more. Returns: data
report_journeyUser journey reportARead-only
Most common navigation paths through the site, up to steps deep (2β7). Optionally pin a start or end step.
Inputs: websiteId (required), endAt, range, steps, +3 more. Returns: data
report_retentionRetention reportARead-only
Cohort retention over the selected period (how many users return on subsequent days).
Inputs: websiteId (required), endAt, range, startAt, +1 more. Returns: data
report_revenueRevenue reportARead-only
Revenue analytics over the period (requires revenue events configured in Umami). currency is required (e.g. USD).
Inputs: currency (required), websiteId (required), unit, endAt, +4 more. Returns: data
report_utmUTM reportCRead-only
Breakdown of traffic by UTM parameters (source, medium, campaign, content, term).
Inputs: websiteId (required), os, tag, url, +14 more. Returns: data
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelogβ¦
TDQS
Scored across 32 tools
Most tools have distinct purposes, but the high number (32) and some similar-sounding names (e.g., get_events vs get_metrics for events, get_realtime vs get_active_visitors) may cause confusion. Descriptions are clear enough to differentiate, but an agent might misselect without careful reading.
All tools follow a consistent verb_noun pattern in snake_case: get_*, list_*, report_*. This is a predictable and clear naming scheme that helps an agent quickly grasp the tool's action and subject.
With 32 tools, the surface is heavy. While the analytics domain is broad and many tools serve distinct analytical needs, the count exceeds the 'heavy' threshold (16-25). Some tools could potentially be consolidated (e.g., report_* tools share similar structure).
The tool set covers the full analytics lifecycle: website and team metadata, time-series data, event tracking, session details, real-time, saved reports, segments, and various report types (funnels, goals, retention, etc.). It includes utility tools like get_website_daterange and get_website_values for validation. No obvious gaps for a read-only analytics server.
Maintenance
Related MCP Connectors
Hosted MCP server for GA4, Google Ads and Search Console. Google OAuth, nothing to install.
Zero-log MCP server with 49 tools for AI guardrails, secret scanning, MCP linting & EU compliance.
491Privacy-first cookieless web analytics with agent one-prompt setup via remote MCP OAuth.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseCqualityCmaintenanceMCP server exposing Umami analytics (Cloud + self-hosted)5MIT
- AlicenseAqualityDmaintenanceRead-only MCP server for Umami analytics. It talks to the Umami REST API directly over HTTP, supporting self-hosted and cloud setups.88 npmMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Umami Analytics that provides read-only tools to query website stats, events, sessions, reports, and more, enabling natural language analytics queries.25 npm3MIT
- AlicenseAqualityDmaintenanceA read-only MCP server for Umami analytics, enabling natural language queries of website stats, traffic trends, events, sessions, and analytics reports.1310 npm1Elastic 2.0