Back to Python Sdk

pagination

examples/stories/pagination/README.md

2.0.0b12.2 KB
Original Source

pagination

Walk a paginated resources/list by hand: feed each result's next_cursor back into list_resources(cursor=...) until it is None. The cursor is an opaque server-chosen string — never parse it, and never terminate on a falsy check (an empty string is a valid cursor under the spec).

Run it

bash
# stdio (default — the client spawns the server as a subprocess)
uv run python -m stories.pagination.client --server server_lowlevel

# HTTP — the client self-hosts the server on a free port, runs, then tears it down
uv run python -m stories.pagination.client --http --server server_lowlevel

Drop --server server_lowlevel (on either transport) to run against the MCPServer variant (single page).

What to look at

  • client.py mainasync with Client(target, mode=mode) as client: is the whole connection. The story owns the construction; target is whatever Client() accepts (an in-process server, a transport, or an HTTP URL) and the entry point picks it.
  • client.pyif page.next_cursor is None: break. Termination is key-absent, not falsy; while cursor: would be a spec bug.
  • server_lowlevel.py — the handler owns the cursor encoding (here: an integer offset as a string) and rejects an unrecognised cursor with -32602 Invalid params, the spec-recommended response.
  • server.pyMCPServer's decorator-registered resources are returned in a single page; the inbound cursor is accepted but ignored. The same client loop still terminates correctly after one request.

Caveats

  • No iter_*() helperClient has no iter_resources() / iter_tools() async-iterator yet; the manual while True loop shown here is the supported pattern.
  • MCPServer is single-pageMCPServer ignores cursor and never sets next_cursor. Whether it grows a page_size= knob or stays single-page by design is open; use the lowlevel server when you need to emit pages today.

Spec

Pagination — server utilities

See also

resources/, tools/, prompts/ — every */list method paginates the same way. Reference test: tests/interaction/lowlevel/test_pagination.py.