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 <strawgate@users.noreply.github.com>
This commit is contained in:
claude[bot] 2025-10-24 22:34:45 +00:00
commit 63add18970
2 changed files with 42 additions and 11 deletions

View file

@ -22,6 +22,7 @@ from mcp.types import (
AudioContent,
ClientCapabilities,
CreateMessageResult,
GetPromptResult,
ImageContent,
IncludeContext,
ModelHint,
@ -32,6 +33,8 @@ from mcp.types import (
TextContent,
)
from mcp.types import CreateMessageRequestParams as SamplingParams
from mcp.types import Prompt as MCPPrompt
from mcp.types import Resource as MCPResource
from pydantic.networks import AnyUrl
from starlette.requests import Request
from typing_extensions import TypeVar
@ -215,6 +218,42 @@ class Context:
related_request_id=self.request_id,
)
async def list_resources(self) -> list[MCPResource]:
"""List all available resources from the server.
Returns:
List of Resource objects available on the server
"""
if self.fastmcp is None:
raise ValueError("Context is not available outside of a request")
return await self.fastmcp._list_resources_mcp()
async def list_prompts(self) -> list[MCPPrompt]:
"""List all available prompts from the server.
Returns:
List of Prompt objects available on the server
"""
if self.fastmcp is None:
raise ValueError("Context is not available outside of a request")
return await self.fastmcp._list_prompts_mcp()
async def get_prompt(
self, name: str, arguments: dict[str, Any] | None = None
) -> GetPromptResult:
"""Get a prompt by name with optional arguments.
Args:
name: The name of the prompt to get
arguments: Optional arguments to pass to the prompt
Returns:
The prompt result
"""
if self.fastmcp is None:
raise ValueError("Context is not available outside of a request")
return await self.fastmcp._get_prompt_mcp(name, arguments)
async def read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents]:
"""Read a resource by URI.

View file

@ -10,8 +10,6 @@ from mcp.types import Prompt
from pydantic import AnyUrl
from typing_extensions import override
from fastmcp.client.client import Client
from fastmcp.client.transports import FastMCPTransport
from fastmcp.server.context import Context
from fastmcp.server.middleware.middleware import CallNext, Middleware, MiddlewareContext
from fastmcp.tools.tool import Tool, ToolResult
@ -55,9 +53,7 @@ class ToolInjectionMiddleware(Middleware):
async def list_prompts(context: Context) -> list[Prompt]:
"""List prompts available on the server."""
async with Client[FastMCPTransport](context.fastmcp) as client:
return await client.list_prompts()
return await context.list_prompts()
list_prompts_tool = Tool.from_function(
@ -73,9 +69,7 @@ async def get_prompt(
] = None,
) -> mcp.types.GetPromptResult:
"""Render a prompt available on the server."""
async with Client[FastMCPTransport](context.fastmcp) as client:
return await client.get_prompt(name=name, arguments=arguments)
return await context.get_prompt(name=name, arguments=arguments)
get_prompt_tool = Tool.from_function(
@ -93,9 +87,7 @@ class PromptToolMiddleware(ToolInjectionMiddleware):
async def list_resources(context: Context) -> list[mcp.types.Resource]:
"""List resources available on the server."""
async with Client[FastMCPTransport](context.fastmcp) as client:
return await client.list_resources()
return await context.list_resources()
list_resources_tool = Tool.from_function(