mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 13:34:17 +02:00
Merge branch 'main' into image
This commit is contained in:
commit
47af422b82
3 changed files with 45 additions and 6 deletions
|
|
@ -62,6 +62,11 @@ class ResourceManager:
|
|||
logger.debug("Listing resources", extra={"count": len(self._resources)})
|
||||
return list(self._resources.values())
|
||||
|
||||
def list_templates(self) -> list[ResourceTemplate]:
|
||||
"""List all registered templates."""
|
||||
logger.debug("Listing templates", extra={"count": len(self._templates)})
|
||||
return list(self._templates.values())
|
||||
|
||||
def add_resource(self, resource: Resource) -> Resource:
|
||||
"""Add a resource to the manager.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ from mcp.server.stdio import stdio_server
|
|||
from mcp.server.sse import SseServerTransport
|
||||
from mcp.types import (
|
||||
Resource as MCPResource,
|
||||
Tool,
|
||||
Tool as MCPTool,
|
||||
ResourceTemplate as MCPResourceTemplate,
|
||||
TextContent,
|
||||
ImageContent,
|
||||
)
|
||||
|
|
@ -95,12 +96,14 @@ class FastMCP:
|
|||
self._mcp_server.call_tool()(self.call_tool)
|
||||
self._mcp_server.list_resources()(self.list_resources)
|
||||
self._mcp_server.read_resource()(self.read_resource)
|
||||
# TODO: This has not been added to MCP yet, see https://github.com/jlowin/fastmcp/issues/10
|
||||
# self._mcp_server.list_resource_templates()(self.list_resource_templates)
|
||||
|
||||
async def list_tools(self) -> list[Tool]:
|
||||
async def list_tools(self) -> list[MCPTool]:
|
||||
"""List all available tools."""
|
||||
tools = self._tool_manager.list_tools()
|
||||
return [
|
||||
Tool(
|
||||
MCPTool(
|
||||
name=info.name,
|
||||
description=info.description,
|
||||
inputSchema=info.parameters,
|
||||
|
|
@ -139,6 +142,17 @@ class FastMCP:
|
|||
for resource in resources
|
||||
]
|
||||
|
||||
async def list_resource_templates(self) -> list[MCPResourceTemplate]:
|
||||
templates = self._resource_manager.list_templates()
|
||||
return [
|
||||
MCPResourceTemplate(
|
||||
uriTemplate=template.uri_template,
|
||||
name=template.name,
|
||||
description=template.description,
|
||||
)
|
||||
for template in templates
|
||||
]
|
||||
|
||||
async def read_resource(self, uri: _BaseUrl) -> Union[str, bytes]:
|
||||
"""Read a resource by URI."""
|
||||
resource = await self._resource_manager.get_resource(uri)
|
||||
|
|
|
|||
|
|
@ -265,8 +265,11 @@ class TestServerResources:
|
|||
== base64.b64encode(b"Binary file data").decode()
|
||||
)
|
||||
|
||||
|
||||
class TestServerResourceTemplates:
|
||||
async def test_resource_with_params(self):
|
||||
"""Test that a resource with function parameters is automatically a template"""
|
||||
"""Test that a resource with function parameters raises an error if the URI
|
||||
parameters don't match"""
|
||||
mcp = FastMCP()
|
||||
|
||||
with pytest.raises(ValueError, match="Mismatch between URI parameters"):
|
||||
|
|
@ -285,6 +288,14 @@ class TestServerResources:
|
|||
def get_data() -> str:
|
||||
return "Data"
|
||||
|
||||
async def test_resource_with_untyped_params(self):
|
||||
"""Test that a resource with untyped parameters raises an error"""
|
||||
mcp = FastMCP()
|
||||
|
||||
@mcp.resource("resource://{param}")
|
||||
def get_data(param) -> str:
|
||||
return "Data"
|
||||
|
||||
async def test_resource_matching_params(self):
|
||||
"""Test that a resource with matching URI and function parameters works"""
|
||||
mcp = FastMCP()
|
||||
|
|
@ -319,7 +330,16 @@ class TestServerResources:
|
|||
result = await client.read_resource("resource://cursor/fastmcp/data")
|
||||
assert result.contents[0].text == "Data for cursor/fastmcp"
|
||||
|
||||
async def test_resource_no_params(self):
|
||||
async def test_resource_multiple_mismatched_params(self):
|
||||
"""Test that mismatched parameters raise an error"""
|
||||
mcp = FastMCP()
|
||||
|
||||
with pytest.raises(ValueError, match="Mismatch between URI parameters"):
|
||||
|
||||
@mcp.resource("resource://{org}/{repo}/data")
|
||||
def get_data(org: str, repo_2: str) -> str:
|
||||
return f"Data for {org}"
|
||||
|
||||
"""Test that a resource with no parameters works as a regular resource"""
|
||||
mcp = FastMCP()
|
||||
|
||||
|
|
@ -341,7 +361,7 @@ class TestServerResources:
|
|||
|
||||
# Should be registered as a template
|
||||
assert len(mcp._resource_manager._templates) == 1
|
||||
assert len(mcp._resource_manager.list_resources()) == 0
|
||||
assert len(await mcp.list_resources()) == 0
|
||||
|
||||
# When accessed, should create a concrete resource
|
||||
resource = await mcp._resource_manager.get_resource("resource://test/data")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue