4242
4343# after mcp imports so any import error maps to this file, not _mcp.py
4444from . import _mcp , _utils , exceptions , messages , models
45- from .exceptions import MCPServerError
4645
47- __all__ = 'MCPServer' , 'MCPServerStdio' , 'MCPServerHTTP' , 'MCPServerSSE' , 'MCPServerStreamableHTTP' , 'load_mcp_servers'
46+ __all__ = (
47+ 'MCPServer' ,
48+ 'MCPServerStdio' ,
49+ 'MCPServerHTTP' ,
50+ 'MCPServerSSE' ,
51+ 'MCPServerStreamableHTTP' ,
52+ 'load_mcp_servers' ,
53+ 'MCPError' ,
54+ )
55+
56+
57+ class MCPError (RuntimeError ):
58+ """Raised when an MCP server returns an error response.
59+
60+ This exception wraps error responses from MCP servers, following the ErrorData schema
61+ from the MCP specification.
62+ """
63+
64+ message : str
65+ """The error message."""
66+
67+ code : int
68+ """The error code returned by the server."""
69+
70+ data : Any | None
71+ """Additional information about the error, if provided by the server."""
72+
73+ def __init__ (self , message : str , code : int , data : Any | None = None ):
74+ self .message = message
75+ self .code = code
76+ self .data = data
77+ super ().__init__ (message )
78+
79+ @classmethod
80+ def from_mcp_sdk_error (cls , error : Any ) -> MCPError :
81+ """Create an MCPError from an MCP SDK McpError.
82+
83+ Args:
84+ error: An McpError from the MCP SDK.
85+
86+ Returns:
87+ A new MCPError instance with the error data.
88+ """
89+ # Extract error data from the McpError.error attribute
90+ error_data = error .error
91+ return cls (message = error_data .message , code = error_data .code , data = error_data .data )
92+
93+ def __str__ (self ) -> str :
94+ if self .data :
95+ return f'{ self .message } (code: { self .code } , data: { self .data } )'
96+ return f'{ self .message } (code: { self .code } )'
97+
4898
4999TOOL_SCHEMA_VALIDATOR = pydantic_core .SchemaValidator (
50100 schema = pydantic_core .core_schema .dict_schema (
@@ -322,30 +372,30 @@ async def list_resources(self) -> list[_mcp.Resource]:
322372 - We also don't subscribe to resource changes to avoid complexity.
323373
324374 Raises:
325- MCPServerError : If the server returns an error.
375+ MCPError : If the server returns an error.
326376 """
327377 async with self : # Ensure server is running
328378 if not self .capabilities .resources :
329379 return []
330380 try :
331381 result = await self ._client .list_resources ()
332382 except mcp_exceptions .McpError as e :
333- raise MCPServerError .from_mcp_sdk_error (e ) from e
383+ raise MCPError .from_mcp_sdk_error (e ) from e
334384 return [_mcp .map_from_mcp_resource (r ) for r in result .resources ]
335385
336386 async def list_resource_templates (self ) -> list [_mcp .ResourceTemplate ]:
337387 """Retrieve resource templates that are currently present on the server.
338388
339389 Raises:
340- MCPServerError : If the server returns an error.
390+ MCPError : If the server returns an error.
341391 """
342392 async with self : # Ensure server is running
343393 if not self .capabilities .resources :
344394 return []
345395 try :
346396 result = await self ._client .list_resource_templates ()
347397 except mcp_exceptions .McpError as e :
348- raise MCPServerError .from_mcp_sdk_error (e ) from e
398+ raise MCPError .from_mcp_sdk_error (e ) from e
349399 return [_mcp .map_from_mcp_resource_template (t ) for t in result .resourceTemplates ]
350400
351401 @overload
@@ -372,7 +422,7 @@ async def read_resource(
372422 Returns `None` if the server does not support resources or the resource is not found.
373423
374424 Raises:
375- MCPServerError : If the server returns an error other than resource not found.
425+ MCPError : If the server returns an error other than resource not found.
376426 """
377427 resource_uri = uri if isinstance (uri , str ) else uri .uri
378428 async with self : # Ensure server is running
@@ -384,7 +434,7 @@ async def read_resource(
384434 # As per https://modelcontextprotocol.io/specification/2025-06-18/server/resources#error-handling
385435 if e .error .code == - 32002 :
386436 return None
387- raise MCPServerError .from_mcp_sdk_error (e ) from e
437+ raise MCPError .from_mcp_sdk_error (e ) from e
388438
389439 if not result .contents :
390440 return None
0 commit comments