PrefectHQ/fastmcp · error · ValueError

Invalid URL: {url}

Error message

Invalid URL: {url}

What it means

infer_transport_type_from_url only accepts HTTP(S) URLs, since it exists to pick between the 'http' (streamable) and 'sse' MCP transports, both of which require an http/https endpoint. If the string does not start with 'http', it raises ValueError('Invalid URL: ...'). This catches typos like forgetting the scheme entirely.

Source

Thrown at fastmcp_slim/fastmcp/mcp_config.py:63

if TYPE_CHECKING:
    from fastmcp.client.transports import (
        ClientTransport,
        FastMCPTransport,
        SSETransport,
        StdioTransport,
        StreamableHttpTransport,
    )


def infer_transport_type_from_url(
    url: str | AnyUrl,
) -> Literal["http", "sse"]:
    """
    Infer the appropriate transport type from the given URL.
    """
    url = str(url)
    if not url.startswith("http"):
        raise ValueError(f"Invalid URL: {url}")

    parsed_url = urlparse(url)
    path = parsed_url.path

    # Match /sse followed by /, ?, &, or end of string
    if re.search(r"/sse(/|\?|&|$)", path):
        return "sse"
    else:
        return "http"


def _coerce_tool_transform_configs(tools: dict[str, Any]) -> dict[str, Any]:
    from fastmcp.tools.tool_transform import ToolTransformConfig

    return {
        name: config
        if isinstance(config, ToolTransformConfig)
        else ToolTransformConfig.model_validate(config)

View on GitHub (pinned to 1f02114297)

Solutions

  1. Prepend the scheme: use 'https://host/path' (or http:// for local dev)
  2. Validate the URL with urlparse before calling
  3. Check the config file entry actually contains a full URL, not a host:port pair

Example fix

// before
transport = infer_transport("localhost:8000/mcp")
// after
transport = infer_transport("https://localhost:8000/mcp")
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
def is_valid_http_url(url) -> bool:
    u = urlparse(str(url))
    return u.scheme in ("http", "https") and bool(u.netloc)

Type guard

def is_http_url(v: object) -> bool:
    try:
        u = urlparse(str(v))
    except ValueError:
        return False
    return u.scheme in ("http", "https") and bool(u.netloc)

Prevention

When it happens

Trigger: Passing a URL like 'localhost:8000/mcp' (no scheme), 'ftp://host/sse', or a bare hostname/path to infer_transport_type_from_url, infer_transport, or an MCPConfig server entry with an http_url-based remote server lacking an http(s) URL.

Common situations: Copy-pasting a server address from docs that omits 'https://'; building the URL from env vars where the scheme variable is empty; hand-editing .mcp.json entries.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/693d3c8deb8aad28. Report an issue: GitHub.