Skip to content

ickas/plausible-mcp

plausible-mcp

CI License: MIT Node: >=20

An MCP server that exposes Plausible Analytics to Claude Desktop, Claude.ai remote connectors, and any other MCP-compatible client. Ships two transports out of the box:

  • stdiodist/index.js, spawned locally by Claude Desktop.
  • Streamable HTTPdist/remote.js, deployable to Railway / Fly / any Docker host so it can be added via Claude.ai's "Add custom connector" dialog.

Small surface, tiny dependency tree — two runtime deps (@modelcontextprotocol/sdk and zod), native fetch, nothing else. Every line of code is meant to be auditable in an afternoon.

Features

Nine tools that cover the common Plausible workflows:

Tool What it does
plausible_list_sites List sites the API key can see. Discovery tool.
plausible_aggregate Top-line totals (visitors, pageviews, bounce rate, visit duration).
plausible_timeseries Metrics bucketed over time (hour/day/week/month).
plausible_breakdown Top-N by any dimension (pages, sources, countries, UTM, custom props).
plausible_realtime Current visitors / visits / pageviews (default 5-minute window).
plausible_compare Period vs prior period with absolute + percent deltas.
plausible_list_goals List conversion goals configured for a site.
plausible_list_custom_properties List custom properties configured for a site.
plausible_query_raw Escape hatch — send a raw Stats API v2 body.

Requirements

  • Node.js 20 or later.

  • A Plausible API key. Create one at Plausible → Settings → API Keys (or on a self-hosted instance: user menu → API Keys).

  • The six Stats API tools (aggregate, timeseries, breakdown, realtime, compare, query_raw) work on every plan, including the regular hosted plausible.io plans.

  • The three Sites API tools (plausible_list_sites, plausible_list_goals, plausible_list_custom_properties) need:

    • an enterprise plan on hosted plausible.io, or
    • a Plausible Enterprise Edition self-hosted instance.

    Plausible Community Edition (the default self-hosted Docker image) does not ship the Sites API at all — those endpoints return 404. In both unsupported cases, set PLAUSIBLE_DISABLE_SITES_API=1 so the tools don't appear and Claude doesn't try them. See the recommended config below.

Install

git clone https://github.com/ickas/plausible-mcp.git
cd plausible-mcp
nvm use            # optional, pins Node 20
npm install
npm run build

The build writes an executable file to dist/index.js. That's the path you'll give Claude Desktop.

Configure Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS (or the equivalent on Windows/Linux) and add an entry under mcpServers:

{
  "mcpServers": {
    "plausible": {
      "command": "node",
      "args": ["/absolute/path/to/plausible-mcp/dist/index.js"],
      "env": {
        "PLAUSIBLE_API_KEY": "your-key-here"
      }
    }
  }
}

Replace /absolute/path/... with the real path (you can get it with realpath dist/index.js inside the repo). Restart Claude Desktop.

Self-hosted Plausible

Set PLAUSIBLE_BASE_URL alongside the API key:

"env": {
  "PLAUSIBLE_API_KEY": "your-key-here",
  "PLAUSIBLE_BASE_URL": "https://analytics.example.com"
}

Usage

Once the server is connected, ask Claude things like:

  • "List my Plausible sites."
  • "How many visitors did example.com get in the last 7 days?"
  • "Give me a day-by-day visitor chart for example.com this month."
  • "What are the top 10 pages on example.com in the last 30 days?"
  • "Which traffic sources drove the most visits last week?"
  • "How did last week compare to the week before on example.com?"
  • "How many people are on example.com right now?"
  • "What conversion goals are configured on example.com?"

Tool-by-tool examples

Each example shows the tool name and the exact input Claude will send.

plausible_aggregate — top-line totals

{
  "site_id": "example.com",
  "date_range": "7d",
  "metrics": ["visitors", "pageviews", "bounce_rate", "visit_duration"]
}

plausible_timeseries — daily visitors this month

{
  "site_id": "example.com",
  "date_range": "month",
  "metrics": ["visitors"],
  "interval": "day"
}

plausible_breakdown — top pages from organic search

{
  "site_id": "example.com",
  "date_range": "30d",
  "metrics": ["visitors", "pageviews"],
  "dimension": "event:page",
  "limit": 10,
  "filters": [["is", "visit:channel", ["Organic Search"]]]
}

plausible_breakdown — traffic sources

{
  "site_id": "example.com",
  "date_range": "7d",
  "metrics": ["visitors", "visits"],
  "dimension": "visit:source"
}

plausible_realtime — current visitors

{ "site_id": "example.com" }

Optional window_minutes (default 5) widens the window — e.g. last hour:

{ "site_id": "example.com", "window_minutes": 60 }

plausible_compare — this week vs last week

{
  "site_id": "example.com",
  "date_range": "7d",
  "metrics": ["visitors", "pageviews", "bounce_rate"]
}

Returns { current, previous, delta } where each delta entry has absolute and percent.

plausible_query_raw — anything the typed tools don't cover

{
  "body": {
    "site_id": "example.com",
    "date_range": "30d",
    "metrics": ["conversion_rate"],
    "dimensions": ["event:goal"],
    "filters": [["is", "event:goal", ["Signup"]]]
  }
}

Full request body reference: https://plausible.io/docs/stats-api.

Deploy as a remote connector (Railway, Fly, Docker, …)

