Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/toolbox-core/src/toolbox_core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
McpHttpTransportV20250326,
McpHttpTransportV20250618,
McpHttpTransportV20251125,
McpHttpTransportV20260618,
McpHttpTransportV20260728,
)
from .protocol import Protocol, ToolSchema
from .tool import ToolboxTool
Expand Down Expand Up @@ -66,8 +66,8 @@ def __init__(
def _create_transport(self, protocol: Protocol) -> ITransport:
self._current_protocol = protocol
match protocol:
case Protocol.MCP_DRAFT:
return McpHttpTransportV20260618(
case Protocol.MCP_v20260728 | Protocol.MCP_DRAFT | Protocol.MCP_v2026_DRAFT:
return McpHttpTransportV20260728(
self._url,
self._session,
protocol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
from .v20250326.mcp import McpHttpTransportV20250326
from .v20250618.mcp import McpHttpTransportV20250618
from .v20251125.mcp import McpHttpTransportV20251125
from .v20260618.mcp import McpHttpTransportV20260618
from .v20260728.mcp import McpHttpTransportV20260728

__all__ = [
"McpHttpTransportV20241105",
"McpHttpTransportV20250326",
"McpHttpTransportV20250618",
"McpHttpTransportV20251125",
"McpHttpTransportV20260618",
"McpHttpTransportV20260728",
]
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
ReceiveResultT = TypeVar("ReceiveResultT", bound=BaseModel)


class McpHttpTransportV20260618(_McpHttpTransportBase):
"""Transport for the MCP draft Request-Metadata (v2026-06-18) protocol."""
class McpHttpTransportV20260728(_McpHttpTransportBase):
"""Transport for the MCP draft Request-Metadata (v2026-07-28) protocol."""

async def _send_request(
self,
Expand Down
11 changes: 6 additions & 5 deletions packages/toolbox-core/src/toolbox_core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,18 @@ class Protocol(str, Enum):
MCP_v20250326 = "2025-03-26"
MCP_v20241105 = "2024-11-05"
MCP_v20251125 = "2025-11-25"
MCP_v2026_DRAFT = "DRAFT-2026-v1"
MCP_v20260728 = "2026-07-28"
MCP_v2026_DRAFT = "2026-07-28"

MCP = MCP_v20251125
MCP_LATEST = MCP_v20251125
MCP_DRAFT = MCP_v2026_DRAFT
MCP = MCP_v20260728
MCP_LATEST = MCP_v20260728
MCP_DRAFT = MCP_v20260728

@staticmethod
def get_supported_mcp_versions() -> list[str]:
"""Returns a list of supported MCP protocol versions."""
return [
Protocol.MCP_DRAFT.value,
Protocol.MCP_v20260728.value,
Protocol.MCP_v20251125.value,
Protocol.MCP_v20250618.value,
Protocol.MCP_v20250326.value,
Expand Down
8 changes: 4 additions & 4 deletions packages/toolbox-core/tests/mcp_transport/test_v20241105.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ async def test_version_negotiation_raises_fallback(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -193,7 +193,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_raises_fallback_200_ok(self, transport):
Expand All @@ -210,7 +210,7 @@ async def test_version_negotiation_raises_fallback_200_ok(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -231,7 +231,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_empty_intersection(self, transport):
Expand Down
8 changes: 4 additions & 4 deletions packages/toolbox-core/tests/mcp_transport/test_v20250326.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ async def test_version_negotiation_raises_fallback(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -211,7 +211,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_raises_fallback_200_ok(self, transport):
Expand All @@ -228,7 +228,7 @@ async def test_version_negotiation_raises_fallback_200_ok(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -249,7 +249,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_empty_intersection(self, transport):
Expand Down
8 changes: 4 additions & 4 deletions packages/toolbox-core/tests/mcp_transport/test_v20250618.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ async def test_version_negotiation_raises_fallback(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -210,7 +210,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_raises_fallback_200_ok(self, transport):
Expand All @@ -227,7 +227,7 @@ async def test_version_negotiation_raises_fallback_200_ok(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -248,7 +248,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_empty_intersection(self, transport):
Expand Down
8 changes: 4 additions & 4 deletions packages/toolbox-core/tests/mcp_transport/test_v20251125.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ async def test_version_negotiation_raises_fallback(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -210,7 +210,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_raises_fallback_200_ok(self, transport):
Expand All @@ -227,7 +227,7 @@ async def test_version_negotiation_raises_fallback_200_ok(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -248,7 +248,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_empty_intersection(self, transport):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from aiohttp import ClientSession
from aioresponses import aioresponses

from toolbox_core.mcp_transport.v20260618 import types
from toolbox_core.mcp_transport.v20260618.mcp import McpHttpTransportV20260618
from toolbox_core.mcp_transport.v20260728 import types
from toolbox_core.mcp_transport.v20260728.mcp import McpHttpTransportV20260728
from toolbox_core.protocol import ManifestSchema, Protocol


Expand Down Expand Up @@ -68,7 +68,7 @@ async def transport(request, mocker):
mocker.patch("toolbox_core.mcp_transport.telemetry.record_operation_duration")
mocker.patch("toolbox_core.mcp_transport.telemetry.record_session_duration")
mock_session = AsyncMock(spec=ClientSession)
transport = McpHttpTransportV20260618(
transport = McpHttpTransportV20260728(
"http://fake-server.com",
session=mock_session,
protocol=Protocol.MCP_DRAFT,
Expand All @@ -79,7 +79,7 @@ async def transport(request, mocker):


@pytest.mark.asyncio
class TestMcpHttpTransportV20260618:
class TestMcpHttpTransportV20260728:

# --- Request Sending Tests (Standard + Header) ---

Expand Down Expand Up @@ -128,7 +128,7 @@ def get_result_model(self):

call_args = transport._session.post.call_args
headers = call_args.kwargs["headers"]
assert headers["MCP-Protocol-Version"] == "DRAFT-2026-v1"
assert headers["MCP-Protocol-Version"] == "2026-07-28"
assert headers["Mcp-Method"] == "method"
assert "Mcp-Name" not in headers

Expand Down Expand Up @@ -242,7 +242,7 @@ async def test_version_negotiation_raises_fallback(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -263,7 +263,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_raises_fallback_200_ok(self, transport):
Expand All @@ -280,7 +280,7 @@ async def test_version_negotiation_raises_fallback_200_ok(self, transport):
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {"supported": ["DRAFT-2026-v1"]},
"data": {"supported": ["2026-07-28"]},
},
}

Expand All @@ -301,7 +301,7 @@ def get_result_model(self):
with pytest.raises(ProtocolNegotiationError) as exc_info:
await transport._send_request("url", TestRequest())

assert exc_info.value.negotiated_version == "DRAFT-2026-v1"
assert exc_info.value.negotiated_version == "2026-07-28"
assert transport._session.post.call_count == 1

async def test_version_negotiation_empty_intersection(self, transport):
Expand Down Expand Up @@ -357,7 +357,7 @@ async def test_tools_list_success(self, transport, mocker):
async def test_tools_list_with_toolset_name_and_query_params(self, mocker):
"""Test listing tools with a toolset name when base_url contains query parameters."""
mock_session = AsyncMock(spec=ClientSession)
transport = McpHttpTransportV20260618(
transport = McpHttpTransportV20260728(
"http://fake-server.com?proj=xyz&env=prod",
session=mock_session,
protocol=Protocol.MCP_DRAFT,
Expand Down Expand Up @@ -499,7 +499,7 @@ async def test_result_meta_parsing_server_info(self, transport):
types.ListToolsRequest(
params=types.ListToolsRequestParams(
field_meta=types.MCPMeta(
protocol_version="DRAFT-2026-v1",
protocol_version="2026-07-28",
client_info=types.Implementation(name="test", version="1.0"),
client_capabilities=types.ClientCapabilities(),
)
Expand Down
8 changes: 4 additions & 4 deletions packages/toolbox-core/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ async def test_load_tool_protocol_fallback_success(test_tool_str):

# We need to mock the transports that client.py will instantiate
with (
patch("toolbox_core.client.McpHttpTransportV20260618") as mock_2026_cls,
patch("toolbox_core.client.McpHttpTransportV20260728") as mock_2026_cls,
patch("toolbox_core.client.McpHttpTransportV20250618") as mock_2025_cls,
):

Expand Down Expand Up @@ -307,7 +307,7 @@ async def test_load_tool_protocol_fallback_infinite_loop_prevention(test_tool_st
from toolbox_core.exceptions import ProtocolNegotiationError

with (
patch("toolbox_core.client.McpHttpTransportV20260618") as mock_2026_cls,
patch("toolbox_core.client.McpHttpTransportV20260728") as mock_2026_cls,
patch("toolbox_core.client.McpHttpTransportV20250618") as mock_2025_cls,
patch("toolbox_core.client.McpHttpTransportV20241105") as mock_2024_cls,
):
Expand Down Expand Up @@ -820,7 +820,7 @@ async def test_client_init_with_client_info():
def test_toolbox_client_no_warning_on_mcp():
"""Test that initializing ToolboxClient with Protocol.MCP issues NO DeprecationWarning."""
# Mock the transport to avoid actual connection attempts or MCP version warnings
with patch("toolbox_core.client.McpHttpTransportV20251125") as mock_transport:
with patch("toolbox_core.client.McpHttpTransportV20260728") as mock_transport:
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")

Expand Down Expand Up @@ -853,7 +853,7 @@ def test_toolbox_client_custom_protocols():
# Check initial_protocol
assert args[2] == Protocol.MCP_DRAFT
# Check supported_protocols (must be sorted from newest to oldest)
assert args[6] == ["DRAFT-2026-v1", "2025-06-18", "2024-11-05"]
assert args[6] == ["2026-07-28", "2025-06-18", "2024-11-05"]


def test_toolbox_client_custom_protocols_invalid():
Expand Down
2 changes: 1 addition & 1 deletion packages/toolbox-core/tests/test_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def test_get_supported_mcp_versions():
sorted from newest to oldest.
"""
expected_versions = [
"DRAFT-2026-v1",
"2026-07-28",
"2025-11-25",
"2025-06-18",
"2025-03-26",
Expand Down
Loading