Skip to content

tool_name_validation

Tool name validation utilities according to SEP-986.

Tool names SHOULD be between 1 and 128 characters in length (inclusive). Tool names are case-sensitive. Allowed characters: uppercase and lowercase ASCII letters (A-Z, a-z), digits (0-9), underscore (_), dash (-), and dot (.). Tool names SHOULD NOT contain spaces, commas, or other special characters.

See: https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names

ToolNameValidationResult dataclass

Result of tool name validation.

Attributes:

Name Type Description
is_valid bool

Whether the tool name conforms to SEP-986 requirements.

warnings list[str]

List of warning messages for non-conforming aspects.

Source code in src/mcp/shared/tool_name_validation.py
27
28
29
30
31
32
33
34
35
36
37
@dataclass
class ToolNameValidationResult:
    """Result of tool name validation.

    Attributes:
        is_valid: Whether the tool name conforms to SEP-986 requirements.
        warnings: List of warning messages for non-conforming aspects.
    """

    is_valid: bool
    warnings: list[str] = field(default_factory=lambda: [])

validate_tool_name

validate_tool_name(name: str) -> ToolNameValidationResult

Validate a tool name according to the SEP-986 specification.

Parameters:

Name Type Description Default
name str

The tool name to validate.

required

Returns:

Type Description
ToolNameValidationResult

ToolNameValidationResult containing validation status and any warnings.

Source code in src/mcp/shared/tool_name_validation.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def validate_tool_name(name: str) -> ToolNameValidationResult:
    """Validate a tool name according to the SEP-986 specification.

    Args:
        name: The tool name to validate.

    Returns:
        ToolNameValidationResult containing validation status and any warnings.
    """
    warnings: list[str] = []

    # Check for empty name
    if not name:
        return ToolNameValidationResult(
            is_valid=False,
            warnings=["Tool name cannot be empty"],
        )

    # Check length
    if len(name) > 128:
        return ToolNameValidationResult(
            is_valid=False,
            warnings=[f"Tool name exceeds maximum length of 128 characters (current: {len(name)})"],
        )

    # Check for problematic patterns (warnings, not validation failures)
    if " " in name:
        warnings.append("Tool name contains spaces, which may cause parsing issues")

    if "," in name:
        warnings.append("Tool name contains commas, which may cause parsing issues")

    # Check for potentially confusing leading/trailing characters
    if name.startswith("-") or name.endswith("-"):
        warnings.append("Tool name starts or ends with a dash, which may cause parsing issues in some contexts")

    if name.startswith(".") or name.endswith("."):
        warnings.append("Tool name starts or ends with a dot, which may cause parsing issues in some contexts")

    # Check for invalid characters
    if not TOOL_NAME_REGEX.match(name):
        # Find all invalid characters (unique, preserving order)
        invalid_chars: list[str] = []
        seen: set[str] = set()
        for char in name:
            if not re.match(r"[A-Za-z0-9._-]", char) and char not in seen:
                invalid_chars.append(char)
                seen.add(char)

        warnings.append(f"Tool name contains invalid characters: {', '.join(repr(c) for c in invalid_chars)}")
        warnings.append("Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)")

        return ToolNameValidationResult(is_valid=False, warnings=warnings)

    return ToolNameValidationResult(is_valid=True, warnings=warnings)

issue_tool_name_warning

issue_tool_name_warning(
    name: str, warnings: list[str]
) -> None

Log warnings for non-conforming tool names.

Parameters:

Name Type Description Default
name str

The tool name that triggered the warnings.

required
warnings list[str]

List of warning messages to log.

required
Source code in src/mcp/shared/tool_name_validation.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def issue_tool_name_warning(name: str, warnings: list[str]) -> None:
    """Log warnings for non-conforming tool names.

    Args:
        name: The tool name that triggered the warnings.
        warnings: List of warning messages to log.
    """
    if not warnings:
        return

    logger.warning(f'Tool name validation warning for "{name}":')
    for warning in warnings:
        logger.warning(f"  - {warning}")
    logger.warning("Tool registration will proceed, but this may cause compatibility issues.")
    logger.warning("Consider updating the tool name to conform to the MCP tool naming standard.")
    logger.warning(f"See SEP-986 ({SEP_986_URL}) for more details.")

validate_and_warn_tool_name

validate_and_warn_tool_name(name: str) -> bool

Validate a tool name and issue warnings for non-conforming names.

This is the primary entry point for tool name validation. It validates the name and logs any warnings via the logging module.

Parameters:

Name Type Description Default
name str

The tool name to validate.

required

Returns:

Type Description
bool

True if the name is valid, False otherwise.

Source code in src/mcp/shared/tool_name_validation.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
def validate_and_warn_tool_name(name: str) -> bool:
    """Validate a tool name and issue warnings for non-conforming names.

    This is the primary entry point for tool name validation. It validates
    the name and logs any warnings via the logging module.

    Args:
        name: The tool name to validate.

    Returns:
        True if the name is valid, False otherwise.
    """
    result = validate_tool_name(name)
    issue_tool_name_warning(name, result.warnings)
    return result.is_valid