fix: bracket IPv6 hosts in server startup log URL (#4372)

This commit is contained in:
Jeremiah Lowin 2026-06-24 17:15:40 -04:00 committed by GitHub
commit ade2b3ff46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 1 deletions

View file

@ -35,6 +35,19 @@ if TYPE_CHECKING:
logger = get_logger(__name__)
def _format_host_for_url(host: str) -> str:
"""Format a host for inclusion in a URL, bracketing IPv6 addresses.
A bare IPv6 address like ``::1`` must be wrapped in brackets when placed
before a ``:port`` suffix, otherwise the result (``http://::1:8000``) is an
invalid URL. Hostnames and IPv4 addresses are returned unchanged, as are
addresses that are already bracketed.
"""
if ":" in host and not host.startswith("["):
return f"[{host}]"
return host
class TransportMixin:
"""Mixin providing transport-related methods for FastMCP.
@ -301,8 +314,9 @@ class TransportMixin:
server = uvicorn.Server(config)
path = getattr(app.state, "path", "").lstrip("/")
mode = " (stateless)" if stateless_http else ""
display_host = _format_host_for_url(host)
logger.info(
f"Starting MCP server {self.name!r} with transport {transport!r}{mode} on http://{host}:{port}/{path}"
f"Starting MCP server {self.name!r} with transport {transport!r}{mode} on http://{display_host}:{port}/{path}"
)
if sockets is not None:

View file

@ -0,0 +1,20 @@
import pytest
from fastmcp.server.mixins.transport import _format_host_for_url
@pytest.mark.parametrize(
"host, expected",
[
("127.0.0.1", "127.0.0.1"),
("localhost", "localhost"),
("0.0.0.0", "0.0.0.0"),
("::1", "[::1]"),
("::", "[::]"),
("fe80::1", "[fe80::1]"),
("[::1]", "[::1]"),
],
)
def test_format_host_for_url(host: str, expected: str):
"""IPv6 hosts are bracketed for use in a URL; everything else is unchanged."""
assert _format_host_for_url(host) == expected