Repository navigation
feat: Structured tool errors, breakdown paging, and inline query rules - #66
Merged
Merged
Conversation
Make the tools easier for every kind of MCP client to drive without
reading SERVER_INSTRUCTIONS first.
- Errors: each failed call returns a second text block with
{"error":{code,message,retryable,retry_after_seconds?}}. Codes are
invalid_input, unauthorized, rate_limited, upstream_unavailable,
invalid_query and internal. Retry-After is parsed as seconds or an
HTTP-date. No structuredContent on errors: MCP SDK v1 clients validate it
against the success outputSchema and throw.
- get_breakdown paging: new offset input; the result carries
pagination {limit, offset, has_more} in both the text and structured
output. has_more comes from fetching one extra row. Rows are ordered by
the first metric with the dimension as a tiebreaker so pages do not
skip or repeat tied rows (event:goal excluded: Plausible rejects it in
order_by).
- Parameter descriptions now carry the metric/dimension/filter rules, so
clients that ignore server instructions still see them.
- Future dates: Plausible accepts ranges that end after today and counts
those days as zero; the instructions said they return a 400.
- Output-shape test: 0, 1 and 5 rows all parse against outputSchema with
the same top-level keys.
Co-authored-by: Claude <claude@anthropic.com>
- A rejected fetch (DNS, TLS, dropped connection) now returns upstream_unavailable with retryable true instead of a non-retryable internal error. - Plausible rejects event:goal in order_by, so tied goals could swap between requests and offset pages skipped or repeated them. Goal breakdowns now fetch every goal and page over a stable order. - The server instructions say that the SDK rejects arguments that fail the input schema before the tool runs, so those errors have no JSON block. Co-authored-by: Claude <claude@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #65. Merge #65 first; GitHub then retargets this PR to
main.Makes the tools easier to drive for every kind of MCP client, including clients that never read
SERVER_INSTRUCTIONSand harnesses that call tools from code.Changes
Structured errors. A failed call now returns two text blocks: the readable message, then
{"error":{"code","message","retryable","retry_after_seconds"?}}. The codes areinvalid_input,unauthorized,rate_limited,upstream_unavailable,invalid_queryandinternal.Retry-Afteris read as seconds or as an HTTP-date, for both 429 and 5xx. Error results have nostructuredContent, because MCP SDK v1 clients (1.27–1.30) check it against the successoutputSchemaand throw -32602.get_breakdownpaging. There is a newoffsetinput, and results carrypagination {limit, offset, has_more}in both the text and the structured output.has_morecomes from fetching one extra row; older self-hosted versions do not haveinclude.total_rows. Rows are sorted by the first metric, then by the dimension, so tied rows do not skip or repeat between pages.event:goalgets the metric sort only, because Plausible rejects it inorder_by.Rules in parameter descriptions. The metric, dimension, filter and date rules are now in the zod
.describe()texts. Themetricstext uses #65's corrected rules.Future dates. The instructions said a range that ends after today returns a 400. In a live test, Plausible accepted it and counted those days as zero, so both texts now say that.
Output-shape test. Results with 0, 1 and 5 rows all parse against
outputSchemaand have the same top-level keys.Testing
pnpm build,pnpm typecheckandpnpm testpass (269 tests).mcp.sentry.dev), with a real MCP client over stdio againstdist/index.js:has_moreis correct on the first page, the last page and past the end.invalid_query, and a bad key givesunauthorized. Error results have nostructuredContent.Created with Claude Code