Skip to content

Sweep the corpus onto x-overslash-pagination, and bound the 17 list actions that declare nothing #577

Description

@angel-manuel

Why

The generic-pagination PR shipped the extension, the runtime, the /v1/search flag and the dashboard pill, but annotated exactly one shipped template (services/gmail.yaml). That was deliberate — twenty template judgements in one diff are impossible to argue with individually — and it leaves the actual damage unfixed. The Metabase case that started this is still live, and eventbrite.list_event_attendees is the same shape waiting.

Read docs/design/generic-pagination.md and the decision entry first; the vocabulary is settled and this issue is about applying it.

Part 1 — annotate what already pages

These declare paging parameters the gateway now knows how to read. Each is mechanical: add a pagination: block naming the parameters that already exist.

service operations page size continuation style
github list_installations, list_repos, list_issues per_page (default 30) RFC 8288 Link (not currently modelled — no page param either, so one must be added) link
stripe list_charges limit (default 10) none declared — needs starting_after cursor
notion search, query_database page_size (body, no default) start_cursor (body) cursor
google_drive list_files, list_permissions pageSize (no default) pageToken cursor
google_keep list_notes pageSize (no default) pageToken cursor
outlook list_messages, list_folders $top (no default) $skip offset
metabase search limit (default 50) offset offset
google_calendar list_events maxResults (no default) none declared — needs pageToken cursor
google_tasks list_tasklists, list_tasks maxResults (no default) none declared — needs pageToken cursor
email search limit (body, no default) none — response carries {results, total, truncated} n/a, page-size half only
slack (MCP) list_channels, read_channel_history limit (defaults 100 / 50) cursor cursor
hubspot (MCP) search_crm_objects, search_owners, get_campaign_contacts_by_type, get_content_analytics_report limit offset offset
whatsapp (MCP) seven list tools limit page (default 0) page

Two things to check as you go, because they are where the value is:

  • A page-size parameter with no default: bounds nothing. page_size.default seeds it. That is most of the table.
  • Several rows need a continuation parameter added to the template, not just annotated — the upstream supports it and we never declared it. Those are the ones that make an action genuinely pageable rather than merely bounded.

Note slack.search_messages spells page size count, which is a seventh spelling and needs no new vocabulary — page_size.param names whatever the parameter is called.

Part 2 — bound what declares nothing

Seventeen HTTP-runtime list operations declare no page size at all. Where the upstream supports one, add the parameter and the pagination: block. Where it does not (Metabase's list_cards is the canonical case — no pagination, no sorting, no field selection), say so in the action's description and point at the paged sibling, which is what metabase.yaml already does in prose.

  • metabase.list_databases, list_cards, popular_items, recents
  • eventbrite.list_my_orders, list_organizations, list_ticket_classes, list_event_attendees — the severe one: an unbounded collection of rich objects, the same shape as the Metabase failure
  • outlook.list_folders
  • stripe.list_customers (its sibling list_charges declares limit)
  • resend.list_domains
  • google_calendar.list_calendars
  • gmail.list_labels
  • MCP side: hubspot.get_crm_objects, query_crm_data, get_properties, search_properties, get_campaign_analytics, get_campaign_asset_metrics; deepwiki.read_wiki_contents

Part 3 — the gate that keeps it swept

Close with a corpus test shaped like registry::tests::shipped_mutating_actions_declare_disclose: every shipped action whose key looks like a list (or that returns a collection) either declares x-overslash-pagination or appears in an ALLOW_MISSING list with a comment saying why the upstream cannot page. Keep the allow-list honest — the existing one is empty and carries the instruction "add entries only with a comment explaining why".

Notes

  • NextStyle::Link is refused on MCP tools at compile: a tool result has no response headers.
  • The gateway does not clamp page_size.max; it bounds default at validation time and writes the dashboard tooltip.
  • Where a parameter already declares its own default:, that wins and page_size.default is inert — validation warns (pagination_default_shadowed). Prefer removing the duplicate over leaving both.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent to pick up

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions