22
33from __future__ import annotations
44
5+ from collections .abc import AsyncIterator
56from contextlib import AsyncExitStack
67from dataclasses import KW_ONLY , dataclass , field
78from typing import Any
2627 ListToolsResult ,
2728 LoggingLevel ,
2829 PaginatedRequestParams ,
30+ Prompt ,
2931 PromptReference ,
3032 ReadResourceResult ,
3133 RequestParamsMeta ,
34+ Resource ,
35+ ResourceTemplate ,
3236 ResourceTemplateReference ,
37+ Tool ,
3338)
3439
3540
@@ -195,7 +200,11 @@ async def list_resources(
195200 cursor : str | None = None ,
196201 meta : RequestParamsMeta | None = None ,
197202 ) -> ListResourcesResult :
198- """List available resources from the server."""
203+ """List a single page of available resources from the server.
204+
205+ Returns one page only. The result may include a `next_cursor` if more
206+ pages are available. Use `list_all_resources` to drain every page.
207+ """
199208 return await self .session .list_resources (params = PaginatedRequestParams (cursor = cursor , _meta = meta ))
200209
201210 async def list_resource_templates (
@@ -204,7 +213,12 @@ async def list_resource_templates(
204213 cursor : str | None = None ,
205214 meta : RequestParamsMeta | None = None ,
206215 ) -> ListResourceTemplatesResult :
207- """List available resource templates from the server."""
216+ """List a single page of available resource templates from the server.
217+
218+ Returns one page only. The result may include a `next_cursor` if more
219+ pages are available. Use `list_all_resource_templates` to drain every
220+ page.
221+ """
208222 return await self .session .list_resource_templates (params = PaginatedRequestParams (cursor = cursor , _meta = meta ))
209223
210224 async def read_resource (self , uri : str , * , meta : RequestParamsMeta | None = None ) -> ReadResourceResult :
@@ -262,7 +276,11 @@ async def list_prompts(
262276 cursor : str | None = None ,
263277 meta : RequestParamsMeta | None = None ,
264278 ) -> ListPromptsResult :
265- """List available prompts from the server."""
279+ """List a single page of available prompts from the server.
280+
281+ Returns one page only. The result may include a `next_cursor` if more
282+ pages are available. Use `list_all_prompts` to drain every page.
283+ """
266284 return await self .session .list_prompts (params = PaginatedRequestParams (cursor = cursor , _meta = meta ))
267285
268286 async def get_prompt (
@@ -299,9 +317,84 @@ async def complete(
299317 return await self .session .complete (ref = ref , argument = argument , context_arguments = context_arguments )
300318
301319 async def list_tools (self , * , cursor : str | None = None , meta : RequestParamsMeta | None = None ) -> ListToolsResult :
302- """List available tools from the server."""
320+ """List a single page of available tools from the server.
321+
322+ Returns one page only. The result may include a `next_cursor` if more
323+ pages are available. Use `list_all_tools` to drain every page.
324+ """
303325 return await self .session .list_tools (params = PaginatedRequestParams (cursor = cursor , _meta = meta ))
304326
327+ async def iter_all_tools (self , * , meta : RequestParamsMeta | None = None ) -> AsyncIterator [Tool ]:
328+ """Yield every tool from the server, paging through `next_cursor`.
329+
330+ Useful for streaming consumers that want to process tools without
331+ materializing the full list in memory.
332+ """
333+ cursor : str | None = None
334+ while True :
335+ result = await self .list_tools (cursor = cursor , meta = meta )
336+ for tool in result .tools :
337+ yield tool
338+ if result .next_cursor is None :
339+ return
340+ cursor = result .next_cursor
341+
342+ async def list_all_tools (self , * , meta : RequestParamsMeta | None = None ) -> list [Tool ]:
343+ """List every tool from the server, draining `next_cursor` across pages.
344+
345+ Unlike `list_tools`, which returns one page, this walks pagination
346+ until the server reports no further pages and returns the combined
347+ list.
348+ """
349+ return [tool async for tool in self .iter_all_tools (meta = meta )]
350+
351+ async def iter_all_prompts (self , * , meta : RequestParamsMeta | None = None ) -> AsyncIterator [Prompt ]:
352+ """Yield every prompt from the server, paging through `next_cursor`."""
353+ cursor : str | None = None
354+ while True :
355+ result = await self .list_prompts (cursor = cursor , meta = meta )
356+ for prompt in result .prompts :
357+ yield prompt
358+ if result .next_cursor is None :
359+ return
360+ cursor = result .next_cursor
361+
362+ async def list_all_prompts (self , * , meta : RequestParamsMeta | None = None ) -> list [Prompt ]:
363+ """List every prompt from the server, draining `next_cursor` across pages."""
364+ return [prompt async for prompt in self .iter_all_prompts (meta = meta )]
365+
366+ async def iter_all_resources (self , * , meta : RequestParamsMeta | None = None ) -> AsyncIterator [Resource ]:
367+ """Yield every resource from the server, paging through `next_cursor`."""
368+ cursor : str | None = None
369+ while True :
370+ result = await self .list_resources (cursor = cursor , meta = meta )
371+ for resource in result .resources :
372+ yield resource
373+ if result .next_cursor is None :
374+ return
375+ cursor = result .next_cursor
376+
377+ async def list_all_resources (self , * , meta : RequestParamsMeta | None = None ) -> list [Resource ]:
378+ """List every resource from the server, draining `next_cursor` across pages."""
379+ return [resource async for resource in self .iter_all_resources (meta = meta )]
380+
381+ async def iter_all_resource_templates (
382+ self , * , meta : RequestParamsMeta | None = None
383+ ) -> AsyncIterator [ResourceTemplate ]:
384+ """Yield every resource template from the server, paging through `next_cursor`."""
385+ cursor : str | None = None
386+ while True :
387+ result = await self .list_resource_templates (cursor = cursor , meta = meta )
388+ for template in result .resource_templates :
389+ yield template
390+ if result .next_cursor is None :
391+ return
392+ cursor = result .next_cursor
393+
394+ async def list_all_resource_templates (self , * , meta : RequestParamsMeta | None = None ) -> list [ResourceTemplate ]:
395+ """List every resource template from the server, draining `next_cursor` across pages."""
396+ return [template async for template in self .iter_all_resource_templates (meta = meta )]
397+
305398 async def send_roots_list_changed (self ) -> None :
306399 """Send a notification that the roots list has changed."""
307400 # TODO(Marcelo): Currently, there is no way for the server to handle this. We should add support.
0 commit comments