Skip to content

methods

Per-version method maps and parse/serialize functions for MCP traffic.

This module is supported public API; the mcp_types._v* packages it draws on are internal validators and not for direct import.

Surface maps key (method, version) to per-version wire types (key absence is the version gate; shape validation is per schema era, i.e. 2025-11-25 for every pre-2026 version and 2026-07-28 for 2026). Monolith maps key method to the version-free mcp_types models user code receives.

The surface maps do not import the per-version wire packages up front: each mcp_types._v* package is ~100 ms of pydantic model construction and a connection negotiates exactly one version, so a row's package is imported the first time that row is read (see _LazyWireMap).

SERVER_RESULTS module-attribute

SERVER_RESULTS: Final[
    Mapping[tuple[str, str], type[BaseModel] | UnionType]
] = _surface(
    {
        (
            "completion/complete",
            "2024-11-05",
        ): "CompleteResult",
        ("initialize", "2024-11-05"): "InitializeResult",
        ("logging/setLevel", "2024-11-05"): "EmptyResult",
        ("ping", "2024-11-05"): "EmptyResult",
        ("prompts/get", "2024-11-05"): "GetPromptResult",
        ("prompts/list", "2024-11-05"): "ListPromptsResult",
        (
            "resources/list",
            "2024-11-05",
        ): "ListResourcesResult",
        (
            "resources/read",
            "2024-11-05",
        ): "ReadResourceResult",
        (
            "resources/subscribe",
            "2024-11-05",
        ): "EmptyResult",
        (
            "resources/templates/list",
            "2024-11-05",
        ): "ListResourceTemplatesResult",
        (
            "resources/unsubscribe",
            "2024-11-05",
        ): "EmptyResult",
        ("tools/call", "2024-11-05"): "CallToolResult",
        ("tools/list", "2024-11-05"): "ListToolsResult",
        (
            "completion/complete",
            "2025-03-26",
        ): "CompleteResult",
        ("initialize", "2025-03-26"): "InitializeResult",
        ("logging/setLevel", "2025-03-26"): "EmptyResult",
        ("ping", "2025-03-26"): "EmptyResult",
        ("prompts/get", "2025-03-26"): "GetPromptResult",
        ("prompts/list", "2025-03-26"): "ListPromptsResult",
        (
            "resources/list",
            "2025-03-26",
        ): "ListResourcesResult",
        (
            "resources/read",
            "2025-03-26",
        ): "ReadResourceResult",
        (
            "resources/subscribe",
            "2025-03-26",
        ): "EmptyResult",
        (
            "resources/templates/list",
            "2025-03-26",
        ): "ListResourceTemplatesResult",
        (
            "resources/unsubscribe",
            "2025-03-26",
        ): "EmptyResult",
        ("tools/call", "2025-03-26"): "CallToolResult",
        ("tools/list", "2025-03-26"): "ListToolsResult",
        (
            "completion/complete",
            "2025-06-18",
        ): "CompleteResult",
        ("initialize", "2025-06-18"): "InitializeResult",
        ("logging/setLevel", "2025-06-18"): "EmptyResult",
        ("ping", "2025-06-18"): "EmptyResult",
        ("prompts/get", "2025-06-18"): "GetPromptResult",
        ("prompts/list", "2025-06-18"): "ListPromptsResult",
        (
            "resources/list",
            "2025-06-18",
        ): "ListResourcesResult",
        (
            "resources/read",
            "2025-06-18",
        ): "ReadResourceResult",
        (
            "resources/subscribe",
            "2025-06-18",
        ): "EmptyResult",
        (
            "resources/templates/list",
            "2025-06-18",
        ): "ListResourceTemplatesResult",
        (
            "resources/unsubscribe",
            "2025-06-18",
        ): "EmptyResult",
        ("tools/call", "2025-06-18"): "CallToolResult",
        ("tools/list", "2025-06-18"): "ListToolsResult",
        (
            "completion/complete",
            "2025-11-25",
        ): "CompleteResult",
        ("initialize", "2025-11-25"): "InitializeResult",
        ("logging/setLevel", "2025-11-25"): "EmptyResult",
        ("ping", "2025-11-25"): "EmptyResult",
        ("prompts/get", "2025-11-25"): "GetPromptResult",
        ("prompts/list", "2025-11-25"): "ListPromptsResult",
        (
            "resources/list",
            "2025-11-25",
        ): "ListResourcesResult",
        (
            "resources/read",
            "2025-11-25",
        ): "ReadResourceResult",
        (
            "resources/subscribe",
            "2025-11-25",
        ): "EmptyResult",
        (
            "resources/templates/list",
            "2025-11-25",
        ): "ListResourceTemplatesResult",
        (
            "resources/unsubscribe",
            "2025-11-25",
        ): "EmptyResult",
        ("tools/call", "2025-11-25"): "CallToolResult",
        ("tools/list", "2025-11-25"): "ListToolsResult",
        (
            "completion/complete",
            "2026-07-28",
        ): "CompleteResult",
        ("prompts/get", "2026-07-28"): "AnyGetPromptResult",
        ("prompts/list", "2026-07-28"): "ListPromptsResult",
        (
            "resources/list",
            "2026-07-28",
        ): "ListResourcesResult",
        (
            "resources/read",
            "2026-07-28",
        ): "AnyReadResourceResult",
        (
            "resources/templates/list",
            "2026-07-28",
        ): "ListResourceTemplatesResult",
        ("server/discover", "2026-07-28"): "DiscoverResult",
        (
            "subscriptions/listen",
            "2026-07-28",
        ): "SubscriptionsListenResult",
        ("tools/call", "2026-07-28"): "AnyCallToolResult",
        ("tools/list", "2026-07-28"): "ListToolsResult",
    }
)

Results servers send, keyed by the originating client request's (method, version).

CLIENT_RESULTS module-attribute

CLIENT_RESULTS: Final[
    Mapping[tuple[str, str], type[BaseModel] | UnionType]
] = _surface(
    {
        ("ping", "2024-11-05"): "EmptyResult",
        ("roots/list", "2024-11-05"): "ListRootsResult",
        (
            "sampling/createMessage",
            "2024-11-05",
        ): "CreateMessageResult",
        ("ping", "2025-03-26"): "EmptyResult",
        ("roots/list", "2025-03-26"): "ListRootsResult",
        (
            "sampling/createMessage",
            "2025-03-26",
        ): "CreateMessageResult",
        (
            "elicitation/create",
            "2025-06-18",
        ): "ElicitResult",
        ("ping", "2025-06-18"): "EmptyResult",
        ("roots/list", "2025-06-18"): "ListRootsResult",
        (
            "sampling/createMessage",
            "2025-06-18",
        ): "CreateMessageResult",
        (
            "elicitation/create",
            "2025-11-25",
        ): "ElicitResult",
        ("ping", "2025-11-25"): "EmptyResult",
        ("roots/list", "2025-11-25"): "ListRootsResult",
        (
            "sampling/createMessage",
            "2025-11-25",
        ): "CreateMessageResult",
    }
)

Results clients send, keyed by the originating server request's (method, version).

SPEC_CLIENT_METHODS module-attribute

SPEC_CLIENT_METHODS: Final[frozenset[str]] = frozenset(
    m for m, _ in CLIENT_REQUESTS
)

Spec request methods a client may send (any version); the server-side spec-method discriminator.

SPEC_CLIENT_NOTIFICATION_METHODS module-attribute

SPEC_CLIENT_NOTIFICATION_METHODS: Final[frozenset[str]] = (
    frozenset(m for m, _ in CLIENT_NOTIFICATIONS)
)

Spec notification methods a client may send (any version); the server-side spec-method discriminator.

MONOLITH_REQUESTS module-attribute

MONOLITH_REQUESTS: Final[
    Mapping[str, type[Request[Any, Any]]]
] = MappingProxyType(
    {
        "completion/complete": types.CompleteRequest,
        "elicitation/create": types.ElicitRequest,
        "initialize": types.InitializeRequest,
        "logging/setLevel": types.SetLevelRequest,
        "ping": types.PingRequest,
        "prompts/get": types.GetPromptRequest,
        "prompts/list": types.ListPromptsRequest,
        "resources/list": types.ListResourcesRequest,
        "resources/read": types.ReadResourceRequest,
        "resources/subscribe": types.SubscribeRequest,
        "resources/templates/list": types.ListResourceTemplatesRequest,
        "resources/unsubscribe": types.UnsubscribeRequest,
        "roots/list": types.ListRootsRequest,
        "sampling/createMessage": types.CreateMessageRequest,
        "server/discover": types.DiscoverRequest,
        "subscriptions/listen": types.SubscriptionsListenRequest,
        "tools/call": types.CallToolRequest,
        "tools/list": types.ListToolsRequest,
    }
)

Monolith request model per method, both directions.

MONOLITH_NOTIFICATIONS module-attribute

MONOLITH_NOTIFICATIONS: Final[
    Mapping[str, type[Notification[Any, Any]]]
] = MappingProxyType(
    {
        "notifications/cancelled": types.CancelledNotification,
        "notifications/elicitation/complete": types.ElicitCompleteNotification,
        "notifications/initialized": types.InitializedNotification,
        "notifications/message": types.LoggingMessageNotification,
        "notifications/progress": types.ProgressNotification,
        "notifications/prompts/list_changed": types.PromptListChangedNotification,
        "notifications/resources/list_changed": types.ResourceListChangedNotification,
        "notifications/resources/updated": types.ResourceUpdatedNotification,
        "notifications/roots/list_changed": types.RootsListChangedNotification,
        "notifications/subscriptions/acknowledged": types.SubscriptionsAcknowledgedNotification,
        "notifications/tools/list_changed": types.ToolListChangedNotification,
    }
)

Monolith notification model per method, both directions.

MONOLITH_RESULTS module-attribute

MONOLITH_RESULTS: Final[
    Mapping[str, type[Result] | UnionType]
] = MappingProxyType(
    {
        "completion/complete": types.CompleteResult,
        "elicitation/create": types.ElicitResult,
        "initialize": types.InitializeResult,
        "logging/setLevel": types.EmptyResult,
        "ping": types.EmptyResult,
        "prompts/get": types.GetPromptResult
        | types.InputRequiredResult,
        "prompts/list": types.ListPromptsResult,
        "resources/list": types.ListResourcesResult,
        "resources/read": types.ReadResourceResult
        | types.InputRequiredResult,
        "resources/subscribe": types.EmptyResult,
        "resources/templates/list": types.ListResourceTemplatesResult,
        "resources/unsubscribe": types.EmptyResult,
        "roots/list": types.ListRootsResult,
        "sampling/createMessage": types.CreateMessageResult
        | types.CreateMessageResultWithTools,
        "server/discover": types.DiscoverResult,
        "subscriptions/listen": types.SubscriptionsListenResult,
        "tools/call": types.CallToolResult
        | types.InputRequiredResult,
        "tools/list": types.ListToolsResult,
    }
)

Monolith result model (or two-arm union) per request method.

CacheableMethod module-attribute

CacheableMethod = Literal[
    "prompts/list",
    "resources/list",
    "resources/read",
    "resources/templates/list",
    "server/discover",
    "tools/list",
]

Methods whose results carry ttlMs/cacheScope; hand-written Literal, welded to CACHEABLE_METHODS by tests.

CACHEABLE_METHODS module-attribute

CACHEABLE_METHODS: Final[frozenset[str]] = frozenset(
    method
    for method, row in (MONOLITH_RESULTS.items())
    if any(
        (issubclass(arm, types.CacheableResult))
        for arm in (
            get_args(row)
            if isinstance(row, UnionType)
            else (row,)
        )
    )
)

Runtime mirror of CacheableMethod, derived from MONOLITH_RESULTS.

INPUT_REQUIRED_METHODS module-attribute

INPUT_REQUIRED_METHODS: Final[frozenset[str]] = frozenset(
    method
    for method, row in (MONOLITH_RESULTS.items())
    if any(
        (issubclass(arm, types.InputRequiredResult))
        for arm in (
            get_args(row)
            if isinstance(row, UnionType)
            else (row,)
        )
    )
)

Methods whose results may be InputRequiredResult, derived from MONOLITH_RESULTS.

is_input_required

is_input_required(
    result: object,
) -> TypeGuard[InputRequiredResult | dict[str, Any]]

True when result is an input_required interim result, typed or wire-shaped.

Source code in src/mcp-types/mcp_types/methods.py
548
549
550
551
552
def is_input_required(result: object) -> TypeGuard[types.InputRequiredResult | dict[str, Any]]:
    """True when `result` is an `input_required` interim result, typed or wire-shaped."""
    if isinstance(result, types.InputRequiredResult):
        return True
    return isinstance(result, Mapping) and cast("Mapping[str, Any]", result).get("resultType") == "input_required"

validate_client_request

validate_client_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = CLIENT_REQUESTS
) -> None

Validate a client request against surface only.

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface (the version gate).

ValidationError

body fails surface validation.

Source code in src/mcp-types/mcp_types/methods.py
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
def validate_client_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = CLIENT_REQUESTS,
) -> None:
    """Validate a client request against `surface` only.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface` (the version gate).
        pydantic.ValidationError: body fails surface validation.
    """
    _check_known_version(version)
    surface[(method, version)].model_validate({**_REQUEST_STUB, **_body(method, params)}, by_name=False)

parse_client_request

parse_client_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = CLIENT_REQUESTS,
    monolith: Mapping[
        str, type[Request[Any, Any]]
    ] = MONOLITH_REQUESTS
) -> Request[Any, Any]

Validate a client request against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel]]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

CLIENT_REQUESTS
monolith Mapping[str, type[Request[Any, Any]]]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_REQUESTS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface (the version gate).

ValidationError

body fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
def parse_client_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = CLIENT_REQUESTS,
    monolith: Mapping[str, type[types.Request[Any, Any]]] = MONOLITH_REQUESTS,
) -> types.Request[Any, Any]:
    """Validate a client request against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface` (the version gate).
        pydantic.ValidationError: body fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    validate_client_request(method, version, params, surface=surface)
    return _monolith_row(monolith, method).model_validate(_body(method, params), by_name=False)

parse_server_request

parse_server_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = SERVER_REQUESTS,
    monolith: Mapping[
        str, type[Request[Any, Any]]
    ] = MONOLITH_REQUESTS
) -> Request[Any, Any]

Validate a server request against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel]]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

SERVER_REQUESTS
monolith Mapping[str, type[Request[Any, Any]]]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_REQUESTS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface (the version gate).

ValidationError

body fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
def parse_server_request(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = SERVER_REQUESTS,
    monolith: Mapping[str, type[types.Request[Any, Any]]] = MONOLITH_REQUESTS,
) -> types.Request[Any, Any]:
    """Validate a server request against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface` (the version gate).
        pydantic.ValidationError: body fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    _check_known_version(version)
    surface_type = surface[(method, version)]
    surface_type.model_validate({**_REQUEST_STUB, **_body(method, params)}, by_name=False)
    return _monolith_row(monolith, method).model_validate(_body(method, params), by_name=False)

validate_client_notification

validate_client_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = CLIENT_NOTIFICATIONS
) -> None

Validate a client notification against surface only.

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

body fails surface validation.

Source code in src/mcp-types/mcp_types/methods.py
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
def validate_client_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = CLIENT_NOTIFICATIONS,
) -> None:
    """Validate a client notification against `surface` only.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: body fails surface validation.
    """
    _check_known_version(version)
    surface[(method, version)].model_validate({**_NOTIFICATION_STUB, **_body(method, params)}, by_name=False)

parse_client_notification

parse_client_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = CLIENT_NOTIFICATIONS,
    monolith: Mapping[
        str, type[Notification[Any, Any]]
    ] = MONOLITH_NOTIFICATIONS
) -> Notification[Any, Any]

Validate a client notification against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel]]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

CLIENT_NOTIFICATIONS
monolith Mapping[str, type[Notification[Any, Any]]]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_NOTIFICATIONS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

body fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
def parse_client_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = CLIENT_NOTIFICATIONS,
    monolith: Mapping[str, type[types.Notification[Any, Any]]] = MONOLITH_NOTIFICATIONS,
) -> types.Notification[Any, Any]:
    """Validate a client notification against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: body fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    validate_client_notification(method, version, params, surface=surface)
    return _monolith_row(monolith, method).model_validate(_body(method, params), by_name=False)

parse_server_notification

parse_server_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel]
    ] = SERVER_NOTIFICATIONS,
    monolith: Mapping[
        str, type[Notification[Any, Any]]
    ] = MONOLITH_NOTIFICATIONS
) -> Notification[Any, Any]

Validate a server notification against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel]]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

SERVER_NOTIFICATIONS
monolith Mapping[str, type[Notification[Any, Any]]]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_NOTIFICATIONS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

body fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
def parse_server_notification(
    method: str,
    version: str,
    params: Mapping[str, Any] | None,
    *,
    surface: Mapping[tuple[str, str], type[BaseModel]] = SERVER_NOTIFICATIONS,
    monolith: Mapping[str, type[types.Notification[Any, Any]]] = MONOLITH_NOTIFICATIONS,
) -> types.Notification[Any, Any]:
    """Validate a server notification against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: body fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    _check_known_version(version)
    surface_type = surface[(method, version)]
    surface_type.model_validate({**_NOTIFICATION_STUB, **_body(method, params)}, by_name=False)
    return _monolith_row(monolith, method).model_validate(_body(method, params), by_name=False)

serialize_server_result

serialize_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel] | UnionType
    ] = SERVER_RESULTS
) -> dict[str, Any]

Validate data against surface and return its surface-shaped dump.

The surface model carries extra="ignore", so fields not in version's schema are dropped from the returned dict.

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

result fails surface validation.

Source code in src/mcp-types/mcp_types/methods.py
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
def serialize_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[tuple[str, str], type[BaseModel] | UnionType] = SERVER_RESULTS,
) -> dict[str, Any]:
    """Validate `data` against `surface` and return its surface-shaped dump.

    The surface model carries `extra="ignore"`, so fields not in `version`'s
    schema are dropped from the returned dict.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: result fails surface validation.
    """
    _check_known_version(version)
    adapter = _adapter(surface[(method, version)])
    return adapter.dump_python(
        adapter.validate_python(data, by_name=False), by_alias=True, mode="json", exclude_none=True
    )

validate_server_result

validate_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel] | UnionType
    ] = SERVER_RESULTS
) -> None

Validate a server result against surface only.

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

result fails surface validation.

Source code in src/mcp-types/mcp_types/methods.py
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
def validate_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[tuple[str, str], type[BaseModel] | UnionType] = SERVER_RESULTS,
) -> None:
    """Validate a server result against `surface` only.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: result fails surface validation.
    """
    serialize_server_result(method, version, data, surface=surface)

parse_server_result

parse_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel] | UnionType
    ] = SERVER_RESULTS,
    monolith: Mapping[
        str, type[Result] | UnionType
    ] = MONOLITH_RESULTS
) -> Result

Validate a server result against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel] | UnionType]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

SERVER_RESULTS
monolith Mapping[str, type[Result] | UnionType]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_RESULTS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

result fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
def parse_server_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[tuple[str, str], type[BaseModel] | UnionType] = SERVER_RESULTS,
    monolith: Mapping[str, type[types.Result] | UnionType] = MONOLITH_RESULTS,
) -> types.Result:
    """Validate a server result against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: result fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    validate_server_result(method, version, data, surface=surface)
    result: types.Result = _adapter(_monolith_row(monolith, method)).validate_python(data, by_name=False)
    return result

validate_client_result

validate_client_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel] | UnionType
    ] = CLIENT_RESULTS
) -> None

Validate a client result against surface only.

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

result fails surface validation.

Source code in src/mcp-types/mcp_types/methods.py
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
def validate_client_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[tuple[str, str], type[BaseModel] | UnionType] = CLIENT_RESULTS,
) -> None:
    """Validate a client result against `surface` only.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: result fails surface validation.
    """
    _check_known_version(version)
    _adapter(surface[(method, version)]).validate_python(data, by_name=False)

parse_client_result

parse_client_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[
        tuple[str, str], type[BaseModel] | UnionType
    ] = CLIENT_RESULTS,
    monolith: Mapping[
        str, type[Result] | UnionType
    ] = MONOLITH_RESULTS
) -> Result

Validate a client result against surface, then parse and return its monolith model.

Parameters:

Name Type Description Default
surface Mapping[tuple[str, str], type[BaseModel] | UnionType]

(method, version) to wire-type map; the version-gate lookup and (per-schema-era) shape check run against this. Pass an extended map to admit custom methods.

CLIENT_RESULTS
monolith Mapping[str, type[Result] | UnionType]

method to version-free model map; the returned instance is parsed from this row. Must cover every method surface admits.

MONOLITH_RESULTS

Raises:

Type Description
ValueError

version is not a known protocol version.

KeyError

(method, version) is not in surface.

ValidationError

result fails surface or monolith validation.

RuntimeError

surface matched but method has no monolith row.

Source code in src/mcp-types/mcp_types/methods.py
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
def parse_client_result(
    method: str,
    version: str,
    data: Mapping[str, Any],
    *,
    surface: Mapping[tuple[str, str], type[BaseModel] | UnionType] = CLIENT_RESULTS,
    monolith: Mapping[str, type[types.Result] | UnionType] = MONOLITH_RESULTS,
) -> types.Result:
    """Validate a client result against `surface`, then parse and return its `monolith` model.

    Args:
        surface: `(method, version)` to wire-type map; the version-gate lookup
            and (per-schema-era) shape check run against this. Pass an extended
            map to admit custom methods.
        monolith: `method` to version-free model map; the returned instance is
            parsed from this row. Must cover every method `surface` admits.

    Raises:
        ValueError: `version` is not a known protocol version.
        KeyError: `(method, version)` is not in `surface`.
        pydantic.ValidationError: result fails surface or monolith validation.
        RuntimeError: surface matched but `method` has no monolith row.
    """
    validate_client_result(method, version, data, surface=surface)
    result: types.Result = _adapter(_monolith_row(monolith, method)).validate_python(data, by_name=False)
    return result

WarmReport dataclass

What one warm() call built (already-built work is skipped and not counted).

A frozen dataclass rather than a tuple, so a later field addition does not change how existing fields are read.

Source code in src/mcp-types/mcp_types/methods.py
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
@dataclass(frozen=True)
class WarmReport:
    """What one `warm()` call built (already-built work is skipped and not counted).

    A frozen dataclass rather than a tuple, so a later field addition does not
    change how existing fields are read.
    """

    models: int
    """Deferred model classes whose validators this call built."""

    adapters: int
    """Deferred TypeAdapters (union / routing adapters) this call built."""

    elapsed_ms: float
    """Wall-clock milliseconds the call took."""

models instance-attribute

models: int

Deferred model classes whose validators this call built.

adapters instance-attribute

adapters: int

Deferred TypeAdapters (union / routing adapters) this call built.

elapsed_ms instance-attribute

elapsed_ms: float

Wall-clock milliseconds the call took.

warm

warm(
    version: str | None = None,
    *,
    all_versions: bool = False
) -> WarmReport

Build the SDK's deferred validators up front, before the first message needs them.

Importing the SDK stays fast because pydantic validators build on first use and each protocol version's wire schemas load with the first message parsed at that version. A long-running host that would rather pay that once, at startup, calls this from a startup hook; nothing in the SDK calls it, and steady-state behaviour is identical either way.

  • warm(version) is what a host wants: it builds the version-independent set (below) and imports that protocol version's wire package and builds its routing surface (the wire models and the cached adapters a connection at that version routes through), so the first connection at that version builds nothing.
  • warm() builds only the version-independent set: the monolith mcp_types models a session routes through, the JSON-RPC envelopes and the module-level union adapters. The first connection still imports and builds its version's routing surface.
  • warm(all_versions=True) warms every known protocol version's routing surface, for a proxy or gateway that serves clients of both eras.

Model classes are completed before the adapters that reference them are built, so no schema is generated twice; anything already built is skipped, so the call is idempotent and repeat calls are cheap.

Parameters:

Name Type Description Default
version str | None

The protocol version whose routing surface to build too.

None
all_versions bool

Warm every known protocol version's routing surface (a proxy or gateway serving both eras; benchmarks and tests).

False

Returns:

Type Description
WarmReport

Counts of what this call built and the milliseconds it took.

Raises:

Type Description
ValueError

version is not a known protocol version.

Source code in src/mcp-types/mcp_types/methods.py
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
def warm(version: str | None = None, *, all_versions: bool = False) -> WarmReport:
    """Build the SDK's deferred validators up front, before the first message needs them.

    Importing the SDK stays fast because pydantic validators build on first use
    and each protocol version's wire schemas load with the first message parsed
    at that version. A long-running host that would rather pay that once, at
    startup, calls this from a startup hook; nothing in the SDK calls it, and
    steady-state behaviour is identical either way.

    * `warm(version)` is what a host wants: it builds the version-independent
      set (below) and imports that protocol version's wire package and builds
      its routing surface (the wire models and the cached adapters a
      connection at that version routes through), so the first connection at
      that version builds nothing.
    * `warm()` builds only the version-independent set: the monolith
      `mcp_types` models a session routes through, the JSON-RPC envelopes and
      the module-level union adapters. The first connection still imports and
      builds its version's routing surface.
    * `warm(all_versions=True)` warms every known protocol version's routing
      surface, for a proxy or gateway that serves clients of both eras.

    Model classes are completed before the adapters that reference them are
    built, so no schema is generated twice; anything already built is skipped,
    so the call is idempotent and repeat calls are cheap.

    Args:
        version: The protocol version whose routing surface to build too.
        all_versions: Warm every known protocol version's routing surface
            (a proxy or gateway serving both eras; benchmarks and tests).

    Returns:
        Counts of what this call built and the milliseconds it took.

    Raises:
        ValueError: `version` is not a known protocol version.
    """
    started = time.perf_counter()
    versions: list[str] = []
    if all_versions:
        versions = sorted(KNOWN_PROTOCOL_VERSIONS)
    elif version is not None:
        _check_known_version(version)
        versions = [version]

    # Model classes first (the exported monolith models, the JSON-RPC
    # envelopes, then the wire packages and their routing rows), so the
    # adapters below never generate a referenced model's schema inline.
    models = _warm_models(getattr(types, name) for name in types.__all__)
    models += _warm_models(row for monolith in _ALL_MONOLITHS for row in monolith.values())
    models += _warm_models(get_args(jsonrpc.JSONRPCMessage))
    rows: list[Any] = []
    for warmed_version in versions:
        package = _wire_package(warmed_version)  # imports the package once
        models += _warm_models(vars(package).values())
        for surface in _ALL_SURFACES:
            rows.extend(surface[key] for key in surface if key[1] == warmed_version)
    models += _warm_models(rows)

    adapters = _warm_adapter(jsonrpc.jsonrpc_message_adapter)
    for adapter in (
        types.client_request_adapter,
        types.client_notification_adapter,
        types.client_result_adapter,
        types.server_request_adapter,
        types.server_notification_adapter,
        types.server_result_adapter,
    ):
        adapters += _warm_adapter(adapter)
    for row in rows:
        # `_adapter` is the cached routing-adapter builder the parse/serialize
        # functions use; warming it here (and completing the adapter's own
        # core schema from the now-complete row model) leaves nothing for the
        # first message at that version to build.
        adapters += _warm_adapter(_adapter(row))
    return WarmReport(models=models, adapters=adapters, elapsed_ms=round((time.perf_counter() - started) * 1000, 1))