Skip to content

feat: implement auto-pagination for MCP server list operations and address review feedback - #4086

Closed
akshay183 wants to merge 2 commits into
openai:mainfrom
akshay183:feat/mcp-pagination
Closed

feat: implement auto-pagination for MCP server list operations and address review feedback#4086
akshay183 wants to merge 2 commits into
openai:mainfrom
akshay183:feat/mcp-pagination

Conversation

@akshay183

@akshay183 akshay183 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

This pull request implements automatic pagination for MCP server list operations (list_tools and list_prompts) in src/agents/mcp/server.py and resolves review feedback regarding cursor evaluation and log redaction.
#4085

Background & Context

When interacting with MCP servers that return paginated tool or prompt lists, the SDK previously fetched only the first page. For large servers, subsequent tools and prompts were omitted. Additionally, review feedback identified two key considerations in the pagination loop:

  1. Opaque Empty String Cursors: Valid pagination cursors represented as empty strings ("") were improperly treated as exhaustion when evaluated with truthiness (if not next_cursor:).
  2. Sensitive Log Exposure: Raw cursor and next_cursor values were written to logger.warning(...) calls during loop detection, potentially exposing opaque server tokens or tenant state in logs.

Key Changes

  • Auto-Pagination: Updated list_tools and list_prompts in src/agents/mcp/server.py to transparently accumulate all pages until nextCursor is None.
  • Strict None Exhaustion Check: Replaced truthiness checks with next_cursor is None and if next_cursor is not None and next_cursor in seen_cursors: to safely support empty string cursor tokens ("").
  • Sensitive Log Redaction: Omitted raw cursor / next_cursor payload values from logger.warning(...) messages in both list_tools and list_prompts.
  • Test Coverage & Verification:
    • Updated unit tests in tests/mcp/test_pagination.py verifying multi-page tool/prompt accumulation, metadata merging, repeated-cursor loop termination, and empty string cursor handling.
    • Included a local integration probe (local_mcp_pagination_probe.py) to verify real Streamable HTTP transport pagination.

- Added auto-pagination logic for `list_tools`, `list_prompts`, `list_resources`, and `list_resource_templates` in `MCPServer`.
- Implemented an infinite loop guard that prevents duplicate fetching if the server repeatedly returns the same cursor.
- Updated existing tests and added dedicated `test_pagination.py` to cover full page accumulation and loop breaking.
- Kept all logic backward compatible.

Co-authored-by: akshay183 <68906315+akshay183@users.noreply.github.com>
@akshay183
akshay183 force-pushed the feat/mcp-pagination branch from ffa9c24 to 090c337 Compare August 1, 2026 11:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ffa9c24a7e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/server.py Outdated
Comment thread src/agents/mcp/server.py Outdated
Comment thread src/agents/mcp/server.py
@akshay183

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4936c7c3a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/server.py Outdated
Comment thread src/agents/mcp/server.py Outdated
@akshay183
akshay183 force-pushed the feat/mcp-pagination branch from 4936c7c to e6a32e8 Compare August 1, 2026 15:06
@akshay183 akshay183 changed the title feat: implement auto-pagination for MCP server list operations feat: implement auto-pagination for MCP server list operations and address review feedback Aug 1, 2026
@akshay183

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Note

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6a32e8db1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/server.py

async def fetch_tools_page(page_cursor: str | None = _cursor) -> Any:
return await self._maybe_serialize_request(
lambda: session.list_tools(cursor=page_cursor)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep cursor TypeErrors out of the retry loop

This new cursor keyword needs corresponding updates to the repo's existing session doubles: DummySession.list_tools(self) in tests/mcp/test_client_session_retries.py has no cursor parameter, and test_list_tools_unlimited_retries configures max_retry_attempts=-1, so the resulting deterministic TypeError is retried forever instead of completing. The same signature mismatch exists for the prompt doubles reached by the new prompt pagination path, so update those fakes/adapters to accept cursor before merging.

Useful? React with 👍 / 👎.

Comment thread src/agents/mcp/server.py
lambda: session.list_tools(cursor=page_cursor)
)

result = await self._run_with_retries(fetch_tools_page)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Share one retry budget across paginated list calls

Because _run_with_retries is now invoked once per fetched page, a multi-page list_tools() call receives a fresh max_retry_attempts allowance for every cursor. For servers that expose many pages and hit transient failures, max_retry_attempts=3 can turn into three retries per page rather than for the SDK-level list operation, substantially exceeding the configured retry/latency budget; keep the retry counter across the whole pagination loop or otherwise cap the aggregate attempt count.

Useful? React with 👍 / 👎.

@seratch

seratch commented Aug 2, 2026

Copy link
Copy Markdown
Member

@akshay183 Thank you so much for reporting and trying to resolve this issue. I've created a PR including your co-autuhored-by credit at #4094 ; the PR doesn't have any remaining review feedback to resolve, so we'll go with the PR instead. Thanks again fro taking the time for this.

@seratch seratch closed this Aug 2, 2026
@akshay183

Copy link
Copy Markdown
Contributor Author

@akshay183 Thank you so much for reporting and trying to resolve this issue. I've created a PR including your co-autuhored-by credit at #4094 ; the PR doesn't have any remaining review feedback to resolve, so we'll go with the PR instead. Thanks again fro taking the time for this.

Great!
thanks for the credit. Glad to contribute to the project...

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants