@@ -44,7 +44,7 @@ Instead, register a template with placeholders:
4444
4545``` python
4646@mcp.resource (" tickets://{ticket_id} " )
47- def get_ticket (ticket_id : str ) -> dict :
47+ def get_ticket (ticket_id : str ) -> dict[ str , str ] :
4848 ticket = helpdesk.find(ticket_id)
4949 return {" id" : ticket_id, " subject" : ticket.subject, " status" : ticket.status}
5050```
@@ -61,7 +61,7 @@ type and the SDK will convert:
6161
6262``` python
6363@mcp.resource (" orders://{order_id} " )
64- def get_order (order_id : int ) -> dict :
64+ def get_order (order_id : int ) -> dict[ str , Any] :
6565 # "12345" from the URI becomes the int 12345
6666 return db.orders.get(order_id)
6767```
@@ -107,7 +107,7 @@ string with slashes, use `{/name*}`:
107107
108108``` python
109109@mcp.resource (" tree://nodes{/path*}" )
110- def walk_tree (path : list[str ]) -> dict :
110+ def walk_tree (path : list[str ]) -> dict[ str , Any] :
111111 # tree://nodes/a/b/c gives path = ["a", "b", "c"]
112112 node = root
113113 for segment in path:
@@ -243,25 +243,31 @@ For fixed URIs, keep a registry and dispatch on exact match:
243243from mcp.server.lowlevel import Server
244244from mcp.types import (
245245 ListResourcesResult,
246+ PaginatedRequestParams,
246247 ReadResourceRequestParams,
247248 ReadResourceResult,
248249 Resource,
249250 TextResourceContents,
250251)
252+ from mcp.server.context import ServerRequestContext
251253
252254RESOURCES = {
253255 " config://features" : lambda : ' {"beta_search": true}' ,
254256 " status://health" : lambda : check_health(),
255257}
256258
257259
258- async def on_list_resources (ctx , params ) -> ListResourcesResult:
260+ async def on_list_resources (
261+ ctx : ServerRequestContext[Any], params : PaginatedRequestParams | None
262+ ) -> ListResourcesResult:
259263 return ListResourcesResult(
260264 resources = [Resource(name = uri, uri = uri) for uri in RESOURCES ]
261265 )
262266
263267
264- async def on_read_resource (ctx , params : ReadResourceRequestParams) -> ReadResourceResult:
268+ async def on_read_resource (
269+ ctx : ServerRequestContext[Any], params : ReadResourceRequestParams
270+ ) -> ReadResourceResult:
265271 if (producer := RESOURCES .get(params.uri)) is not None :
266272 return ReadResourceResult(
267273 contents = [TextResourceContents(uri = params.uri, text = producer())]
@@ -292,6 +298,7 @@ Parse your templates once, then match incoming URIs against them in
292298your read handler:
293299
294300``` python
301+ from mcp.server.context import ServerRequestContext
295302from mcp.server.lowlevel import Server
296303from mcp.shared.uri_template import UriTemplate
297304from mcp.types import ReadResourceRequestParams, ReadResourceResult, TextResourceContents
@@ -302,7 +309,9 @@ TEMPLATES = {
302309}
303310
304311
305- async def on_read_resource (ctx , params : ReadResourceRequestParams) -> ReadResourceResult:
312+ async def on_read_resource (
313+ ctx : ServerRequestContext[Any], params : ReadResourceRequestParams
314+ ) -> ReadResourceResult:
306315 if (vars := TEMPLATES [" files" ].match(params.uri)) is not None :
307316 content = read_file_safely(vars [" path" ])
308317 return ReadResourceResult(contents = [TextResourceContents(uri = params.uri, text = content)])
@@ -353,10 +362,12 @@ the protocol `ResourceTemplate` type, using the same template strings
353362you parsed above:
354363
355364``` python
356- from mcp.types import ListResourceTemplatesResult, ResourceTemplate
365+ from mcp.types import ListResourceTemplatesResult, PaginatedRequestParams, ResourceTemplate
357366
358367
359- async def on_list_resource_templates (ctx , params ) -> ListResourceTemplatesResult:
368+ async def on_list_resource_templates (
369+ ctx : ServerRequestContext[Any], params : PaginatedRequestParams | None
370+ ) -> ListResourceTemplatesResult:
360371 return ListResourceTemplatesResult(
361372 resource_templates = [
362373 ResourceTemplate(name = " files" , uri_template = str (TEMPLATES [" files" ])),
0 commit comments