refactor: McpError renamed to MCPError and flatten parameters (#1956)

Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
This commit is contained in:
Marcelo Trylesinski 2026-01-26 14:37:44 +01:00 • committed by GitHub
commit acba5478a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 253 additions and 326 deletions

View file

@ -2,7 +2,7 @@
import pytest
from mcp.shared.exceptions import McpError, UrlElicitationRequiredError
from mcp.shared.exceptions import MCPError, UrlElicitationRequiredError
from mcp.types import URL_ELICITATION_REQUIRED, ElicitRequestURLParams, ErrorData
@ -137,7 +137,7 @@ def test_url_elicitation_required_error_data_contains_elicitations() -> None:
def test_url_elicitation_required_error_inherits_from_mcp_error() -> None:
"""Test that UrlElicitationRequiredError inherits from McpError."""
"""Test that UrlElicitationRequiredError inherits from MCPError."""
elicitation = ElicitRequestURLParams(
mode="url",
message="Auth required",
@ -146,7 +146,7 @@ def test_url_elicitation_required_error_inherits_from_mcp_error() -> None:
)
error = UrlElicitationRequiredError([elicitation])
assert isinstance(error, McpError)
assert isinstance(error, MCPError)
assert isinstance(error, Exception)

View file

@ -7,7 +7,7 @@ import mcp.types as types
from mcp import Client
from mcp.client.session import ClientSession
from mcp.server.lowlevel.server import Server
from mcp.shared.exceptions import McpError
from mcp.shared.exceptions import MCPError
from mcp.shared.memory import create_client_server_memory_streams
from mcp.shared.message import SessionMessage
from mcp.types import (
@ -77,7 +77,7 @@ async def test_request_cancellation():
types.CallToolResult,
)
pytest.fail("Request should have been cancelled") # pragma: no cover
except McpError as e:
except MCPError as e:
# Expected - request was cancelled
assert "Request cancelled" in str(e)
ev_cancelled.set()
@ -164,7 +164,7 @@ async def test_error_response_id_type_mismatch_string_to_int():
but the client sent "id": 0 (integer).
"""
ev_error_received = anyio.Event()
error_holder: list[McpError] = []
error_holder: list[MCPError | Exception] = []
async with create_client_server_memory_streams() as (client_streams, server_streams):
client_read, client_write = client_streams
@ -191,8 +191,8 @@ async def test_error_response_id_type_mismatch_string_to_int():
nonlocal error_holder
try:
await client_session.send_ping()
pytest.fail("Expected McpError to be raised") # pragma: no cover
except McpError as e:
pytest.fail("Expected MCPError to be raised") # pragma: no cover
except MCPError as e:
error_holder.append(e)
ev_error_received.set()
@ -246,7 +246,7 @@ async def test_response_id_non_numeric_string_no_match():
request_read_timeout_seconds=0.5,
)
pytest.fail("Expected timeout") # pragma: no cover
except McpError as e:
except MCPError as e:
assert "Timed out" in str(e)
ev_timeout.set()
@ -279,7 +279,7 @@ async def test_connection_closed():
# any request will do
await client_session.initialize()
pytest.fail("Request should have errored") # pragma: no cover
except McpError as e:
except MCPError as e:
# Expected - request errored
assert "Connection closed" in str(e)
ev_response.set()

View file

@ -25,10 +25,9 @@ from mcp.client.sse import _extract_session_id_from_endpoint, sse_client
from mcp.server import Server
from mcp.server.sse import SseServerTransport
from mcp.server.transport_security import TransportSecuritySettings
from mcp.shared.exceptions import McpError
from mcp.shared.exceptions import MCPError
from mcp.types import (
EmptyResult,
ErrorData,
Implementation,
InitializeResult,
JSONRPCResponse,
@ -70,7 +69,7 @@ class ServerTest(Server): # pragma: no cover
await anyio.sleep(2.0)
return f"Slow response from {parsed.netloc}"
raise McpError(error=ErrorData(code=404, message="OOPS! no resource with that URI was found"))
raise MCPError(code=404, message="OOPS! no resource with that URI was found")
@self.list_tools()
async def handle_list_tools() -> list[Tool]:
@ -266,7 +265,7 @@ async def test_sse_client_exception_handling(
initialized_sse_client_session: ClientSession,
) -> None:
session = initialized_sse_client_session
with pytest.raises(McpError, match="OOPS! no resource with that URI was found"):
with pytest.raises(MCPError, match="OOPS! no resource with that URI was found"):
await session.read_resource(uri="xxx://will-not-work")
@ -282,7 +281,7 @@ async def test_sse_client_timeout( # pragma: no cover
assert isinstance(response, ReadResourceResult)
with anyio.move_on_after(3):
with pytest.raises(McpError, match="Read timed out"):
with pytest.raises(MCPError, match="Read timed out"):
response = await session.read_resource(uri="slow://2")
# we should receive an error here
return

View file

@ -26,6 +26,7 @@ from starlette.requests import Request
from starlette.routing import Mount
import mcp.types as types
from mcp import MCPError
from mcp.client.session import ClientSession
from mcp.client.streamable_http import StreamableHTTPTransport, streamable_http_client
from mcp.server import Server
@ -44,16 +45,9 @@ from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
from mcp.server.transport_security import TransportSecuritySettings
from mcp.shared._httpx_utils import create_mcp_http_client
from mcp.shared.context import RequestContext
from mcp.shared.exceptions import McpError
from mcp.shared.message import ClientMessageMetadata, ServerMessageMetadata, SessionMessage
from mcp.shared.session import RequestResponder
from mcp.types import (
InitializeResult,
JSONRPCRequest,
TextContent,
TextResourceContents,
Tool,
)
from mcp.types import InitializeResult, JSONRPCRequest, TextContent, TextResourceContents, Tool
from tests.test_helpers import wait_for_server
# Test constants
@ -987,11 +981,7 @@ async def initialized_client_session(basic_server: None, basic_server_url: str):
@pytest.mark.anyio
async def test_streamable_http_client_basic_connection(basic_server: None, basic_server_url: str):
"""Test basic client connection with initialization."""
async with streamable_http_client(f"{basic_server_url}/mcp") as (
read_stream,
write_stream,
_,
):
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, _):
async with ClientSession(
read_stream,
write_stream,
@ -1030,7 +1020,7 @@ async def test_streamable_http_client_tool_invocation(initialized_client_session
@pytest.mark.anyio
async def test_streamable_http_client_error_handling(initialized_client_session: ClientSession):
"""Test error handling in client."""
with pytest.raises(McpError) as exc_info:
with pytest.raises(MCPError) as exc_info:
await initialized_client_session.read_resource(uri="unknown://test-error")
assert exc_info.value.error.code == 0
assert "Unknown resource: unknown://test-error" in exc_info.value.error.message
@ -1067,15 +1057,8 @@ async def test_streamable_http_client_session_persistence(basic_server: None, ba
@pytest.mark.anyio
async def test_streamable_http_client_json_response(json_response_server: None, json_server_url: str):
"""Test client with JSON response mode."""
async with streamable_http_client(f"{json_server_url}/mcp") as (
read_stream,
write_stream,
_,
):
async with ClientSession(
read_stream,
write_stream,
) as session:
async with streamable_http_client(f"{json_server_url}/mcp") as (read_stream, write_stream, _):
async with ClientSession(read_stream, write_stream) as session:
# Initialize the session
result = await session.initialize()
assert isinstance(result, InitializeResult)
@ -1104,11 +1087,7 @@ async def test_streamable_http_client_get_stream(basic_server: None, basic_serve
if isinstance(message, types.ServerNotification): # pragma: no branch
notifications_received.append(message)
async with streamable_http_client(f"{basic_server_url}/mcp") as (
read_stream,
write_stream,
_,
):
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, _):
async with ClientSession(read_stream, write_stream, message_handler=message_handler) as session:
# Initialize the session - this triggers the GET stream setup
result = await session.initialize()
@ -1137,11 +1116,7 @@ async def test_streamable_http_client_session_termination(basic_server: None, ba
captured_session_id = None
# Create the streamable_http_client with a custom httpx client to capture headers
async with streamable_http_client(f"{basic_server_url}/mcp") as (
read_stream,
write_stream,
get_session_id,
):
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, get_session_id):
async with ClientSession(read_stream, write_stream) as session:
# Initialize the session
result = await session.initialize()
@ -1165,7 +1140,7 @@ async def test_streamable_http_client_session_termination(basic_server: None, ba
):
async with ClientSession(read_stream, write_stream) as session: # pragma: no branch
# Attempt to make a request after termination
with pytest.raises(McpError, match="Session terminated"): # pragma: no branch
with pytest.raises(MCPError, match="Session terminated"): # pragma: no branch
await session.list_tools()
@ -1201,11 +1176,7 @@ async def test_streamable_http_client_session_termination_204(
captured_session_id = None
# Create the streamable_http_client with a custom httpx client to capture headers
async with streamable_http_client(f"{basic_server_url}/mcp") as (
read_stream,
write_stream,
get_session_id,
):
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, get_session_id):
async with ClientSession(read_stream, write_stream) as session:
# Initialize the session
result = await session.initialize()
@ -1229,10 +1200,7 @@ async def test_streamable_http_client_session_termination_204(
):
async with ClientSession(read_stream, write_stream) as session: # pragma: no branch
# Attempt to make a request after termination
with pytest.raises( # pragma: no branch
McpError,
match="Session terminated",
):
with pytest.raises(MCPError, match="Session terminated"): # pragma: no branch
await session.list_tools()

View file

@ -12,20 +12,12 @@ from starlette.applications import Starlette
from starlette.routing import WebSocketRoute
from starlette.websockets import WebSocket
from mcp import MCPError
from mcp.client.session import ClientSession
from mcp.client.websocket import websocket_client
from mcp.server import Server
from mcp.server.websocket import websocket_server
from mcp.shared.exceptions import McpError
from mcp.types import (
EmptyResult,
ErrorData,
InitializeResult,
ReadResourceResult,
TextContent,
TextResourceContents,
Tool,
)
from mcp.types import EmptyResult, InitializeResult, ReadResourceResult, TextContent, TextResourceContents, Tool
from tests.test_helpers import wait_for_server
SERVER_NAME = "test_server_for_WS"
@ -58,7 +50,7 @@ class ServerTest(Server): # pragma: no cover
await anyio.sleep(2.0)
return f"Slow response from {parsed.netloc}"
raise McpError(error=ErrorData(code=404, message="OOPS! no resource with that URI was found"))
raise MCPError(code=404, message="OOPS! no resource with that URI was found")
@self.list_tools()
async def handle_list_tools() -> list[Tool]:
@ -84,12 +76,7 @@ def make_server_app() -> Starlette: # pragma: no cover
async with websocket_server(websocket.scope, websocket.receive, websocket.send) as streams:
await server.run(streams[0], streams[1], server.create_initialization_options())
app = Starlette(
routes=[
WebSocketRoute("/ws", endpoint=handle_ws),
]
)
app = Starlette(routes=[WebSocketRoute("/ws", endpoint=handle_ws)])
return app
@ -176,7 +163,7 @@ async def test_ws_client_exception_handling(
initialized_ws_client_session: ClientSession,
) -> None:
"""Test exception handling in WebSocket communication"""
with pytest.raises(McpError) as exc_info:
with pytest.raises(MCPError) as exc_info:
await initialized_ws_client_session.read_resource("unknown://example")
assert exc_info.value.error.code == 404