If you'd rather not run the binary locally, you can host it as a remote MCP server and add it via Claude.ai's "Add custom connector" dialog or Claude Desktop's remote-connector flow.

What you get

Two entrypoints are built from the same code:

  • dist/index.js — local stdio transport (Claude Desktop spawns it).
  • dist/remote.jsStreamable HTTP transport, listens on $PORT, exposes the same nine tools at POST /mcp (default path).

One-click-ish Railway deploy

  1. Push this repo to your GitHub account (a fork or your own copy works).

  2. On https://railway.com, click New → Deploy from GitHub repo and pick the repo. Railway picks up the included Dockerfile and railway.toml automatically.

  3. In Variables, set:

    Key Value
    PLAUSIBLE_API_KEY Your Plausible API key.
    PLAUSIBLE_BASE_URL Self-hosted URL (e.g. https://analytics.example.com) — omit for https://plausible.io.
    PLAUSIBLE_SITE_ID (Optional) default site domain.
    PLAUSIBLE_DISABLE_SITES_API 1 on hosted plausible.io non-enterprise or self-hosted Community Edition (recommended).
    MCP_BEARER_TOKEN (Optional) shared secret for CLI clients. See Auth model below.
  4. In Settings → Networking, click Generate Domain to get a public HTTPS URL.

  5. Health-check it: curl https://<your-domain>/health should return JSON.

  6. In Claude.ai or Claude Desktop, open Settings → Connectors → Add custom connector and paste https://<your-domain>/mcp. Leave the OAuth fields empty.

Auth model

The remote endpoint is open by default. Two options to lock it down:

  1. Shared secret (recommended for personal use): set MCP_BEARER_TOKEN=<random-string>. The server enforces Authorization: Bearer <token> on every /mcp request. Works with custom clients that can set a header. Note that Claude.ai's connector dialog does not let you set arbitrary headers — it only supports OAuth — so use the bearer token for CLI / scripted clients, and rely on the URL being unguessable for the Claude.ai integration itself.
  2. Plain unguessable URL: Railway-generated subdomains are random enough for personal use. Don't share the URL.

OAuth 2.1 (matching MCP's spec) is not implemented yet. PRs welcome.

Other env vars for the remote entrypoint

Key Default Notes
PORT 8080 Set by Railway automatically.
MCP_PATH /mcp Move the endpoint if you want.
MCP_DISABLE_CORS 0 Set to 1 to drop the permissive CORS headers.

Build & run the Docker image yourself

docker build -t plausible-mcp .
docker run --rm -p 8080:8080 \
  -e PLAUSIBLE_API_KEY=your-key \
  -e PLAUSIBLE_BASE_URL=https://analytics.example.com \
  -e PLAUSIBLE_SITE_ID=example.com \
  -e PLAUSIBLE_DISABLE_SITES_API=1 \
  plausible-mcp

Then curl http://localhost:8080/health.

Development

npm run dev           # tsup watch mode
npm run typecheck     # tsc --noEmit
npm run lint          # biome check
npm run format        # biome format --write
npm run build         # bundle to dist/index.js (stdio) and dist/remote.js (HTTP)
npm start             # run the stdio entrypoint
npm run start:remote  # run the HTTP entrypoint on $PORT (default 8080)

Configuration

Env var Required Default Notes
PLAUSIBLE_API_KEY yes Plausible API bearer token.
PLAUSIBLE_BASE_URL no https://plausible.io Override for self-hosted instances.
PLAUSIBLE_SITE_ID no Default site domain. When set, every tool's site_id becomes optional and falls back to this value.
PLAUSIBLE_DISABLE_SITES_API no 0 Set to 1 (or true/yes/on) to hide plausible_list_sites, plausible_list_goals, plausible_list_custom_properties.

Recommended setup by Plausible deployment

The three Sites API tools (plausible_list_sites, plausible_list_goals, plausible_list_custom_properties) are unavailable on most setups. Hide them and pin the site so Claude doesn't waste a tool call probing for a 404 / 406 response.

Hosted plausible.io, regular Growth/Business plan:

"env": {
  "PLAUSIBLE_API_KEY": "your-key-here",
  "PLAUSIBLE_SITE_ID": "example.com",
  "PLAUSIBLE_DISABLE_SITES_API": "1"
}

Self-hosted Plausible Community Edition (the standard Docker image):

"env": {
  "PLAUSIBLE_API_KEY": "your-self-hosted-key",
  "PLAUSIBLE_BASE_URL": "https://analytics.example.com",
  "PLAUSIBLE_SITE_ID": "example.com",
  "PLAUSIBLE_DISABLE_SITES_API": "1"
}

Hosted plausible.io enterprise / self-hosted Plausible Enterprise Edition:

You can drop PLAUSIBLE_DISABLE_SITES_API and let all nine tools show up.

The remaining six tools (aggregate, timeseries, breakdown, realtime, compare, query_raw) use the Stats API and work everywhere — on every hosted plan and every self-hosted edition.

Security

  • Only talks to the Plausible endpoint you configure. No telemetry.
  • The API key is read from process.env and passed in the Authorization header. It is never logged, never written to disk, and never sent anywhere except Plausible.
  • See SECURITY.md for disclosure details.

Contributing

PRs welcome! See CONTRIBUTING.md for the dev loop and expectations.

License

MIT — see LICENSE.

About

An MCP server that exposes Plausible Analytics to Claude Desktop, Claude.ai remote connectors, and any other MCP-compatible client.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors