Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/mcp/server/lowlevel/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ def pkg_version(package: str) -> str:
try:
from importlib.metadata import version

return version(package)
# `version()` can return None (not just raise) on some
# environments, e.g. an embedded Python whose package metadata
# is present but unreadable; `server_version` is typed `str`,
# so fall back to "unknown" rather than let None crash init.
return version(package) or "unknown"
except Exception: # pragma: no cover
pass

Expand Down
19 changes: 19 additions & 0 deletions tests/server/test_lowlevel_input_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,22 @@ async def test_callback(client_session: ClientSession) -> CallToolResult:
assert any(
"Tool 'unknown_tool' not listed, no validation will be performed" in record.message for record in caplog.records
)


def test_create_initialization_options_falls_back_when_package_version_is_none(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""A None from importlib.metadata.version does not crash create_initialization_options.

On some environments (e.g. an embedded Python whose package metadata is present but
unreadable) importlib.metadata.version returns None instead of raising. server_version is
typed str, so without a guard that None reaches InitializationOptions and raises a
ValidationError, killing the server before the stdio handshake. It must fall back to
"unknown" instead.
"""
monkeypatch.setattr("importlib.metadata.version", lambda package: None)

# No explicit version, so create_initialization_options falls back to pkg_version("mcp").
options = Server("test-server").create_initialization_options()

assert options.server_version == "unknown"
Loading