Skip to content

Commit 1e4a286

Browse files
committed
Update @mcp.resource to use function documentation as default description if not provided
1 parent 70115b9 commit 1e4a286

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

src/mcp/server/fastmcp/resources/types.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import httpx
1212
import pydantic.json
1313
import pydantic_core
14-
from pydantic import Field, ValidationInfo
14+
from pydantic import AnyUrl, Field, ValidationInfo, validate_call
1515

1616
from mcp.server.fastmcp.resources.base import Resource
1717

@@ -71,6 +71,31 @@ async def read(self) -> str | bytes:
7171
except Exception as e:
7272
raise ValueError(f"Error reading resource {self.uri}: {e}")
7373

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+
7499

75100
class FileResource(Resource):
76101
"""A resource that reads from a file.

src/mcp/server/fastmcp/server.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ def __init__(
116116
self._mcp_server = MCPServer(
117117
name=name or "FastMCP",
118118
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+
),
122124
)
123125
self._tool_manager = ToolManager(
124126
warn_on_duplicate_tools=self.settings.warn_on_duplicate_tools
@@ -381,16 +383,16 @@ def decorator(fn: AnyFunction) -> AnyFunction:
381383
uri_template=uri,
382384
name=name,
383385
description=description,
384-
mime_type=mime_type or "text/plain",
386+
mime_type=mime_type,
385387
)
386388
else:
387389
# Register as regular resource
388-
resource = FunctionResource(
389-
uri=AnyUrl(uri),
390+
resource = FunctionResource.from_function(
391+
fn=fn,
392+
uri=uri,
390393
name=name,
391394
description=description,
392-
mime_type=mime_type or "text/plain",
393-
fn=fn,
395+
mime_type=mime_type,
394396
)
395397
self.add_resource(resource)
396398
return fn

0 commit comments

Comments
 (0)