Plausible Analytics MCP Server
Provides read-only tools for querying website traffic from Plausible Analytics, including aggregate totals, timeseries trends, top-N breakdowns, realtime visitor counts, and site access checks.
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., "@Plausible Analytics MCP ServerWhat were my top traffic sources last month?"
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.
Plausible Analytics MCP Server
A strictly-validated, fully tested Model Context Protocol server that lets Claude (or any MCP client) answer questions about your website traffic using the Plausible Analytics Stats API v2.
Built by AI coding agents under Sabry's direction and review.
Not yet exercised against a live Plausible account; all tests run against a mocked HTTP layer.
Ask things like "How did signups trend week over week this quarter?", "Which campaigns drove the most conversions last month?" or "How many people are on the site right now?" and the model calls strict, read-only tools against your Plausible account.
Why this exists
Plausible is a privacy-friendly analytics product that many B2B SaaS teams use in place of Google Analytics. Its Stats API v2 is a single, well-documented POST /api/v2/query endpoint. That makes it a good base for a small MCP server that still has to handle the hard parts: strict input validation, readable errors, pagination, rate limits, timeouts, and keeping secrets out of logs.
Related MCP server: Plausible Analytics MCP Server
Features
5 read-only tools covering totals, trends, top-N breakdowns, realtime traffic and access checks.
Strict input schemas (zod). Unknown metrics or dimensions, malformed dates and invalid combinations are rejected before a request is made, so no calls from the 600/hour budget are wasted.
Rules from the docs enforced in the server. Examples:
scroll_depth/time_on_pageneedevent:page;conversion_rateand revenue metrics needevent:goal; session metrics can't be mixed with most event dimensions;case_sensitiveworks only withis/contains.Actionable errors. 400/401/402/403/404/429/5xx, timeouts and network failures each map to a message that tells the model what to do next. They come back as
isErrortool results, not protocol failures.Reliability: per-request timeout, one bounded retry for transient 5xx/network errors, and no automatic retry on 429. Rate-limit responses include
Retry-After.Context-safe output: Markdown tables by default or JSON on request. Pagination has an explicit
next_offset, and a hard 25k-character budget drops whole rows so JSON stays valid.Self-hosted friendly: point
PLAUSIBLE_BASE_URLat your own instance. Path prefixes behind a reverse proxy are supported.No secrets in logs: logs are structured JSON on stderr only. The API key is never logged, and it is redacted if an upstream error ever echoes it.
Tools
Tool | What it answers | Requests |
| "Can this key read | 1 |
| Totals over a date range, e.g. visitors, bounce rate, conversions | 1 |
| Metrics bucketed by hour/day/week/month, with empty buckets filled in | 1 |
| Top pages/sources/countries/devices/UTMs/goals/custom props, paginated | 1 |
| Unique visitors in the last N minutes, plus the top pages they are on | 1–2 |
Every tool is annotated readOnlyHint: true, destructiveHint: false. site_id is optional on all tools when PLAUSIBLE_DEFAULT_SITE_ID is set.
Common arguments
date_range: a preset ("day","24h","7d","28d","30d","91d","month","6mo","12mo","year","all") or a custom range{"from": "2024-01-01", "to": "2024-01-31"}. The custom range also accepts ISO datetimes with an offset.metrics: any ofvisitors,visits,pageviews,views_per_visit,bounce_rate,visit_duration,events,scroll_depth,percentage,conversion_rate,group_conversion_rate,average_revenue,total_revenue,time_on_page.filters: list of{dimension, operator, values, case_sensitive?}, combined with AND. Within one filter,valuesare ORed. The operators areis,is_not,contains,contains_not,matchesandmatches_not(re2 regex).Dimensions:
event:page,event:goal,event:hostname,visit:source,visit:channel,visit:referrer,visit:utm_*,visit:device,visit:browser,visit:os,visit:country_name,visit:city_name, entry/exit pages, … and custom properties asevent:props:<name>.response_format:"markdown"(default) or"json".
Examples
// plausible_get_aggregate: last 7 days for the pricing page
{ "site_id": "example.com", "date_range": "7d",
"filters": [{ "dimension": "event:page", "operator": "is", "values": ["/pricing"] }] }
// plausible_get_timeseries: daily signups this month
{ "site_id": "example.com", "date_range": "month", "interval": "day",
"metrics": ["visitors", "events"],
"filters": [{ "dimension": "event:goal", "operator": "is", "values": ["Signup"] }] }
// plausible_get_breakdown: top 10 sources, then the next page
{ "site_id": "example.com", "dimensions": ["visit:source"], "date_range": "30d", "limit": 10 }
{ "site_id": "example.com", "dimensions": ["visit:source"], "date_range": "30d", "limit": 10, "offset": 10 }
// plausible_get_breakdown: conversion rate per campaign, case-insensitive country filter
{ "site_id": "example.com", "dimensions": ["visit:utm_campaign"],
"metrics": ["visitors", "conversion_rate"],
"filters": [
{ "dimension": "event:goal", "operator": "is", "values": ["Signup"] },
{ "dimension": "visit:country_name", "operator": "contains", "values": ["united"], "case_sensitive": false }
] }
// plausible_get_realtime_visitors
{ "site_id": "example.com", "window_minutes": 5, "top_pages": 5 }Sample Markdown output from plausible_get_breakdown:
## example.com — 30d by visit:source
| visit:source | visitors |
| --- | --- |
| Google | 1,204 |
| Direct / None | 877 |
Rows 1-2 of 14. More available: call again with offset=2.Setup
Requirements: Node.js 22 or newer, and a Plausible Stats API key. The Stats API is a Business-plan feature on plausible.io and is available on self-hosted instances. To create a key: Settings → API Keys → New API Key → Stats API. The key is scoped to the team selected when you create it.
git clone https://github.com/go-ai-now/mcp-server-plausible.git && cd mcp-server-plausible
npm ci
npm run buildClaude Desktop
Add this to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"plausible": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-plausible/dist/index.js"],
"env": {
"PLAUSIBLE_API_KEY": "your-stats-api-key",
"PLAUSIBLE_DEFAULT_SITE_ID": "example.com"
}
}
}
}Claude Code
claude mcp add plausible \
--env PLAUSIBLE_API_KEY=your-stats-api-key \
--env PLAUSIBLE_DEFAULT_SITE_ID=example.com \
-- node /absolute/path/to/mcp-server-plausible/dist/index.jsOr commit a project-scoped .mcp.json that reads the key from the developer's own environment, so the secret itself is never committed:
{
"mcpServers": {
"plausible": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-plausible/dist/index.js"],
"env": { "PLAUSIBLE_API_KEY": "${PLAUSIBLE_API_KEY}" }
}
}
}Environment variables
Variable | Required | Default | Description |
| yes | — | Stats API key. The server exits with a clear message if it is missing. |
| no |
| Base URL for self-hosted instances, e.g. |
| no | — | Site used when a tool call omits |
| no |
| Per-request timeout (1000–120000). |
| no | off |
|
Security notes
Read-only by design. The server only calls
POST /api/v2/query, which cannot change data. No write, delete or admin endpoints are wired in.Least privilege. Create a dedicated Stats API key for this server, scoped to the team whose sites the assistant should see. Revoke it in Plausible to cut off access instantly.
Secrets. The key is read from the environment only. It is sent only in the
Authorizationheader toPLAUSIBLE_BASE_URL, never logged, and redacted from any upstream error text before that text reaches the model.Transport. The server warns on startup if
PLAUSIBLE_BASE_URLuses plainhttp://to a non-local host, because the key would travel unencrypted.Untrusted input. All tool arguments are validated against strict schemas: bounded lengths and counts, allow-listed metrics, dimensions and operators, and no unknown keys. Regex filters are evaluated by Plausible with re2, which is linear-time.
stdout hygiene. stdout carries only MCP JSON-RPC. Diagnostics go to stderr.
Data exposure. Plausible is designed not to collect personal data, but aggregate traffic numbers may still be business-sensitive. Treat the MCP client that holds this server as having read access to your analytics.
Design notes
Why not a raw "run any query" tool? Strict per-task tools give the model better affordances and better error messages. They also make it much harder to build a query that burns rate limit and fails. The four query tools cover the Stats API's documented use cases.
Realtime. Stats API v2 has no dedicated realtime endpoint. Following the docs, "realtime" is a query over a short ISO datetime range (
[now − N min, now]in UTC). The legacy v1/realtime/visitorsendpoint exists, but this server deliberately stays on v2 only.No "list sites". Listing sites belongs to the separate Sites API, which needs a different key type.
plausible_check_site_accessprobes one site with a single cheap query instead.Retries. Queries are idempotent reads, so one retry on 5xx/network/timeout is safe. 429 is never retried automatically: that would spend more of the hourly budget, so the model gets
Retry-Afterand decides.Gap filling. Timeseries asks Plausible for
time_labelsand fills empty buckets:0for counts,nullfor ratios. If returned buckets don't match the labels, the data is returned untouched rather than guessed.
Development
npm ci
npm run typecheck # tsc --noEmit (src + tests)
npm test # vitest, fully offline: HTTP is stubbed, no API key needed
npm run build # emits dist/The tests cover:
schema validation and the cross-field rules
request building
mapping of 400/401/402/429/5xx, timeouts, network errors and non-JSON responses
secret redaction, including a check that no log line contains the key
output limits and pagination maths
end-to-end tests that connect a real MCP
Clientto the server overInMemoryTransportand call every tool
Project layout:
src/
index.ts stdio entry point (env -> config -> server)
server.ts createServer(): wires the client and tools; no process/env access
config.ts env parsing + validation
logger.ts stderr-only JSON logger
format.ts tables, units, character budget
plausible/
schema.ts zod schemas + documented cross-field rules
query-builder.ts tool input -> /api/v2/query body
client.ts fetch wrapper: timeout, retry, error mapping
errors.ts typed errors and LLM-oriented messages
types.ts wire types
tools/ one file per tool + shared plumbing
test/ unit + end-to-end testsLicense
MIT © go-ai-now. See LICENSE.
Not affiliated with or endorsed by Plausible Insights OÜ. "Plausible" is used only to describe compatibility.
Available Tools
5 toolsplausible_check_site_accessPlausible: check site accessARead-onlyIdempotent
Verify that the configured API key can query a site, and show today's visitor count as a smoke test.
Call this first when a user mentions a new site, or when other tools return authentication or "not found" errors. The Stats API has no "list sites" endpoint (that is the separate Sites API with a different key type), so this checks one site at a time.
Example: {"site_id": "example.com"}
| Name | Required | Description | Default |
|---|---|---|---|
| site_id | No | Site domain exactly as registered in Plausible, e.g. "example.com". Optional when PLAUSIBLE_DEFAULT_SITE_ID is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnly, idempotent, and non-destructive behavior. The description adds value by framing it as a smoke test, stating it shows today's visitor count, and disclosing that there is no list-sites endpoint in the Stats API—useful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short, purposeful sentences: purpose, when to call, API limitation context, and a concrete example. Every sentence earns its place and no filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-optional-parameter tool with no output schema, the description covers purpose, trigger conditions, limitation, and an example. It names the observable result (today's visitor count), though it does not specify exact output formatting or error signaling, leaving a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already fully documents site_id's pattern, length, and optionality. The description's example reinforces usage but does not add meaning beyond what the schema already provides, matching the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: "Verify that the configured API key can query a site, and show today's visitor count as a smoke test." This unambiguously distinguishes it from sibling data-query tools like plausible_get_aggregate or plausible_get_timeseries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to invoke the tool: "Call this first when a user mentions a new site, or when other tools return authentication or 'not found' errors." It also explains why it checks one site at a time, referencing the separate Sites API absence, leaving no ambiguity about alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plausible_get_aggregatePlausible: aggregate statsARead-onlyIdempotent
Get headline totals for a site over a date range (one number per metric, no grouping).
Use this for questions like "how many visitors last week?" or "what was the bounce rate in March for /pricing?". Use plausible_get_timeseries for trends over time and plausible_get_breakdown for top-N lists.
Examples:
Last 7 days overview: {"site_id": "example.com", "date_range": "7d"}
Conversions of a goal: {"date_range": "30d", "metrics": ["visitors", "events", "conversion_rate"], "filters": [{"dimension": "event:goal", "operator": "is", "values": ["Signup"]}]}
Custom range for one page: {"date_range": {"from": "2024-03-01", "to": "2024-03-31"}, "filters": [{"dimension": "event:page", "operator": "is", "values": ["/pricing"]}]}
Notes: scroll_depth/time_on_page need an event:page filter; conversion_rate and revenue metrics need an event:goal filter; percentage is not available here (it needs a dimension).
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Filters combined with logical AND. Each filter matches if any of its values match. | |
| metrics | No | Metrics to compute. Default: visitors, visits, pageviews, bounce_rate, visit_duration | |
| site_id | No | Site domain exactly as registered in Plausible, e.g. "example.com". Optional when PLAUSIBLE_DEFAULT_SITE_ID is set. | |
| date_range | No | Either a preset ("day", "24h", "7d", "28d", "30d", "91d", "month", "6mo", "12mo", "year", "all") or a custom range {"from": "2024-01-01", "to": "2024-01-31"} | 30d |
| response_format | No | "markdown" (default) for a readable table, "json" for machine-readable rows | markdown |
| include_imported | No | Include data imported from Google Analytics / CSV where Plausible supports it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only and idempotent, and the description adds valuable behavioral constraints: results are ungrouped headliners, and specific metrics have prerequisites such as 'scroll_depth/time_on_page need an event:page filter' and 'conversion_rate and revenue metrics need an event:goal filter.' It also notes percentage is unavailable because it requires a dimension.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by usage guidance, examples, and caveats. Every section earns its place given the six parameters and the need to disambiguate from sibling tools.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description defines the result shape ('one number per metric, no grouping') and mentions the response_format parameter. It covers parameter combinations, metric constraints, and sibling differentiation, making it complete for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters. The description still adds value with realistic examples showing parameter composition, and the Notes section clarifies metric-filter dependencies that the schema enum alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get headline totals for a site over a date range (one number per metric, no grouping).' This clearly distinguishes the tool from the timeseries and breakdown siblings by highlighting the absence of grouping.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this tool for 'how many visitors last week?' type questions and explicitly directs agents to plausible_get_timeseries for trends and plausible_get_breakdown for top-N lists. This gives unambiguous selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plausible_get_breakdownPlausible: breakdown by dimensionARead-onlyIdempotent
Rank groups by metrics: top pages, sources, countries, devices, UTM campaigns, goals, custom properties. Paginated.
Examples:
Top 10 traffic sources this month: {"site_id": "example.com", "dimensions": ["visit:source"], "date_range": "month", "limit": 10}
Top pages with engagement: {"dimensions": ["event:page"], "metrics": ["visitors", "pageviews", "bounce_rate", "time_on_page"]}
Goal conversions by campaign: {"dimensions": ["visit:utm_campaign"], "metrics": ["visitors", "conversion_rate"], "filters": [{"dimension": "event:goal", "operator": "is", "values": ["Signup"]}]}
Next page of results: repeat the call with "offset" set to next_offset from the previous response.
Rules: session metrics (bounce_rate, views_per_visit, visit_duration) cannot be combined with event dimensions other than event:page. "percentage" gives each group's share of the total.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Rows per page (1-1000, default 25) | |
| offset | No | Rows to skip, for pagination. Use next_offset from the previous page | |
| filters | No | Filters combined with logical AND. Each filter matches if any of its values match. | |
| metrics | No | Metrics per group. Default: ["visitors"] | |
| site_id | No | Site domain exactly as registered in Plausible, e.g. "example.com". Optional when PLAUSIBLE_DEFAULT_SITE_ID is set. | |
| order_by | No | Sort order. Default: first metric descending | |
| date_range | No | Either a preset ("day", "24h", "7d", "28d", "30d", "91d", "month", "6mo", "12mo", "year", "all") or a custom range {"from": "2024-01-01", "to": "2024-01-31"} | 30d |
| dimensions | Yes | Group by these dimensions (1-3), e.g. ["visit:source"] or ["visit:country_name", "visit:city_name"] | |
| response_format | No | "markdown" (default) for a readable table, "json" for machine-readable rows | markdown |
| include_imported | No | Include imported (e.g. Google Analytics) data where supported |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: pagination behavior (next_offset), the session-metrics restriction, and the meaning of 'percentage'. It doesn't describe rate limits or error behavior, but for a read-only analytics query tool, the disclosed constraints are sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, followed by four illustrative examples and two critical rules. Every sentence earns its place. The examples are formatted as JSON snippets that an agent can directly adapt.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only analytics tool with 100% schema coverage and no output schema, the description covers the essential operational knowledge: what dimensions/metrics are available, how pagination works, and a key constraint. It doesn't mention response format details (e.g., markdown vs json) but the schema covers response_format. The only minor gap is not explaining what happens when no metrics are specified, though the schema default covers that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 10 parameters thoroughly. The description adds value by showing realistic parameter combinations in examples (e.g., filters with goal dimension, metrics arrays, offset for pagination) and by explaining the 'percentage' metric's meaning. This goes beyond the schema's enum list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Rank groups by metrics') and enumerates the exact dimensions it supports (top pages, sources, countries, devices, UTM campaigns, goals, custom properties). This clearly distinguishes it from sibling tools like plausible_get_aggregate (which returns totals) and plausible_get_timeseries (which returns time-series data). The title and description align well.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides concrete examples for common use cases (top sources, top pages with engagement, goal conversions by campaign) and explicitly explains pagination via next_offset. It also states a critical rule about session metrics not being combinable with event dimensions other than event:page, which prevents invalid calls. While it doesn't explicitly name sibling tools, the examples and scope make the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plausible_get_realtime_visitorsPlausible: realtime visitorsARead-only
Get how many unique visitors are on the site right now (last few minutes), optionally with the pages they are viewing.
Examples:
Current visitors: {"site_id": "example.com"}
Last 15 minutes, top 10 pages: {"window_minutes": 15, "top_pages": 10}
Implemented with a Stats API v2 query over the last N minutes (UTC). Uses 1 request, or 2 when top_pages > 0.
| Name | Required | Description | Default |
|---|---|---|---|
| site_id | No | Site domain exactly as registered in Plausible, e.g. "example.com". Optional when PLAUSIBLE_DEFAULT_SITE_ID is set. | |
| top_pages | No | Also list the N most-visited pages in the window. 0 skips the extra request | |
| window_minutes | No | Look-back window in minutes (1-60). Plausible's dashboard uses 5 | |
| response_format | No | "markdown" (default) for a readable table, "json" for machine-readable rows | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and non-destructive, so the bar for extra disclosure is lower. The description adds meaningful behavior beyond annotations: it uses Stats API v2 over a UTC window and makes 1 or 2 requests depending on top_pages. This helps an agent understand side effects and cost without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core capability is in the opening sentence, followed by useful examples and a relevant implementation note. The sentence about request count earns its place because it warns about the extra call when top_pages is used. No redundant schema repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only, zero-required-parameter tool with fully documented schemas, the description is largely complete. It covers the operation, examples, parameter behavior, response format choices, and request count. It does not explain authentication or error behavior, but those are likely covered by the wider Plausible integration context and the openWorldHint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of the parameters with defaults, ranges, and meaning, so the schema already does the heavy lifting. The description's examples add a little extra value by showing valid combinations, but they do not introduce meaning absent from the input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Get how many unique visitors are on the site right now (last few minutes)'. This clearly distinguishes it from siblings like plausible_get_aggregate, plausible_get_timeseries, and plausible_get_breakdown because it targets live visitors rather than historical analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it via the realtime framing and gives concrete examples, but it does not explicitly state when not to use it or name alternatives. An agent can infer the right context, but the tool does not explain how it differs from aggregate/timeseries/breakdown tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plausible_get_timeseriesPlausible: timeseriesARead-onlyIdempotent
Get metrics bucketed over time (hour/day/week/month) to see trends, spikes and drops.
Examples:
Daily visitors for the last 30 days: {"site_id": "example.com", "date_range": "30d", "interval": "day"}
Hourly traffic today from one country: {"date_range": "day", "interval": "hour", "filters": [{"dimension": "visit:country_name", "operator": "is", "values": ["Germany"]}]}
Monthly signups this year: {"date_range": "year", "interval": "month", "metrics": ["visitors", "events"], "filters": [{"dimension": "event:goal", "operator": "is", "values": ["Signup"]}]}
Dates/times are in the site's reporting timezone. Hourly buckets over long ranges produce many rows; prefer day/week for ranges over a few days.
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Filters combined with logical AND. Each filter matches if any of its values match. | |
| metrics | No | Metrics per bucket. Default: visitors, pageviews | |
| site_id | No | Site domain exactly as registered in Plausible, e.g. "example.com". Optional when PLAUSIBLE_DEFAULT_SITE_ID is set. | |
| interval | No | Bucket size. "auto" lets Plausible pick one that suits the date range | auto |
| fill_gaps | No | Return every bucket in the range, including empty ones (counts become 0, ratios null) | |
| date_range | No | Either a preset ("day", "24h", "7d", "28d", "30d", "91d", "month", "6mo", "12mo", "year", "all") or a custom range {"from": "2024-01-01", "to": "2024-01-31"} | 30d |
| response_format | No | "markdown" (default) for a readable table, "json" for machine-readable rows | markdown |
| include_imported | No | Include imported (e.g. Google Analytics) data where supported |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only and idempotent behavior. The description adds useful behavioral context beyond that: dates/times use the site's reporting timezone, and hourly buckets over long ranges can produce many rows. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: one purpose sentence, three useful JSON examples, and one operational caveat. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters, a rich schema, and safe annotations, the description covers the key decision points: range, interval, filters, metrics, and output-size trade-offs. The schema handles the remaining constraints appropriately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds practical meaning through complete example payloads showing how filters, date_range, interval, and metrics fit together, plus the guidance to prefer day/week for long ranges.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get metrics bucketed over time (hour/day/week/month)'. This clearly differentiates it from sibling tools like aggregate, breakdown, and realtime by its time-series nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete usage scenarios via examples (daily visitors, hourly traffic from a country, monthly signups) and an operational warning about long hourly ranges. However, it never explicitly names sibling alternatives or states when to use aggregate/breakdown instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
plausible_check_site_access - First observed
plausible_get_aggregate - First observed
plausible_get_breakdown - First observed
plausible_get_realtime_visitors - First observed
plausible_get_timeseries
TDQS
Scored across 5 tools
Each tool targets a clearly distinct operation: access verification, aggregate totals, time-series trends, dimension breakdowns, and realtime visitors. The descriptions cross-reference when to use each, leaving no meaningful overlap.
All tools follow the same pattern: the plausible_ prefix followed by a verb and a resource/query type (check_site_access, get_aggregate, get_timeseries, get_breakdown, get_realtime_visitors). Naming is uniform and predictable.
Five tools is well-scoped for a read-only analytics server. Each tool covers a fundamental Stats API query mode without unnecessary bloat or redundancy.
The server covers the core Plausible analytics surface: totals, trends, breakdowns, realtime visitors, and access verification. The lack of site listing is noted as an API limitation, not a gap in this tool set.
Maintenance
Related MCP Connectors
Query site stats, realtime visitors, breakdowns and goals from Plausible Analytics.
Read and edit GA4, Search Console and Google Tag Manager from any MCP client. 29 tools.
Analytics for MCP servers. Query your tool calls, first-call success, retries and schema cost.
Privacy-first web analytics. Query pageviews, referrers, trends, and AI insights.
Related MCP Servers
- FlicenseBqualityDmaintenanceAllows AI models to query and retrieve analytics data from Plausible Analytics through the Plausible API, enabling natural language interactions with website statistics.18-
- AlicenseAqualityCmaintenanceEnables AI assistants to query website statistics from Plausible Analytics, providing access to metrics like real-time visitors, traffic trends, and page performance. It supports both Plausible Cloud and self-hosted instances through the Stats API v2.647 npm1MIT
- FlicenseNot gradedqualityDmaintenanceEnables querying Plausible Analytics data for website statistics, traffic, engagement, and conversions through natural language, with support for filters, dimensions, and time-series.6-
- AlicenseAqualityDmaintenanceMCP server that provides read access to Plausible Analytics data with natural-language date resolution, enabling users to query analytics like 'yesterday' or 'last week' without needing to know exact date formats.8MIT