Skip to content

fix(mcp): page through tools/list nextCursor - #825

Merged
0xKT merged 2 commits into
EverMind-AI:mainfrom
yudongyouqing:fix/mcp_tools_list_pagination
Oct 3, 2026
Merged

0xKT merged 2 commits into
EverMind-AI:mainfrom
yudongyouqing:fix/mcp_tools_list_pagination

Conversation

@yudongyouqing

Copy link
Copy Markdown
Contributor

Summary

Type

  • Fix

Verification

  • Relevant tests pass locally
  • Relevant lint / type checks pass locally
  • User-facing docs or screenshots are updated when needed

Commands run on macOS, Python 3.12, on top of a clean checkout of main:

  • uv run pytest tests/test_mcp_client.py tests/test_mcp_client_transport.py tests/test_mcp_manager.py tests/test_mcp_bridge.py tests/test_mcp_change_probe.py tests/test_mcp_endpoint.py tests/test_mcp_naming.py tests/test_mcp_prompts.py tests/test_mcp_resources.py tests/test_mcp_session_addressing.py tests/test_agent_loop_mcp_meta_tools.py tests/test_agent_loop_mcp_sync.py tests/test_acp_per_session_mcp.py tests/test_cli_mcp_commands.py tests/test_sandbox_unit.py -q -> 357 passed.
  • The two new pagination tests in tests/test_mcp_client.py were each watched failing before the fix: two pages register every tool; a repeated cursor terminates paging.
  • uv run --frozen --python 3.12 --all-extras pytest -q -> 26998 passed, 109 skipped, 21 failed. The 21 failures are the same set that fails on unmodified main in this environment (verified by stashing this change): test_agents_research_tools.py (13), test_agents_research_verbatim_sink.py (5), test_simulation_scenario.py and test_simulation_suite.py (2), test_rpc_files.py::test_a_host_without_libreoffice_says_so (1, LibreOffice not installed locally). None touch the changed modules.
  • uv run ruff check and ruff format --check on the four touched files -> clean.
  • make lint-imports -> 10 kept, 0 broken.

Risk

  • Security impact considered

  • Backward compatibility considered

  • Rollback path is clear for risky changes

  • No wire or config change. A server that does not paginate (nextCursor absent or None) behaves exactly as before; the repeated-cursor guard is the only new stop condition, and it only fires where the old code would have registered one page and moved on.

  • Rollback is a straight revert of this commit.

Related Issues

Fixes #301

A server that exposes more tools than its page size silently lost every
tool after the first page: the connection fetched tools/list once and
never followed nextCursor. The agent-browser "all" profile exceeds one
64-tool page, so only the first page registered. The connection now
keeps requesting with the returned cursor until the server stops paging,
and a repeated cursor stops the loop rather than paging forever.
@0xKT

0xKT commented Oct 3, 2026

Copy link
Copy Markdown
Member

Thanks for the fix -- following nextCursor is the right call. CI is red on one step only: python lint -> Type check (call correctness) (make lint-types). Unit shards, ruff, import contracts and deptry are all green.

R1 (blocking) raven/mcp/client.py:265

session.list_tools(cursor=cursor) resolves to the overload that mcp 1.30.0 (the pinned version) marks @deprecated("Use list_tools(params=PaginatedRequestParams(...)) instead"). The ty gate keeps main at zero diagnostics and exits non-zero on warnings as well, so this single warning[deprecated] fails the job.

Fix -- extend the local import at line 252 and pass the cursor through params:

from mcp import ClientSession, types
...
page = await session.list_tools(params=types.PaginatedRequestParams(cursor=cursor))

The three test fakes that take cursor= then need to take params instead, or they raise TypeError: unexpected keyword argument 'params':

  • tests/test_mcp_client.py:108
  • tests/test_mcp_manager.py:281
  • tests/test_sandbox_unit.py:1804
async def list_tools(self, *, params=None):
    cursor = params.cursor if params else None

Verify:

make lint-types
uv run pytest tests/test_mcp_client.py tests/test_mcp_manager.py tests/test_sandbox_unit.py -x

yudongyouqing added a commit to yudongyouqing/Raven that referenced this pull request Oct 3, 2026
Address the review on EverMind-AI#825: the `list_tools(cursor=...)` overload is
deprecated in the pinned mcp 1.30.0, and the ty gate exits non-zero on
warnings, so `make lint-types` fails. Pass the cursor via
`params=types.PaginatedRequestParams(cursor=cursor)` instead, and teach
the three session fakes to take `params`.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@yudongyouqing

yudongyouqing commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the precise pointer. Addressed in e13ea4d: the call now goes through params=types.PaginatedRequestParams(cursor=cursor) with types added to the local import, and the three fakes in test_mcp_client.py, test_mcp_manager.py and test_sandbox_unit.py take params instead of cursor. ty check on raven/ is clean of the deprecation now, and tests/test_mcp_client.py tests/test_mcp_manager.py tests/test_sandbox_unit.py pass locally.

Address the review on EverMind-AI#825: the `list_tools(cursor=...)` overload is
deprecated in the pinned mcp 1.30.0, and the ty gate exits non-zero on
warnings, so `make lint-types` fails. Pass the cursor via
`params=types.PaginatedRequestParams(cursor=cursor)` instead, and teach
the three session fakes to take `params`.
@yudongyouqing
yudongyouqing force-pushed the fix/mcp_tools_list_pagination branch from 9620620 to e13ea4d Compare October 3, 2026 06:40
@0xKT
0xKT merged commit 5be9698 into EverMind-AI:main Oct 3, 2026
22 checks passed
@0xKT

0xKT commented Oct 3, 2026

Copy link
Copy Markdown
Member

Merged in 5be9698 -- thanks @yudongyouqing! Servers that page tools/list now register their full tool set instead of silently stopping at the first page, and the quick turnaround on the review made this an easy merge. Thanks also to @icn5381 for the original analysis in #301 / #302.

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.

fix: handle paginated MCP tools/list responses

2 participants