Problem
McpClient.list_tools() (backend/src/octave/mcp/client.py) sends tools/list once and ignores the result's nextCursor — servers with enough tools to paginate return a silently-truncated list.
Fix
Loop tools/list passing cursor=nextCursor until nextCursor is null; concatenate pages. Add a defensive page cap (e.g. 100) that raises McpError on breach (guard against a server echoing the same cursor forever). Test via the in-process harness in backend/tests/mcp/conftest.py: a server returning two pages, assert the client returns both.
Context
Found while scoping #77. The ToolRegistry (#77) deliberately assumes list_tools() is complete; when this lands the registry inherits correctness with zero changes.
Problem
McpClient.list_tools()(backend/src/octave/mcp/client.py) sendstools/listonce and ignores the result'snextCursor— servers with enough tools to paginate return a silently-truncated list.Fix
Loop
tools/listpassingcursor=nextCursoruntilnextCursoris null; concatenate pages. Add a defensive page cap (e.g. 100) that raisesMcpErroron breach (guard against a server echoing the same cursor forever). Test via the in-process harness inbackend/tests/mcp/conftest.py: a server returning two pages, assert the client returns both.Context
Found while scoping #77. The
ToolRegistry(#77) deliberately assumeslist_tools()is complete; when this lands the registry inherits correctness with zero changes.