Split protocol types into a standalone mcp-types package (#2973)
This commit is contained in:
parent
03681ed55e
commit
0ee7f1b293
3 changed files with 1040 additions and 867 deletions
|
|
@ -1,20 +1,19 @@
|
|||
"""Tests for the wire-method maps and two-step parse functions in `mcp.types.methods`."""
|
||||
"""Tests for the wire-method maps and two-step parse functions in `mcp_types.methods`."""
|
||||
|
||||
import importlib.util
|
||||
from collections.abc import Mapping
|
||||
from types import MappingProxyType, UnionType
|
||||
from typing import Any, get_args
|
||||
|
||||
import mcp_types as types
|
||||
import mcp_types.v2025_11_25 as v2025
|
||||
import mcp_types.v2026_07_28 as v2026
|
||||
import pydantic
|
||||
import pytest
|
||||
from mcp_types import methods
|
||||
from mcp_types.version import KNOWN_PROTOCOL_VERSIONS
|
||||
from pydantic import BaseModel
|
||||
|
||||
import mcp.types as types
|
||||
import mcp.types.v2025_11_25 as v2025
|
||||
import mcp.types.v2026_07_28 as v2026
|
||||
from mcp.shared.version import KNOWN_PROTOCOL_VERSIONS
|
||||
from mcp.types import methods
|
||||
|
||||
# Transcribed from each schema's ClientRequest/ServerRequest/ClientNotification/
|
||||
# ServerNotification unions, minus the tasks/* family (extensions register those).
|
||||
EXPECTED_METHODS: dict[str, dict[str, frozenset[str]]] = {
|
||||
|
|
@ -298,11 +297,11 @@ EMPTY_CLIENT_RESPONSE_METHODS = frozenset({"ping"})
|
|||
|
||||
# Pre-2026 versions share the 2025-11-25 surface package.
|
||||
PACKAGE_BY_VERSION = {
|
||||
"2024-11-05": "mcp.types.v2025_11_25",
|
||||
"2025-03-26": "mcp.types.v2025_11_25",
|
||||
"2025-06-18": "mcp.types.v2025_11_25",
|
||||
"2025-11-25": "mcp.types.v2025_11_25",
|
||||
"2026-07-28": "mcp.types.v2026_07_28",
|
||||
"2024-11-05": "mcp_types.v2025_11_25",
|
||||
"2025-03-26": "mcp_types.v2025_11_25",
|
||||
"2025-06-18": "mcp_types.v2025_11_25",
|
||||
"2025-11-25": "mcp_types.v2025_11_25",
|
||||
"2026-07-28": "mcp_types.v2026_07_28",
|
||||
}
|
||||
|
||||
# The three reserved `params._meta` entries the 2026 surface requires on every request.
|
||||
|
|
@ -920,7 +919,7 @@ def test_serialize_server_result_raises_key_error_for_an_absent_row_and_value_er
|
|||
|
||||
def test_importing_the_module_builds_no_adapters_and_identical_rows_share_one():
|
||||
# Execute a fresh copy so the cache assertion is order-independent.
|
||||
spec = importlib.util.find_spec("mcp.types.methods")
|
||||
spec = importlib.util.find_spec("mcp_types.methods")
|
||||
assert spec is not None and spec.loader is not None
|
||||
fresh = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(fresh)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,20 @@
|
|||
"""Assert every per-version surface model's wire fields are a subset of its `mcp.types` superset counterpart."""
|
||||
"""Assert every per-version surface model's wire fields are a subset of its `mcp_types` superset counterpart."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
from types import ModuleType
|
||||
|
||||
import mcp_types as monolith
|
||||
import mcp_types._types as _types
|
||||
import mcp_types.v2025_11_25 as v2025_11_25
|
||||
import mcp_types.v2026_07_28 as v2026_07_28
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
import mcp.types as monolith
|
||||
import mcp.types._types as _types
|
||||
import mcp.types.v2025_11_25 as v2025_11_25
|
||||
import mcp.types.v2026_07_28 as v2026_07_28
|
||||
|
||||
SURFACES: tuple[ModuleType, ...] = (v2025_11_25, v2026_07_28)
|
||||
|
||||
# Envelope fields the monolith models on `mcp.types.jsonrpc` instead of on each request/notification.
|
||||
# Envelope fields the monolith models on `mcp_types.jsonrpc` instead of on each request/notification.
|
||||
ENVELOPE_FIELDS: frozenset[str] = frozenset({"jsonrpc", "id"})
|
||||
|
||||
# Surface classes whose monolith counterpart has a different name (key: "<surface_tail>.<ClassName>").
|
||||
|
|
@ -186,7 +185,7 @@ def test_monolith_is_superset_of_surface_fields(
|
|||
assert not missing, f"{qualname}: monolith {mono_cls.__name__} missing wire fields {sorted(missing)}"
|
||||
|
||||
|
||||
# Monolith model classes intentionally kept out of `mcp.types.__all__`.
|
||||
# Monolith model classes intentionally kept out of `mcp_types.__all__`.
|
||||
PRIVATE_MONOLITH_MODELS: frozenset[str] = frozenset(
|
||||
{
|
||||
"MCPModel", # internal base; users subclass the concrete spec types instead
|
||||
|
|
@ -205,7 +204,7 @@ def test_every_public_monolith_model_is_exported_from_mcp_types() -> None:
|
|||
and obj.__module__ == _types.__name__
|
||||
}
|
||||
missing = defined - set(monolith.__all__) - PRIVATE_MONOLITH_MODELS
|
||||
assert not missing, f"_types models not in mcp.types.__all__: {sorted(missing)}"
|
||||
assert not missing, f"_types models not in mcp_types.__all__: {sorted(missing)}"
|
||||
|
||||
|
||||
def test_every_surface_class_is_accounted_for() -> None:
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
from typing import Any
|
||||
|
||||
from inline_snapshot import snapshot
|
||||
from pydantic import BaseModel
|
||||
|
||||
from mcp.types import (
|
||||
from mcp_types import (
|
||||
METHOD_NOT_FOUND,
|
||||
CallToolRequest,
|
||||
CallToolRequestParams,
|
||||
|
|
@ -24,6 +22,7 @@ from mcp.types import (
|
|||
TextContent,
|
||||
Tool,
|
||||
)
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
def _body(model: BaseModel) -> dict[str, Any]:
|
||||
|
|
|
|||
Loading…
Reference in a new issue