Plausible Analytics MCP Server
# Plausible Analytics MCP Server
A stdio-based Model Context Protocol (MCP) server that gives Large Language Models (LLMs) tools to read analytics data from a Plausible Analytics account (cloud-hosted or self-hosted). It operates as a read-only proxy — it does not store, transform, cache, or mutate anything. Every tool call maps to exactly one Plausible API request.
## Prerequisites
- **Python**: 3.12 or higher
- **Package Manager**: [`uv`](https://github.com/astral-sh/uv)
- **Plausible Account**: Plausible Cloud or self-hosted instance with an API key (Personal Access Token)
## Setup Instructions
1. Clone the repository and navigate into the directory:
```bash
git clone <repository-url>
cd plausible-mcp
```
2. Install dependencies using `uv`:
```bash
uv sync
```
3. Create and configure your environment file:
```bash
cp .env.example .env
```
4. Edit `.env` to set your credentials:
```env
PLAUSIBLE_API_KEY=your_secret_api_key_here
PLAUSIBLE_BASE_URL=https://plausible.io
```
*(For self-hosted instances, replace `https://plausible.io` with your custom instance URL).*
## Running the Server
Start the server locally over stdio transport:
```bash
uv run python -m src.server
```
## MCP Client Configuration (Claude Desktop)
To connect this MCP server to Claude Desktop, add the following entry to your `claude_desktop_config.json` file (typically located at `%APPDATA%\Claude\claude_desktop_config.json` on Windows or `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
```json
{
"mcpServers": {
"plausible-mcp": {
"command": "uv",
"args": [
"--directory",
"C:/path/to/plausible-mcp",
"run",
"python",
"-m",
"src.server"
],
"env": {
"PLAUSIBLE_API_KEY": "your_secret_api_key_here",
"PLAUSIBLE_BASE_URL": "https://plausible.io"
}
}
}
}
```
## Tool Reference
### 1. `list_sites`
- **Description**: Returns the list of sites/domains accessible by the configured Plausible API key.
- **Parameters**: None
- **Example Call**:
```python
list_sites()
```
### 2. `query_stats`
- **Description**: General-purpose analytics query endpoint wrapping Plausible Stats API v2 (`POST /api/v2/query`).
- **Parameters**:
- `site_id` (`str`, required): The domain name configured in Plausible (min length 1).
- `metrics` (`list[Metric]`, required): List of confirmed metrics (e.g. `visitors`, `visits`, `pageviews`, `bounce_rate`, `visit_duration`, `events`, `scroll_depth`, `percentage`, `conversion_rate`, `group_conversion_rate`, `average_revenue`, `total_revenue`, `time_on_page`).
- `date_range` (`DateRangePreset` | `DateRangeCustom`, required): Either a preset string (`day`, `24h`, `7d`, `28d`, `30d`, `91d`, `month`, `6mo`, `12mo`, `year`, `all`) or a 2-element list of ISO8601 date/datetime strings (e.g., `["2026-01-01", "2026-01-07"]`).
- `dimensions` (`list[str]`, optional): List of event, visit, or time dimensions (e.g., `visit:source`, `event:page`, `time:day`).
- `filters` (`list[FilterClause]`, optional): Structurally validated filter clauses (e.g., `[["is", "visit:country", ["US"]]]`).
- `order_by` (`list[tuple[str, "asc" | "desc"]]`, optional): Sorting specifications.
- `pagination` (`Pagination`, optional): Limits and offsets (`{"limit": 10000, "offset": 0}`).
- **Example Call**:
```python
query_stats(
site_id="example.com",
metrics=["visitors", "pageviews"],
date_range="7d",
dimensions=["visit:source"],
order_by=[("visitors", "desc")]
)
```
### 3. `get_realtime_visitors`
- **Description**: Convenience wrapper querying the current active visitor count over a server-fixed 5-minute window (`now - 5 minutes` to `now`).
- **Parameters**:
- `site_id` (`str`, required): The domain name configured in Plausible.
- **Example Call**:
```python
get_realtime_visitors(site_id="example.com")
```
## Known Limitations
- **Filter DSL Structural Validation Only**: Filter clauses undergo structural validation (checking element length and operator string), but semantic validation of Plausible's full filter DSL is delegated to the Plausible API itself.
- **stdio Transport Only**: Only stdio transport is supported in this release.
- **Single Account / Single API Key**: Designed for single-tenant operations per server instance.
- **Read-Only Scope**: Purely read-only proxy. Endpoint calls to record pageviews, provision sites, or mutate goals are strictly out of scope.
## License
Not yet decided.
TDQS
Scored across 3 tools
The three tools are mostly distinct: list_sites retrieves site metadata, query_stats provides general analytics data, and get_realtime_visitors focuses on current active visitors. There is slight overlap between query_stats and get_realtime_visitors, but the descriptions clearly differentiate realtime from historical querying.
All tool names follow the verb_noun pattern: list_sites, query_stats, get_realtime_visitors. The naming is consistent, predictable, and clearly indicates the action and target resource.
With only 3 tools, the server is minimal but focused. The count is not excessive and covers the core analytics needs (site listing, stats querying, and realtime tracking) without adding redundant tools.
The server covers the essential read-only analytics lifecycle for Plausible: listing sites, querying statistics, and checking realtime visitors. Minor gaps exist such as site management (add/delete) or specific breakdown endpoints, but query_stats likely abstracts several API v2 query types, so the surface is reasonably complete for typical analytics workflows.