Skip to content

feat: add cursor pagination support to all client list methods #718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 15, 2025

Conversation

jerome3o-anthropic
Copy link
Contributor

@jerome3o-anthropic jerome3o-anthropic commented May 15, 2025

Summary

This PR adds cursor-based pagination support to all list methods in the Python MCP client SDK. The client is now ready to handle paginated responses from servers, though server implementations don't yet support pagination.

Changes

  • Added optional cursor parameter to all client list methods:

    • list_tools(cursor=None)
    • list_resources(cursor=None)
    • list_prompts(cursor=None)
    • list_resource_templates(cursor=None)
  • Added comprehensive tests verifying cursor parameter acceptance for all list methods

Test Plan

Tests verify that the cursor parameter is properly accepted in various forms:

  • Omitted (backward compatibility)
  • cursor=None
  • cursor="some_value"
  • cursor=""

Note: The tests don't demonstrate actual pagination because no server in the SDK currently implements it. The tests only verify that the client accepts and passes the cursor parameter correctly.

Notes

This addresses the issue reported in Slack where users couldn't access the cursor parameter in list_tools() and had to drop down to session.send_request() to use pagination.

Servers will need to be updated separately to actually implement cursor-based pagination - this PR just ensures the client is ready for it.

Add cursor-based pagination support to the list_tools method in the
client session, along with comprehensive tests. This enables clients
to handle large tool lists efficiently by fetching them in pages.

- Update list_tools method to accept and handle cursor parameter
- Properly propagate cursor from server response
- Add test_list_tools_cursor.py with complete test coverage
- Test pagination flow, empty results, and edge cases

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Reduce test complexity to just verify cursor parameter acceptance
- Add docstring note explaining that FastMCP doesn't implement pagination yet
- Test cursor as None, string, empty string, and omitted
- Add cursor parameter to list_resources(), list_prompts(), and list_resource_templates()
- Add tests verifying cursor parameter acceptance for all list methods
- Note: Server implementations don't yet support pagination, but client is ready
- Move list_tools test into test_list_methods_cursor.py
- Remove redundant test_list_tools_cursor.py file
- All cursor pagination tests are now in one place
@jerome3o-anthropic jerome3o-anthropic changed the title feat: implement pagination support for list_tools in client feat: add cursor pagination support to all client list methods May 15, 2025
@jerome3o-anthropic jerome3o-anthropic requested review from ihrpr and removed request for jspahrsummers May 15, 2025 02:45
Copy link

@mcp-shadow mcp-shadow bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend accepting this PR for the following reasons:

  1. This PR adds cursor-based pagination support to client list methods, which is aligned with the MCP protocol's support for pagination as defined in the types.py file. The protocol already includes PaginatedRequest and PaginatedResult classes.

  2. The implementation is simple, clean, and backward compatible. It adds an optional cursor parameter to all list methods with a default value of None, ensuring that existing code that calls these methods without a cursor will continue to work.

  3. The changes are well-tested with comprehensive tests for all four list methods (list_tools, list_resources, list_prompts, and list_resource_templates), covering various parameter scenarios.

  4. The PR addresses a real user need described in the PR description - users previously had to drop to the lower-level session.send_request() method to use pagination.

  5. While the server implementations don't currently support pagination, this change ensures that the client is future-proofed for when servers add this capability. This is a forward-thinking change that maintains protocol compliance.

  6. The code follows Python 3.10+ features using the modern | syntax for Union types.

Minor Improvements

A few minor suggestions for improvement:

  1. Consider adding docstring updates to each modified method to document the new cursor parameter. For example:

    async def list_tools(self, cursor: str | None = None) -> types.ListToolsResult:
        """Send a tools/list request.
        
        Args:
            cursor: Optional cursor for pagination. If provided, the server should 
                   return results starting after this cursor.
        """
  2. Consider creating a typing alias for the cursor parameter type to improve maintainability, though this is a minor point since the type is already defined in types.py.

Overall, this PR provides a valuable improvement that brings the client implementation closer to full protocol compliance and resolves a user-reported issue. The changes are minimal, well-tested, and follow Python best practices.

Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with 🐈‍⬛ , LGTM!

Have you tried testing with servers that support pagination?

@ihrpr ihrpr merged commit a00b20a into main May 15, 2025
13 checks passed
@ihrpr ihrpr deleted the jerome/feature/client-list-tools-pagination branch May 15, 2025 08:04
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.

2 participants