Skip to main content
Glama
Schneckenhausmann

plausible-whenever-mcp

README.md
# plausible-whenever-mcp

> The [Plausible Analytics](https://plausible.io) MCP server that finally understands **"yesterday"**.

A local [Model Context Protocol](https://modelcontextprotocol.io) server that gives an AI assistant full read access to your Plausible data — and, crucially, resolves **natural-language dates** (`yesterday`, `last week`, `last 30 days`, `3 days ago`…) in your site's own timezone. So prompts like *"analyze yesterday's traffic"* just work, even with small local LLMs.

## Why this exists

The Plausible Stats API has presets like `day`, `7d` and `month`, but **no "yesterday"** — and to query a specific past day you must send explicit `YYYY-MM-DD` dates. LLMs (especially smaller local models) routinely get this wrong because they don't reliably know today's date or your site's timezone. The result: "yesterday" silently returns the wrong range, or the model burns turns guessing date formats (`/`, `..`, `YYYYMMDD`, `date` vs `date_range`…) and gives up.

**This server moves all of that to the server side.** The model says `date_range: "yesterday"`; the server computes the exact dates in your site's timezone before calling Plausible. There is no tool where the model must know Plausible's native date format — and if it ever passes something unrecognizable, the error message lists exactly what's accepted.

## Features

- 🗓️ **Natural-language dates** resolved in the site timezone — keywords, synonyms, `N days ago`, `last N days/weeks/months`, single dates, and ranges with `,` `..` `/` or `to` separators.
- 🧰 **8 tools** covering the full read API: sites, realtime, aggregates, time series, breakdowns, period comparison, plus a raw query escape hatch — and *all* of them resolve friendly dates.
- 🏠 **Self-hosted friendly** — works against any Plausible instance via `PLAUSIBLE_BASE_URL`, with a `PLAUSIBLE_TIMEZONE` override for instances where the Sites API (timezone auto-detect) is disabled.
- 🤖 **Tuned for local LLMs** — forgiving inputs, self-explaining errors, and clean tool output (no HTML dumps).
- 🔒 **Read-only** — every tool only ever reads your analytics.

## Tools

| Tool | What it does |
|------|--------------|
| `list_sites` | List sites your API key can access (with timezones). |
| `get_current_time` | Today + yesterday as concrete dates in a site's timezone. |
| `get_realtime_visitors` | People on the site right now. |
| `get_stats` | Aggregate totals for a period (visitors, pageviews, bounce rate…). |
| `get_timeseries` | Traffic over time (hour/day/week/month) for trends and charts. |
| `get_breakdown` | Top pages, sources, countries, devices, browsers, UTM tags… |
| `compare_periods` | Two periods side by side with absolute + % deltas. |
| `query` | Raw Stats API v2 escape hatch for anything else. |

### Date expressions accepted everywhere

- **Keywords** (resolved in the site timezone): `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `this_year`, `last_year`, `last_7_days`, `last_30_days`, `last_90_days`, `last_12_months`
- **Natural phrasing & synonyms:** `3 days ago`, `day before yesterday`, `last 14 days`, `last 6 months`, `previous month`, `the last week`, `ytd`, `mtd`, `all time`, …
- **Plausible presets:** `day`, `7d`, `30d`, `month`, `6mo`, `12mo`, `year`, `all`
- **A single date:** `2024-03-15` → that one day
- **An explicit range** (any separator): `2024-01-01,2024-01-31`, `2024-01-01..2024-01-31`, `2024-01-01/2024-01-31`, `2024-01-01 to 2024-01-31`

## Install

Requires Node.js ≥ 18 and a Plausible **Stats API key** (Plausible dashboard → *Settings → API Keys*; on self-hosted: `<your-instance>/settings/api-keys`).

```bash
git clone https://github.com/Schneckenhausmann/plausible-whenever-mcp.git
cd plausible-whenever-mcp
npm install
npm run build
```

## Configure

Set environment variables (see [`.env.example`](.env.example)):

| Variable | Required | Description |
|----------|----------|-------------|
| `PLAUSIBLE_API_KEY` | **Yes** | Your Plausible Stats API key. |
| `PLAUSIBLE_BASE_URL` | No | Self-hosted instance URL (default `https://plausible.io`). |
| `PLAUSIBLE_DEFAULT_SITE_ID` | No | Default site **domain** so you can omit `site_id` on every call. |
| `PLAUSIBLE_TIMEZONE` | No | IANA timezone (e.g. `Europe/Berlin`) for relative dates. Recommended on self-hosted instances where the Sites API is disabled (otherwise falls back to UTC). |

### Connect to Claude Desktop

`~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "plausible": {
      "command": "node",
      "args": ["/absolute/path/to/plausible-whenever-mcp/dist/index.js"],
      "env": {
        "PLAUSIBLE_API_KEY": "your-key",
        "PLAUSIBLE_DEFAULT_SITE_ID": "example.com"
      }
    }
  }
}
```

For a **self-hosted** instance, add `PLAUSIBLE_BASE_URL` and `PLAUSIBLE_TIMEZONE`:

```json
{
  "mcpServers": {
    "plausible": {
      "command": "node",
      "args": ["/absolute/path/to/plausible-whenever-mcp/dist/index.js"],
      "env": {
        "PLAUSIBLE_API_KEY": "your-key",
        "PLAUSIBLE_BASE_URL": "https://analytics.example.com",
        "PLAUSIBLE_DEFAULT_SITE_ID": "example.com",
        "PLAUSIBLE_TIMEZONE": "Europe/Berlin"
      }
    }
  }
}
```

### Connect to Claude Code

```bash
claude mcp add plausible \
  --env PLAUSIBLE_API_KEY=your-key \
  --env PLAUSIBLE_DEFAULT_SITE_ID=example.com \
  -- node /absolute/path/to/plausible-whenever-mcp/dist/index.js
```

## Example prompts that just work

- *"Look at yesterday's data for example.com and analyze it."*
- *"Top 10 pages last week vs the week before."*
- *"Show the hourly visitor trend for yesterday — we had a spike in the morning."*
- *"Which countries drove the most traffic last month?"*

## Self-hosted note

On Plausible Community Edition the **Sites API** (`/api/v1/sites`) is often disabled, so:

- `list_sites` will report `sites_api_available: false` and point at your configured default — this is expected and **does not** affect any stats queries.
- Timezones can't be auto-detected, so set `PLAUSIBLE_TIMEZONE` to keep relative dates correct.

## Develop

```bash
npm run build      # compile TypeScript -> dist/
npm run dev        # tsc --watch
npm test           # build + run the date-resolver test suite
npm run inspector  # open the MCP Inspector against the server
```

## Acknowledgments

Built fresh, but inspired by two excellent MIT-licensed projects — thank you to their authors:

- [**Defilan/plausible-mcp**](https://github.com/Defilan/plausible-mcp) by Defilan — clean stdio tool surface.
- [**getsentry/plausible-mcp**](https://github.com/getsentry/plausible-mcp) by Sergiy Dybskiy — per-tool architecture and the period-comparison idea.

Full third-party license notices are in [CREDITS.md](CREDITS.md).

## License

[MIT](LICENSE) © 2026 Nikias Herzhauser

TDQS

A4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct analytics function: period comparison, dimension breakdown, current time, real-time visitors, aggregate stats, time series, site listing, and a raw query fallback. No overlapping purposes.

Naming Consistency4/5

Most tools follow a clear 'verb_noun' pattern (get_stats, list_sites, compare_periods), but 'query' deviates by being a bare verb. This minor inconsistency is easily understood.

Tool Count5/5

8 tools is well-scoped for a Plausible analytics client. It covers all common analytics queries without unnecessary bloat or gaps.

Completeness4/5

The tool set covers essential stats queries and includes a raw query tool for edge cases. Minor gaps like site management or event details exist but are outside the server's stated purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues