Skip to content

Commit 45b1ed6

Browse files
committed
fix: Utilize pydantic constraints
1 parent f80e09f commit 45b1ed6

File tree

2 files changed

+2
-37
lines changed

2 files changed

+2
-37
lines changed

src/mcp/types.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import re
21
from collections.abc import Callable
32
from typing import Annotated, Any, Generic, Literal, TypeAlias, TypeVar
43

5-
from pydantic import BaseModel, ConfigDict, Field, FileUrl, RootModel, field_validator
4+
from pydantic import BaseModel, ConfigDict, Field, FileUrl, RootModel, StringConstraints
65
from pydantic.networks import AnyUrl, UrlConstraints
76
from typing_extensions import deprecated
87

@@ -40,10 +39,6 @@
4039
RequestId = Annotated[int, Field(strict=True)] | str
4140
AnyFunction: TypeAlias = Callable[..., Any]
4241

43-
# Tool name validation pattern (ASCII letters, digits, underscore, dash, dot)
44-
# Pattern ensures entire string contains only valid characters by using ^ and $ anchors
45-
TOOL_NAME_PATTERN = re.compile(r"^[A-Za-z0-9_.-]+$")
46-
4742

4843
class RequestParams(BaseModel):
4944
class Meta(BaseModel):
@@ -204,7 +199,7 @@ class EmptyResult(Result):
204199
class BaseMetadata(BaseModel):
205200
"""Base class for entities with name and optional title fields."""
206201

207-
name: str
202+
name: Annotated[str, StringConstraints(min_length=1, max_length=128, pattern=r"^[A-Za-z0-9_.-]+$")]
208203
"""The programmatic name of the entity."""
209204

210205
title: str | None = None
@@ -896,17 +891,6 @@ class Tool(BaseMetadata):
896891
"""
897892
model_config = ConfigDict(extra="allow")
898893

899-
@field_validator("name")
900-
@classmethod
901-
def _validate_tool_name(cls, value: str) -> str:
902-
if not (1 <= len(value) <= 128):
903-
raise ValueError(f"Invalid tool name length: {len(value)}. Tool name must be between 1 and 128 characters.")
904-
905-
if not TOOL_NAME_PATTERN.fullmatch(value):
906-
raise ValueError("Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.).")
907-
908-
return value
909-
910894
"""
911895
See [MCP specification](https://modelcontextprotocol.io/specification/draft/server/tools#tool-names)
912896
for more information on tool naming conventions.

tests/test_types.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,3 @@ async def test_method_initialization():
7272
)
7373
def test_tool_allows_valid_names(name: str) -> None:
7474
Tool(name=name, inputSchema={"type": "object"})
75-
76-
77-
@pytest.mark.parametrize(
78-
("name", "expected"),
79-
[
80-
("", "Invalid tool name length: 0. Tool name must be between 1 and 128 characters."),
81-
("x" * 129, "Invalid tool name length: 129. Tool name must be between 1 and 128 characters."),
82-
("has space", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
83-
("comma,name", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
84-
("not/allowed", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
85-
("name@", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
86-
("name#", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
87-
("name$", "Invalid tool name characters. Allowed: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.)."),
88-
],
89-
)
90-
def test_tool_rejects_invalid_names(name: str, expected: str) -> None:
91-
with pytest.raises(ValueError) as exc_info:
92-
Tool(name=name, inputSchema={"type": "object"})
93-
assert expected in str(exc_info.value)

0 commit comments

Comments
 (0)