# MCPTools now discovers every page of tools from a ClientSession

> Agno's MCPTools now follows tools/list pagination on a caller-supplied ClientSession and registers the tools from every page, where it used to stop after the first page.

- Published: 2026-09-23
- Author: XilongZhu
- Categories: Changelog
- Canonical: https://www.agno.com/articles/mcptools-now-discovers-every-page-of-tools-from-a-clientsession
- Markdown: https://www.agno.com/articles/mcptools-now-discovers-every-page-of-tools-from-a-clientsession.md

MCP servers can split their tool list into pages and hand back a `next_cursor` for the next one, and Agno's `MCPTools` now follows that cursor on a `ClientSession` you pass in. Before, any tool on a later page never reached your agent, and a tool named in `include_tools` that lived on page two failed validation.

This run uses an in-process FastMCP server that lists one tool per page:

```python
from fastmcp import Client, FastMCP
from agno.tools.mcp import MCPTools

server = FastMCP("docs", list_page_size=1)

@server.tool
def search_docs(query: str) -> str:
    return "results"

@server.tool
def read_page(path: str) -> str:
    return "page"

async with Client(server) as client:
    tools = MCPTools(session=client.session)
    await tools.build_tools()
    print(list(tools.functions))
```

```text
Before: ['search_docs']
        include_tools=['read_page'] -> ValueError: Included tool(s) not present in the toolkit: read_page
Now:    ['search_docs', 'read_page']
        include_tools=['read_page'] -> ['read_page']
```

`MCPTools` now requests pages until the server returns no `next_cursor`, and it checks `include_tools` and `exclude_tools` only after it has every page. The cursor is opaque, so an empty or repeated cursor still leads to another request. Discovery stops at 250 pages, the same default budget as the FastMCP `Client`, and raises a `RuntimeError` at that limit so a partial catalog never registers. If a later page fails or discovery gets cancelled, the toolkit keeps the functions it already had.

Connections that `MCPTools` opens itself go through the FastMCP `Client`, which returns the complete list in one call, so that path works as before.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/91_tools/mcp_tools.py), and learn more about [MCPTools configuration](https://docs.agno.com/tools/mcp/overview#mcptools-configuration) in the documentation.
