Skip to content

feat: add paginated list decorators for prompts, resources, and tools#1286

Merged
maxisbey merged 11 commits into
mainfrom
feat/list-pagination
Sep 23, 2025
Merged

feat: add paginated list decorators for prompts, resources, and tools#1286
maxisbey merged 11 commits into
mainfrom
feat/list-pagination

Conversation

@maxisbey
Copy link
Copy Markdown
Contributor

@maxisbey maxisbey commented Aug 20, 2025

Summary

This PR adds pagination support for listing prompts, resources, and tools using cursor-based pagination as defined in the MCP spec.

The lowlevel Server decorators list_resources, list_prompts, and list_tools now handle two types of handlers:

  • No pagination (original functionality)
    • A handler with the signature Callable[[], Awaitable[list[<resource, prompt, or tool>]]]
    • This matches the original way these decorators work and means the API is still backwards compatible.
  • Pagination (new functionality)
    • A handler with the signature Callable[[List<___>Request], Awaitable[List<___>Result]]
    • The cursor for a paginated request will be in the corresponding List<___>Request object depending on the decorator which the handle can now optionally handle.
    • The response object is a List<___>Response which the handler can specify the cursor for the next page.
    • This allows future extensions to the Request or Response objects to still be supported.

How It Works

The decorators now automatically detect whether a callback accepts a cursor parameter:

# Non-paginated (existing code continues to work)
@server.list_resources()
async def list_resources() -> list[Resource]:
    return [...]

# Paginated (new capability)
@server.list_resources()
async def list_resources(cursor: Cursor | None) -> ListResourcesResult:
    return ListResourcesResult(resources=[...], nextCursor="...")

Changes

  • Modify list_prompts(), list_resources(), and list_tools() decorators to support both signatures
  • Add comprehensive unit tests for pagination and signature detection
  • Add examples demonstrating pagination usage
  • Tool cache properly maintained for both paginated and non-paginated modes

Test plan

  • Unit tests pass for all three decorators with both signatures
  • Tests verify cursor passthrough for both None and string values
  • Function inspection tests cover various callback signatures
  • Backward compatibility verified with existing non-paginated handlers
  • Manually tested via the inspector and with example client code

🤖 Generated with Claude Code

👨 Below generated by the human, Max Isbey

Manual testing

I spun up the MCP inspector and ran the example pagination server in both stdio mode and SSE mode. Below is some testing evidence using the SSE mode:

Clicking "List More Resources" correctly lists all 30 resources:

Note: this works for prompts and tools as well

Requesting a resource works:

Running the pagination client example code works listing all 30 resources:

Loading
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.

5 participants