Skip to content

Commit 1e5776f

Browse files
strawgategithub-actions[bot]jlowin
authored
Add list_resources, list_prompts, and get_prompt methods to Context (#2249)
* Add list_resources, list_prompts, and get_prompt methods to Context - Add Context.list_resources() to list all available resources - Add Context.list_prompts() to list all available prompts - Add Context.get_prompt() to get a specific prompt with arguments - Update ToolInjectionMiddleware to use new Context methods instead of creating temporary Client instances - Remove unused Client and FastMCPTransport imports from tool_injection.py This improves API consistency by allowing middleware/tools to use Context methods directly without needing to create temporary Client instances. Fixes #2245 Co-authored-by: William Easton <[email protected]> * Update docs --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: William Easton <[email protected]> Co-authored-by: Jeremiah Lowin <[email protected]>
1 parent 2f13119 commit 1e5776f

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

docs/servers/context.mdx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ The `Context` object provides a clean interface to access MCP features within yo
1414

1515
- **Logging**: Send debug, info, warning, and error messages back to the client
1616
- **Progress Reporting**: Update the client on the progress of long-running operations
17-
- **Resource Access**: Read data from resources registered with the server
17+
- **Resource Access**: List and read data from resources registered with the server
18+
- **Prompt Access**: List and retrieve prompts registered with the server
1819
- **LLM Sampling**: Request the client's LLM to generate text based on provided messages
1920
- **User Elicitation**: Request structured input from users during tool execution
2021
- **State Management**: Store and share data between middleware and the handler within a single request
@@ -177,16 +178,40 @@ See [Progress Reporting](/servers/progress) for detailed patterns and examples.
177178

178179
### Resource Access
179180

180-
Read data from resources registered with your FastMCP server, allowing access to files, configuration, or dynamic content.
181+
List and read data from resources registered with your FastMCP server, allowing access to files, configuration, or dynamic content.
181182

182183
```python
184+
# List available resources
185+
resources = await ctx.list_resources()
186+
187+
# Read a specific resource
183188
content_list = await ctx.read_resource("resource://config")
184189
content = content_list[0].content
185190
```
186191

187-
**Method signature:**
192+
**Method signatures:**
193+
- **`ctx.list_resources() -> list[MCPResource]`**: <VersionBadge version="2.13.0" /> Returns list of all available resources
188194
- **`ctx.read_resource(uri: str | AnyUrl) -> list[ReadResourceContents]`**: Returns a list of resource content parts
189195

196+
### Prompt Access
197+
198+
<VersionBadge version="2.13.0" />
199+
200+
List and retrieve prompts registered with your FastMCP server, allowing tools and middleware to discover and use available prompts programmatically.
201+
202+
```python
203+
# List available prompts
204+
prompts = await ctx.list_prompts()
205+
206+
# Get a specific prompt with arguments
207+
result = await ctx.get_prompt("analyze_data", {"dataset": "users"})
208+
messages = result.messages
209+
```
210+
211+
**Method signatures:**
212+
- **`ctx.list_prompts() -> list[MCPPrompt]`**: Returns list of all available prompts
213+
- **`ctx.get_prompt(name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult`**: Get a specific prompt with optional arguments
214+
190215
### State Management
191216

192217
<VersionBadge version="2.11.0" />

src/fastmcp/server/context.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
AudioContent,
2323
ClientCapabilities,
2424
CreateMessageResult,
25+
GetPromptResult,
2526
ImageContent,
2627
IncludeContext,
2728
ModelHint,
@@ -32,6 +33,8 @@
3233
TextContent,
3334
)
3435
from mcp.types import CreateMessageRequestParams as SamplingParams
36+
from mcp.types import Prompt as MCPPrompt
37+
from mcp.types import Resource as MCPResource
3538
from pydantic.networks import AnyUrl
3639
from starlette.requests import Request
3740
from typing_extensions import TypeVar
@@ -215,6 +218,42 @@ async def report_progress(
215218
related_request_id=self.request_id,
216219
)
217220

221+
async def list_resources(self) -> list[MCPResource]:
222+
"""List all available resources from the server.
223+
224+
Returns:
225+
List of Resource objects available on the server
226+
"""
227+
if self.fastmcp is None:
228+
raise ValueError("Context is not available outside of a request")
229+
return await self.fastmcp._list_resources_mcp()
230+
231+
async def list_prompts(self) -> list[MCPPrompt]:
232+
"""List all available prompts from the server.
233+
234+
Returns:
235+
List of Prompt objects available on the server
236+
"""
237+
if self.fastmcp is None:
238+
raise ValueError("Context is not available outside of a request")
239+
return await self.fastmcp._list_prompts_mcp()
240+
241+
async def get_prompt(
242+
self, name: str, arguments: dict[str, Any] | None = None
243+
) -> GetPromptResult:
244+
"""Get a prompt by name with optional arguments.
245+
246+
Args:
247+
name: The name of the prompt to get
248+
arguments: Optional arguments to pass to the prompt
249+
250+
Returns:
251+
The prompt result
252+
"""
253+
if self.fastmcp is None:
254+
raise ValueError("Context is not available outside of a request")
255+
return await self.fastmcp._get_prompt_mcp(name, arguments)
256+
218257
async def read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents]:
219258
"""Read a resource by URI.
220259

src/fastmcp/server/middleware/tool_injection.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from pydantic import AnyUrl
1111
from typing_extensions import override
1212

13-
from fastmcp.client.client import Client
14-
from fastmcp.client.transports import FastMCPTransport
1513
from fastmcp.server.context import Context
1614
from fastmcp.server.middleware.middleware import CallNext, Middleware, MiddlewareContext
1715
from fastmcp.tools.tool import Tool, ToolResult
@@ -55,9 +53,7 @@ async def on_call_tool(
5553

5654
async def list_prompts(context: Context) -> list[Prompt]:
5755
"""List prompts available on the server."""
58-
59-
async with Client[FastMCPTransport](context.fastmcp) as client:
60-
return await client.list_prompts()
56+
return await context.list_prompts()
6157

6258

6359
list_prompts_tool = Tool.from_function(
@@ -73,9 +69,7 @@ async def get_prompt(
7369
] = None,
7470
) -> mcp.types.GetPromptResult:
7571
"""Render a prompt available on the server."""
76-
77-
async with Client[FastMCPTransport](context.fastmcp) as client:
78-
return await client.get_prompt(name=name, arguments=arguments)
72+
return await context.get_prompt(name=name, arguments=arguments)
7973

8074

8175
get_prompt_tool = Tool.from_function(
@@ -93,9 +87,7 @@ def __init__(self) -> None:
9387

9488
async def list_resources(context: Context) -> list[mcp.types.Resource]:
9589
"""List resources available on the server."""
96-
97-
async with Client[FastMCPTransport](context.fastmcp) as client:
98-
return await client.list_resources()
90+
return await context.list_resources()
9991

10092

10193
list_resources_tool = Tool.from_function(

0 commit comments

Comments
 (0)