Skip to content

Bound automatic pagination in the MCP client - #505

Open
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:bound_client_automatic_pagination
Open

Bound automatic pagination in the MCP client#505
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:bound_client_automatic_pagination

Conversation

@koic

@koic koic commented Aug 10, 2026

Copy link
Copy Markdown
Member

Motivation and Context

MCP::Client#tools, #resources, #resource_templates, and #prompts follow nextCursor until the server stops offering one. The seen set in fetch_all_pages catches a server that repeats or cycles cursors, but a fresh cursor on every response walks past that guard, and the client keeps requesting and retaining pages for as long as the server keeps producing them. The transports' per-message limits do not help here, since each individual page can be small.

MCP::Client.new now takes max_pages:, defaulting to MAX_PAGES (1000). Reaching it raises PaginationLimitError rather than truncating the collection silently, since a short array would be indistinguishable from a server that genuinely ran out of items. The single-page list_* methods are unchanged, so callers who need their own policy still have one.

How Has This Been Tested?

New tests in test/mcp/client_test.rb cover a server that returns a distinct cursor per page, the boundary where a server stops exactly at max_pages, and the argument validation. The existing repeat-cursor and cycling-cursor tests are unaffected. bundle exec rake (tests, RuboCop, and conformance baseline) passes.

Breaking Changes

An all-pages call against a server offering more than 1000 pages now raises MCP::Client::PaginationLimitError instead of continuing. Pass a larger max_pages: to MCP::Client.new if that is expected.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

## Motivation and Context

`MCP::Client#tools`, `#resources`, `#resource_templates`, and `#prompts` follow `nextCursor`
until the server stops offering one. The `seen` set in `fetch_all_pages` catches a server that
repeats or cycles cursors, but a fresh cursor on every response walks past that guard, and
the client keeps requesting and retaining pages for as long as the server keeps producing them.
The transports' per-message limits do not help here, since each individual page can be small.

`MCP::Client.new` now takes `max_pages:`, defaulting to `MAX_PAGES` (1000). Reaching it raises
`PaginationLimitError` rather than truncating the collection silently, since a short array would
be indistinguishable from a server that genuinely ran out of items. The single-page `list_*` methods
are unchanged, so callers who need their own policy still have one.

## How Has This Been Tested?

New tests in `test/mcp/client_test.rb` cover a server that returns a distinct cursor per page,
the boundary where a server stops exactly at `max_pages`, and the argument validation.
The existing repeat-cursor and cycling-cursor tests are unaffected.
`bundle exec rake` (tests, RuboCop, and conformance baseline) passes.

## Breaking Changes

An all-pages call against a server offering more than 1000 pages now raises
`MCP::Client::PaginationLimitError` instead of continuing. Pass a larger `max_pages:` to
`MCP::Client.new` if that is expected.
@koic koic changed the title Bound Automatic Pagination in the MCP Client Bound automatic pagination in the MCP client Aug 10, 2026
@koic
koic force-pushed the bound_client_automatic_pagination branch from bf772b2 to 3ff7075 Compare August 10, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant