Skip to content

Stop listRoots pagination on an empty nextCursor - #1276

Open
JunyangLian wants to merge 1 commit into
modelcontextprotocol:mainfrom
JunyangLian:fix/listroots-empty-cursor
Open

JunyangLian wants to merge 1 commit into
modelcontextprotocol:mainfrom
JunyangLian:fix/listroots-empty-cursor

Conversation

@JunyangLian

Copy link
Copy Markdown

Motivation

McpAsyncServerExchange#listRoots() follows nextCursor until it is null. A client that answers roots/list with "nextCursor": "" instead of omitting the field makes the aggregate call request page after page, and McpSyncServerExchange#listRoots() blocks forever.

The client-side aggregate methods already stop on next != null && !next.isEmpty() (see #954); this applies the same guard to the server exchange, which the issue calls out as the last aggregate list method without it.

Changes

  • Stop pagination on a null or empty nextCursor in McpAsyncServerExchange#listRoots().
  • Add testListRootsStopsPagingOnEmptyNextCursor, which serves a second page carrying nextCursor: "" and asserts exactly two roots/list requests. Without the guard the expander returns a null publisher for the third request and the test fails.

Tests

./mvnw -pl mcp-core test -Dtest=McpAsyncServerExchangeTests -> 38 tests, 0 failures.

Fixes #1274

McpAsyncServerExchange#listRoots() kept requesting roots/list while a client reported nextCursor as an empty string, so the aggregated call never completed and the sync exchange blocked forever. End pagination on an empty cursor, matching the client-side guard in McpAsyncClient, and add a regression test.

This branch has not been deployed

No deployments
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.

listRoots() does not stop paginating on an empty nextCursor

1 participant