PeppolStatus
Server Details
Peppol market intelligence and network monitoring: migrations, provider churn, leads, and uptime.
- Status
- Healthy
- Uptime
- 100.0% over 57 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 63 tools
The tool set covers many closely related entities (providers, access points, seats, SMPs, vendors) and includes multiple summary/stat/history tools that could be confused from names alone. However, the detailed descriptions clarify scope and most tools target distinct resources or actions, so an agent can usually disambiguate with effort.
All tool names use snake_case and follow a predictable verb_noun or list_noun pattern (get_*, list_*), with consistent suffixes such as _stats, _history, _by_key. Minor variations like get_provider_sla vs get_provider_sla_by_key are still readable and consistent.
63 tools is far beyond what is typically manageable for an MCP server, making the surface overwhelming for an agent to navigate. While each tool may correspond to a real endpoint, the sheer volume is an extreme mismatch for a coherent tool set.
The server appears to cover the Peppol monitoring domain exhaustively: participants, providers, access points, seats, SMPs, hosts, compliance, software, doctypes, network stats, churn, adoption, anomalies, and incidents. Read-only analytics is the clear purpose, so the absence of create/update/delete tools is appropriate and no obvious gaps are present.
Available Tools
65 toolsget_access_pointARead-onlyInspect
Get an access point
One Provider's detail: display name, verified flag, member seats (each with its embedded provider or unverified cert-CN), roster size, and the country + document-scheme composition of its roster. A request for a STALE key (a seat since curated, so its old unverified key left the directory) resolves to the current Provider; the returned key is always the canonical current one. software groups the Provider's sighted hosts by registrable domain with the crawled identity of each, and hostname_count / smp_hostname_count give the true totals behind the capped hostnames / smp_hostnames samples. smp_tenants lists the Access Points (seats) that serve the participants on this Provider's SMP hosts — on a multi-tenant SMP most of the hosted footprint belongs to other APs — with smp_tenant_count / smp_tenant_other / smp_tenant_no_ap so the rows add up to hosted_participant_count (both come from the same rollup run); smp_hosted_by is the reverse: other providers' SMPs that carry this AP's participants. Each sub_providers bucket names its Vendor (name) and links to the Vendor's row (vendor_key).
A Vendor key (v-<slug>) returns the Vendor detail instead and needs a Market-tier key: the Providers it connects through (via), its participants and Companies, the signals that back the row, and the composition of its roster. A Vendor has no Seats, no certificate and no hosts of its own.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`), or a Vendor key (`v-exact`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, so the description carries the behavioral burden and does so well: it explains that a request for a STALE key resolves to the current Provider, that the returned key is always canonical, and that Vendor keys require a Market-tier key. These are non-obvious behaviors beyond the annotation.
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?
It is front-loaded with the core action, but the body is extremely long and dense with field-level jargon (smp_tenants, smp_hosted_by, sub_providers, hostname_count) that reads as output documentation. Some of this is warranted by the absence of an output schema, but the volume hinders quick scanning for tool selection.
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, the description correctly assumes the job of describing returns, and it covers both branches (Provider and Vendor), key resolution behavior, and the tier prerequisite. It is complete enough to call correctly, with the only gap being the lack of explicit sibling routing.
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 supplies key examples, so baseline would be 3. The description adds genuine meaning beyond the schema: the two key forms select different return shapes (Provider vs Vendor detail), stale keys silently resolve, and Vendor keys carry an authorization requirement.
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 gives a specific verb+resource and, unusually, defines what an 'access point' actually is (a Provider's detail) and distinguishes it from the Vendor branch. It clarifies the two key namespaces (c-/o- vs v-), which helps separate it from the many siblings, though it never explicitly names a sibling like get_provider or list_access_points.
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?
There is no when-to-use or when-not-to-use guidance and no named alternative, despite a dense field of similar siblings (get_provider, get_public_provider, get_seat, list_access_points). The only routing hints are implicit in the return-field descriptions and the tier note for Vendor keys.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_point_churnRead-onlyInspect
Get an access point's churn
An Access Point's joiner / mover / leaver activity over a period: a daily category series with derived net growth, period totals, and the 'won from / lost to' counterpart breakdown. Joiners are first-ever serving seats (from 2026-08-02 onward, first-full-deep-sweep completion); movers change Provider (both sides resolved to the current identity); leavers deregister while served. Defaults to the trailing 30 days.
A Vendor key (v-<slug>) returns the same shape for the Vendor, from a daily comparison of its membership. Movement is counted from churn_since; there is no history before it. A counterpart is a Provider or another Vendor (kind). match_totals and the newly_matched / no_longer_matched series count membership changes with no real event behind them (a signal appeared or disappeared): they are a data-quality figure, not movement, and are never in net_growth.
For a Provider key, counterpart_flow gives each mover side (out, in) its top counterpart with its share and the effective number of counterparts, over the requested period. The share is null under 25 movers on that side and the effective number under 100. A Vendor key has no counterpart_flow.
PLATFORM MOVES. A mover is a platform move when the platform that serves the participant stayed and only the certificate Seat changed: it is not a customer decision. The verdict is per DIRECTED provider pair (from → to), over all its movers since 2026-08-02, with one of two reasons (same_host, sub_provider): at least 90% of the movers whose endpoint host can be compared (5 or more, and at least 50% of all movers of the pair) kept their endpoint host, or at least 90% of 25 or more movers still carry, at the new provider, the sub-provider brand of the provider they left. It is a CURRENT judgment, computed again on every rollup cycle. For a Provider key, the movers of a platform-move pair are in platform_won / platform_lost of the counterpart and not in its won / lost; the flag is per direction (counterpart → Provider, Provider → counterpart). totals.platform_in / totals.platform_out are their sums. totals.movers_in, totals.movers_out, net_growth and the daily series still count all movers. A Vendor key is not changed: its counterparts have no platform fields.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive period end, `YYYY-MM-DD` UTC. Defaults to today. | |
| key | Yes | The Provider key (e.g. `c-tickstar`), or a Vendor key (`v-exact`). | |
| from | No | Inclusive period start, `YYYY-MM-DD` UTC. Defaults to 29 days before `to`. |
get_access_point_roster_mixRead-onlyInspect
Get a filtered access point roster breakdown
The five roster breakdowns of GET /v1/aps/{key} (country, entity type, NACE Rev. 2.1 division, size class, region) recomputed over a FILTERED slice of the roster, so a breakdown stays true while the roster is cut down. The filters are the same names and shapes as GET /v1/participants, scoped to this provider's seats.
BOUNDED BY DESIGN. The breakdowns are computed only when the filtered slice is narrow (under an internal cap of 10,000 participants). A request that narrows on nothing, that carries a filter this endpoint cannot express (doctype, transport_profile, q, host, sub_provider, postcode, provenance, vat_liable), or whose slice is too wide answers degraded: true with every mix null — never a wrong number and never an error. Callers fall back to the stored whole-roster mixes on GET /v1/aps/{key}.
Counts are sparse the same way the stored mixes are: company enrichment covers a handful of registers, so every mix except country_mix sums BELOW participant_count and the un-enriched remainder is derived from the total rather than served as a bucket.
A Vendor key (v-<slug>) answers the same question over the Vendor's roster and needs a Market-tier key. seat then selects one Seat the Vendor connects through.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`), or a Vendor key (`v-exact`). | |
| smp | No | Comma-array of SMP hostnames serving the participant. | |
| seat | No | Scope the slice to ONE member seat of this provider. A seat that is not a member answers an empty (not degraded) slice. Single-valued. | |
| size | No | Comma-array of company size classes (as stored). | |
| region | No | Comma-array of company seat region codes (`NO-32,BE-BRU`). | |
| scheme | No | Comma-array of Peppol identifier schemes. | |
| sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`). | |
| country | No | Comma-array of ISO-3166-1 alpha-2 country codes. Matched on the participant's card country, falling back to the country its ICD prefix implies — the same rule the stored `country_mix` buckets on. | |
| not_size | No | Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_region | No | Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| registered | No | Restrict to participants present (`true`) or absent (`false`) in the Peppol Directory. | |
| entity_type | No | Comma-array of company legal-form families (`company`, `natural_person`, `association`, `public`). | |
| not_country | No | Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_entity_type | No | Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. |
get_adoptionRead-onlyInspect
Get a country's adoption aggregates
Peppol adoption for one country as one bare object: headline totals (universe, on_peppol, penetration), the single-dimension cuts (sector with a NACE Rev. 2.1 section rollup (A–V), region, FR-only département, size class (FR and NO), BE-only province + postcode + mandate scope, legal-form family, and company age), the same categorical cuts cross-tabbed by company-age band (cuts_by_age), and the trend (monthly new adopters plus per-run penetration history). Region cells carry ISO 3166-2 (BE, NO, SK) / INSEE région (FR) codes and sector cells the NACE Rev. 2.1 division code, so the choropleth joins geometry with no string matching. Numerator cells below 10 matched companies are suppressed (on_peppol/penetration null, suppressed true); denominators are never suppressed. Cached for a day (data moves monthly).
| Name | Required | Description | Default |
|---|---|---|---|
| country | Yes | Country code — `be`, `fr`, `sk`, `no`, `se`, `fi` or `si`. |
get_anomalyARead-onlyInspect
Get an anomaly
One anomaly by its stable content-derived key.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The stable anomaly key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already indicates a safe read operation, and the description's 'Get' is consistent with that. The description adds little behavioral context beyond what annotations provide, but there is no contradiction.
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 only two sentences, front-loaded with the tool's purpose, and contains no unnecessary words or repetitive information.
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-by-id tool with one parameter, a readOnlyHint, and no output schema, this description is complete. It conveys the essential purpose and the key concept without needing extra detail.
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?
The schema fully documents the 'id' parameter as 'The stable anomaly key.' The description adds 'content-derived' to clarify the key's origin, but this is a minor addition given the schema's already high coverage.
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 clearly states the tool's action ('Get an anomaly') and resource ('anomaly'), and specifies it retrieves a single anomaly by its stable content-derived key. This distinguishes it from sibling list_anomalies and other get_* tools.
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 usage when you have a known stable key for a specific anomaly, but it does not explicitly mention alternatives like list_anomalies for browsing or searching. The guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_compliance_statsARead-onlyInspect
Network compliance landscape
The free compliance landscape (issue #692): per-country error rates — the share of a country's registered participants that break at least one published Peppol rule — and the per-rule breakdown of every open finding. Counts ONLY: no participant, seat or hostname appears here; the participant-level records are GET /v1/compliance/findings (Network tier). Read from the pre-computed compliance rollup tables and edge-cached. Keyless-cacheable.
Pass country to scope the whole body to one country (issue #716): the same shape, with countries holding that one cell, rules its own breakdown, each rule's share a share of THAT country's open findings, and the code echoed back in country. A country scope is how a structural national pattern is told apart from a real problem — AU and NZ, for example, break not_in_peppol_directory almost everywhere because A-NZ PINT participants are absent from the European Peppol Directory by design.
| Name | Required | Description | Default |
|---|---|---|---|
| country | No | Scope the landscape to one ISO 3166-1 alpha-2 country (or `ZZ`, the bucket for findings whose subject resolves to no country). A country the rollup has not seen returns an empty landscape, not an error. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description does not need to restate safety. It adds valuable behavioral context beyond the annotation: data is read from pre-computed rollup tables, edge-cached, keyless-cacheable, and contains only aggregate counts with no participant/seat/hostname identifiers. These details help an agent understand latency, freshness, and privacy characteristics.
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 longer than necessary and contains nonessential noise such as GitHub issue references (#692, #716) and the awkward 'The free compliance landscape' phrasing. However, the core information is front-loaded in the first paragraph, and the country-scope explanation is substantive rather than padding. It is verbose but still scannable.
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 single-optional-parameter read-only tool with no output schema, the description is remarkably complete. It explains the returned aggregate shape, the no-identifying-data guarantee, the country-scoping behavior, and the cache/rollup origin. An agent has enough information to decide whether to use this tool, pass a country, and correctly interpret the result.
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?
The schema already describes the sole parameter with 100% coverage, so the baseline is 3. The description adds meaningful value by explaining how passing country changes the entire response body, that share percentages are relative to that country's open findings, and that the country code is echoed back. The AU/NZ example further clarifies interpretation of scoped results.
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 identifies a specific verb and resource: it returns the compliance landscape with per-country error rates and per-rule breakdowns. It also distinguishes itself from sibling tools by explicitly stating it returns counts only and that participant-level records are served by GET /v1/compliance/findings (Network tier). The odd phrase 'The free compliance landscape' is a minor distraction, but the core purpose is unambiguous.
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 gives clear usage guidance: if an agent needs participant, seat, or hostname records, it must use GET /v1/compliance/findings instead. It also explains when and why to pass the country parameter, including a concrete AU/NZ example to distinguish structural patterns from real problems. This effectively routes agents between this tool and its sibling alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_compliance_stats_historyARead-onlyInspect
Network compliance trend
The network compliance picture over time: one point per UTC day the rollup ran, carrying that day's participant denominator, affected participants, error rate and open findings by grade. The series starts the day the rollup first ran. Keyless-cacheable.
Pass country for one country's trend (issue #716) — the same series shape, restricted to that country and echoed back in country. The per-country series starts the day the country rollup first ran, which is later than the network one.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago. | |
| country | No | Scope the trend to one ISO 3166-1 alpha-2 country (or `ZZ`). A country the rollup has not seen returns an empty series, not an error. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering safety, the description adds useful behavior: keyless cacheability, per-UTC-day rollup granularity, series-start semantics, and the country echo. It does not describe exact JSON field names, but the data content is sufficiently specified for a read-only history tool.
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 flows from headline to network-series details to country variant, with most sentences earning their place. Minor noise includes the 'issue #716' parenthetical and slight redundancy between the headline and the first sentence.
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?
There is no output schema, so the description carries the return-value burden; it does so by stating point contents, series-start behavior, and country-scoping results. It could be more explicit about the exact response structure, but nothing essential is missing for correct invocation.
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 meaningful semantics for `country`—same series shape, echoed back, and a later series start—while to/from are already fully described by the 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 description clearly identifies the resource (network compliance) and the temporal dimension ('one point per UTC day... over time'), making it easy to distinguish from a current-snapshot compliance endpoint. It lacks an explicit retrieval verb in the description itself, but the intent is unmistakable.
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 gives clear context for both invocation modes: omit `country` for the network trend or pass `country` for a single-country trend, including the later series-start date for country rollups. It does not explicitly contrast with `get_compliance_stats` or state when-not to use this tool, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_country_churnARead-onlyInspect
Per-country participant churn
New (joiner) vs departed (leaver) participants for one country, as a daily series and an all-time monthly rollup, from the hourly churn rollup. A valid but unknown country returns empty arrays. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound of the daily series (YYYY-MM-DD UTC). Defaults to today. | |
| code | Yes | Two-letter country code (ISO 3166-1 alpha-2), case-insensitive. | |
| from | No | Inclusive lower bound of the daily series (YYYY-MM-DD UTC). Defaults to 30 days ago. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals the return structure (daily series, all-time monthly rollup), the data source (hourly churn rollup), and an important edge case ('valid but unknown country returns empty arrays'). Also notes 'keyless-cacheable' behavior. No contradiction 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?
Three sentences cover purpose, output shape, edge case, and caching, with no filler. The most important information is front-loaded.
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?
No output schema exists, so the description carries the burden of describing returns. It explains the series types and the edge case, but could be more explicit about the exact array fields. Overall adequate for the tool's moderate complexity.
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 parameters are already documented. The description adds semantic context for the country code (valid but unknown -> empty arrays) and clarifies that from/to bound the daily series. This provides extra meaning beyond the raw 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 description clearly states the resource and scope: 'Per-country participant churn' and 'New (joiner) vs departed (leaver) participants for one country'. It distinguishes from sibling tools like get_access_point_churn by focusing on country-level data, and specifies the output shape (daily series + monthly rollup).
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 usage context is implied by the name and description (for country-level churn), but there are no explicit alternatives or when-not-to-use conditions. Sibling tool names exist but are not referenced, so the agent must infer when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_country_providersARead-onlyInspect
Providers serving a country
The Access Points serving one country, ranked two ways from the hourly rollup: providers by participant (Peppol-ID) count, and providers_by_company by the number of DISTINCT organizations (real businesses) each serves (issue #467). Each row's key is the /v1/aps/{key} handle and share is that provider's fraction of the country's AP-served total for its metric. company_coverage (0..1) is how much ID→organization dedup the market shows — ~0 (and providers_by_company empty) for markets without register enrichment, meaningfully positive for BE/FR. A valid but unknown country returns empty lists. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Two-letter country code (ISO 3166-1 alpha-2), case-insensitive. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds meaningful context: unknown countries return empty lists, company_coverage semantics and empty providers_by_company for unenriched markets, and keyless-cacheability. This enriches the agent's understanding of edge cases and output interpretation.
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 main purpose and then provides necessary detail in a compact set of sentences. It includes some technical specifics (issue #467) that may be unnecessary but does not waste words overall.
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 a single parameter and no output schema, the description fully covers the return fields, ranking logic, and edge cases. It provides enough information for an agent to know what the tool returns and how to interpret it, making it contextually complete.
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?
The input schema already provides 100% coverage for the single parameter (code) with a clear description. The tool description does not add syntax details but does clarify the country context and behavior for unknown codes, which is marginal value. Baseline 3 is appropriate.
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 clearly states it lists access points serving a country with two ranking metrics, giving a specific verb and resource. It distinguishes itself through country-scoped ranking but does not explicitly name sibling alternatives like list_providers.
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 intended use is implied: when you need country-level provider rankings. However, there is no explicit statement of when to use this tool over alternatives or exclusions, so guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_deregistered_company_statsARead-onlyInspect
Get the company breakdown of the De-registered IDs
Who left: the De-registered IDs of /v1/stats/deregistered (same population, same daily rollup, same deregistered total) by company profile, register status, lifetime, re-activation and leftovers.
entity_type, sector, size and region come from the company register (BE, FR, NO, SE, FI and SI only) and cover the enriched IDs: the cells of each of the four add up to enriched, with the key unknown for an enriched ID that has no value in that breakdown. Each cell carries base, the registered IDs in the same cell, so the two mixes can be compared. company_status is the status of the company in its register now: active (still in business, gone from Peppol), ceased, or unmatched (no register match). lifetime is the time from the join date to the de-registration; unknown holds the IDs with no usable join date or a leave before 2026-08-02. leftovers counts the De-registered IDs that still have a Peppol Directory entry (directory_card). reactivation is the share of the IDs de-registered since 2026-08-02 that are registered again.
A count below 10 is withheld (count: null, suppressed: true), and so is a cell with a registered base from 1 to 9 (base: null too). When one cell alone of a breakdown is withheld, the next-smallest cell is withheld with it, so that it cannot be had back by subtraction (not for leftovers, which is part of no total). Counts only: no company and no natural person is named.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, it discloses substantial behavior: small-count suppression (`count: null`, `suppressed: true`), the complementary-suppression rule that withholds the next-smallest cell to prevent recovery by subtraction (with the leftovers exception), and a privacy guarantee that no company or natural person is named. These are exactly the operational traits an agent needs and cannot get from the sparse schema or 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 purpose is front-loaded in sentence one, and the dense detail that follows is almost entirely load-bearing: register coverage, the `enriched` totals, cell `base` semantics, and suppression rules. It is long and packed, but each clause explains a field or a caveat rather than padding; only the parenthetical asides make it heavier than strictly necessary.
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, the description must carry the entire return-value burden, and it does: it defines every breakdown dimension, the `base` field for comparing mixes, the `unknown` buckets, the register-status enum, and the suppression behavior. Nothing an agent needs to correctly interpret a response appears to be missing.
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?
The tool takes no parameters, so the baseline is 4; there is no schema documentation to compete with. The description instead invests in defining the output cells (`entity_type`, `sector`, `size`, `region`, `company_status`, `lifetime`, `reactivation`, `leftovers`, `base`), which is valuable even though it is not, strictly, parameter semantics.
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 opening sentence names a specific verb and resource ('Get the company breakdown of the De-registered IDs') and anchors it to the `/v1/stats/deregistered` endpoint, making clear it is the company-breakdown companion to the aggregate tool. An agent can distinguish it from siblings like get_deregistered_stats and list_deregistered_ids. It stops short of explicitly naming the sibling to prefer for totals, keeping it at 4.
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?
'Same population, same daily rollup, same `deregistered` total' as `/v1/stats/deregistered` frames the relationship to the aggregate stats tool, implying this is the drill-down you pick when you need per-company-profile segmentation rather than totals. There are no parameters, so there is no filter-selection guidance to give, but the description never explicitly states the alternative or when-not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_deregistered_statsARead-onlyInspect
Get the De-registered overview
The participants that left the network. A De-registered ID is a participant that is not registered now AND has at least one closed registration row. An ID that was never observed registered (not scanned yet, or never in the SML) is not de-registered: it is counted apart in never_registered and is in no other number here. leavers is the sub-count of the De-registered IDs that left while a Provider served them.
deregistered, share_pct and countries are the stock of the daily rollup (as_of). flow and weekly are the leave flow from the network growth series of /v1/network/stats, to the last complete UTC day: flow.d7 and flow.d30 are the same counts as leavers.last_7d and leavers.last_30d there. A day with no completed change scan is a gap: its de-registrations are counted on the next scanned day, so a period sums all its days and gap_days only marks it. A period or a week of gap days only has leavers: null — a gap is never 0. Joiners do not depend on the change scan, so a gap day keeps them. annualized_leave_rate_pct is the Leaver rate (annualized), the same figure as leavers.annualized_pct of /v1/network/stats: the 30-day leavers as a percentage of the registered participants at the start of the period, × 365 / the days of the period. Leave dates are reliable from 2026-08-02 (reliable_from); a period that would open earlier is clamped to it, and the weekly trend starts there. The event date of a de-registration is about 3 days after the true leave (3 consecutive scans without the ID).
Free. The company breakdown of the same population is /v1/stats/deregistered/companies (Market).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only `readOnlyHint: true` annotated, the description adds extensive behavioral context: gap-day handling, `leavers: null` semantics, `reliable_from` clamping, and the roughly 3-day lag between true leave and event date. These details materially affect how an agent interprets the returned stats and are not available from annotations or schema.
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 purpose is front-loaded and the dense metric explanations are relevant because there is no output schema to carry them. The block is long and could be better structured with headings or bullets, but nearly every sentence contributes to correct interpretation.
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?
Given the lack of an output schema, the description thoroughly defines the returned fields (`deregistered`, `share_pct`, `countries`, `flow`, `weekly`, `leavers`, `gap_days`, `annualized_leave_rate_pct`) and their caveats. It provides enough context for an agent to understand and use the stats 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?
The tool takes zero parameters, so there are no parameter semantics to document. Per the rubric, a zero-parameter tool has a baseline of 4.
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 ('Get') and resource ('De-registered overview'), then immediately defines the de-registered population and contrasts it with never_registered. It also distinguishes related endpoints, including the company breakdown at `/v1/stats/deregistered/companies` and the flow source at `/v1/network/stats`, so an agent can tell it apart from siblings.
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 clear context for when this overview is the right population to inspect and names the sibling endpoint for company breakdown. It does not explicitly state when not to use it or how it relates to `list_deregistered_ids`, but the alternatives are visible enough for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_doctype_familyARead-onlyInspect
Doctypes within a family
The concrete document types within one family (issue #647): each doctype's local name, version, participant count, and share of the family. An unknown family returns an empty doctypes array. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| family | Yes | The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds useful behavioral details: an unknown family returns an empty 'doctypes' array, and the result is keyless-cacheable. This helps the agent anticipate edge-case responses and cache semantics.
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 with the core concept, followed by concrete output details and edge-case behavior. The internal reference '(issue #647)' adds little value for an AI agent and slightly reduces focus, but overall the structure is efficient.
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 single-parameter, read-only tool with no output schema, the description provides the key output fields, the empty-result behavior, and cacheability. It could also state the exact return container or an explicit when-to-use clause, but nothing essential is missing for basic invocation.
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 'family' parameter is already fully documented with examples. The description does not add extra meaning beyond reinforcing that doctypes are scoped within one family, which matches the baseline for full schema coverage.
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 clearly identifies the resource ('concrete document types within one family') and specifies the output fields: local name, version, participant count, and share of the family. It lacks an explicit verb like 'returns' and does not directly contrast with sibling tools, but the resource and scope are unambiguous.
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?
No guidance is given about when to choose this tool over alternatives such as get_doctype_stats or get_doctype_stats_history. The intended use is only implied by the resource description, and no exclusions or alternatives are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_doctype_family_countriesARead-onlyInspect
A family's receivers by country
One document family's receiving participants sliced by ISO-3166 alpha-2 country (issue #652), each with its share of the family total. The country is derived from the participant identifier's ICD; unresolved identifiers bucket as ZZ. An unknown family returns an empty countries array. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| family | Yes | The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond the readOnlyHint annotation: the country is derived from the participant identifier's ICD, unresolved identifiers bucket as `ZZ`, unknown families return an empty `countries` array, and the result is keyless-cacheable. It also indicates each entry carries a share of the family total. No contradiction 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 with the core purpose, followed by derivation details and edge cases. The internal reference `(issue #652)` is extraneous noise for an AI agent, but the remaining sentences are short and informative.
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, the description does a good job of explaining the result shape: a `countries` array, per-country shares, the `ZZ` bucket, and empty behavior for unknown families. However, it does not specify exact output item field names or the share's type/format (e.g., decimal ratio vs percentage), which would make it fully self-contained.
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 defines `family` as the doctype family name with examples. The description reinforces the family concept and mentions the unknown-family empty-result behavior, but adds little new parameter-level meaning beyond what the schema and annotations already provide.
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 clearly defines the resource: a single doctype family's receiving participants aggregated by ISO-3166 alpha-2 country, with each country's share of the family total. It distinguishes itself from siblings like get_doctype_family_providers by focusing on receivers rather than providers, and from get_doctype_family by adding the country-slice dimension.
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 intended use is implied: call this when you need a receiver-by-country breakdown for one document family. However, it does not explicitly state when not to use it, nor does it reference alternatives such as get_doctype_family_providers for a provider-side equivalent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_doctype_family_providersARead-onlyInspect
A family's receivers by provider
One document family's receiving participants sliced by hosting provider (issue #652), attributed via the SMP-hosted footprint (the participant's current SMP host mapped to a provider), each with its share of the family total. Participants whose SMP host maps to no known provider are omitted. An unknown family returns an empty providers array. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| family | Yes | The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses meaningful behavioral details: attribution via SMP-hosted footprint, omission of participants whose host maps to no known provider, empty `providers` array for unknown families, and keyless-cacheability. These details materially affect interpretation of results and are exactly the kind of context annotations do not provide.
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, leading with the core definition and then covering edge cases. The issue reference '#652' is marginally useful context but not essential for invocation; overall, every substantive sentence earns its place.
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 one-parameter read-only lookup with no output schema, the description covers the mapping rule, exclusion behavior, unknown-family behavior, and caching, which is enough to invoke the tool correctly. It stops short of enumerating exact output field names, but the phrase 'each with its share of the family total' conveys the essential response shape.
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 single parameter `family` already includes its type and realistic examples. The description adds only a small behavioral clarification that an unknown family returns an empty array, but it does not need to compensate for missing schema detail.
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 clearly defines the resource as 'one document family's receiving participants' and the grouping dimension as 'hosting provider,' with each provider's share of the family total. This distinguishes it from sibling tools like get_doctype_family_countries by the slicing dimension, though it stops short of naming a sibling explicitly.
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 intended use is implied: call this when you need provider-level breakdowns for a single doctype family. However, it does not explicitly state when to prefer this over get_country_providers or get_doctype_family_countries, nor does it describe exclusion cases for alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_doctype_statsARead-onlyInspect
Document-type landscape
The free document-type landscape (issue #647): per-family participant share (Invoice, Order, Credit Note, …), the wildcard-doctype bucket, and the participant denominator. Read from the pre-computed doctype rollup tables and edge-cached. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint, and the description adds non-obvious behavioral detail: results come from pre-computed rollup tables, are edge-cached, and are keyless-cacheable. This helps the agent understand performance and consistency expectations beyond the read-only annotation.
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 with the key term, then expands with concrete dimensions. Minor redundancy exists between the heading phrase and the first sentence, but no sentence is wasted.
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?
Because there is no output schema, the description does the work of explaining what the result will represent (per-family shares, wildcard bucket, denominator). It is adequate for a zero-argument read-only tool, though it could explicitly state the return shape (list vs table).
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?
The tool has zero parameters and the schema coverage is 100%, so there is nothing for the description to document. Per the baseline for 0-parameter tools, this is handled appropriately.
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 names the resource ('document-type landscape') and specifies the content: per-family participant share, the wildcard-doctype bucket, and the participant denominator. It does not use an explicit verb like 'returns', but the topic is specific enough to separate it from generic stats tools; its relationship to get_doctype_stats_history is only implied.
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?
No guidance is given about when to choose this tool over siblings such as get_doctype_family or get_doctype_stats_history. The edge-cached/pre-computed phrasing implies a fast current snapshot, but there is no explicit when-to-use or when-not-to-use information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_doctype_stats_historyARead-onlyInspect
Document-type landscape history
The document-type landscape over time: per UTC day, the participant count for each family, from the doctype history rollup. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers the read-only safety profile. The description adds a useful data-source detail ('from the doctype history rollup') and the 'Keyless-cacheable' behavior, but does not elaborate on caching implications or return shape. This is adequate but not deeply transparent.
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?
Two sentences deliver the core purpose, temporal granularity, metric, data source, and cacheability with no filler. The main idea is front-loaded in the first sentence, making it quick for an agent to scan.
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 history tool with two optional, fully documented parameters and no nested output, the description sufficiently explains what is returned: per-day participant counts by family. It could be strengthened by explicitly noting the relationship to get_doctype_stats, but it is otherwise complete.
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 description does not need to restate parameter meanings. It reinforces the UTC-day and historical framing, which aligns with the from/to date parameters, but adds no new parameter-level detail beyond the 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 description clearly states the tool returns document-type landscape history with a specific unit of analysis: per UTC day, participant count per family. This distinguishes it as a historical time-series counterpart to the current-state tools, though it does not explicitly name or contrast a sibling tool.
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 temporal phrasing ('over time', 'per UTC day', 'history') implies this is for historical trends rather than current snapshots, and the from/to parameters support that use. However, it does not explicitly state when to choose this over get_doctype_stats or provide any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_hostARead-onlyInspect
Get a host's current state
Current role, verdict, network attribution (IPs/PTR), TLS certificate and operating provider for a host. ?at= returns point-in-time state. profile carries the crawled software identity of the host's registrable domain when one is publishable (curated, or extraction confidence 0.8+ — then unverified).
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Point-in-time ISO 8601 instant; omitted returns current state. | |
| hostname | Yes | The host's fully-qualified hostname. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, but the description adds meaningful behavioral context: it lists the returned categories, explains the effect of `?at=`, and describes the conditional publishability and verification caveat of `profile`. It does not cover auth, rate limits, or pagination, but those are less critical for a read-only host lookup.
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 and then provides relevant operational details in a compact paragraph. It is dense but not bloated, and every clause contributes useful context.
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, the description usefully enumerates the main returned data and explains the `profile` field's conditional behavior. It remains incomplete regarding selection against sibling tools and does not describe pagination or error behavior, but it is sufficient to call the tool 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 both parameters. The description adds clarifying value for `at` (point-in-time state), but offers no additional detail for `hostname` and mentions `profile` as an output rather than a parameter. Baseline 3 is appropriate.
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 clear verb+resource ('Get a host's current state') and enumerates the returned information (role, verdict, network attribution, TLS certificate, provider). It does not explicitly differentiate itself from siblings like get_host_software or get_host_uptime, so it falls short of a 5.
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 mention of current state and the `?at=` parameter implies when the tool is useful (current vs. point-in-time host state). However, there is no explicit guidance on when to choose this tool over sibling alternatives such as get_host_software or list_hosts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_host_uptimeARead-onlyInspect
Get a host's uptime aggregates
The aggregate ladder for a host at a chosen resolution, per-location plus the __all__ rollup, optionally windowed by [from, to), cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Exclusive upper bound (ISO 8601). | |
| from | No | Inclusive lower bound (ISO 8601). Must not be after `to`. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| hostname | Yes | The host's fully-qualified hostname. | |
| location | No | Restrict to one probe location, or `__all__` for the rollup. | |
| resolution | No | Aggregate tier. Defaults to hourly. | hourly |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses key behavioral traits: it returns a per-location rollup including __all__, supports date-range windowing with half-open semantics, and is cursor-paginated. These details are not present in the annotation and add meaningful context for the agent.
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 two succinct sentences. The first sentence delivers the primary purpose immediately, and the second elaborates on key details without redundancy. Every phrase earns its place, and there is no filler.
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?
Given the tool's complexity (7 parameters, aggregate levels, pagination) and lack of an output schema, the description covers the main functional aspects: aggregate ladder, per-location rollup, windowing, and cursor pagination. It does not describe the exact return fields of an uptime aggregate, but the schema and annotations largely compensate.
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?
The input schema already provides comprehensive descriptions for all 7 parameters with 100% coverage, achieving the baseline. The description adds minimal parameter-specific meaning, mostly rephrasing concepts like resolution and windowing already documented in the 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 description opens with 'Get a host's uptime aggregates,' a specific verb and resource combination that clearly states the tool's function. It further differentiates from siblings by detailing the aggregate ladder, per-location rollup, and optional windowing, which distinguishes it from other host/network tools.
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 usage for retrieving uptime aggregates at various resolutions and locations, with windowing and pagination. It provides clear context for when to use the tool but does not explicitly mention exclusions or alternatives, such as using get_host for basic host details or list_hosts for enumeration.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_id_qualityARead-onlyInspect
Peppol ID quality summary
Per-scheme (ICD) summary of the structural identifier checks: how many participants were checked, how many failed their scheme's rule, and the resulting violation rate. Ordered by violation count, busiest first.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations provide readOnlyHint=true, and the description adds meaningful behavioral context beyond that: it explains the tool returns counts of participants checked, failures, and violation rates, and that results are 'Ordered by violation count, busiest first.' This gives a clear picture of output structure without contradicting the read-only annotation.
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 with the essential purpose ('Peppol ID quality summary'), followed by a concise but informative breakdown of what the summary contains and how it is ordered. Every sentence adds value with no fluff or 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, parameterless, read-only tool, the description fully covers what the agent needs to know: the aggregation level (per-scheme), the metrics provided (participants checked, failures, violation rate), and ordering. Given the lack of an output schema, the description sufficiently explains the return content without missing critical details.
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?
The input schema declares zero parameters, so there are no parameter semantics to describe. The description thus correctly focuses on output semantics. Baseline of 4 is appropriate for a no-parameter tool.
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 clearly identifies the tool as a 'Peppol ID quality summary' with specific details about per-scheme (ICD) aggregation of structural identifier checks. It distinguishes itself from siblings like list_id_quality_malformed and get_id_quality_hosting by focusing on summary statistics rather than listing individual malformed IDs or host-specific data.
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 usage when a summary-level per-scheme quality view is needed, mentioning 'summary' and 'resulting violation rate.' However, it does not explicitly state when to prefer this tool over alternatives such as list_id_quality_malformed or get_id_quality_hosting, nor does it provide clear exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_id_quality_hostingARead-onlyInspect
Hosting rollup for malformed identifiers
Which Access Points and SMPs serve the malformed identifiers, honouring the same scheme/reason/q filters as the malformed list. Access points and SMPs are ranked by malformed-id count; totals covers the filtered set.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Case-insensitive substring match on the identifier value. | |
| smp | No | Filter to malformed ids homed on one SMP hostname. | |
| reason | No | Filter by the kind of structural failure. | |
| scheme | No | Filter to one Peppol ICD scheme (e.g. `0208`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include readOnlyHint=true, and the description does not contradict this. It adds behavioral context by explaining that results are ranked by malformed-id count and that totals cover the filtered set, going beyond the basic read-only annotation.
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 two sentences: a concise headline followed by a detailed summary. Every word adds value, with no redundancy or fluff.
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 rollup with no output schema, the description adequately explains what is returned (Access Points, SMPs, ranking, totals) and how filtering works. It lacks explicit return structure but is sufficient for a tool of this complexity.
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?
The input schema covers all 4 parameters with descriptions, so baseline is 3. The description mentions the scheme, reason, and q filters, confirming their role, but does not add new semantic meaning beyond the 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 description clearly states this tool provides a hosting rollup for malformed identifiers, listing which Access Points and SMPs serve them. It distinguishes itself from sibling list tools by being an aggregated view, with a specific scope and resource.
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 usage as a companion to the malformed list tool ('honouring the same filters as the malformed list'), but does not explicitly state when to choose this over get_id_quality or list_id_quality_malformed. Context is clear, but exclusions and direct alternatives are not provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_historyARead-onlyInspect
Get the network verdict history
The host verdict mix over time, derived from the temporal verdict table in one windowed pass: per UTC day, the rows open at 00:00 that day, counted by verdict. Two caveats. Counts are (hostname, role) pairs — a host serving two roles counts twice, the same grain as /v1/network. And before 2026-08-15 an unresolvable host was recorded as down, so unresolvable reads 0 over the earlier stretch. The series starts 2026-07-21, the first day the table covers; an earlier from is clamped to it. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago; clamped to 2026-07-21. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, but the description adds substantial behavioral context: counts are (hostname, role) pairs and can double-count; pre-2026-08-15 unresolvable hosts were recorded as 'down'; the series starts on 2026-07-21; 'from' is clamped; and the data is keyless-cacheable. This goes well beyond the read-only hint and protects against misinterpretation.
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 a one-line summary and then expands into necessary caveats and temporal boundaries. Every sentence adds useful information, though a few implementation details ('derived from the temporal verdict table in one windowed pass') are slightly beyond what an agent strictly needs.
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?
Given there is no output schema, the description does a good job explaining the returned data's semantics: daily granularity, verdict counting, pairing behavior, historical caveats, and date clamping. It could be slightly more explicit about the exact response shape or verdict values, but for a simple two-parameter history tool it is substantially complete.
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%, and the schema already documents defaults, inclusivity, UTC format, and clamping. The description repeats the clamp behavior but adds no new parameter-level meaning beyond what the schema provides, so the baseline 3 is appropriate.
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+resource ('Get the network verdict history') and then defines the exact scope: host verdict mix per UTC day, counted by verdict. The resource is clearly distinct from sibling history tools like get_participant_history or get_doctype_stats_history, so an agent can tell where it belongs.
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 — when you need host verdict mix over time — but it never states this explicitly nor names alternatives such as get_network_summary. It provides clear context about data granularity but no direct when/when-not guidance, so it stays at the implied-usage level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_statsRead-onlyInspect
Get the network-level statistics
How the whole network moves: Movers (AP) and Movers (SMP), Cross-border moves, Bulk moves, Joiners, Leavers and Net growth, the Leaver rate (annualized), Concentration (AP) and Concentration (SMP) (HHI, top 5, top 10), Concentration per country, Foreign-served participants and penetration. Each flow statistic gives its count over the last 7 and 30 days, the 7-day mean and the change against the period before.
Every rate is of the registered-participant count at the START of its period (base, the end of base_day) and is returned beside its absolute count. A day with no completed change scan is a gap: gap_days counts them, and moves found after a gap are counted on the next scan day. A 7-day mean is the mean over the scanned days of its window; a gap day is in neither the sum nor the divisor, and a window of gap days only has no mean (null). The series starts 2026-08-02; a window that would open earlier is clamped to it. as_of is the last complete UTC day and every flow period ends there. Concentration, Foreign-served participants and penetration are snapshots: each is the latest stored value and carries its own day, which can be one day after as_of.
concentration_by_country gives, per country, how the Peppol IDs of that country are shared over the providers that serve it: the HHI, the effective number of providers (10000 / HHI), the largest provider with its share, the top-4 and top-10 shares and the number of providers above 1%. The basis is the provider rosters (certificate seats); Vendors are not counted. Only a country with 8 or more providers is returned.
The headline numbers are free. The organic/bulk split, the cross-border split, the bulk share, penetration and the 30-day trends are returned for a Market key only (see x-required-tier on the fields); the body is private to the caller.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_network_stats_historyRead-onlyInspect
Get one network-level statistic as a daily series
One point for every UTC day of the window. stat is required. A flow statistic (ap_switching = Movers (AP), cross_border = Cross-border moves, smp_switching = Movers (SMP), growth = Net growth with Joiners and Leavers) carries per day its counts (values), the registered-participant count at the start of the day (base), the first key as a percentage of that base (pct) and its 7-day mean (mean_7d). For cross_border, base is all AP moves of the day and pct is the cross-border share of them. A day with no completed change scan has gap: true and values: null — a gap is never 0. The 7-day mean is the mean over the scanned days of day − 6 .. day: a gap day is in neither the sum nor the divisor, and the mean is null when all are gaps. It is the same figure as trend_30d of /v1/network/stats. For growth, a gap day keeps joiners and nulls leavers and net. A stock statistic (concentration_ap = Concentration (AP), concentration_ap_country = Concentration per country, concentration_smp = Concentration (SMP), foreign_served = Foreign-served participants, penetration) carries values, null on a day with no snapshot; foreign_served also carries base, the registered participants of that day. concentration_ap, concentration_ap_country, foreign_served and penetration have no history before their first snapshot. A day with no snapshot is absent, not 0. The series starts 2026-08-02.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to yesterday, the last complete day. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago; clamped to 2026-08-02. | |
| stat | No | REQUIRED. The statistic to return: `ap_switching` (keys total, organic, bulk, platform), `cross_border` (cross, same, unknown, strict_cross, strict_unknown), `smp_switching` (total), `growth` (net, joiners, leavers), `concentration_ap` / `concentration_smp` (cr5_pct, cr10_pct, hhi, total, providers), `concentration_ap_country` (per country with 8 or more providers: hhi, effective_providers, leader_pct, top4_pct, top10_pct, providers_over_1pct, providers, total), `foreign_served` (pct, foreign, domestic, unknown) or `penetration` (per country: pct, on_peppol, universe). |
get_network_summaryARead-onlyInspect
Get the network summary
Current host verdict counts, open incidents and anomalies in the last 24h, plus how fresh the Peppol Directory export behind every other endpoint is.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful behavioral context beyond the readOnlyHint: it specifies the aggregation scope (last 24h), the types of data returned, and that the freshness measurement refers to the Peppol Directory export behind every other endpoint. However, it does not detail the output shape or any aggregation quirks, which could matter when an agent interprets the result.
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?
Two concise, information-dense sentences. The main action is front-loaded, and every clause adds distinct information about the tool's output without 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 parameterless, read-only summary tool, the description covers the essential output components and time window. It is slightly incomplete only in not clarifying how this relates to the generic get_summary sibling, but the content list makes the scope understandable.
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?
The tool takes zero parameters, so the schema already communicates everything needed. The description's mention of the time horizon and data categories adds mild context, but no parameter-specific semantics are required.
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 identifies a specific resource ('network summary') and enumerates the exact contents: host verdict counts, open incidents, anomalies in the last 24h, plus freshness of the Peppol Directory export. This makes the tool's function clear, though it does not explicitly differentiate itself from the similarly named sibling get_summary.
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 a use case (top-level network overview) by listing aggregate counts and recent anomalies, but it provides no explicit when-to-use guidance or exclusions relative to other get_* tools. An agent must infer when this summary is appropriate rather than being told directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participantARead-onlyInspect
Get a participant's current state
Directory presence, SML registration + current SMP, business card, the company-register enrichment block, endpoints and serving seats for a Peppol participant. Discovered participants carry no card; unmatched participants carry company: null.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Canonical `scheme::value` Peppol identifier (e.g. `0208::0762747721`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds meaningful behavioral context by enumerating the exact fields returned and by noting edge cases ('Discovered participants carry no card; unmatched participants carry company: null'). This goes beyond the basic operation and helps set expectations for response shape, even though it doesn't discuss error handling or auth.
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?
Two sentences: the first states the core purpose immediately; the second enumerates included components and edge cases. Every sentence earns its place with no redundancy or filler.
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 a single parameter, a readOnly annotation, and no output schema, the description covers the main aspects well: what is returned and a couple of edge cases. The phrase 'unmatched participants' is slightly ambiguous (whether it means participant not found or company not matched), so a perfect 5 would require clearer error/not-found semantics.
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%—the 'id' parameter is fully documented as a canonical 'scheme::value' Peppol identifier with an example. The description adds no additional meaning to the parameter, so the baseline of 3 applies.
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+resource: 'Get a participant's current state', then enumerates exactly what that includes (directory presence, SML registration, SMP, business card, endpoints, etc.). This clearly distinguishes from siblings like get_participant_history (current vs history) and list_participants (single vs list).
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 phrase 'current state' provides clear context for when to use this tool—when you need a snapshot of a participant's current data rather than history or statistics. The list of components also hints at use cases. However, it does not explicitly name alternatives or exclusions such as 'for historical data use get_participant_history'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participant_availabilityARead-onlyInspect
Get a participant's measured availability
The real, probe-measured reachability of one Peppol ID over time. Two lanes — the participant's SMP host (discovery) and its Access Point host(s) (delivery) — are read from the uptime ladder and merged per bucket into one verdict (available | degraded | unreachable | no_data): an AP with any down check is unreachable; an AP up/degraded with the SMP down is degraded (discovery impaired, still deliverable); both lanes up is available. Returns per-lane UptimeBucket ladders, the worst-of combined lane, 30/90-day + full headline uptime (degraded counts as available), a monthly 99.5% Peppol AP service-level TARGET (never a contractual claim), host-change markers and window-overlapping incidents. daily spans the full history; hourly covers the last 90 days. Buckets before the 2026-08-02 AP epoch carry partial AP attribution (pre_epoch).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Canonical `scheme::value` Peppol identifier (e.g. `0208::0762747721`). | |
| to | No | Exclusive upper bound (ISO 8601). Defaults to now. | |
| from | No | Inclusive lower bound (ISO 8601). Must not be after `to`. | |
| resolution | No | Aggregate tier. `daily` spans the full history; `hourly` the last 90 days. | daily |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description thoroughly discloses complex behavior: the two-lane merging logic (SMP vs AP), the exact verdict definitions (available/degraded/unreachable/no_data), how degraded counts as available for uptime, the monthly target semantics (not contractual), and temporal attribution (pre_epoch). This goes far beyond what the annotation provides and avoids any contradiction.
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 lengthy but well-structured: a one-line purpose, then a detailed but organized explanation of semantics and return content. Each sentence contributes substantively (merge logic, verdict definitions, return fields, historical scope). It is appropriately detailed for a tool with complex behavior, though slightly verbose in the middle section.
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?
Given the tool's complexity and the absence of an output schema, the description fully specifies the return contents (per-lane UptimeBuckets, combined lane, headline uptime ranges, service-level target, host-change markers, incidents), historical coverage, and edge cases like pre_epoch attribution. An agent has enough information to understand exactly what it will receive and how the data is derived.
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 id, to, from, and resolution with clear meanings. The description adds minimal new semantic value—only the note about pre_epoch attribution, which is contextual but not tied to a specific parameter. The baseline of 3 is appropriate since the schema carries the parameter documentation load.
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 a participant's measured availability' and elaborates on the probe-measured reachability of one Peppol ID over time. The description clearly defines what the tool does and the return structure, making it distinct from siblings like get_participant_stats or get_participant_history, even without naming them.
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 explains the tool's scope and semantics but provides no explicit guidance on when to use it versus alternative participant-related tools (e.g., get_participant_stats, get_participant_history). Usage context is implied from the function name and detailed output, but no when-to-use or when-not-to-use directives are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participant_historyARead-onlyInspect
List a participant's temporal history
The participant's temporal rows across the directory/card/registration/SMP fact families, newest-first, cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Canonical `scheme::value` Peppol identifier. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and the description's 'List' is consistent. It adds behavioral context beyond the annotation: newest-first ordering, cursor pagination, and the specific fact families included, which is useful for the agent.
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?
Two concise sentences: the first front-loads the core action, the second adds scope, ordering, and pagination details. No unnecessary words or 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?
Given readOnlyHint and full schema coverage, the description explains scope, ordering, and pagination. However, it does not describe the return structure (no output schema exists), which is a minor gap but not critical for a listing tool.
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%, with each parameter already described in detail. The description only adds behavioral context (cursor-paginated) rather than further parameter semantics, so it does not exceed the baseline for well-documented schemas.
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 'List' and identifies the resource as 'participant's temporal history' with explicit scope (directory/card/registration/SMP fact families), ordering, and pagination. This clearly distinguishes it from siblings like get_participant_stats_history and list_participant_events.
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 clear context on what data is covered (temporal rows across specified fact families) and mentions cursor-paginated, implying when to use it. However, it does not explicitly state alternatives or when not to use this tool, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participant_joinersARead-onlyInspect
Network joiners curve
The real onboarding curve (issue #222): joiner counts bucketed by derived network join date (business-card RegistrationDate, else genuine first-seen), with a whole-network coverage split (registration_date / first_seen / unknown). The unknown/seed tail is reported in coverage only, never folded into a bucket. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| bucket | No | Bucket granularity. Defaults to `year`. | year |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses meaningful behavioral details: derivation from business-card RegistrationDate or first-seen, the handling of unknown/seed tail (reported only in coverage, never bucketed), and keyless-cacheability. It adds significant context without contradicting 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 well-structured, with the title line followed by a brief explanation. The reference to 'issue #222' is somewhat extraneous, but the rest is informative and to the point.
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?
Given the tool has one optional parameter and no output schema, the description provides solid context: what the curve represents, the join date derivation logic, coverage categories, and the unknown tail behavior. It is sufficiently complete for an agent to select and invoke correctly, though it stops short of specifying the exact response shape.
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% for the single 'bucket' parameter, including its enum, default, and description. The tool description does not add additional parameter context beyond the schema, which is sufficient.
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 clearly identifies the tool as returning a 'Network joiners curve' with joiner counts bucketed by derived join date. It distinguishes from sibling tools by calling it 'The real onboarding curve' and specifying whole-network coverage split, making it distinct from related participant/network tools.
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 usage for onboarding/joiner analysis with a coverage split, but it does not explicitly state when to use this over siblings or provide exclusions. The context suggests it's the go-to for joiners curves, but no direct alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participants_mixRead-onlyInspect
Get a filtered participant breakdown
The participant set broken down by country, entity type, NACE Rev. 2.1 division, size class, region and serving Access Point, over a FILTERED slice — so a breakdown stays true while the list is cut down. The filters are the same names and shapes as GET /v1/participants.
TWO SOURCES, one shape, named by source. A request that narrows on NOTHING is answered from the hourly rollup (source: "rollup", with refreshed_at) — the whole-network breakdown, no scan. A request that narrows is computed live (source: "slice").
BOUNDED BY DESIGN. A live slice is computed only while it is narrow (under an internal cap of 10,000 participants). A slice wider than the cap, or a request carrying a filter this endpoint cannot express (doctype, transport_profile, q, host, sub_provider), answers degraded: true with every mix null — never a wrong number and never an error. Callers fall back to the whole-network breakdown on GET /v1/stats/participants.
Counts are sparse the same way the rollup facets are: company enrichment covers a handful of registers, so every mix except country_mix sums BELOW participant_count and the un-enriched remainder is derived from the total rather than served as a bucket. ap_mix names the busiest Access Point Seats and folds the rest into one __other__ bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| ap | No | Comma-array of serving Access Point SeatIDs (`PBE000123,PNO000456`). | |
| smp | No | Comma-array of current SMP hostnames (`smp1.example,smp2.example`). | |
| size | No | Comma-array of company size band codes, as stored (`12,21`): the INSEE trancheEffectifs codes for FR (`NN` = unknown), and for NO the same code set plus `1-4`. | |
| region | No | Comma-array of company seat region codes (`BE-BRU,BE-VLG`). | |
| scheme | No | Comma-array of Peppol identifier schemes. | |
| sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`). | |
| country | No | Comma-array of ISO-3166-1 alpha-2 country codes. Matched on the participant's card country, falling back to the country its ICD prefix implies — the same rule `country_mix` buckets on. | |
| not_smp | No | Comma-array of SMP hostnames to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_size | No | Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| postcode | No | Comma-array of company seat postcodes. | |
| not_region | No | Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| provenance | No | Comma-array of provenance values. | |
| registered | No | Filter by current SML registration state. | |
| vat_liable | No | Filter by company VAT-liable / mandate-scope flag. | |
| entity_type | No | Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`), from the company-register enrichment denormalized onto the participant. | |
| not_country | No | Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_entity_type | No | Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. |
get_participant_statsARead-onlyInspect
Participant facet stats
Global participant facet counts (per country/scheme/smp/ap/doctype/transport_profile, registered share, provenance split) plus an estimated total, from the hourly rollup. total_count counts every ID ever registered; registered_count and the country_registered facet scope the same data to the LIVE (registered) IDs (issue #818). Keyless-cacheable — safe for the marketing site to hit directly.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, but the description adds substantial behavioral context: it is derived from an hourly rollup, it is keyless-cacheable, and it explains the distinction between total_count (all IDs ever) and registered_count (LIVE IDs). This goes well beyond the annotation and informs the agent about data freshness and caching semantics. No contradiction 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 (three sentences) and front-loads the core purpose. It uses a clear title and then provides necessary details without fluff. Every sentence adds value: the facets, the count semantics, and the caching note. Well structured.
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, the description must explain what is returned. It does so thoroughly: lists the facet dimensions, mentions registered share and provenance split, explains total_count vs registered_count, and notes the hourly rollup freshness. This is sufficient for an agent to understand the tool's output without needing an output schema.
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?
There are zero parameters, so the input schema is empty. The baseline for zero parameters is 4. The description doesn't need to elaborate on parameters; it focuses on output semantics, which is appropriate. Since there are no parameters, no additional information could be added.
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 clearly identifies the tool as providing global participant facet counts across multiple dimensions (country, scheme, smp, ap, doctype, transport_profile), plus registered share and provenance split, with an estimated total. It distinguishes itself from sibling tools like get_participant (individual) and get_participant_stats_history (historical) by focusing on current rollup stats. The verb 'get' and resource 'participant stats' are specific and unambiguous.
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 notes it is keyless-cacheable and safe for the marketing site to hit directly, which gives a usage context. However, it does not explicitly state when to use this tool instead of get_participant_stats_history or other stats tools. The guidance is implied (current vs historical) but not spelled out as an alternative, so the agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participant_stats_historyARead-onlyInspect
Participant facet history
A daily time series over one participant facet dimension (adoption curves / QoQ trends), from daily snapshots of the rollup. History accrues from the day the feature shipped. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today. | |
| key | No | Comma-separated facet keys to filter to (e.g. `BE,NL` for `dimension=country`). Omit for every key in the dimension. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago. | |
| limit | No | Max points returned, clamped to [1, 10000]. Defaults to 10000. | |
| dimension | Yes | Which series to return: `total` (whole-network count) or a facet dimension. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds useful behavioral context: 'Keyless-cacheable' indicates caching behavior, and 'History accrues from the day the feature shipped' clarifies data availability. This goes beyond the annotation without contradicting it, though it omits details like rate limits or consequences of no data.
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 extremely concise: three short sentences with no wasted words. The title is front-loaded, and the subsequent sentences efficiently convey the core concept and key behavioral traits.
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 5 parameters and no output schema, the description covers the core concept (daily time series per facet) and adds caching and data start date. However, it lacks details on return format, how multiple keys combine (logical OR vs AND), or behavior for dates with no data. Given the complexity, there are clear gaps.
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 does not add explicit parameter-level meaning beyond the schema's own descriptions. However, the high-level context (e.g., 'facet dimension' aligns with the dimension parameter) provides some supporting semantics, but no additional depth.
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 clearly identifies the tool as providing a daily time series over a participant facet dimension, mentioning adoption curves and QoQ trends. It distinguishes from siblings like get_participant_stats and get_participant_history by specifying the time-series nature per facet, but doesn't explicitly compare or contrast with similar sibling tools.
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?
No explicit guidance on when to use this tool versus alternatives. The description implies it's for single-facet daily history, but it does not state exclusions or recommend other tools for different use cases (e.g., get_participant_history for per-participant history).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_providerBRead-onlyInspect
Get a curated provider
A curated provider navigable to its seats and each seat's observed hosts.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The curated provider slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already indicates a safe read operation. The description adds that the provider is 'navigable to its seats and each seat's observed hosts,' providing context about the returned structure. However, it does not mention rate limits, pagination, or other behavioral details, so it only modestly extends the annotation.
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 two short sentences, front-loaded with the core purpose and a clarifying second sentence. It is concise with zero redundancy or unnecessary detail.
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 single-parameter read-only tool with no output schema, the description provides sufficient context: it identifies the resource and hints at the navigable structure. It could be more explicit about the response being a single provider object, but the get verb and slug parameter imply this.
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?
The input schema covers 100% of parameter descriptions, with 'slug' described as 'The curated provider slug.' The tool description repeats the 'curated provider' wording but adds no new semantics. Baseline 3 is appropriate given the high schema coverage.
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 clearly states the tool gets a 'curated provider' and elaborates that it is navigable to seats and observed hosts. This distinguishes it from siblings like list_providers and get_provider_sla, though it does not explicitly name them. The verb 'Get' and the specific resource make the purpose clear.
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 does not provide any guidance on when to use this tool versus alternatives such as list_providers or get_provider_sla. It implies usage through the slug parameter and 'navigable' wording, but there are no explicit when-to-use or when-not-to-use instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_provider_movesRead-onlyInspect
Get moves between providers
The from→to matrix of participants that changed Access Point provider in a trailing window: who lost participants to whom, for the whole network, in one call. The top largest providers on each side keep their identity (from = sources, to = destinations; a provider can be on both). Every other provider folds into one "Other" node per side, and other gives the number of folded providers and their participants.
pairs is the COMPLETE folded matrix, largest first: a null from or to is the "Other" node of that side, zero cells are omitted, and the values sum to total exactly. A node's value is all its moves in the window, also the moves to or from a folded provider.
A move inside one provider (between two of its own Access Points) is not counted. Every day is the PROBE-OBSERVATION day — when the change scan saw the SMP record change — not the day a migration was executed. A window with no moves returns total: 0 and empty lists.
PLATFORM MOVES. A mover is a platform move when the platform that serves the participant stayed and only the certificate Seat changed: it is not a customer decision. The verdict is per DIRECTED provider pair (from → to), over all its movers since 2026-08-02, with one of two reasons (same_host, sub_provider): at least 90% of the movers whose endpoint host can be compared (5 or more, and at least 50% of all movers of the pair) kept their endpoint host, or at least 90% of 25 or more movers still carry, at the new provider, the sub-provider brand of the provider they left. It is a CURRENT judgment, computed again on every rollup cycle. The movers of a platform-move pair are in no node, in no cell and not in total: platform gives their number and the number of directed provider pairs they come from. The matrix has Providers only; a Vendor is not in it.
country_share gives the movers of one country (FR) among all movers of the window that have a country. The matrix has no country filter; this share includes the platform moves.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many providers keep their identity on each side. The matrix has at most `(top + 1)²` cells. | |
| days | No | The trailing window in days, ending today (UTC). |
get_provider_roster_spreadRead-onlyInspect
Get the provider roster-size spread per country
How Access Point provider roster sizes are spread in each country, in one call. A roster size is the number of participant IDs one provider serves in the country (country_roster of GET /v1/aps?country=). Each country row is the five-number summary over the providers with at least one participant there: n providers, min, q1, median, q3, max, and total (the sum). Quantiles use linear interpolation between the two closest ranks (type 7), rounded to 2 decimals.
points is every roster size in ascending order when the country has fewer than points_max providers, and null at or above it. The response carries sizes only, no provider key or name. Countries are ordered by median, largest first. A summary of a country with few providers says little: the console does not draw a country with fewer than 8.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_provider_slaARead-onlyInspect
List provider SLA scorecards
Per-provider SLA scorecards for one trailing period: checks-weighted uptime across each provider's mapped hosts, incident count, total downtime minutes and the single worst host. Ordered worst uptime first (providers with no checks in the window last). Materialized hourly by the batch runner. Not paginated (the envelope's next_cursor is always null).
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | Trailing window: `30d` (default) or `90d`. | 30d |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals ordering (worst uptime first, providers with no checks last), data freshness (materialized hourly by batch runner), and pagination (next_cursor always null). These are non-obvious behavioral details that help the agent set expectations.
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 three sentences with no redundancy. The first sentence states the core purpose, the second describes the data returned and ordering, and the third covers materialization and pagination. Every sentence carries meaningful information.
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?
Given this is a simple list endpoint with one optional parameter, no output schema, and a readOnly annotation, the description covers all essential aspects: what data is included, the ordering, freshness, and pagination behavior. It is sufficiently complete for an agent to invoke and interpret results 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?
The schema provides 100% coverage for the single `period` parameter, fully explaining the 30d/90d options and default. The description does not add further parameter-specific semantics, so the baseline score of 3 applies.
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 'List provider SLA scorecards,' using a specific verb and resource, then elaborates on the exact contents (checks-weighted uptime, incident count, downtime minutes, worst host). This clearly distinguishes it from sibling tools like get_provider_sla_by_key, which would target a single provider.
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 usage for viewing all providers' SLA scorecards over a trailing period and notes the hourly materialization, which is useful context. However, it does not explicitly mention alternatives or when to prefer get_provider_sla_by_key for a specific provider, so the guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_provider_sla_by_keyARead-onlyInspect
Get a provider's SLA scorecards
One provider's SLA scorecards, one per trailing period (30d and 90d). key is the provider's natural key (as reported by GET /v1/providers). Empty items when the provider has no SLA data yet.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The provider natural key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation covers the safety profile, and the description adds behavioral detail: empty items when no SLA data exists and the structure of one scorecard per trailing period. This goes beyond the annotation, though it does not cover error responses or authentication specifics.
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 clearly structured, opening with the core verb and resource. The following sentences add distinct value: output periods, parameter source, and empty-items behavior. 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 single-parameter read-only tool, the description provides sufficient information to select and invoke it: purpose, key semantics, output structure, and no-data behavior. No output schema exists, but the description covers essential return semantics clearly.
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 enhances the parameter meaning by noting the key is the provider's natural key as reported by GET /v1/providers, adding a source reference beyond the schema's 'provider natural key'.
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 clearly states the tool gets a provider's SLA scorecards, with specifics about trailing periods (30d and 90d). The 'by_key' designation and natural key reference make the resource and scope unambiguous, even without explicit sibling differentiation.
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 clear context for when to use the tool: when retrieving SLA scorecards for a specific provider by natural key. It explains the output includes one scorecard per trailing period, but does not explicitly mention alternatives or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_public_providerARead-onlyInspect
Get a public provider profile
The FREE, crawlable public subset for one curated provider (same shape as a GET /v1/providers/public item). Reachable with no API key.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The curated provider slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already noting the read-only safety, the description adds valuable context: the tool requires no API key, returns a public subset, and the response shape matches a known list item. This goes beyond the annotation to disclose access requirements and data scope.
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?
Two focused sentences, front-loaded with the core purpose, then concise clarifying details. Every word earns its place with no redundancy or filler.
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 single-parameter read-only tool, the description is complete: it specifies the return shape, access requirements, and scope. No output schema exists, but the description sufficiently covers what the agent needs to select and invoke this tool.
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 parameter description 'The curated provider slug' is already in the schema. The tool description adds no further meaning about the slug, so it meets the baseline but does not elevate it.
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 clearly states the tool fetches a public provider profile, using the specific verb 'Get' and resource 'public provider'. It distinguishes from siblings like get_provider and list_public_providers by emphasizing it is the 'FREE, crawlable public subset' and 'same shape as a GET /v1/providers/public item'.
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 provides clear context: this is the public, no-API-key subset for a single curated provider, which implies use when unauthenticated public data is needed. However, it does not explicitly mention alternatives (e.g., use get_provider for full data) or state when not to use it, so it falls short of full alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_seatARead-onlyInspect
Get a seat
A Peppol certificate seat: its embedded provider (verified mapping or unverified cert-CN fallback) and the hosts it was observed operating.
| Name | Required | Description | Default |
|---|---|---|---|
| seatId | Yes | The seat identifier (e.g. `POP000748`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already declares the tool as read-only. The description adds useful context about the provider mapping fallback (verified vs. cert-CN unverified) and that hosts are 'observed operating,' but it does not disclose additional behavioral aspects like error handling, authentication, or rate limits. This is a moderate addition over the annotation.
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 concise, with just two sentences. The first sentence 'Get a seat' front-loads the action, and the second sentence provides essential context. No filler or redundant information 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 read-only tool with one required parameter and no output schema, the description adequately describes the return value (provider and hosts). It is reasonably complete, though it could mention error cases or response structure explicitly. The absence of an output schema places more responsibility on the description, which it largely fulfills.
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?
The schema provides 100% coverage for seatId with a clear description and example. The tool description does not add parameter-specific details, but it does explain what a seat is, indirectly aiding comprehension of the identifier. This meets the baseline for high schema coverage.
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 states 'Get a seat' and then defines what a seat is: 'A Peppol certificate seat: its embedded provider (verified mapping or unverified cert-CN fallback) and the hosts it was observed operating.' This clearly identifies the resource and its unique characteristics, distinguishing it from siblings like get_provider or get_host.
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 no guidance on when to use this tool versus alternatives. It does not mention specific scenarios, exclusions, or when to prefer a different sibling tool, leaving the agent without explicit usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_seat_complianceARead-onlyInspect
Get a seat's compliance scorecard
One seat's compliance posture: the registrations under it, its OPEN findings broken down by rule, the daily trend, and where the seat sits against the network. This is what a Peppol Authority's periodic scan reports, from the same published rules (GET /v1/compliance/rules), before the letter arrives.
Rates are open findings per 1,000 registrations, and null when the seat hosts no registrations. The network median and 90th percentile are taken over every seat that hosts registrations — a seat with no finding of a rule counts as 0 — so they describe the whole network, not only the seats that break the rule.
Read from a daily rollup: snapshot_date is the day it describes, and is null (with zero counts and empty lists) for a seat no scan has covered yet.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many daily snapshots the trend covers (default 90). | |
| seatId | Yes | The seat identifier (e.g. `POP000748`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses important behavioral details: rates are per 1,000 registrations and null for seats with no registrations; network percentiles include all seats with registrations, counting no-findings as 0; snapshot_date is null for unscanned seats. These edge cases and calculation semantics are not available from annotations or schema.
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 moderately detailed but front-loaded with a clear one-sentence summary, followed by necessary semantic clarifications. The narrative about the Peppol Authority's scan adds context but is slightly embellished; still, every substantive sentence provides definitional or edge-case value.
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, the description does the work of explaining what the tool returns: registrations, OPEN findings by rule, daily trend, and network comparison. It also defines null behavior and the daily rollup semantics. It stops short of an explicit response shape, but for a scorecard tool this is a strong, usable description.
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 baseline is 3. The schema already documents seatId and days with examples and bounds. The description adds conceptual context around daily rollups and rate calculation, but does not add new parameter-level meaning beyond what the schema states.
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?
Description opens with a specific verb and resource: 'Get a seat's compliance scorecard.' It then enumerates the content (registrations, OPEN findings by rule, daily trend, network position), making it clear this is a single-seat compliance view, distinct from sibling tools like get_compliance_stats or list_compliance_findings.
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 gives clear context: it is a per-seat compliance posture, described as what a Peppol Authority's periodic scan reports. It does not explicitly name alternatives or state when not to use it, but the scope ('One seat's compliance posture') differentiates it from network-level siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_seat_slaARead-onlyInspect
Get a seat's SLA scorecards
One seat's SLA scorecards, one per trailing period (30d and 90d). seatId is the seat identifier (as reported by GET /v1/aps/{key} on seats[].seat_id). Empty items when the seat has no SLA data yet.
| Name | Required | Description | Default |
|---|---|---|---|
| seatId | Yes | The seat identifier (e.g. `POP000748`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true, safety is already disclosed. The description adds behavioral context by specifying the trailing periods (30d and 90d) and that an empty items array is returned when the seat has no SLA data. This goes beyond annotations and provides meaningful return-behavior transparency.
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 extremely concise: three short sentences, front-loaded with the main purpose, and every sentence earns its place. There is no redundancy or filler.
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-parameter tool with no output schema, the description covers the purpose, parameter provenance, and return behavior (trailing periods, empty items). However, it does not describe the inner structure of a scorecard (e.g., fields like score or status), which would be helpful given the absence of an output schema. This minor gap prevents a 5.
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?
The schema already fully documents seatId with a precise example. The description adds extra semantic value by explaining that seatId is the seat identifier as reported by `GET /v1/aps/{key}` on `seats[].seat_id`, which helps agents extract the value from another endpoint's response. This goes beyond the schema's basic type/description.
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 starts with 'Get a seat's SLA scorecards', a specific verb+resource that clearly distinguishes from sibling tools like get_seat or get_provider_sla. It further clarifies the scope by stating it returns one scorecard per trailing period (30d and 90d), leaving no ambiguity about what the tool does.
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 context on when to use the tool (for a seat's SLA scorecards) and explains how to obtain the seatId via a specific endpoint, which is useful guidance. However, it does not explicitly mention alternatives or exclusion criteria (e.g., 'use get_provider_sla for provider-level SLA'), so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sml_statusARead-onlyInspect
Get SML/SMK zone status
One entry per monitored zone: quorum verdict, per-location canary breakdown, DNAME cutover state, management-host TLS snapshot and zone incidents.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description aligns by describing a read-only status snapshot. It adds transparency by disclosing the per-zone layout and the specific status fields, which goes beyond the annotation. However, it does not address potential errors or pagination, but this is reasonable for a zero-parameter read-only tool.
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 exactly two sentences: the first gives the purpose, the second lists the content. It is front-loaded and every phrase earns its place, providing substantial information without fluff or 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?
With no output schema and no parameters, the description compensates by itemizing the returned fields and the per-zone structure. It does not detail the exact JSON format or error behaviors, but for a simple read-only status helper, it provides a sufficiently complete picture for an agent to understand what to expect.
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?
The tool has zero parameters, so there is no parameter-specific information to add. Per the rubric, a zero-parameter tool receives a baseline score of 4, as the description cannot contribute additional parameter semantics beyond what is inherently absent from the 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 description clearly states 'Get SML/SMK zone status' with a specific verb and resource, then elaborates the exact components returned (quorum verdict, canary breakdown, etc.). It distinguishes itself from sibling tools that target access points, hosts, or participants, making the tool's purpose unambiguous.
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 usage when the agent needs this specific status data, but it does not explicitly state when to use this tool over alternatives or mention any exclusions. There is no reference to sibling tools or conditions, so the agent must infer applicability from the resource name and contents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_softwareARead-onlyInspect
Get one software product (Market)
One engine of the software library: the same row the list returns (product metadata, host count per observed role, first/last seen, the compliance signal and the host-count trend) plus the catalogue version and generation stamp. engine is a catalogue engine slug as published in engine on the list; an unknown slug is a 404.
Beyond the list row it also returns advisory_list[] (issue #798): every live advisory of the engine's lanes with its id, normalized severity, CVSS score, summary, url and publication stamp, newest first. Null when no lane of the engine has an advisory feed; [] when it has one and upstream has published nothing. Market tier.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Trend window in trailing UTC days, 1..90 (default 90). | |
| engine | Yes | The catalogue engine slug, e.g. `phoss`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals meaningful behavior: unknown slug returns 404, `advisory_list` is null when no advisory feed exists versus [] when upstream has published nothing, and advisories are returned newest first. This is substantial behavioral detail the schema and annotations do not provide.
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 dense but well-organized: first sentence states scope, second defines the engine parameter and error behavior, third details the advisory_list return contract. Minor extras like the issue reference and 'Market tier' add context but could be trimmed without losing essential information.
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?
Since there is no output schema, the description carries the full burden of explaining the return value. It lists the returned row fields, the advisory fields, ordering, null/[] semantics, and error behavior. For a read-only getter with two documented parameters, nothing critical is missing.
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?
The schema already documents both parameters with 100% coverage, so the baseline is 3. The description adds value by explaining the `engine` slug semantics, linking it to the list output, and specifying the 404 failure mode. The `days` parameter gets no extra elaboration, but the schema already covers its range and default.
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 one software product (Market)', then identifies the resource as a catalogue engine slug. It enumerates the returned content (product metadata, host counts, compliance signal, advisory list), which clearly distinguishes it from list-style siblings like list_software.
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 clearly frames this as a single-engine lookup and gives a precondition: `engine` must be a catalogue slug 'as published in `engine` on the list', with an unknown slug resulting in 404. It does not explicitly name alternatives or when-not-to-use conditions, but the single-row scope is clear enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_software_statsARead-onlyInspect
Software landscape
The free host-software landscape (issue #490): k-anonymised vendor share (k=5, the sub-k tail folded into other), version distribution within each named vendor (k=10), ASN hosting share, and a two-denominator coverage block (host-weighted ~90% and participant-weighted ~50%, each named, no bare coverage scalar). Computed live from the temporal software table and edge-cached. Names no operator. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds genuinely non-obvious behavior: k-anonymity thresholds (k=5, k=10) and the folding of the sub-k tail into 'other', edge caching, keyless-cacheable access, and 'Names no operator' as a privacy guarantee. It stops short of describing latency or staleness semantics beyond 'computed live'.
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?
It is a single dense paragraph that front-loads a vague heading ('Software landscape') before the real content. Almost every clause carries information, but the parenthetical density and unexplained jargon ('two-denominator coverage block', 'no bare coverage scalar') cost readability without a clear structural hierarchy.
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, the description carries the burden of explaining the return and does so thoroughly: vendor share, version distribution, ASN share, and the two named denominators (~90% host-weighted, ~50% participant-weighted). The main gap is the absence of any statement about the time window covered or how it relates to the history variant.
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?
The tool takes zero parameters, so the baseline is 4. The description correctly adds no parameter framing and instead spends its words on output content, which is the right allocation for a parameterless read tool.
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 states a specific resource and enumerates its contents: k-anonymised vendor share (k=5), version distribution per vendor (k=10), ASN hosting share, and a two-denominator coverage block. It does not, however, name or contrast itself against the obvious sibling get_software_stats_history, leaving the live-vs-historical distinction to inference from 'Computed live'.
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?
There is no explicit when-to-use statement and no named alternative. The only routing clue is the indirect 'Computed live from the temporal software table and edge-cached', which an agent could read as a contrast to the history sibling, but this is never stated. An agent must infer selection from the sibling list alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_software_stats_historyARead-onlyInspect
Software landscape history
The software landscape over time, derived from the temporal software table in one windowed pass: per UTC day, the host-weighted identified/total targets and the k-anonymised vendor shares. Keyless-cacheable.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today. | |
| from | No | Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds useful behavioral detail: it is computed in 'one windowed pass', grouped by UTC day, host-weighted, k-anonymised, and keyless-cacheable. These details help an agent understand performance, privacy, and response shape semantics.
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, front-loaded with the resource, and every sentence adds value. The heading 'Software landscape history' plus the explanatory sentence and cacheability note are sufficient without filler.
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, two-optional-parameter time-series tool without an output schema, the description conveys the time granularity, the metrics, and the date defaults. It doesn't describe row counts, edge cases, or the exact JSON return shape, but an agent has enough context to invoke and interpret results.
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?
The input schema already fully documents both optional date parameters with defaults and formats. The description adds nothing new about parameter meaning, so the baseline score of 3 applies.
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 states the resource — 'software landscape history' — and the exact output semantics (per UTC day, host-weighted identified/total targets, k-anonymised vendor shares). It is clear enough to distinguish from the non-temporal get_software_stats sibling, though it never explicitly names that alternative.
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 use case is implied by 'over time' and the tool name, but there is no explicit guidance about when to choose this over get_software_stats or other history tools. An agent can infer it is for historical trends, yet the description doesn't state boundary conditions such as 'current snapshot -> get_software_stats'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_summaryARead-onlyInspect
Get the public dashboard summary
The free marketing-dashboard rollup: the network-wide host rollup (fleet count + mean uptime/latency), the hourly fleet-average p50 latency trend over the last 24h, and the top-10 providers by market share (0..1 fraction). No host list, full registry or arbitrary per-host uptime is exposed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already supplied by annotations, the description adds valuable behavioral context: it is a 'public' rollup, so no authentication is implied, and it precisely defines the data scope. It discloses exactly what data is included and excluded, going well beyond the annotation's read-only hint.
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 concise: a short title line followed by one dense sentence enumerating the contents and exclusions. Every phrase adds information, with no redundant filler.
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?
The description fully covers what to expect from the tool (three data components) and what not to expect (host lists, registry, per-host uptime). Since there is no output schema, this enumeration is essential and fully sufficient for a no-parameter read-only tool.
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?
The tool has zero parameters, so the description cannot add parameter-specific semantics. Per the rubric, a baseline of 4 is appropriate for no-parameter tools.
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 clearly states the tool retrieves the public dashboard summary and enumerates three specific data components: network-wide host rollup, hourly fleet-average p50 latency trend, and top-10 providers by market share. It also distinguishes itself from siblings by explicitly stating what is not exposed (no host list, full registry, or arbitrary per-host uptime), making its purpose unambiguous.
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 explicit usage context: it is a 'free marketing-dashboard rollup' for public summary data. It also gives a clear when-not by excluding host lists and per-host uptime, implying users should seek other tools for those details. This is sufficient guidance for selecting this tool over the many sibling get/list tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_access_point_churn_participantsARead-onlyInspect
List participants behind a churn category
The drill-down: the participant IDs behind one churn category count for this Provider over the period, newest observation day first. counterpart narrows a mover category to the participants won from or lost to one Provider. Cursor-paginated in pages of at most 500: follow next_cursor until it is null. A Vendor key (v-<slug>) lists the Vendor's events, also accepts newly_matched and no_longer_matched, and adds counterpart_kind to each item.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive period end, `YYYY-MM-DD` UTC. | |
| key | Yes | The Provider key, or a Vendor key (`v-<slug>`). | |
| from | No | Inclusive period start, `YYYY-MM-DD` UTC. | |
| limit | No | Page size, clamped to [1, 500]. Defaults to 500 (20 through MCP). | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| category | Yes | The churn category to expand. `newly_matched` and `no_longer_matched` are valid for a Vendor key only; with a Provider key they are a 400. | |
| counterpart | No | Filter to one counterpart Provider key: the Provider the participants were won from (`mover_in`) or lost to (`mover_out`). Allowed with the two mover categories only. For a Vendor key the counterpart can also be a Vendor key. An unknown key returns an empty list. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, so this description carries real behavioral weight and delivers: cursor pagination in pages of at most 500 with the next_cursor-until-null loop, ordering by newest observation day first, the Vendor-key mode that adds counterpart_kind, and error behavior (400 for vendor-only categories with a Provider key; empty list for unknown counterpart).
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 sentences, front-loaded with the purpose before pagination and Vendor-key edge cases. Dense but every sentence carries information an agent needs; nothing is padding, though the Vendor-key sentence packs several facts together.
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 7-parameter, cursor-paginated list tool with no output schema, the description covers the loop control (next_cursor/null), ordering, the Provider-vs-Vendor key split, category validity, and counterpart constraints. An agent has everything needed to invoke it 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 coverage is 100%, so the baseline is 3, but the description adds meaning beyond it: `counterpart` is framed as won-from (mover_in) or lost-to (mover_out) and is Valid only for mover categories, and `key` is explained to accept either a Provider key or a Vendor key. This is genuine additive semantics rather than restatement.
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+resource ('List participants behind a churn category') and immediately clarifies it is the drill-down producing the participant IDs behind one category count. An agent can distinguish it from count-level siblings like get_access_point_churn, though it never names list_cohort_move_participants, the closest sibling.
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?
Gives real context: it explains the drill-down relationship to a churn category count and the conditions under which `counterpart` applies (mover categories only) and when a Vendor key is used. It stops short of explicitly routing the agent away from any alternative tool, so no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_access_pointsARead-onlyInspect
List access points
The Access Point directory: every Provider in its serving role, with its member seats and roster size (current participant count), busiest first. A Provider is resolved from each seat with the precedence curated mapping (verified) → exact signing-cert O= string (unverified) → bare SeatID. Not paginated (the envelope's next_cursor is always null). Pass ?country=CC to compare providers within one market instead of network-wide. Every item carries the windowed net growth; a MARKET-tier key additionally gets the four churn components behind each net (joiners, movers_in, movers_out, leavers × 7d/30d/90d), which a lower-tier key simply does not receive.
kind selects the row kinds. The default is provider, and the list is then Provider rows only. A Vendor is a curated software or service brand that connects its customers through the Seats of one or more Providers; kind=vendor returns the Vendor rows and kind=all returns both, each item marked by kind. A Vendor's participants are always also in the count of the Provider that serves them: never add Provider rows and Vendor rows into one total, share or rank.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Which row kinds to return. `provider` (default): Provider rows only. `vendor`: Vendor rows only. `all`: both, sorted together by `participant_count`. `vendor` and `all` need a MARKET-tier key; a lower-tier key gets a 403, never a list without the Vendors. Any other value is a 400. | provider |
| country | No | Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged. A MARKET-tier key additionally gets the scoped churn components `country_joiners|movers_in|movers_out|leavers_7d|30d|90d`. A Vendor row carries `country_roster` and `country_orgs` only: there is no country-scoped Vendor movement. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, so the description carries the rest and does it well: it discloses that the result is not paginated (next_cursor always null), that sorting is busiest-first, that a MARKET-tier key receives churn components while a lower-tier key does not, and the crucial anti-double-counting rule for Provider vs Vendor rows. Auth/tier behavior is covered at a high level; a note on what happens with an unauthenticated or wrong-tier key beyond 'does not receive' is the main omission.
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?
Structure is decent (what the directory returns, then how kind selects row types), but much of the kind/country prose restates the enum and parameter descriptions almost verbatim from the schema, notably the 403-for-lower-tier-key rule and the country field inventory. The double-counting warning earns its place; the duplicated parameter detail does not.
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, the description fully carries the return contract: field inventory per item, the extra country-scoped fields, tier-gated churn components at 7d/30d/90d, sort order, and pagination behavior. An agent can interpret the response without guessing, and the Provider/Vendor aggregation caveat removes the most likely analytical error.
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 and the schema already documents kind and country mechanics. The description adds intent and consequence beyond the schema: country is for 'compare providers within one market instead of network-wide', and the warning that Vendor participants are always also counted in their serving Provider, so rows must never be summed into one total, share or rank. That is real semantic value on top of the 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 description gives a specific verb and a precisely scoped resource: 'The Access Point directory: every Provider in its serving role, with its member seats and roster size (current participant count), busiest first.' An agent knows exactly what rows come back and in what order. It never explicitly distinguishes itself from the singular get_access_point or from list_providers, so it stops short of a 5.
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?
Usage guidance exists at the parameter level ('Pass ?country=CC to compare providers within one market instead of network-wide', and the kind selection rules), which is genuinely helpful for steering an invocation. However, it never states when to reach for this tool versus the sibling directory tools, so tool-level selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_anomaliesBRead-onlyInspect
List anomalies
The anomaly feed, newest-first, cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | Filter to anomalies targeting one host. | |
| seat | No | Filter to anomalies targeting one seat. | |
| grade | No | Filter by grade. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| since | No | Only include items at or after this ISO 8601 instant. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| detector | No | Filter by detector. | |
| acknowledged | No | Filter by acknowledgement state. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read; the description adds 'newest-first' ordering, which is genuinely new behavioral context. 'Cursor-paginated' largely restates the cursor/next_cursor schema, and nothing is said about default volume, clamping, or rate limits.
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?
Two short sentences, front-loaded and waste-free. The first line restates the tool name, which is mildly redundant but harmless at this length.
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 an 8-filter paginated feed with no output schema and minimal annotations, the description omits what the anomalies are, what filters exist, and what a record looks like. It is too thin to fully orient an agent, even though the schema covers the parameters.
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% across all 8 parameters, including enum values and the limit clamp, so the schema carries the semantic load. The description adds no parameter-level detail, which is the expected baseline when the schema is complete.
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 (List) and resource (anomalies), and the second sentence clarifies the feed's ordering. It does not explicitly differentiate from the sibling get_anomaly (singular) or the many other list_* tools, so an agent must infer the distinction.
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?
No guidance on when to use this versus get_anomaly or other list tools, and no prerequisites or exclusions. The agent gets the 'what' but not the 'when.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cohort_move_participantsARead-onlyInspect
List participants in a bulk AP migration
The drill-down: the participant IDs behind one cohort, oldest observation day first. A cohort's membership is DEFINED as the mover events its provider pair and day range select, so this list is always in step with the cohort's counts. Cursor-paginated on (day, value).
id is the request-lifetime handle from GET /v1/stats/cohort-moves. The detector re-clusters the trailing window on every run, so a handle whose cohort boundaries have since shifted answers 404 rather than a stale list — re-read the feed instead of persisting ids.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The cohort handle: 16 lowercase hex characters. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses several behaviors beyond the readOnlyHint annotation: cursor-pagination on (day, value), the definition of membership being tied to mover events, and the 404 response for stale handles with advice to re-read the feed. These are significant behavioral details not captured in 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 well-structured with a clear lead sentence, then supporting details about pagination and id semantics. Every sentence adds value, and the content is front-loaded with the primary purpose. It is appropriately concise for the complexity involved.
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?
Given the lack of an output schema, the description adequately covers what is needed: it explains pagination, ordering (oldest observation day first), and the staleness behavior. It does not explicitly describe the structure of each returned participant item, but the nature of the tool (listing participant IDs) makes that less critical. Overall, the description is fairly complete.
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?
The schema already documents all three parameters with descriptions (coverage 100%). The description adds meaningful semantics for `id` by explaining it is a request-lifetime handle from a specific endpoint and that it can go stale, and for `cursor` by noting it is returned as `next_cursor`. This goes beyond the schema's basic type and pattern descriptions.
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 clearly states the tool's function: 'List participants in a bulk AP migration' and further explains it as 'the drill-down: the participant IDs behind one cohort'. It distinguishes itself from sibling tools by specifying it operates on a cohort handle, and it names the source endpoint for that handle, making the purpose unambiguous.
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 gives clear context: this is the drill-down for a cohort, and it explains that the `id` comes from `GET /v1/stats/cohort-moves`. It advises not to persist ids because they can go stale. While it doesn't explicitly name alternatives, the context makes the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cohort_movesRead-onlyInspect
List bulk AP migrations
Detected bulk migrations between Access Points, largest first. A cohort is a gap-≤3-day island of (from_provider, to_provider) mover days that clears three thresholds: at least 25 participants, at least 40 % of them on the busiest day (which rejects a steady drip), and at most 20 active days for the pair over the trailing 40 days (which rejects a recurring partnership).
Every day is the PROBE-OBSERVATION day — the day the change scan saw the SMP record change, not the day the migration was executed — so a cohort is always a [first_day, last_day] range and peak_day is the busiest observation day. Render the range, never a single date.
top_country is derived from the ICD prefix of the participant identifiers, not from business-card country fields. merge_suspect marks a cohort large enough (or whose source provider no longer resolves in the directory) to be a provider merge or a renamed provider rather than that many independent customer decisions — the canonical case is Sovos → Sage, 10,574 participants. Such rows are data events, not customer decisions; verify one before quoting it. The flag is a CURRENT judgment, re-evaluated on every recompute, not frozen at detection.
PLATFORM MOVES. A mover is a platform move when the platform that serves the participant stayed and only the certificate Seat changed: it is not a customer decision. The verdict is per DIRECTED provider pair (from → to), over all its movers since 2026-08-02, with one of two reasons (same_host, sub_provider): at least 90% of the movers whose endpoint host can be compared (5 or more, and at least 50% of all movers of the pair) kept their endpoint host, or at least 90% of 25 or more movers still carry, at the new provider, the sub-provider brand of the provider they left. It is a CURRENT judgment, computed again on every rollup cycle. A cohort of such a pair has platform_move: true. It stays in the list. A Vendor's cohorts (provider=v-<slug>) are not changed and have no platform_move.
from/to are OVERLAP bounds (a cohort counts when its range intersects the window), defaulting to the trailing 90 days the detector re-clusters. Mover history begins 2026-07-24, so no cohort predates it. id is a request-lifetime handle for the participant drill-down — never persist one.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Inclusive upper bound of the observation window (`YYYY-MM-DD` UTC); a cohort matches when its `first_day` is at or before it. Defaults to today. | |
| from | No | Inclusive lower bound of the observation window (`YYYY-MM-DD` UTC); a cohort matches when its `last_day` is at or after it. Defaults to 90 days ago. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| provider | No | Only cohorts involving this Provider key (`/v1/aps/{key}`). Matches EITHER side unless `direction` narrows it. A Vendor key (`v-<slug>`) returns the cohorts of that Vendor's movers instead: each item has `kind: "vendor"`, one side of the pair is the Vendor, and the floor is 5 participants. Vendor cohorts are in no other response of this endpoint. | |
| direction | No | Which side of the `provider` filter to take: `in` = cohorts the provider received, `out` = cohorts it lost, `both` = either. Only meaningful together with `provider`. | both |
| merge_suspect | No | How to treat probable provider merges / slug changes: `include` (default), `exclude` for real customer migrations only, or `only` to review the flagged rows. | include |
| min_participants | No | Only cohorts with at least this many participants. The detector's own floor is 25, so a lower value cannot surface smaller groups. With a Vendor key as `provider` the floor and the default are 5. |
list_compliance_findingsARead-onlyInspect
List compliance findings
Deterministic verdicts against the published rules, newest first and keyset-paginated on (first_detected_at, finding_id). A finding stays open until the registration is corrected, at which point the next scan stamps resolved_at; first_detected_at survives every re-scan. Distinct from /v1/anomalies, which reports observed behaviour rather than rule breaches. The first page's meta.facets gives rule and grade counts over the filtered set.
| Name | Required | Description | Default |
|---|---|---|---|
| rule | No | Filter to one rule code (from `GET /v1/compliance/rules`). | |
| seat | No | Filter to one operating seat id (e.g. `PBE000123`). | |
| grade | No | Filter by severity. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| since | No | Only findings whose `last_seen_at` or `resolved_at` is at or after this ISO 8601 instant: everything the latest scans still confirm, plus everything opened, changed or resolved since. A finding whose evidence has not moved for weeks stays in the answer for as long as its rule keeps being scanned, so polling this converges on the live set. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| scheme | No | Filter to one participant scheme id, for participant-grain rules. | |
| status | No | Lifecycle slice; defaults to the open findings. | open |
| country | No | Filter to one ISO 3166-1 alpha-2 country. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only signal readOnlyHint=true, and the description adds substantial behavioral context: deterministic verdicts, newest-first ordering, keyset pagination on a composite key, the open/resolved lifecycle, persistence of `first_detected_at` across rescans, and `meta.facets` on the first page. This goes well beyond what annotations or the schema alone would tell the agent.
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 dense sentences each contribute distinct information: what the tool returns, ordering/pagination, lifecycle behavior, and differentiation from anomalies. There is no filler or repetition of schema content, and the most identifying facts are front-loaded.
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?
Given the tool has 9 optional parameters and no output schema, the description covers the operational essentials: deterministic rule-based results, ordering, pagination key, lifecycle transitions, polling convergence, and first-page facets. An agent has enough context to select the tool, set filters, and interpret pagination without major gaps.
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 input schema already fully documents all nine parameters, including defaults, enums, and the `since` polling semantics. The description adds no parameter-specific details but does explain global behavior like facets, which is consistent with the baseline-3 expectation when the schema carries the parameter burden.
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 names a specific verb ('List') and resource ('compliance findings'), then clarifies the domain further as 'deterministic verdicts against the published rules' with explicit ordering and pagination semantics. It also distinguishes itself from `/v1/anomalies`, so an agent can tell it apart from the most similar sibling without reading schemas.
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 explicitly contrasts this tool with `/v1/anomalies`, saying anomalies report observed behaviour rather than rule breaches, which is a clear when-not-to-use signal. It does not enumerate all alternative siblings or spell out an exhaustive 'use this when...' statement, but it covers the main routing ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_compliance_rulesARead-onlyInspect
List the compliance rule catalogue
The published rules registrations are judged against: what each rule requires, what it applies to, how severe a breach is, and how many findings requires, what it applies to, and how severe a breach is. Free — the rules themselves are public; the findings against them are on GET /v1/compliance/findings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals this is a safe read operation. The description adds useful context that the rules are free and public, and that findings are not included here. It does not discuss pagination, result shape, or any access requirements, but for a simple list operation the annotation plus description is adequate.
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 first and last sentences are useful, but the middle sentence is garbled and repetitive: 'how many findings requires, what it applies to, and how severe a breach is' appears twice with broken phrasing. This redundancy undermines clarity and suggests an editing error, so the description is not cleanly concise.
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 zero-parameter, read-only list tool, the description is mostly complete: it identifies the resource and points to the findings endpoint for related data. However, there is no output schema and the description does not clarify the catalogue item structure or pagination behavior, leaving a small but real 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?
This tool has zero parameters, so the baseline is 4. There are no parameter semantics to clarify, and the description appropriately focuses on behavior and scope rather than parameters.
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 'List the compliance rule catalogue,' which clearly identifies the action and resource. It also distinguishes this tool from the related findings tool by explicitly directing findings to `GET /v1/compliance/findings`.
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 clear usage context: this endpoint lists the public rules catalogue, while findings are located elsewhere via the findings endpoint. It could be more explicit by naming the sibling tool `list_compliance_findings`, but the separation between rules and findings is clearly conveyed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_deregistered_idsARead-onlyInspect
List the latest De-registered IDs
The De-registered IDs of /v1/stats/deregistered (same population, same daily rollup) with the newest leave date: at most 1000, newest first, cursor-paginated. Each item is a /v1/participants list item plus left_at, the close of its latest registration.
left_at is recorded about 3 days after the true leave, and a date before 2026-08-02 is not reliable. An ID that is registered again since the rollup run is left out, so a page can be shorter than total says. /v1/participants?registered=false is a wider list: it also holds the never-registered IDs, which are not de-registered.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, clamped to [1, 100]. Defaults to 25. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers safety, but the description goes well beyond it: cursor pagination with newest-first ordering, a hard 1000-item ceiling, ~3-day recording lag for left_at, unreliability before 2026-08-02, and the fact that pages can be shorter than 'total' because re-registered IDs are dropped. That is exactly the kind of hidden behavior annotations cannot express.
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?
Purpose and scope are front-loaded, and the dense caveats (lag, unreliable date floor, dropped re-registrations, wider alternative) each carry information an agent needs. It is slightly long, but no sentence is filler.
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, the description carries the return shape itself — each item is a /v1/participants list item plus left_at, the close of its latest registration. Combined with pagination rules and data-freshness caveats, nothing an agent needs to call or interpret this tool is missing.
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 limit and cursor are already documented and the baseline would be 3. The description adds real semantics on top: it states the newest-first ordering, the implicit cap of 1000, and that shorter-than-expected pages are legal — context that changes how an agent consumes cursor and reads limit.
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?
Opens with a specific verb+resource ("List the latest De-registered IDs") and immediately pins the population to the same set as /v1/stats/deregistered with the newest leave date, size cap, and sort order. It also explicitly contrasts itself with the wider /v1/participants?registered=false list, so an agent can tell it apart from the participant-listing siblings.
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?
Gives a clear routing rule: use this for de-registered IDs, and use /v1/participants?registered=false if never-registered IDs must be included — an explicit when-not. Minor deduction because the alternative is named as an HTTP endpoint rather than a sibling tool (e.g. list_participants), leaving the agent to map it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eventsARead-onlyInspect
List global change events
Every typed change event, newest-first, cursor-paginated. Any anomaly an event triggered is embedded on it. cursor walks older events; prev_cursor walks the newer edge (for live polling). The first page carries a meta block with exact type facets + filter count and an auto-bucketed timeline chart.
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | Filter to events for one host. | |
| seat | No | Filter to events referencing one seat. | |
| type | No | Comma-array of change-event types (a single value is valid). | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| since | No | Only include items at or after this ISO 8601 instant. | |
| until | No | Only include events at or before this ISO 8601 instant. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| doctype | No | Filter to events touching one document-type URN. Matches both payload shapes: the merged `endpoint_changed` `doctypes` array and the legacy singular `doctype` on pre-merge rows. | |
| participant | No | Filter to one participant (`scheme::value`). | |
| prev_cursor | No | Opaque newer-direction cursor (from a page's `prev_cursor`): returns events newer than it, newest-first. Mutually exclusive with `cursor`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already covering the safety profile, the description adds real behavioral context: newest-first ordering, cursor semantics, the newer-edge polling capability, embedded anomalies on each event, and a first-page meta block with type facets and a timeline chart. It does not mention rate limits or filtering cost, but the added context is substantial.
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 tight sentences, front-loaded with the resource and scope, then ordering, pagination, and response shape. No filler; every clause carries information an agent needs.
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?
No output schema exists, so the description correctly shoulders the burden of describing the return shape: the embedded anomalies, the first-page meta block with exact type facets, filter count, and bucketed timeline, plus the pagination cursors. It omits details on the meta block's structure and error behavior, leaving minor gaps.
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 every parameter is already documented in the schema, making 3 the baseline. The description reinforces cursor/prev_cursor navigation and notes that prev_cursor is mutually exclusive with cursor, but that exclusivity is also in the schema, so marginal added value.
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 ('List global change events') and adds scope detail (typed change events, newest-first, cursor-paginated). The 'global' scope implicitly separates it from the participant-scoped sibling list_participant_events, but no sibling is named explicitly.
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?
Explains the mechanics of when to use each direction of pagination ('cursor walks older events; prev_cursor walks the newer edge (for live polling)'), which is genuine usage guidance. It never states when to prefer this tool over list_participant_events or list_anomalies, nor any prerequisite conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_host_incidentsARead-onlyInspect
List a host's incidents
Incidents for one host, newest-first, cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| since | No | Only include items at or after this ISO 8601 instant. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| status | No | Filter by incident lifecycle state. | |
| hostname | Yes | The host's fully-qualified hostname. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, and the description adds meaningful behavior: newest-first ordering and cursor-based pagination. This goes beyond the annotation and the schema to disclose how results are returned, though it does not mention details like auth or rate limits.
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 two short sentences, front-loaded with the primary purpose and immediately followed by key behavioral details. Every word earns its place with no 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?
With five parameters all fully documented in the schema, the description provides the essential runtime behavior (ordering, pagination) not covered by the schema. Since there is no output schema, a brief note on return shape could improve completeness, but the current level is sufficient for a list operation.
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?
The schema provides 100% parameter description coverage, so the description does not need to explain parameters. It adds no additional semantic meaning beyond what the schema already offers for the five parameters, 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 clearly states 'List a host's incidents', specifying the verb, resource, and scope ('for one host'). This distinguishes it from sibling tools like list_incidents (likely all incidents) and list_hosts (hosts themselves). The added 'newest-first, cursor-paginated' details further clarify behavior.
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 gives clear context that this tool is for retrieving incidents for a single specific host, which implies when to use it. However, it does not explicitly name alternatives or state when not to use it (e.g., for cross-host incident queries), so it lacks exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_hostsARead-onlyInspect
List monitored hosts
Every monitored host with its current verdict, latest hourly all-locations latency and 24h uptime, worst-first, plus a network-wide rollup.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint: true, so the safety profile is covered. The description adds valuable behavioral context by specifying exactly what is returned: current verdict, latest latency, 24h uptime, ordering (worst-first), and the network-wide rollup, which goes beyond the annotation.
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 extremely concise: two sentences that front-load the core purpose ('List monitored hosts') and then add essential output details. Every sentence is informative with no wasted words.
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 list tool with no parameters and no output schema, the description provides comprehensive information about the return value: the fields, ordering, and inclusion of a rollup. It fully explains what the agent can expect, making it complete for its complexity.
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?
The tool has zero parameters, so the schema provides no parameter semantics. The description correctly omits any parameter details. Baseline for 0 parameters is 4, and there is nothing to add.
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 clearly states the tool's purpose: 'List monitored hosts' with a specific verb and resource. It further distinguishes itself from siblings like get_host and get_network_summary by detailing the unique output: verdict, latency, uptime, worst-first ordering, and a network-wide rollup.
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 usage for obtaining a broad overview of all monitored hosts, including metrics and a rollup. It does not explicitly name alternatives or exclusions (e.g., 'for a single host, use get_host'), but the context is clear enough for an agent to select this tool when a comprehensive list is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_id_quality_malformedARead-onlyInspect
List malformed participant identifiers
The individual identifiers that failed their scheme's structural rule, keyset-paginated on (scheme, value). The first page's meta.facets gives scheme and reason counts over the filtered set.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Case-insensitive substring match on the identifier value. | |
| smp | No | Filter to malformed ids homed on one SMP hostname (from `meta.facets.smp`). | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| reason | No | Filter by the kind of structural failure. | |
| scheme | No | Filter to one Peppol ICD scheme (e.g. `0208`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, and the description adds behavioral context by mentioning keyset-pagination on (scheme, value) and the presence of meta.facets on the first page. This goes beyond the annotation without over-explaining.
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 two sentences, front-loaded with the purpose, and every clause adds value. It avoids repetition of schema details and focuses on non-obvious behavior.
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?
Given there is no output schema, the description explains the pagination approach and the meta.facets structure, which is useful. It doesn't detail the exact fields of each malformed identifier, but the phrase 'individual identifiers' gives a reasonable hint. Overall, it's complete enough for a list/filter tool with well-documented schema.
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 all parameters already have descriptions. The tool description does not add additional parameter semantics, but it implicitly relates cursor and limit to the pagination strategy, which is marginal value. Baseline 3 is appropriate.
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 clearly states the tool lists malformed participant identifiers, defines what those are ('identifiers that failed their scheme's structural rule'), and distinguishes it by introducing the pagination and facets. The verb 'list' and resource are specific, differentiating it from sibling tools like get_id_quality.
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 clear context for use: it's for viewing malformed identifiers, with keyset pagination and facet counts for analysis. It does not explicitly state when not to use or name alternatives, but the context is strong enough that an agent can infer appropriate use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_incidentsARead-onlyInspect
List incidents
The global incident feed, newest-first, cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | Filter to one host's incidents. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| since | No | Only include items at or after this ISO 8601 instant. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| status | No | Filter by incident lifecycle state. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnly annotation already signals safety, and the description adds useful behavioral details: global scope, newest-first ordering, and cursor pagination. This goes beyond the annotation and helps the agent understand the tool's operational behavior without needing to inspect schema details.
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 extremely concise, front-loading the purpose ('List incidents') and adding only essential qualifiers in a compact form. Every word earns its place, making it easy to parse quickly.
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?
Given the read-only annotation, complete schema, and simple list operation, the description provides adequate context for invocation: it names the global feed, ordering, and pagination. It does not describe the return structure, but since there is no output schema, this is a minor gap; overall, the tool is well contextualized.
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?
The input schema covers all parameters thoroughly (100% coverage), so the description adds little parameter semantics. The description's 'newest-first' and 'cursor-paginated' align with the limit and cursor parameters, but these are also inferred from the schema, so no extra value beyond 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 clearly states the tool lists incidents, with specific qualifiers: global feed, newest-first, cursor-paginated. This distinguishes it from sibling list_host_incidents by emphasizing the global scope, making the purpose unambiguous.
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 clear context: it is the global incident feed, so the agent knows to use this for all incidents. It does not explicitly exclude alternatives or mention host-specific listing, but the 'global' qualifier alone implies the appropriate use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_participant_eventsARead-onlyInspect
List a participant's change events
The participant's typed change events, newest-first, cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Canonical `scheme::value` Peppol identifier. | |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description adds useful behavioral details: events are 'newest-first' and 'cursor-paginated'. This goes beyond the annotation by specifying ordering and pagination style.
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 two sentences: the first states the purpose, the second provides key behavioral details. No filler or redundant information.
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 list tool with well-described parameters and annotations, the description provides adequate context (ordering, pagination, scope). It could mention the response shape but 'change events' is sufficient for a list tool.
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 parameters (id, limit, cursor) with clear meaning. The description adds little beyond referencing pagination (cursor-paginated), which is already implied by the schema's cursor parameter.
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 clearly states the action ('List') and the specific resource ('a participant's change events'), which distinguishes it from sibling tools like get_participant_history or list_events. The additional phrase 'typed change events' further narrows the scope.
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 usage for participant change events but does not explicitly state when to use this tool versus alternatives such as list_events or get_participant. No exclusion or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_participantsRead-onlyInspect
List participants
The participant set, keyset-paginated. Default sort is first-seen newest-first. Comma-array filters (country, scheme, smp, ap, doctype, transport_profile, host, provenance, and the company-register cuts entity_type, sector, size, region, postcode), the single-valued sub_provider cut, registered + vat_liable booleans, and a smart q (a full Peppol ID or a bare identifier number matches the ID; other text is a name search on the business-card name or the company-register name — see q). First-page meta carries estimated totals and rollup facets; meta.filter_count is a bounded exact count that degrades to null (never an error) if it exceeds the query timeout. A name search that exceeds the query timeout returns an empty first page with meta.search_degraded, and a 503 on a later page. Discovered participants carry no name/card fields (privacy).
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Smart search. A full Peppol ID (`scheme::value`, or a bare `icd:value`) matches that ID exactly. A bare identifier number (digits only, 4 or more) matches the participants whose ID is that number under any ICD prefix, and also names that contain it. Any other text is a name search: it matches the business-card name or the company-register name. The words can be in any order. All words must match (at most 8 words are used). Case, accents and punctuation are ignored. The search needs at least one word of 3 or more characters, else 400. A name that the response withholds is not searchable: the card name of a `discovered` participant and the register name of a natural person. If a name search exceeds the query timeout, the first page is returned empty with `meta.search_degraded: true`; a later page (with `cursor`) returns 503. Neither is cacheable. Use a narrower term. | |
| ap | No | Comma-array of serving Access Point SeatIDs (`PBE000123,PNO000456`). | |
| smp | No | Comma-array of current SMP hostnames (`smp1.example,smp2.example`). | |
| host | No | Comma-array of endpoint-URL hostnames (`ap.example.com`). Matches a participant if ANY of its current endpoints publishes an endpoint URL on one of the given hosts — the exact participant set an Access Point host serves. Case-insensitive. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies. | |
| size | No | Comma-array of company size band codes, as stored (`12,21`): the INSEE trancheEffectifs codes for FR (`NN` = unknown), and for NO the same code set plus `1-4`. | |
| sort | No | Sort + keyset key. `registered`, `entity_type` (the Type column) and `sector` (the Activity / NACE-division column) order over `(<col>, first_seen_at, id)`; the `entity_type`/`sector` views show only enriched (non-null) participants. The `name` sort lists only participants that have a business-card name: a participant with only a company-register name is NOT in a `name`-sorted list (and not in its `meta.filter_count`), although `q` can find it under the other sorts. The `country` sort lists only participants with a country. It is IGNORED when `doctype`/`transport_profile`/`host` is set WITHOUT any other narrowing filter, and when `sub_provider` is set without `q` or one of those endpoint filters — those results are driven from the matching index and ordered by identifier (`scheme`, `value`), the only ordering that stays inside the query timeout. Otherwise (an endpoint filter combined with `country`/`smp`/`ap`/`registered`/`provenance`/`q`, or `sub_provider` with `q`) the normal sort applies. | first_seen.desc |
| limit | No | Page size, clamped to [1, 200]. Defaults to 50. | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` by the previous page. | |
| region | No | Comma-array of company seat region codes (`BE-BRU,BE-VLG`). | |
| scheme | No | Comma-array of Peppol identifier schemes. | |
| sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`). | |
| country | No | Comma-array of ISO country codes (`BE,NL`). | |
| doctype | No | Comma-array of Peppol document type ids. Matches a participant if ANY of its current endpoints declares one of the given doctypes. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies. | |
| not_smp | No | Comma-array of SMP hostnames to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_size | No | Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| postcode | No | Comma-array of company seat postcodes. | |
| not_region | No | Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| not_sector | No | Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| provenance | No | Comma-array of provenance values. | |
| registered | No | Filter by current SML registration state. | |
| vat_liable | No | Filter by company VAT-liable / mandate-scope flag. | |
| entity_type | No | Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`), from the company-register enrichment denormalized onto the participant. | |
| not_country | No | Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| sub_provider | No | ONE curated sub-provider (reseller) slug (`codabox`) — the same slugs `GET /v1/aps/{key}` reports in `sub_providers[].sub_provider`. Matches a participant the daily rollup fingerprinted to that brand on ANY of its current endpoints, from three signals: the SMP `ServiceDescription`, the SMP technical-contact domain, and the endpoint host. Only curated names resolve, so the free-text long tail is not addressable here. Unlike the other filters this one takes a single value: a comma list, or a value that is not a slug (lowercase alphanumerics, dash-separated), is a 400. The sub-provider is an ADDITIVE annotation — the `ap` seat stays the operator of record. Results are ordered by identifier (`scheme`, `value`) and `sort` is ignored, EXCEPT alongside `q` or `doctype`/`transport_profile`/`host`, where the requested `sort` applies. Combining it with any other filter (`country`, `scheme`, `smp`, `ap`, `registered`, `provenance`, `entity_type`, `sector`, `size`, `region`, `postcode`, `vat_liable`) evaluates that filter against the rollup's DAILY SNAPSHOT of those participant columns, not the live row — a participant changing SMP or country is reflected here on the next rollup. Those combinations report an exact `meta.filter_count` (`filter_count_source: "exact"`); adding `q` or an endpoint filter falls back to the bounded count. | |
| not_entity_type | No | Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both. | |
| transport_profile | No | Comma-array of transport profile ids (`peppol-transport-as4-v2_0`). Matches a participant if ANY of its current endpoints uses one of the given profiles. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies. |
list_provider_certsARead-onlyInspect
Get a provider's certificate posture
A curated provider's whole-fleet certificate posture in one call: per-Seat cert counts, soonest expiry, expired / expiring-within-30-days counts, observed cert organisations and last identity shift, plus the rolled-up fleet summary.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The curated provider slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals a safe read operation, and the description adds valuable context about the specific content returned (per-Seat counts, expiries, identity shifts). It does not discuss pagination limits or error cases, but for a read-only aggregate tool this is acceptable.
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 one well-formed sentence with a clear subject and a structured list of outputs. It packs substantial detail without redundancy, though the list is slightly long; still, each item earns its place.
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, the description carries the responsibility of explaining the return payload, and it does so thoroughly by listing all components (cert counts, expiry thresholds, organisations, identity shift). Given the tool's single-parameter simplicity and read-only nature, the description is sufficiently complete.
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?
The single parameter 'slug' is fully described in the schema as 'The curated provider slug', which makes the schema coverage 100%. The tool description adds no additional parameter-level detail, so it relies on the schema as 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 ('Get') and a specific resource ('provider's certificate posture'), and enumerates the exact data returned. It clearly distinguishes this tool from siblings like get_provider or get_network_summary by focusing solely on certificate-related metrics.
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 phrase 'whole-fleet certificate posture in one call' implies this is the go-to tool for a consolidated cert summary, and the detailed output list makes its use case obvious. It does not explicitly mention when not to use it or point to alternatives, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_providersARead-onlyInspect
List providers
The OpenPeppol member registry with role flags, country, mapped hostnames and per-provider participant counts (market share), busiest first. Not paginated (the envelope's next_cursor is always null).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, it discloses that results are not paginated ('next_cursor' is always null) and are ordered busiest first. These are non-obvious behavioral details that help the agent correctly process the response.
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 two sentences: a clear title and a dense, efficient second sentence covering contents, ordering, and pagination. Every word earns its place.
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?
Despite lacking an output schema, the description covers key aspects: data returned, ordering, and pagination behavior. This is sufficient for an agent to understand what the tool does and what to expect.
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?
The tool has zero parameters, so the schema provides no semantic information. The description compensates by detailing what the returned list contains, meeting the baseline expectation for a no-parameter tool.
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 clearly states it lists providers from the OpenPeppol member registry with specific attributes (role flags, country, hostnames, participant counts), distinguishing it from sibling list tools. The verb 'List' and resource 'providers' are explicit.
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 clear context on what the tool returns, implying it is for obtaining a comprehensive provider registry view. It does not explicitly contrast with alternatives, but the detailed content makes selection obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_public_providersARead-onlyInspect
List public provider profiles
The FREE, crawlable public subset for each curated provider, busiest first: identity + role flags, the seat-directory columns (legal entity, commercial name, website, infra provider, hosting), mapped hostnames, participant count, roster country mix, the 30d/90d uptime headline, a cert-health summary and an as_of freshness stamp. Reachable with no API key. limit clamps to [1, 500] (default 100). Not paginated (the envelope's next_cursor is always null).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of providers to return, clamped to [1, 500]. Defaults to 100. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses several behavioral traits: results are 'busiest first', 'Not paginated' with next_cursor always null, limit clamping to [1,500], and the 'as_of' freshness stamp. It also reveals access requirements ('no API key').
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 dense but efficient; the opening phrase identifies the tool, followed by a structured list of returned fields and two key behavioral notes. No wasted words.
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 one optional parameter and no output schema, the description provides a thorough enumeration of the returned fields, ordering, pagination, and authentication requirement, making it sufficient for an agent to 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?
The input schema fully describes the single limit parameter (default, min, max), so schema coverage is 100%. The description restates the clamp behavior but adds no new parameter-level semantics beyond what the schema already states, warranting the baseline score.
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 'List public provider profiles', a specific verb+resource. It distinguishes from sibling list_providers by emphasizing 'FREE, crawlable public subset' and 'Reachable with no API key', making clear this is the unauthenticated public variant.
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 provides clear context that this is for public, crawlable data without an API key, implying use when no auth is desired. However, it does not explicitly name sibling alternatives like list_providers or state when not to use this tool, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_smpsARead-onlyInspect
List SMPs
The SMP directory: every current SMP hostname with the seat(s) and provider that sign its metadata, busiest first. A hostname is listed if it currently homes participants (from the participant rollup's smp facet) or carries an open smp-signing certificate. participant_count comes from that bounded top-N facet, so a hostname with a signing cert but outside the top-N carries a null count (unknown), not zero. The provider is resolved from the most-recent open signing cert with the precedence curated mapping (verified) → unverified cert-CN — the same as /v1/aps. provider is who OPERATES the host; owner names the party the curated registry says OWNS it, and is set only when that is a different party (a shared registry SMP served under another party's cert), else null. Not paginated (the envelope's next_cursor is always null).
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Case-insensitive substring filter on the SMP hostname. | |
| limit | No | Cap on returned rows (non-negative integer). Defaults to all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the readOnlyHint annotation: it explains that participant_count can be null rather than zero when outside a bounded top-N facet, that provider resolution follows a specific precedence from the most-recent open signing cert, that 'provider' and 'owner' have distinct semantics, and that pagination is disabled with next_cursor always null. This is exactly the kind of edge-case disclosure that helps an agent interpret results correctly.
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 dense but every sentence earns its place: it starts with the core definition and then methodically covers membership criteria, count semantics, provider resolution, owner/provider distinction, and pagination. Nothing is redundant, and the structure makes a complex directory semantics easy to follow.
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 and only a readOnlyHint annotation, the description carries the full burden of explaining what the tool returns and how to interpret it. It covers the key output fields (hostname, seats, provider, participant_count, owner), explains the null-count edge case, defines provider resolution precedence, and clarifies pagination behavior. This is complete enough for an agent to call the tool and correctly interpret its results.
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?
The input schema already documents both parameters fully with 100% coverage: q is a case-insensitive substring filter and limit caps rows with a default to all. The description does not add further parameter-specific detail, so the baseline score of 3 applies. It does add surrounding context about result ordering and non-pagination, but that is behavioral rather than parameter semantics.
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 ('List SMPs') and immediately defines the SMP directory as 'every current SMP hostname with the seat(s) and provider that sign its metadata, busiest first.' It clearly differentiates this from the many sibling list_* tools by specifying exact inclusion criteria (hosts participants or carries an open smp-signing certificate).
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 the tool by fully specifying what it returns, but it does not explicitly state when to prefer it over siblings like list_hosts or list_providers, nor does it mention any exclusions. The purpose is clear enough that an agent could infer usage, but no direct routing guidance or alternative names are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_softwareARead-onlyInspect
List the software library (Market)
The software catalogue's PRODUCT taxonomy joined to what the network shows: for every engine, its display name, vendor, category and homepage, the current host count broken down by observed role, when it was first and last seen, a compliance signal for the seats running it, and a host-count trend of up to 90 UTC days.
Every catalogue engine appears, including one the network does not currently show (hosts: 0, a flat trend) — the library is the catalogue, not only today's sightings. category is the vendor's own framing; roles is the OBSERVED fact and is the one to trust where the two disagree.
compliance.seats_linked is deliberately not called "owned": an engine → seat link is MANY-TO-MANY, so a seat whose hosts run two engines is counted under both and its findings appear under both. Summing open_findings across engines therefore OVER-COUNTS the network total; the figure answers "how much compliance debt sits behind this engine", never "who is to blame". compliance is null when no seat is linked to the engine, and snapshot_date always travels with the numbers because the daily rollup can be a day stale.
lanes[] (issue #798) reports each tracked upstream LANE of the engine — a lane is not an engine: oxalis covers three independent release ladders — with its latest_release and the hosts_current / hosts_behind / hosts_unknown split of the hosts running it (all three null when any is below 10). advisories summarises the live advisories published for the product by CVSS severity. Both are NULL — never [] or zero counts — for the engines the catalogue tracks no upstream feed for. Market tier.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Trend window in trailing UTC days, 1..90 (default 90). The ceiling is part of the contract — `days` can only narrow the window, never widen it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint, and the description goes well beyond it: it discloses that `lanes[]` split fields are all null when any is below 10, that `advisories` and `lanes` are NULL rather than empty/zero when no upstream feed is tracked, that `snapshot_date` can be a day stale, and that the seat-link is many-to-many so summed findings over-count. That is exactly the kind of behavioral context annotations cannot carry.
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?
It is front-loaded with a correct one-line summary, but the body is a dense wall of caveats and parenthetical internal references ('deliberately not called owned', 'issue #798') that read like spec documentation rather than agent guidance. Much context is warranted by the absent output schema, but the density costs readability.
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, the description must document the return shape, and it does so field-cluster by field-cluster (taxonomy fields, host counts by role, first/last seen, compliance, lanes, advisories) including null semantics and staleness. For a complex, Market-tier catalogue listing this is essentially complete.
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?
There is one parameter with 100% schema description coverage, including the 1..90 ceiling contract, so the schema carries the load and baseline 3 applies. The description only alludes to a 'trend of up to 90 UTC days' and adds no syntax or format detail beyond the 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 opening line states a specific verb and resource ('List the software library') and the body clarifies the scope as the product catalogue joined to network observations, which meaningfully distinguishes it from a single-engine lookup. However it never names a sibling (e.g. get_software, get_software_stats) to route the agent, so it falls short of the 5-level sibling differentiation.
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 provides interpretation guidance — trust observed `roles` over vendor `category`, do not sum `open_findings` across engines, `compliance` is null when no seat is linked — which is useful but is about reading results, not about when to choose this tool over get_software or get_software_stats. Usage is implied rather than explicitly scoped against alternatives.
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.
1 tool update
- Changed
get_network_stats_history2 fields changed- changed
Input schema / properties / stat / descriptionPrevious value: -"REQUIRED. The statistic to return: `ap_switching` (keys total, organic, bulk), `cross_border` (cross, same, unknown, strict_cross, strict_unknown), `smp_switching` (total), `growth` (net, joiners, leavers), `concentration_ap` / `concentration_smp` (cr5_pct, cr10_pct, hhi, total, providers), `foreign_served` (pct, foreign, domestic, unknown) or `penetration` (per country: pct, on_peppol, universe)."New value: +"REQUIRED. The statistic to return: `ap_switching` (keys total, organic, bulk, platform), `cross_border` (cross, same, unknown, strict_cross, strict_unknown), `smp_switching` (total), `growth` (net, joiners, leavers), `concentration_ap` / `concentration_smp` (cr5_pct, cr10_pct, hhi, total, providers), `concentration_ap_country` (per country with 8 or more providers: hhi, effective_providers, leader_pct, top4_pct, top10_pct, providers_over_1pct, providers, total), `foreign_served` (pct, foreign, domestic, unknown) or `penetration` (per country: pct, on_peppol, universe)." - changed
Input schema / properties / stat / enumPrevious value: -[ - "ap_switching", - "cross_border", - "smp_switching", - "growth", - "concentration_ap", - "concentration_smp", - "foreign_served", - "penetration" -]New value: +[ + "ap_switching", + "cross_border", + "smp_switching", + "growth", + "concentration_ap", + "concentration_ap_country", + "concentration_smp", + "foreign_served", + "penetration" +]
5 tool updates
- Changed
get_access_point_roster_mix1 field changed- changed
Input schema / properties / not_size / descriptionPrevious value: -"Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."
- Changed
get_participants_mix2 fields changed- changed
Input schema / properties / not_size / descriptionPrevious value: -"Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both." - changed
Input schema / properties / size / descriptionPrevious value: -"Comma-array of company size classes (as stored; SIRENE only)."New value: +"Comma-array of company size band codes, as stored (`12,21`): the INSEE trancheEffectifs codes for FR (`NN` = unknown), and for NO the same code set plus `1-4`."
- Added
get_provider_moves - Added
get_provider_roster_spread - Changed
list_participants2 fields changed- changed
Input schema / properties / not_size / descriptionPrevious value: -"Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of company size band codes (as stored: `21,NN`; FR and NO only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both." - changed
Input schema / properties / size / descriptionPrevious value: -"Comma-array of company size classes (as stored; SIRENE only)."New value: +"Comma-array of company size band codes, as stored (`12,21`): the INSEE trancheEffectifs codes for FR (`NN` = unknown), and for NO the same code set plus `1-4`."
6 tool updates
- Changed
get_access_point1 field changed- changed
Input schema / properties / key / descriptionPrevious value: -"The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`)."New value: +"The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`), or a Vendor key (`v-exact`)."
- Changed
get_access_point_churn1 field changed- changed
Input schema / properties / key / descriptionPrevious value: -"The Provider key (e.g. `c-tickstar`)."New value: +"The Provider key (e.g. `c-tickstar`), or a Vendor key (`v-exact`)."
- Changed
get_access_point_roster_mix1 field changed- changed
Input schema / properties / key / descriptionPrevious value: -"The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`)."New value: +"The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`), or a Vendor key (`v-exact`)."
- Changed
list_access_point_churn_participants4 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"The churn category to expand."New value: +"The churn category to expand. `newly_matched` and `no_longer_matched` are valid for a Vendor key only; with a Provider key they are a 400." - changed
Input schema / properties / category / enumPrevious value: -[ - "joiner", - "mover_in", - "mover_out", - "leaver" -]New value: +[ + "joiner", + "mover_in", + "mover_out", + "leaver", + "newly_matched", + "no_longer_matched" +] - changed
Input schema / properties / counterpart / descriptionPrevious value: -"Filter to one counterpart Provider key: the Provider the participants were won from (`mover_in`) or lost to (`mover_out`). Not allowed with `joiner` or `leaver`. An unknown key returns an empty list."New value: +"Filter to one counterpart Provider key: the Provider the participants were won from (`mover_in`) or lost to (`mover_out`). Allowed with the two mover categories only. For a Vendor key the counterpart can also be a Vendor key. An unknown key returns an empty list." - changed
Input schema / properties / key / descriptionPrevious value: -"The Provider key."New value: +"The Provider key, or a Vendor key (`v-<slug>`)."
- Changed
list_access_points2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged. A MARKET-tier key additionally gets the scoped churn components `country_joiners|movers_in|movers_out|leavers_7d|30d|90d`."New value: +"Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged. A MARKET-tier key additionally gets the scoped churn components `country_joiners|movers_in|movers_out|leavers_7d|30d|90d`. A Vendor row carries `country_roster` and `country_orgs` only: there is no country-scoped Vendor movement." - added
Input schema / properties / kindAdded value: +{ + "default": "provider", + "description": "Which row kinds to return. `provider` (default): Provider rows only. `vendor`: Vendor rows only. `all`: both, sorted together by `participant_count`. `vendor` and `all` need a MARKET-tier key; a lower-tier key gets a 403, never a list without the Vendors. Any other value is a 400.", + "enum": [ + "provider", + "vendor", + "all" + ], + "type": "string" +}
- Changed
list_cohort_moves2 fields changed- changed
Input schema / properties / min_participants / descriptionPrevious value: -"Only cohorts with at least this many participants. The detector's own floor is 25, so a lower value cannot surface smaller groups."New value: +"Only cohorts with at least this many participants. The detector's own floor is 25, so a lower value cannot surface smaller groups. With a Vendor key as `provider` the floor and the default are 5." - changed
Input schema / properties / provider / descriptionPrevious value: -"Only cohorts involving this Provider key (`/v1/aps/{key}`). Matches EITHER side unless `direction` narrows it."New value: +"Only cohorts involving this Provider key (`/v1/aps/{key}`). Matches EITHER side unless `direction` narrows it. A Vendor key (`v-<slug>`) returns the cohorts of that Vendor's movers instead: each item has `kind: \"vendor\"`, one side of the pair is the Vendor, and the floor is 5 participants. Vendor cohorts are in no other response of this endpoint."
3 tool updates
- Added
get_deregistered_company_stats - Added
get_deregistered_stats - Added
list_deregistered_ids
1 tool update
- Changed
list_participants2 fields changed- changed
Input schema / properties / q / descriptionPrevious value: -"Smart search: `scheme::value`/bare value → ID lookup; else name-contains."New value: +"Smart search. A full Peppol ID (`scheme::value`, or a bare `icd:value`) matches that ID exactly. A bare identifier number (digits only, 4 or more) matches the participants whose ID is that number under any ICD prefix, and also names that contain it. Any other text is a name search: it matches the business-card name or the company-register name. The words can be in any order. All words must match (at most 8 words are used). Case, accents and punctuation are ignored. The search needs at least one word of 3 or more characters, else 400. A name that the response withholds is not searchable: the card name of a `discovered` participant and the register name of a natural person. If a name search exceeds the query timeout, the first page is returned empty with `meta.search_degraded: true`; a later page (with `cursor`) returns 503. Neither is cacheable. Use a narrower term." - changed
Input schema / properties / sort / descriptionPrevious value: -"Sort + keyset key. `registered`, `entity_type` (the Type column) and `sector` (the Activity / NACE-division column) order over `(<col>, first_seen_at, id)`; the `entity_type`/`sector` views show only enriched (non-null) participants. It is IGNORED when `doctype`/`transport_profile`/`host` is set WITHOUT any other narrowing filter, and when `sub_provider` is set without `q` or one of those endpoint filters — those results are driven from the matching index and ordered by identifier (`scheme`, `value`), the only ordering that stays inside the query timeout. Otherwise (an endpoint filter combined with `country`/`smp`/`ap`/`registered`/`provenance`/`q`, or `sub_provider` with `q`) the normal sort applies."New value: +"Sort + keyset key. `registered`, `entity_type` (the Type column) and `sector` (the Activity / NACE-division column) order over `(<col>, first_seen_at, id)`; the `entity_type`/`sector` views show only enriched (non-null) participants. The `name` sort lists only participants that have a business-card name: a participant with only a company-register name is NOT in a `name`-sorted list (and not in its `meta.filter_count`), although `q` can find it under the other sorts. The `country` sort lists only participants with a country. It is IGNORED when `doctype`/`transport_profile`/`host` is set WITHOUT any other narrowing filter, and when `sub_provider` is set without `q` or one of those endpoint filters — those results are driven from the matching index and ordered by identifier (`scheme`, `value`), the only ordering that stays inside the query timeout. Otherwise (an endpoint filter combined with `country`/`smp`/`ap`/`registered`/`provenance`/`q`, or `sub_provider` with `q`) the normal sort applies."
1 tool update
- Changed
list_access_point_churn_participants3 fields changed- added
Input schema / properties / counterpartAdded value: +{ + "description": "Filter to one counterpart Provider key: the Provider the participants were won from (`mover_in`) or lost to (`mover_out`). Not allowed with `joiner` or `leaver`. An unknown key returns an empty list.", + "type": "string" +} - added
Input schema / properties / cursorAdded value: +{ + "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", + "type": "string" +} - added
Input schema / properties / limitAdded value: +{ + "default": 500, + "description": "Page size, clamped to [1, 500]. Defaults to 500 (20 through MCP).", + "maximum": 500, + "minimum": 1, + "type": "integer" +}
3 tool updates
- Changed
get_adoption2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country code — `be`, `fr`, `sk`, `no`, `se` or `fi`."New value: +"Country code — `be`, `fr`, `sk`, `no`, `se`, `fi` or `si`." - changed
Input schema / properties / country / enumPrevious value: -[ - "be", - "fr", - "sk", - "no", - "se", - "fi" -]New value: +[ + "be", + "fr", + "sk", + "no", + "se", + "fi", + "si" +]
- Added
get_network_stats - Added
get_network_stats_history
6 tool updates
- Removed
get_host_software - Changed
list_anomalies1 field changed- changed
Input schema / properties / detector / enumPrevious value: -[ - "cert_identity_shift", - "off_cadence_rotation", - "endpoint_off_footprint", - "moved_to_unverified_seat", - "mass_change_burst", - "split_id_registration", - "software_version_downgrade", - "software_vendor_swap", - "host_tls_cert_expired", - "host_tls_cert_expiring" -]New value: +[ + "cert_identity_shift", + "off_cadence_rotation", + "endpoint_off_footprint", + "moved_to_unverified_seat", + "mass_change_burst", + "split_id_registration", + "host_tls_cert_expired", + "host_tls_cert_expiring" +]
- Changed
list_events1 field changed- changed
Input schema / properties / type / items / enumPrevious value: -[ - "participant_registered", - "participant_deregistered", - "participant_smp_changed", - "endpoint_changed", - "doctype_support_changed", - "ap_seat_changed", - "host_cert_rotated", - "hosting_changed", - "directory_card_changed", - "software_changed", - "version_changed" -]New value: +[ + "participant_registered", + "participant_deregistered", + "participant_smp_changed", + "endpoint_changed", + "doctype_support_changed", + "ap_seat_changed", + "host_cert_rotated", + "hosting_changed", + "directory_card_changed" +]
- Removed
list_host_software - Removed
list_host_software_history - Removed
list_software_anomalies
3 tool updates
- Changed
get_access_point_roster_mix2 fields changed- changed
Input schema / properties / not_sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both." - changed
Input schema / properties / sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`)."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`)."
- Changed
get_participants_mix2 fields changed- changed
Input schema / properties / not_sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both." - changed
Input schema / properties / sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`)."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`)."
- Changed
list_participants2 fields changed- changed
Input schema / properties / not_sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both." - changed
Input schema / properties / sector / descriptionPrevious value: -"Comma-array of 2-digit NACE divisions (`47,62`)."New value: +"Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`)."
1 tool update
- Changed
list_access_points1 field changed- changed
Input schema / properties / country / descriptionPrevious value: -"Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged."New value: +"Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged. A MARKET-tier key additionally gets the scoped churn components `country_joiners|movers_in|movers_out|leavers_7d|30d|90d`."
1 tool update
- Added
get_participants_mix
1 tool update
- Added
get_access_point_roster_mix
1 tool update
- Changed
list_participants6 fields changed- added
Input schema / properties / not_countryAdded value: +{ + "description": "Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / not_entity_typeAdded value: +{ + "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / not_regionAdded value: +{ + "description": "Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / not_sectorAdded value: +{ + "description": "Comma-array of 2-digit NACE divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / not_sizeAdded value: +{ + "description": "Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / not_smpAdded value: +{ + "description": "Comma-array of SMP hostnames to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03¬_region=NO-32` applies both.", + "items": { + "type": "string" + }, + "type": "array" +}
1 tool update
- Changed
get_adoption2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country code — `be`, `fr`, `sk`, `no` or `se`."New value: +"Country code — `be`, `fr`, `sk`, `no`, `se` or `fi`." - changed
Input schema / properties / country / enumPrevious value: -[ - "be", - "fr", - "sk", - "no", - "se" -]New value: +[ + "be", + "fr", + "sk", + "no", + "se", + "fi" +]
1 tool update
- Changed
get_adoption2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country code — `be`, `fr`, `sk` or `no`."New value: +"Country code — `be`, `fr`, `sk`, `no` or `se`." - changed
Input schema / properties / country / enumPrevious value: -[ - "be", - "fr", - "sk", - "no" -]New value: +[ + "be", + "fr", + "sk", + "no", + "se" +]
1 tool update
- Changed
get_adoption2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country code — `be` or `fr`."New value: +"Country code — `be`, `fr`, `sk` or `no`." - changed
Input schema / properties / country / enumPrevious value: -[ - "be", - "fr" -]New value: +[ + "be", + "fr", + "sk", + "no" +]
Related MCP Connectors
Search EU public tenders across TED and 8 national portals. Monitor, match, and analyse procurement.
Belgium Peppol BIS 3.0 e-invoices for AI agents: send, check recipient, get delivery proof.
- AimOAuthcom.startaiming
Market knowledge layer for AI agents: competitors, opinions and regulations shaping your market.
Validate EU VAT numbers in VIES and check Peppol e-invoicing, with source and date on every fact
Related MCP Servers
AlicenseAqualityAmaintenanceBid/no-bid intelligence for EU public tenders, built on 592,000 real TED contract awards: competition density, price corridor, SME fit and beachhead ranking. Free guest access; an API key unlocks the live board.4MIT- AlicenseAqualityCmaintenanceStructured business intelligence for AI agents. 5.5M verified entities across 34 countries, 40.3M BORME mercantile acts, EU VAT validation, GLEIF, healthcare registries. 20 tools.61MIT
- AlicenseNot gradedqualityCmaintenanceProvides free read-only business checks for IBANs, EU VAT number format, Peppol e-invoice rules, supplier bank-detail changes, and CSV/XLSX data cleaning.MIT
- FlicenseNot gradedqualityDmaintenanceEU e-invoicing — UBL/CII conversion to XRechnung and FatturaPA-
Glama MCP Gateway
Add one secure layer between your agents and this server.