Split protocol types into a standalone mcp-types package (#2973)

This commit is contained in:
Marcelo Trylesinski 2026-06-25 19:18:38 +02:00 • committed by GitHub
commit 0ee7f1b293
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
118 changed files with 1040 additions and 867 deletions

View file

@ -4,11 +4,11 @@ from typing import Any
from unittest.mock import patch
import pytest
from mcp_types import JSONRPCNotification, JSONRPCRequest
import mcp.shared.memory
from mcp.client._transport import WriteStream
from mcp.shared.message import SessionMessage
from mcp.types import JSONRPCNotification, JSONRPCRequest
class SpyMemoryObjectSendStream:

View file

@ -8,20 +8,10 @@ from contextlib import asynccontextmanager, contextmanager
from unittest.mock import patch
import anyio
import mcp_types as types
import pytest
from inline_snapshot import snapshot
from mcp import MCPError, types
from mcp.client._memory import InMemoryTransport
from mcp.client._transport import TransportStreams
from mcp.client.client import Client
from mcp.client.streamable_http import streamable_http_client
from mcp.server import Server, ServerRequestContext
from mcp.server.mcpserver import MCPServer
from mcp.shared.memory import MessageStream, create_client_server_memory_streams
from mcp.shared.message import SessionMessage
from mcp.shared.version import LATEST_HANDSHAKE_VERSION
from mcp.types import (
from mcp_types import (
CallToolResult,
EmptyResult,
GetPromptResult,
@ -42,6 +32,17 @@ from mcp.types import (
Tool,
ToolsCapability,
)
from mcp_types.version import LATEST_HANDSHAKE_VERSION
from mcp import MCPError
from mcp.client._memory import InMemoryTransport
from mcp.client._transport import TransportStreams
from mcp.client.client import Client
from mcp.client.streamable_http import streamable_http_client
from mcp.server import Server, ServerRequestContext
from mcp.server.mcpserver import MCPServer
from mcp.shared.memory import MessageStream, create_client_server_memory_streams
from mcp.shared.message import SessionMessage
from tests.interaction._connect import BASE_URL, mounted_app
pytestmark = pytest.mark.anyio

View file

@ -8,16 +8,16 @@ from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
import httpx
import mcp_types as types
import pytest
from mcp_types import TextContent, Tool
from starlette.applications import Starlette
from starlette.routing import Mount
from mcp import types
from mcp.client.session import ClientSession
from mcp.client.streamable_http import streamable_http_client
from mcp.server import Server, ServerRequestContext
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
from mcp.types import TextContent, Tool
from tests.interaction.transports import StreamingASGITransport
# The in-process app is mounted at this origin purely so URLs are well-formed; nothing listens here.

View file

@ -1,11 +1,12 @@
from collections.abc import Callable
import mcp_types as types
import pytest
from mcp_types import ListToolsResult
from mcp import Client, types
from mcp import Client
from mcp.server import Server, ServerRequestContext
from mcp.server.mcpserver import MCPServer
from mcp.types import ListToolsResult
from .conftest import StreamSpyCollection

View file

@ -1,11 +1,11 @@
import pytest
from mcp_types import INVALID_REQUEST, ListRootsResult, Root, TextContent
from pydantic import FileUrl
from mcp import Client
from mcp.client import ClientRequestContext
from mcp.server.mcpserver import Context, MCPServer
from mcp.shared.exceptions import MCPError
from mcp.types import INVALID_REQUEST, ListRootsResult, Root, TextContent
@pytest.mark.anyio

View file

@ -1,15 +1,16 @@
from typing import Literal
import mcp_types as types
import pytest
from mcp import Client, types
from mcp.server.mcpserver import Context, MCPServer
from mcp.shared.session import RequestResponder
from mcp.types import (
from mcp_types import (
LoggingMessageNotificationParams,
TextContent,
)
from mcp import Client
from mcp.server.mcpserver import Context, MCPServer
from mcp.shared.session import RequestResponder
class LoggingCollector:
def __init__(self):

View file

@ -7,16 +7,17 @@ that don't follow SDK conventions.
import json
import httpx
import mcp_types as types
import pytest
from mcp_types import RootsListChangedNotification
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.routing import Route
from mcp import ClientSession, MCPError, types
from mcp import ClientSession, MCPError
from mcp.client.streamable_http import streamable_http_client
from mcp.shared.session import RequestResponder
from mcp.types import RootsListChangedNotification
pytestmark = pytest.mark.anyio

View file

@ -2,10 +2,7 @@ import logging
from typing import Any
import pytest
from mcp import Client
from mcp.server import Server, ServerRequestContext
from mcp.types import (
from mcp_types import (
CallToolRequestParams,
CallToolResult,
ListToolsResult,
@ -14,6 +11,9 @@ from mcp.types import (
Tool,
)
from mcp import Client
from mcp.server import Server, ServerRequestContext
def _make_server(
tools: list[Tool],

View file

@ -17,18 +17,9 @@ from typing import Any, cast
import anyio
import httpx
import mcp_types as types
import pytest
from mcp import types
from mcp.client._probe import _parse_supported, negotiate_auto
from mcp.client.session import ClientSession
from mcp.shared.exceptions import MCPError
from mcp.shared.version import (
HANDSHAKE_PROTOCOL_VERSIONS,
LATEST_MODERN_VERSION,
MODERN_PROTOCOL_VERSIONS,
)
from mcp.types import (
from mcp_types import (
INTERNAL_ERROR,
INVALID_REQUEST,
METHOD_NOT_FOUND,
@ -37,6 +28,15 @@ from mcp.types import (
Implementation,
ServerCapabilities,
)
from mcp_types.version import (
HANDSHAKE_PROTOCOL_VERSIONS,
LATEST_MODERN_VERSION,
MODERN_PROTOCOL_VERSIONS,
)
from mcp.client._probe import _parse_supported, negotiate_auto
from mcp.client.session import ClientSession
from mcp.shared.exceptions import MCPError
pytestmark = pytest.mark.anyio

View file

@ -1,10 +1,5 @@
import pytest
from mcp import Client
from mcp.client import ClientRequestContext
from mcp.server.mcpserver import Context, MCPServer
from mcp.shared.exceptions import MCPError
from mcp.types import (
from mcp_types import (
INVALID_REQUEST,
CreateMessageRequestParams,
CreateMessageResult,
@ -14,6 +9,11 @@ from mcp.types import (
ToolUseContent,
)
from mcp import Client
from mcp.client import ClientRequestContext
from mcp.server.mcpserver import Context, MCPServer
from mcp.shared.exceptions import MCPError
@pytest.mark.anyio
async def test_sampling_callback():

View file

@ -7,21 +7,9 @@ from typing import Any, cast
import anyio
import anyio.abc
import anyio.streams.memory
import mcp_types as types
import pytest
from pydantic import FileUrl, ValidationError
from mcp import MCPError, types
from mcp.client import ClientRequestContext
from mcp.client.client import Client
from mcp.client.session import DEFAULT_CLIENT_INFO, ClientSession
from mcp.server import Server, ServerRequestContext
from mcp.shared.direct_dispatcher import create_direct_dispatcher_pair
from mcp.shared.dispatcher import CallOptions, DispatchContext, OnNotify, OnRequest
from mcp.shared.message import SessionMessage
from mcp.shared.session import RequestResponder
from mcp.shared.transport_context import TransportContext
from mcp.shared.version import HANDSHAKE_PROTOCOL_VERSIONS, LATEST_HANDSHAKE_VERSION
from mcp.types import (
from mcp_types import (
CONNECTION_CLOSED,
INTERNAL_ERROR,
INVALID_PARAMS,
@ -44,6 +32,19 @@ from mcp.types import (
client_notification_adapter,
client_request_adapter,
)
from mcp_types.version import HANDSHAKE_PROTOCOL_VERSIONS, LATEST_HANDSHAKE_VERSION
from pydantic import FileUrl, ValidationError
from mcp import MCPError
from mcp.client import ClientRequestContext
from mcp.client.client import Client
from mcp.client.session import DEFAULT_CLIENT_INFO, ClientSession
from mcp.server import Server, ServerRequestContext
from mcp.shared.direct_dispatcher import create_direct_dispatcher_pair
from mcp.shared.dispatcher import CallOptions, DispatchContext, OnNotify, OnRequest
from mcp.shared.message import SessionMessage
from mcp.shared.session import RequestResponder
from mcp.shared.transport_context import TransportContext
_SendToClient = anyio.streams.memory.MemoryObjectSendStream[SessionMessage | Exception]
_RecvFromClient = anyio.streams.memory.MemoryObjectReceiveStream[SessionMessage]

View file

@ -3,11 +3,7 @@
import anyio
import pytest
from inline_snapshot import snapshot
from mcp import Client
from mcp.client import ClientRequestContext
from mcp.server.mcpserver import Context, MCPServer
from mcp.types import (
from mcp_types import (
CallToolResult,
CreateMessageRequestParams,
CreateMessageResult,
@ -15,6 +11,10 @@ from mcp.types import (
TextContent,
)
from mcp import Client
from mcp.client import ClientRequestContext
from mcp.server.mcpserver import Context, MCPServer
pytestmark = pytest.mark.anyio

View file

@ -2,10 +2,10 @@ import contextlib
from unittest import mock
import httpx
import mcp_types as types
import pytest
import mcp
from mcp import types
from mcp.client.session_group import (
ClientSessionGroup,
ClientSessionParameters,

View file

@ -26,6 +26,7 @@ import pytest
import trio
import trio.testing
from anyio.streams.memory import MemoryObjectReceiveStream
from mcp_types import CONNECTION_CLOSED, JSONRPCMessage, JSONRPCRequest, JSONRPCResponse
from mcp.client import stdio
from mcp.client._transport import ReadStream
@ -42,7 +43,6 @@ from mcp.os.posix.utilities import terminate_posix_process_tree
from mcp.os.win32.utilities import FallbackProcess
from mcp.shared.exceptions import MCPError
from mcp.shared.message import SessionMessage
from mcp.types import CONNECTION_CLOSED, JSONRPCMessage, JSONRPCRequest, JSONRPCResponse
# ---------------------------------------------------------------------------
# In-process fake of the spawned server process

View file

@ -13,11 +13,11 @@ import anyio
import httpx
import pytest
from inline_snapshot import snapshot
from mcp_types import METHOD_NOT_FOUND, JSONRPCError, JSONRPCNotification, JSONRPCRequest, JSONRPCResponse
from mcp.client.streamable_http import streamable_http_client
from mcp.shared.inbound import MCP_PROTOCOL_VERSION_HEADER, encode_header_value
from mcp.shared.message import ClientMessageMetadata, SessionMessage
from mcp.types import METHOD_NOT_FOUND, JSONRPCError, JSONRPCNotification, JSONRPCRequest, JSONRPCResponse
@pytest.mark.parametrize(

View file

@ -6,14 +6,15 @@ from typing import Any
import anyio
import anyio.lowlevel
import mcp_types as types
import pytest
from mcp_types import ListResourcesResult, Resource
from mcp import Client, types
from mcp import Client
from mcp.client import _memory
from mcp.client._memory import InMemoryTransport
from mcp.server import Server, ServerRequestContext
from mcp.server.mcpserver import MCPServer
from mcp.types import ListResourcesResult, Resource
@pytest.fixture

View file

@ -24,7 +24,7 @@ flows — with a single subprocess test for stdio.
rewrite preserved behaviour; a passing test that pins the wrong output exactly does. Known
divergences are recorded as data on the requirement (see below), not worked around in the test.
- **Spec-mandated assertions, not implementation quirks.** Error *codes* are asserted against
the constants in `mcp.types`; error *message strings* are pinned only where they are the
the constants in `mcp_types`; error *message strings* are pinned only where they are the
SDK's own deliberate output.
- **No sleeps, no real I/O.** Concurrency is coordinated with `anyio.Event`; every wait that
could hang is bounded by `anyio.fail_after(5)`. The HTTP and OAuth tests drive the Starlette
@ -243,7 +243,7 @@ many requirements at once; if the assertions would be separate, write separate t
|---|---|
| the result of a transformation (arguments → output, exception → error result) | `result == snapshot(...)` of the full object, so any field the implementation adds or drops fails the test |
| pass-through of an opaque value (`_meta`, cursors) | identity against the same variable that was sent — a snapshot of a pass-through value only matches the input because a human checked two literals correspond |
| an error | `pytest.raises(MCPError)` and a snapshot of `exc.value.error` when the message is the SDK's own; a plain `==` on `.code` against the `mcp.types` constant when it is not |
| an error | `pytest.raises(MCPError)` and a snapshot of `exc.value.error` when the message is the SDK's own; a plain `==` on `.code` against the `mcp_types` constant when it is not |
| third-party output embedded in a result (validation messages) | the stable prefix only — never pin text that changes with a dependency upgrade |
### Notifications and concurrency

View file

@ -14,6 +14,16 @@ from typing import Any, Protocol
import httpx
from httpx_sse import ServerSentEvent, aconnect_sse
from mcp_types import (
ClientCapabilities,
Implementation,
InitializeRequestParams,
JSONRPCMessage,
JSONRPCRequest,
JSONRPCResponse,
jsonrpc_message_adapter,
)
from mcp_types.version import LATEST_HANDSHAKE_VERSION, MODERN_PROTOCOL_VERSIONS
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import Response
@ -31,16 +41,6 @@ from mcp.server.sse import SseServerTransport
from mcp.server.streamable_http import EventStore
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
from mcp.server.transport_security import TransportSecuritySettings
from mcp.shared.version import LATEST_HANDSHAKE_VERSION, MODERN_PROTOCOL_VERSIONS
from mcp.types import (
ClientCapabilities,
Implementation,
InitializeRequestParams,
JSONRPCMessage,
JSONRPCRequest,
JSONRPCResponse,
jsonrpc_message_adapter,
)
from tests.interaction.transports._bridge import StreamingASGITransport
# The in-process app is mounted at this origin purely so URLs are well-formed; nothing listens here.

View file

@ -9,12 +9,12 @@ them.
from types import TracebackType
import anyio
from mcp_types import ClientResult, ServerNotification, ServerRequest
from typing_extensions import Self
from mcp.client._transport import ReadStream, Transport, TransportStreams, WriteStream
from mcp.shared.message import SessionMessage
from mcp.shared.session import RequestResponder
from mcp.types import ClientResult, ServerNotification, ServerRequest
# TODO: this union is the parameter type of every client message handler (MessageHandlerFnT),
# but the SDK does not export a name for it -- writing a correctly-typed handler requires

View file

@ -18,8 +18,7 @@ assumptions about which side produced what.
from dataclasses import dataclass
import httpx
from mcp.types import JSONRPCMessage, jsonrpc_message_adapter
from mcp_types import JSONRPCMessage, jsonrpc_message_adapter
#: Substrings that must not appear anywhere in a request body or JSON-RPC frame on a legacy
#: exchange. Matching is by raw substring against the by-alias JSON serialisation, so a leaked

Some files were not shown because too many files have changed in this diff Show more