1313from mcp .server .fastmcp .resources .types import FunctionResource , Resource
1414from mcp .server .fastmcp .utilities .context_injection import find_context_parameter , inject_context
1515from mcp .server .fastmcp .utilities .convertors import CONVERTOR_TYPES , Convertor
16- from mcp .server .fastmcp .utilities .func_metadata import (
17- use_defaults_on_optional_validation_error ,func_metadata
18- )
16+ from mcp .server .fastmcp .utilities .func_metadata import func_metadata , use_defaults_on_optional_validation_error
1917from mcp .types import Annotations , Icon
2018
2119if TYPE_CHECKING :
2422 from mcp .shared .context import LifespanContextT , RequestT
2523
2624
27-
2825class ResourceTemplate (BaseModel ):
2926 """A template for dynamically creating resources."""
3027
@@ -105,7 +102,7 @@ def from_function(
105102 # Validate path parameters match required function parameters
106103 if path_params != required_params :
107104 raise ValueError (
108- f"Mismatch between URI path parameters { path_params } and required function parameters { required_params } with context parameters { context_kwarg } "
105+ f"Mismatch between URI path parameters { path_params } and required function parameters { required_params } "
109106 )
110107
111108 # Validate query parameters are a subset of optional function parameters
@@ -129,7 +126,6 @@ def from_function(
129126 optional_params = optional_params ,
130127 context_kwarg = context_kwarg ,
131128 )
132-
133129
134130 def _generate_pattern (self ) -> tuple [re .Pattern [str ], dict [str , Convertor [Any ]]]:
135131 """Compile the URI template into a regex pattern and associated converters."""
@@ -159,7 +155,7 @@ def _generate_pattern(self) -> tuple[re.Pattern[str], dict[str, Convertor[Any]]]
159155 pattern_parts .append (re .escape (part ))
160156
161157 return re .compile ("^" + "/" .join (pattern_parts ) + "$" ), converters
162-
158+
163159 @staticmethod
164160 def _analyze_function_params (fn : Callable [..., Any ]) -> tuple [set [str ], set [str ]]:
165161 """Analyze function signature to extract required and optional parameters.
@@ -185,7 +181,6 @@ def matches(self, uri: str) -> dict[str, Any] | None:
185181 if not self ._compiled_pattern or not self ._convertors :
186182 self ._compiled_pattern , self ._convertors = self ._generate_pattern ()
187183
188-
189184 # Split URI into path and query parts
190185 if "?" in uri :
191186 path , query = uri .split ("?" , 1 )
@@ -220,7 +215,7 @@ async def create_resource(
220215 self ,
221216 uri : str ,
222217 params : dict [str , Any ],
223- context : Context [ServerSessionT , LifespanContextT , RequestT ] | None = None , # type: ignore
218+ context : Context [ServerSessionT , LifespanContextT , RequestT ] | None = None , # type: ignore
224219 ) -> Resource :
225220 """Create a resource from the template with the given parameters."""
226221 try :
@@ -233,14 +228,14 @@ async def create_resource(
233228 if name in self .required_params or name in self .optional_params
234229 }
235230 # Add context to params
236- fn_params = inject_context (self .fn , fn_params , context , self .context_kwarg ) # type: ignore
231+ fn_params = inject_context (self .fn , fn_params , context , self .context_kwarg ) # type: ignore
237232 # self.fn is now multiply-decorated:
238233 # 1. validate_call for coercion/validation
239234 # 2. our new decorator for default fallback on optional param validation err
240235 result = self .fn (** fn_params )
241236 if inspect .iscoroutine (result ):
242237 result = await result
243-
238+
244239 return FunctionResource (
245240 uri = uri , # type: ignore
246241 name = self .name ,
0 commit comments