fix: tolerate unsupported optional mcp lists
This commit is contained in:
@@ -4,6 +4,7 @@ from collections.abc import Awaitable, Callable
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, TypeVar
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
import httpx
|
||||||
from mcp import McpError
|
from mcp import McpError
|
||||||
from mcp.types import METHOD_NOT_FOUND
|
from mcp.types import METHOD_NOT_FOUND
|
||||||
|
|
||||||
@@ -64,6 +65,11 @@ async def _list_optional_capabilities(
|
|||||||
root = _root_exception(exc)
|
root = _root_exception(exc)
|
||||||
if isinstance(root, McpError) and root.error.code == METHOD_NOT_FOUND:
|
if isinstance(root, McpError) and root.error.code == METHOD_NOT_FOUND:
|
||||||
return []
|
return []
|
||||||
|
if (
|
||||||
|
isinstance(root, httpx.HTTPStatusError)
|
||||||
|
and root.response.status_code in {400, 404}
|
||||||
|
):
|
||||||
|
return []
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
import pytest
|
import pytest
|
||||||
from mcp import McpError
|
from mcp import McpError
|
||||||
from mcp.types import ErrorData
|
from mcp.types import ErrorData
|
||||||
@@ -155,6 +156,29 @@ class _BrokenResourceAdapter(_Adapter):
|
|||||||
raise RuntimeError("resource listing broke")
|
raise RuntimeError("resource listing broke")
|
||||||
|
|
||||||
|
|
||||||
|
class _HttpOptionalUnsupportedAdapter(_Adapter):
|
||||||
|
async def list_resources(
|
||||||
|
self,
|
||||||
|
connection: McpSourceConnection,
|
||||||
|
auth: AuthRecord | None,
|
||||||
|
) -> list[DiscoveredResource]:
|
||||||
|
request = httpx.Request("POST", "https://example.test/mcp")
|
||||||
|
response = httpx.Response(400, request=request)
|
||||||
|
raise ExceptionGroup(
|
||||||
|
"unhandled errors in a TaskGroup",
|
||||||
|
[httpx.HTTPStatusError("bad request", request=request, response=response)],
|
||||||
|
)
|
||||||
|
|
||||||
|
async def list_prompts(
|
||||||
|
self,
|
||||||
|
connection: McpSourceConnection,
|
||||||
|
auth: AuthRecord | None,
|
||||||
|
) -> list[DiscoveredPrompt]:
|
||||||
|
request = httpx.Request("POST", "https://example.test/mcp")
|
||||||
|
response = httpx.Response(404, request=request)
|
||||||
|
raise httpx.HTTPStatusError("not found", request=request, response=response)
|
||||||
|
|
||||||
|
|
||||||
async def test_discover_connection_capabilities_collects_all_capability_families() -> (
|
async def test_discover_connection_capabilities_collects_all_capability_families() -> (
|
||||||
None
|
None
|
||||||
):
|
):
|
||||||
@@ -188,6 +212,20 @@ async def test_discover_connection_capabilities_treats_missing_optional_families
|
|||||||
assert capabilities.prompts == []
|
assert capabilities.prompts == []
|
||||||
|
|
||||||
|
|
||||||
|
async def test_discover_connection_capabilities_treats_optional_http_400_404_as_empty() -> (
|
||||||
|
None
|
||||||
|
):
|
||||||
|
capabilities = await discover_connection_capabilities(
|
||||||
|
connection=_connection(),
|
||||||
|
auth=None,
|
||||||
|
adapter=_HttpOptionalUnsupportedAdapter(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert [tool.name for tool in capabilities.tools] == ["echo"]
|
||||||
|
assert capabilities.resources == []
|
||||||
|
assert capabilities.prompts == []
|
||||||
|
|
||||||
|
|
||||||
async def test_discover_connection_capabilities_reraises_non_method_not_found_errors() -> (
|
async def test_discover_connection_capabilities_reraises_non_method_not_found_errors() -> (
|
||||||
None
|
None
|
||||||
):
|
):
|
||||||
|
|||||||
Reference in New Issue
Block a user