@@ -163,7 +163,13 @@ def __init__(
163163 website_url = website_url ,
164164 icons = icons ,
165165 version = version ,
166- ** self ._create_handler_kwargs (),
166+ on_list_tools = self ._handle_list_tools ,
167+ on_call_tool = self ._handle_call_tool ,
168+ on_list_resources = self ._handle_list_resources ,
169+ on_read_resource = self ._handle_read_resource ,
170+ on_list_resource_templates = self ._handle_list_resource_templates ,
171+ on_list_prompts = self ._handle_list_prompts ,
172+ on_get_prompt = self ._handle_get_prompt ,
167173 # TODO(Marcelo): It seems there's a type mismatch between the lifespan type from an MCPServer and Server.
168174 # We need to create a Lifespan type that is a generic on the server type, like Starlette does.
169175 lifespan = (lifespan_wrapper (self , self .settings .lifespan ) if self .settings .lifespan else default_lifespan ), # type: ignore
@@ -281,81 +287,66 @@ def run(
281287 case "streamable-http" : # pragma: no cover
282288 anyio .run (lambda : self .run_streamable_http_async (** kwargs ))
283289
284- def _create_handler_kwargs (
285- self ,
286- ) -> dict [str , Callable [[ServerRequestContext [Any , Any ], Any ], Awaitable [Any ]]]:
287- """Create on_* kwargs for the lowlevel Server constructor."""
288-
289- async def handle_list_tools (ctx : Any , params : Any ) -> ListToolsResult :
290- return ListToolsResult (tools = await self .list_tools ())
291-
292- async def handle_call_tool (ctx : Any , params : Any ) -> CallToolResult :
293- try :
294- result = await self .call_tool (params .name , params .arguments or {})
295- except MCPError :
296- raise
297- except Exception as e :
298- return CallToolResult (content = [TextContent (type = "text" , text = str (e ))], is_error = True )
299- if isinstance (result , CallToolResult ):
300- return result
301- if isinstance (result , tuple ) and len (result ) == 2 :
302- unstructured_content , structured_content = result
303- return CallToolResult (
304- content = list (unstructured_content ), # type: ignore[arg-type]
305- structured_content = structured_content , # type: ignore[arg-type]
306- )
307- if isinstance (result , dict ):
308- return CallToolResult (
309- content = [TextContent (type = "text" , text = json .dumps (result , indent = 2 ))],
310- structured_content = result ,
311- )
312- return CallToolResult (content = list (result ))
313-
314- async def handle_list_resources (ctx : Any , params : Any ) -> ListResourcesResult :
315- return ListResourcesResult (resources = await self .list_resources ())
316-
317- async def handle_read_resource (ctx : Any , params : Any ) -> ReadResourceResult :
318- results = await self .read_resource (params .uri )
319- contents : list [TextResourceContents | BlobResourceContents ] = []
320- for item in results :
321- if isinstance (item .content , bytes ):
322- contents .append (
323- BlobResourceContents (
324- uri = params .uri ,
325- blob = base64 .b64encode (item .content ).decode (),
326- mime_type = item .mime_type or "application/octet-stream" ,
327- _meta = item .meta ,
328- )
290+ async def _handle_list_tools (self , ctx : Any , params : Any ) -> ListToolsResult :
291+ return ListToolsResult (tools = await self .list_tools ())
292+
293+ async def _handle_call_tool (self , ctx : Any , params : Any ) -> CallToolResult :
294+ try :
295+ result = await self .call_tool (params .name , params .arguments or {})
296+ except MCPError :
297+ raise
298+ except Exception as e :
299+ return CallToolResult (content = [TextContent (type = "text" , text = str (e ))], is_error = True )
300+ if isinstance (result , CallToolResult ):
301+ return result
302+ if isinstance (result , tuple ) and len (result ) == 2 :
303+ unstructured_content , structured_content = result
304+ return CallToolResult (
305+ content = list (unstructured_content ), # type: ignore[arg-type]
306+ structured_content = structured_content , # type: ignore[arg-type]
307+ )
308+ if isinstance (result , dict ):
309+ return CallToolResult (
310+ content = [TextContent (type = "text" , text = json .dumps (result , indent = 2 ))],
311+ structured_content = result ,
312+ )
313+ return CallToolResult (content = list (result ))
314+
315+ async def _handle_list_resources (self , ctx : Any , params : Any ) -> ListResourcesResult :
316+ return ListResourcesResult (resources = await self .list_resources ())
317+
318+ async def _handle_read_resource (self , ctx : Any , params : Any ) -> ReadResourceResult :
319+ results = await self .read_resource (params .uri )
320+ contents : list [TextResourceContents | BlobResourceContents ] = []
321+ for item in results :
322+ if isinstance (item .content , bytes ):
323+ contents .append (
324+ BlobResourceContents (
325+ uri = params .uri ,
326+ blob = base64 .b64encode (item .content ).decode (),
327+ mime_type = item .mime_type or "application/octet-stream" ,
328+ _meta = item .meta ,
329329 )
330- else :
331- contents . append (
332- TextResourceContents (
333- uri = params . uri ,
334- text = item . content ,
335- mime_type = item .mime_type or "text/plain" ,
336- _meta = item .meta ,
337- )
330+ )
331+ else :
332+ contents . append (
333+ TextResourceContents (
334+ uri = params . uri ,
335+ text = item .content ,
336+ mime_type = item .mime_type or "text/plain" ,
337+ _meta = item . meta ,
338338 )
339- return ReadResourceResult (contents = contents )
340-
341- async def handle_list_resource_templates (ctx : Any , params : Any ) -> ListResourceTemplatesResult :
342- return ListResourceTemplatesResult (resource_templates = await self .list_resource_templates ())
343-
344- async def handle_list_prompts (ctx : Any , params : Any ) -> ListPromptsResult :
345- return ListPromptsResult (prompts = await self .list_prompts ())
346-
347- async def handle_get_prompt (ctx : Any , params : Any ) -> GetPromptResult :
348- return await self .get_prompt (params .name , params .arguments )
349-
350- return {
351- "on_list_tools" : handle_list_tools ,
352- "on_call_tool" : handle_call_tool ,
353- "on_list_resources" : handle_list_resources ,
354- "on_read_resource" : handle_read_resource ,
355- "on_list_resource_templates" : handle_list_resource_templates ,
356- "on_list_prompts" : handle_list_prompts ,
357- "on_get_prompt" : handle_get_prompt ,
358- }
339+ )
340+ return ReadResourceResult (contents = contents )
341+
342+ async def _handle_list_resource_templates (self , ctx : Any , params : Any ) -> ListResourceTemplatesResult :
343+ return ListResourceTemplatesResult (resource_templates = await self .list_resource_templates ())
344+
345+ async def _handle_list_prompts (self , ctx : Any , params : Any ) -> ListPromptsResult :
346+ return ListPromptsResult (prompts = await self .list_prompts ())
347+
348+ async def _handle_get_prompt (self , ctx : Any , params : Any ) -> GetPromptResult :
349+ return await self .get_prompt (params .name , params .arguments )
359350
360351 async def list_tools (self ) -> list [MCPTool ]:
361352 """List all available tools."""
0 commit comments