File tree Expand file tree Collapse file tree 2 files changed +36
-9
lines changed
Filter options
Expand file tree Collapse file tree 2 files changed +36
-9
lines changed
Original file line number Diff line number Diff line change 11
11
import httpx
12
12
import pydantic.json
13
13
import pydantic_core
14
- from pydantic import Field, ValidationInfo
14
+ from pydantic import AnyUrl, Field, ValidationInfo, validate_call
15
15
16
16
from mcp.server.fastmcp.resources.base import Resource
17
17
@@ -71,6 +71,31 @@ async def read(self) -> str | bytes:
71
71
except Exception as e:
72
72
raise ValueError(f"Error reading resource {self.uri}: {e}")
73
73
74
+ @classmethod
75
+ def from_function(
76
+ cls,
77
+ fn: Callable[..., Any],
78
+ uri: str,
79
+ name: str | None = None,
80
+ description: str | None = None,
81
+ mime_type: str | None = None,
82
+ ):
83
+ """Create a template from a function."""
84
+ func_name = name or fn.__name__
85
+ if func_name == "<lambda>":
86
+ raise ValueError("You must provide a name for lambda functions")
87
+
88
+ # ensure the arguments are properly cast
89
+ fn = validate_call(fn)
90
+
91
+ return cls(
92
+ uri=AnyUrl(uri),
93
+ name=name,
94
+ description=description or fn.__doc__ or "",
95
+ mime_type=mime_type or "text/plain",
96
+ fn=fn,
97
+ )
98
+
74
99
75
100
class FileResource(Resource):
76
101
"""A resource that reads from a file.
Original file line number Diff line number Diff line change @@ -116,9 +116,11 @@ def __init__(
116
116
self._mcp_server = MCPServer(
117
117
name=name or "FastMCP",
118
118
instructions=instructions,
119
- lifespan=lifespan_wrapper(self, self.settings.lifespan)
120
- if self.settings.lifespan
121
- else default_lifespan,
119
+ lifespan=(
120
+ lifespan_wrapper(self, self.settings.lifespan)
121
+ if self.settings.lifespan
122
+ else default_lifespan
123
+ ),
122
124
)
123
125
self._tool_manager = ToolManager(
124
126
warn_on_duplicate_tools=self.settings.warn_on_duplicate_tools
@@ -381,16 +383,16 @@ def decorator(fn: AnyFunction) -> AnyFunction:
381
383
uri_template=uri,
382
384
name=name,
383
385
description=description,
384
- mime_type=mime_type or "text/plain" ,
386
+ mime_type=mime_type,
385
387
)
386
388
else:
387
389
# Register as regular resource
388
- resource = FunctionResource(
389
- uri=AnyUrl(uri),
390
+ resource = FunctionResource.from_function(
391
+ fn=fn,
392
+ uri=uri,
390
393
name=name,
391
394
description=description,
392
- mime_type=mime_type or "text/plain",
393
- fn=fn,
395
+ mime_type=mime_type,
394
396
)
395
397
self.add_resource(resource)
396
398
return fn
You can’t perform that action at this time.
0 commit comments