Umami MCP Server
by Mzaxd
README.md
# Umami MCP Server
Read-only MCP server for Umami analytics. It talks to the Umami REST API directly over HTTP, supports self-hosted Umami first, and also works with Umami Cloud API keys.
This repo is built so upper-layer agents can ask for analytics without re-reading the Umami docs each time. No browser automation, no DOM scraping, no write operations.
## Features
- Read-only MCP tools for the most common Umami analytics queries
- Two auth modes:
- `UMAMI_API_KEY`
- `UMAMI_USERNAME` + `UMAMI_PASSWORD`
- Self-hosted bearer token caching in memory
- Automatic re-login and one retry on `401` for username/password mode
- ISO time strings and millisecond timestamps both accepted
- Shared filter handling across stats, pageviews, breakdowns, and event series
- Strict TypeScript with small, maintainable modules
- Clear structured tool output and explicit error categories
## Requirements
- Node.js `>= 20`
- pnpm `>= 10`
## Install
From npm:
```bash
npm install -g umami-analytics-mcp
```
Or run without installing:
```bash
npx -y umami-analytics-mcp
```
For local development in this repo:
```bash
pnpm install
```
## Configure
Create a `.env` file from `.env.example`.
```bash
cp .env.example .env
```
Fill in one of the following auth options:
1. API key mode
```env
UMAMI_API_URL=https://api.umami.is/v1
UMAMI_API_KEY=your-api-key
UMAMI_DEFAULT_TIMEZONE=Asia/Shanghai
```
2. Self-hosted username/password mode
```env
UMAMI_API_URL=https://umami.example.com/api
UMAMI_USERNAME=admin
UMAMI_PASSWORD=secret
UMAMI_DEFAULT_TIMEZONE=Asia/Shanghai
```
Notes:
- `UMAMI_API_URL` should point to the API base, not just the site origin.
- If both `UMAMI_API_KEY` and username/password are set, `UMAMI_API_KEY` wins.
- `UMAMI_DEFAULT_TIMEZONE` is used when a tool supports timezone and you omit it.
## Run Locally
Development mode:
```bash
pnpm dev
```
Build and run:
```bash
pnpm build
pnpm start
```
The server uses MCP stdio transport, so it stays attached to stdin/stdout until the client disconnects.
If installed from npm, the equivalent command is:
```bash
umami-analytics-mcp
```
## Test
```bash
pnpm test
pnpm build
```
There is also a real-API integration test template that is skipped by default:
```bash
UMAMI_INTEGRATION_TEST=1 pnpm test:integration
```
## MCP Inspector
Build first:
```bash
pnpm build
```
Then launch the official MCP Inspector against the built server:
```bash
npx @modelcontextprotocol/inspector node dist/cli.js
```
For hot reload during development, this also works:
```bash
npx @modelcontextprotocol/inspector pnpm dev
```
If you want to test the published package path instead, use:
```bash
npx @modelcontextprotocol/inspector npx -y umami-analytics-mcp
```
Make sure the same Umami environment variables are available to the Inspector process.
Recommended smoke calls in Inspector:
1. `umami_ping`
2. `umami_list_websites`
3. `umami_get_stats`
4. `umami_get_breakdown`
## Tools
### `umami_ping`
Validates configuration and authentication.
Example:
```json
{}
```
### `umami_list_websites`
Lists accessible websites.
Example:
```json
{}
```
### `umami_find_website`
Fuzzy search by website name or domain.
Example:
```json
{
"query": "example.com"
}
```
### `umami_get_stats`
Summary stats for a website and time range.
Example:
```json
{
"websiteId": "8f2f8ce2-1234-4567-89ab-0123456789ab",
"startAt": "2026-04-23T00:00:00+08:00",
"endAt": "2026-04-23T23:59:59+08:00",
"filters": {
"path": "/pricing"
}
}
```
### `umami_get_pageviews`
Time-series pageviews and sessions.
Example:
```json
{
"websiteId": "8f2f8ce2-1234-4567-89ab-0123456789ab",
"startAt": "2026-04-17T00:00:00+08:00",
"endAt": "2026-04-23T23:59:59+08:00",
"unit": "day",
"compare": "prev",
"filters": {
"path": "/blog"
}
}
```
### `umami_get_breakdown`
Breakdown rows such as top pages, referrers, countries, browsers, devices, and more.
Example:
```json
{
"websiteId": "8f2f8ce2-1234-4567-89ab-0123456789ab",
"startAt": "2026-04-17T00:00:00+08:00",
"endAt": "2026-04-23T23:59:59+08:00",
"type": "path",
"limit": 10,
"expanded": false
}
```
### `umami_get_active`
Returns the current active visitor count.
Example:
```json
{
"websiteId": "8f2f8ce2-1234-4567-89ab-0123456789ab"
}
```
### `umami_get_events_series`
Returns custom event counts over time.
Example:
```json
{
"websiteId": "8f2f8ce2-1234-4567-89ab-0123456789ab",
"startAt": "2026-04-17T00:00:00+08:00",
"endAt": "2026-04-23T23:59:59+08:00",
"unit": "day"
}
```
## Shared Filters
These tools support the same `filters` object:
- `path`
- `referrer`
- `title`
- `query`
- `browser`
- `os`
- `device`
- `country`
- `region`
- `city`
- `hostname`
## Error Handling
Tool errors are returned as structured MCP tool results with these categories:
- `config_missing`
- `auth_failed`
- `website_not_found`
- `umami_http_error`
- `network_timeout`
- `network_error`
- `invalid_input`
## Mount In Any Stdio MCP Client
Any stdio-based MCP client can run this server with:
- `command`: `npx`
- `args`: `["-y", "umami-analytics-mcp"]`
- `env`: your Umami variables
Example JSON snippet for clients that use an `mcpServers` object:
```json
{
"mcpServers": {
"umami": {
"command": "npx",
"args": ["-y", "umami-analytics-mcp"],
"env": {
"UMAMI_API_URL": "https://umami.example.com/api",
"UMAMI_USERNAME": "admin",
"UMAMI_PASSWORD": "secret",
"UMAMI_DEFAULT_TIMEZONE": "Asia/Shanghai"
}
}
}
}
```
For a local unreleased checkout, you can still point directly to the built file:
```json
{
"mcpServers": {
"umami": {
"command": "node",
"args": ["/absolute/path/to/umami-mcp/dist/cli.js"]
}
}
}
```
## Publish To npm
This repo is now structured as an npm CLI package.
Recommended release flow:
```bash
pnpm test
pnpm build
pnpm pack --dry-run
npm login
pnpm publish
```
Notes:
- The package name is set to `umami-analytics-mcp` because `umami-mcp` is already taken on npm.
- The current `license` is `UNLICENSED` as a safe placeholder. Replace it before a real public open-source release if you want a permissive license.
- If you later publish under your own npm scope, change only the `name` field in `package.json`.
## Internal Docs
- API summary used by this repo: [docs/umami-api.md](docs/umami-api.md)
TDQS
A4.2/5.0
Scored across 8 tools
Disambiguation5/5
Each tool serves a distinct purpose: searching, listing, validating, and retrieving various analytics metrics (active visitors, breakdown, events, pageviews, stats). No overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent 'umami_verb_noun' pattern (e.g., umami_find_website, umami_get_active). The pattern is uniform and predictable.
Tool Count5/5
With 8 tools, the set is well-scoped for an analytics API. It covers essential query operations without being bloated or sparse.
Completeness5/5
The tool set provides comprehensive read-only access to Umami analytics: website listing/search, active visitors, pageviews, events, breakdowns, stats, and authentication validation. No obvious gaps for querying use cases.
Maintenance
ActivityInactive
ResponsivenessNo issues