Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-fastmcp-slim for
openSUSE:Factory checked in at 2026-07-09 22:20:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-fastmcp-slim (Old)
and /work/SRC/openSUSE:Factory/.python-fastmcp-slim.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-fastmcp-slim"
Thu Jul 9 22:20:26 2026 rev:4 rq:1364635 version:3.4.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-fastmcp-slim/python-fastmcp-slim.changes
2026-07-06 12:37:38.654481303 +0200
+++
/work/SRC/openSUSE:Factory/.python-fastmcp-slim.new.1991/python-fastmcp-slim.changes
2026-07-09 22:21:11.853839732 +0200
@@ -1,0 +2,10 @@
+Thu Jul 9 05:28:00 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 3.4.4:
+ * Relax the Streamable HTTP host/origin guard defaults added in
+ 3.4.3 to restore compatibility with existing ASGI, serverless
+ and reverse-proxy deployments
+ * Add Hugging Face OAuth authentication provider (PKCE, Dynamic
+ Client Registration)
+
+-------------------------------------------------------------------
Old:
----
fastmcp_slim-3.4.3.tar.gz
New:
----
fastmcp_slim-3.4.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-fastmcp-slim.spec ++++++
--- /var/tmp/diff_new_pack.xWG3se/_old 2026-07-09 22:21:12.513862278 +0200
+++ /var/tmp/diff_new_pack.xWG3se/_new 2026-07-09 22:21:12.517862414 +0200
@@ -17,7 +17,7 @@
Name: python-fastmcp-slim
-Version: 3.4.3
+Version: 3.4.4
Release: 0
Summary: The fast, Pythonic way to build MCP servers and clients (slim)
License: Apache-2.0
++++++ fastmcp_slim-3.4.3.tar.gz -> fastmcp_slim-3.4.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fastmcp_slim-3.4.3/PKG-INFO
new/fastmcp_slim-3.4.4/PKG-INFO
--- old/fastmcp_slim-3.4.3/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/fastmcp_slim-3.4.4/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: fastmcp-slim
-Version: 3.4.3
+Version: 3.4.4
Summary: The dependency-slim FastMCP package.
Project-URL: Homepage, https://gofastmcp.com
Project-URL: Repository, https://github.com/PrefectHQ/fastmcp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/fastmcp_slim-3.4.3/fastmcp/server/auth/providers/huggingface.py
new/fastmcp_slim-3.4.4/fastmcp/server/auth/providers/huggingface.py
--- old/fastmcp_slim-3.4.3/fastmcp/server/auth/providers/huggingface.py
1970-01-01 01:00:00.000000000 +0100
+++ new/fastmcp_slim-3.4.4/fastmcp/server/auth/providers/huggingface.py
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,279 @@
+"""Hugging Face OAuth provider for FastMCP."""
+
+from __future__ import annotations
+
+import contextlib
+from collections.abc import Mapping
+from typing import Any, Literal
+
+import httpx
+from key_value.aio.protocols import AsyncKeyValue
+from pydantic import AnyHttpUrl
+
+from fastmcp.server.auth import TokenVerifier
+from fastmcp.server.auth.auth import AccessToken
+from fastmcp.server.auth.oauth_proxy import OAuthProxy
+from fastmcp.utilities.auth import parse_scopes
+from fastmcp.utilities.logging import get_logger
+
+logger = get_logger(__name__)
+
+HUGGINGFACE_AUTHORIZATION_ENDPOINT = "https://huggingface.co/oauth/authorize"
+HUGGINGFACE_TOKEN_ENDPOINT = "https://huggingface.co/oauth/token"
+HUGGINGFACE_USERINFO_ENDPOINT = "https://huggingface.co/oauth/userinfo"
+HUGGINGFACE_WHOAMI_ENDPOINT = "https://huggingface.co/api/whoami-v2"
+
+DEFAULT_HUGGINGFACE_SCOPES = ["openid", "profile"]
+
+
+def _extract_scopes(data: Mapping[str, Any]) -> list[str]:
+ scope_value = data.get("scope") or data.get("scopes")
+ if isinstance(scope_value, str):
+ return parse_scopes(scope_value) or []
+ if isinstance(scope_value, list):
+ return [str(scope).strip() for scope in scope_value if
str(scope).strip()]
+
+ auth = data.get("auth")
+ if not isinstance(auth, Mapping):
+ return []
+ access_token = auth.get("accessToken")
+ if not isinstance(access_token, Mapping):
+ return []
+
+ nested_scopes = access_token.get("scopes") or access_token.get("scope")
+ if isinstance(nested_scopes, str):
+ return parse_scopes(nested_scopes) or []
+ if isinstance(nested_scopes, list):
+ return [
+ str(scope.get("name") if isinstance(scope, Mapping) else
scope).strip()
+ for scope in nested_scopes
+ if str(scope.get("name") if isinstance(scope, Mapping) else
scope).strip()
+ ]
+ return []
+
+
+class HuggingFaceTokenVerifier(TokenVerifier):
+ """Token verifier for Hugging Face OAuth access tokens.
+
+ Hugging Face OAuth access tokens are opaque, so validation is performed by
+ calling Hugging Face's userinfo endpoint.
+ """
+
+ def __init__(
+ self,
+ *,
+ required_scopes: list[str] | None = None,
+ timeout_seconds: int = 10,
+ http_client: httpx.AsyncClient | None = None,
+ ):
+ super().__init__(required_scopes=required_scopes)
+ self.timeout_seconds = timeout_seconds
+ self._http_client = http_client
+
+ async def verify_token(self, token: str) -> AccessToken | None:
+ """Verify a Hugging Face OAuth token using the userinfo endpoint."""
+ try:
+ async with (
+ contextlib.nullcontext(self._http_client)
+ if self._http_client is not None
+ else httpx.AsyncClient(timeout=self.timeout_seconds)
+ ) as client:
+ userinfo_response = await client.get(
+ HUGGINGFACE_USERINFO_ENDPOINT,
+ headers={
+ "Authorization": f"Bearer {token}",
+ "User-Agent": "FastMCP-HuggingFace-OAuth",
+ },
+ )
+ if userinfo_response.status_code != 200:
+ logger.debug(
+ "Hugging Face token verification failed: %d",
+ userinfo_response.status_code,
+ )
+ return None
+
+ userinfo = userinfo_response.json()
+ sub = userinfo.get("sub")
+ if not sub:
+ logger.debug("Hugging Face userinfo missing 'sub' claim")
+ return None
+
+ token_scopes = _extract_scopes(userinfo)
+ whoami: dict[str, Any] | None = None
+ if not token_scopes or (
+ self.required_scopes
+ and not
set(self.required_scopes).issubset(set(token_scopes))
+ ):
+ whoami = await self._fetch_whoami(client, token)
+ if whoami:
+ token_scopes = list(
+ dict.fromkeys([*token_scopes,
*_extract_scopes(whoami)])
+ )
+
+ if not token_scopes:
+ token_scopes = list(DEFAULT_HUGGINGFACE_SCOPES)
+
+ if self.required_scopes and not
set(self.required_scopes).issubset(
+ set(token_scopes)
+ ):
+ logger.debug(
+ "Hugging Face token missing required scopes. Has %d,
needs %d",
+ len(token_scopes),
+ len(self.required_scopes),
+ )
+ return None
+
+ username = (
+ userinfo.get("preferred_username")
+ or userinfo.get("nickname")
+ or userinfo.get("name")
+ )
+ return AccessToken(
+ token=token,
+ client_id=str(sub),
+ scopes=token_scopes,
+ expires_at=None,
+ claims={
+ "sub": str(sub),
+ "name": userinfo.get("name"),
+ "preferred_username": username,
+ "email": userinfo.get("email"),
+ "email_verified": userinfo.get("email_verified"),
+ "profile": userinfo.get("profile"),
+ "picture": userinfo.get("picture"),
+ "organizations": userinfo.get("organizations"),
+ "huggingface_userinfo": userinfo,
+ "huggingface_whoami": whoami,
+ },
+ )
+
+ except httpx.RequestError as e:
+ logger.debug("Failed to verify Hugging Face token: %s", e)
+ return None
+ except Exception as e:
+ logger.debug("Hugging Face token verification error: %s", e)
+ return None
+
+ async def _fetch_whoami(
+ self, client: httpx.AsyncClient, token: str
+ ) -> dict[str, Any] | None:
+ response = await client.get(
+ HUGGINGFACE_WHOAMI_ENDPOINT,
+ headers={
+ "Authorization": f"Bearer {token}",
+ "User-Agent": "FastMCP-HuggingFace-OAuth",
+ },
+ )
+ if response.status_code != 200:
+ logger.debug("Hugging Face whoami lookup failed: %d",
response.status_code)
+ return None
+ return response.json()
+
+
+class HuggingFaceProvider(OAuthProxy):
+ """Complete Hugging Face OAuth provider for FastMCP."""
+
+ def __init__(
+ self,
+ *,
+ client_id: str,
+ client_secret: str | None = None,
+ base_url: AnyHttpUrl | str,
+ resource_base_url: AnyHttpUrl | str | None = None,
+ issuer_url: AnyHttpUrl | str | None = None,
+ redirect_path: str | None = None,
+ required_scopes: list[str] | None = None,
+ valid_scopes: list[str] | None = None,
+ timeout_seconds: int = 10,
+ allowed_client_redirect_uris: list[str] | None = None,
+ client_storage: AsyncKeyValue | None = None,
+ jwt_signing_key: str | bytes | None = None,
+ require_authorization_consent: bool | Literal["remember", "external"]
= True,
+ consent_csp_policy: str | None = None,
+ forward_resource: bool = True,
+ fallback_refresh_token_expiry_seconds: int | None = None,
+ fastmcp_access_token_expiry_seconds: int | None = None,
+ token_expiry_threshold_seconds: int = 0,
+ extra_authorize_params: dict[str, str] | None = None,
+ extra_token_params: dict[str, str] | None = None,
+ http_client: httpx.AsyncClient | None = None,
+ enable_cimd: bool = True,
+ ):
+ """Initialize Hugging Face OAuth provider.
+
+ Args:
+ client_id: Hugging Face OAuth app client ID. Public apps and CIMD
+ client IDs are supported.
+ client_secret: Hugging Face OAuth app client secret. Optional for
+ public PKCE apps; when omitted, ``jwt_signing_key`` is
required.
+ base_url: Public URL where OAuth endpoints will be accessible.
+ required_scopes: Required Hugging Face scopes. Defaults to
+ ``["openid", "profile"]``.
+ valid_scopes: Scopes clients may request. Defaults to required
scopes.
+ extra_authorize_params: Extra authorization parameters, such as
+ ``{"orgIds": "your-org-id"}`` for organization grants.
+ """
+ required_scopes_final = (
+ parse_scopes(required_scopes)
+ if required_scopes is not None
+ else list(DEFAULT_HUGGINGFACE_SCOPES)
+ ) or []
+ valid_scopes_final = parse_scopes(valid_scopes)
+
+ # Do not pass provider-level required_scopes into the verifier here.
+ # Hugging Face's userinfo endpoint validates opaque access tokens and
+ # returns identity claims, but granted scopes are carried reliably in
+ # the upstream token response. OAuthProxy stores those scopes, enforces
+ # provider.required_scopes against FastMCP-issued tokens, and
+ # _uses_alternate_verification() patches the stored upstream scopes
+ # onto the returned AccessToken.
+ token_verifier = HuggingFaceTokenVerifier(
+ timeout_seconds=timeout_seconds,
+ http_client=http_client,
+ )
+
+ super().__init__(
+ upstream_authorization_endpoint=HUGGINGFACE_AUTHORIZATION_ENDPOINT,
+ upstream_token_endpoint=HUGGINGFACE_TOKEN_ENDPOINT,
+ upstream_client_id=client_id,
+ upstream_client_secret=client_secret,
+ token_verifier=token_verifier,
+ base_url=base_url,
+ resource_base_url=resource_base_url,
+ redirect_path=redirect_path,
+ issuer_url=issuer_url or base_url,
+ allowed_client_redirect_uris=allowed_client_redirect_uris,
+ client_storage=client_storage,
+ jwt_signing_key=jwt_signing_key,
+ require_authorization_consent=require_authorization_consent,
+ consent_csp_policy=consent_csp_policy,
+ forward_resource=forward_resource,
+
fallback_refresh_token_expiry_seconds=fallback_refresh_token_expiry_seconds,
+
fastmcp_access_token_expiry_seconds=fastmcp_access_token_expiry_seconds,
+ token_expiry_threshold_seconds=token_expiry_threshold_seconds,
+ extra_authorize_params=extra_authorize_params,
+ extra_token_params=extra_token_params,
+ token_endpoint_auth_method="client_secret_basic"
+ if client_secret
+ else "none",
+ valid_scopes=valid_scopes_final,
+ enable_cimd=enable_cimd,
+ )
+
+ logger.debug(
+ "Initialized Hugging Face OAuth provider for client %s with
scopes: %s",
+ client_id,
+ required_scopes_final,
+ )
+
+ self.required_scopes = required_scopes_final
+ self.update_default_scopes(valid_scopes_final or required_scopes_final)
+
+ def _uses_alternate_verification(self) -> bool:
+ """Patch returned token scopes from the upstream token response.
+
+ Hugging Face OAuth access tokens are opaque. The userinfo endpoint
+ validates the token and returns identity claims, but scope information
is
+ carried by the token response stored in OAuthProxy's upstream token
set.
+ """
+ return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fastmcp_slim-3.4.3/fastmcp/server/http.py
new/fastmcp_slim-3.4.4/fastmcp/server/http.py
--- old/fastmcp_slim-3.4.3/fastmcp/server/http.py 2020-02-02
01:00:00.000000000 +0100
+++ new/fastmcp_slim-3.4.4/fastmcp/server/http.py 2020-02-02
01:00:00.000000000 +0100
@@ -5,7 +5,7 @@
from contextvars import ContextVar
from fnmatch import fnmatchcase
from ipaddress import ip_address
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, Literal
from urllib.parse import urlsplit
from uuid import uuid4
@@ -36,6 +36,8 @@
logger = get_logger(__name__)
DEFAULT_HOSTS = ("127.0.0.1", "localhost", "::1")
+HostOriginProtection = bool | Literal["auto"]
+HostOriginProtectionMode = Literal["auto", "strict"]
class FastMCPStreamableHTTPSessionManager(StreamableHTTPSessionManager):
@@ -228,34 +230,81 @@
app: ASGIApp,
allowed_hosts: Sequence[str] | None = None,
allowed_origins: Sequence[str] | None = None,
+ mode: HostOriginProtectionMode = "auto",
) -> None:
self.app = app
self.allowed_hosts = tuple(allowed_hosts or ())
self.allowed_origins = tuple(allowed_origins or ())
+ self.mode = mode
+ self.has_explicit_allowed_hosts = allowed_hosts is not None
+ self.has_explicit_allowed_origins = allowed_origins is not None
async def __call__(self, scope: Scope, receive: Receive, send: Send) ->
None:
if scope["type"] != "http":
await self.app(scope, receive, send)
return
- allowed_hosts = self._allowed_hosts_for_scope(scope)
headers = Headers(scope=scope)
host = headers.get("host", "")
- if not _host_matches(host, allowed_hosts):
+ if self._should_validate_host(scope) and not _host_matches(
+ host,
+ self._allowed_hosts_for_scope(scope),
+ ):
response = Response("Misdirected Request", status_code=421)
await response(scope, receive, send)
return
origin = headers.get("origin")
request_origin = _request_origin(scope, host)
- if origin and not self._origin_allowed(origin, request_origin, host):
+ if (
+ origin
+ and self._should_validate_origin(scope, host)
+ and not self._origin_allowed(
+ origin,
+ request_origin,
+ host,
+ allow_same_origin_fallback=self._allow_same_origin_fallback(
+ scope,
+ host,
+ ),
+ )
+ ):
response = Response("Forbidden Origin", status_code=403)
await response(scope, receive, send)
return
await self.app(scope, receive, send)
+ def _should_validate_host(self, scope: Scope) -> bool:
+ if self.mode == "strict" or self.has_explicit_allowed_hosts:
+ return True
+
+ server = scope.get("server")
+ return bool(server and _is_loopback_host(server[0]))
+
+ def _should_validate_origin(self, scope: Scope, host: str) -> bool:
+ if (
+ self.mode == "strict"
+ or self.has_explicit_allowed_hosts
+ or self.has_explicit_allowed_origins
+ or _is_loopback_host(host)
+ ):
+ return True
+
+ server = scope.get("server")
+ return bool(server and _is_loopback_host(server[0]))
+
+ def _allow_same_origin_fallback(self, scope: Scope, host: str) -> bool:
+ if not self.has_explicit_allowed_origins:
+ return True
+
+ if self.mode == "strict" or self.has_explicit_allowed_hosts:
+ return True
+
+ server = scope.get("server")
+ return _is_loopback_host(host) or bool(server and
_is_loopback_host(server[0]))
+
def _allowed_hosts_for_scope(self, scope: Scope) -> tuple[str, ...]:
allowed_hosts = list(DEFAULT_HOSTS)
allowed_hosts.extend(self.allowed_hosts)
@@ -268,10 +317,19 @@
return tuple(allowed_hosts)
- def _origin_allowed(self, origin: str, request_origin: str, host: str) ->
bool:
+ def _origin_allowed(
+ self,
+ origin: str,
+ request_origin: str,
+ host: str,
+ allow_same_origin_fallback: bool,
+ ) -> bool:
if _origin_matches(origin, self.allowed_origins):
return True
+ if not allow_same_origin_fallback:
+ return False
+
origin_host = _origin_host(origin)
if _is_loopback_host(origin_host) and _is_loopback_host(host):
return True
@@ -491,7 +549,7 @@
debug: bool = False,
routes: list[BaseRoute] | None = None,
middleware: list[Middleware] | None = None,
- host_origin_protection: bool = True,
+ host_origin_protection: HostOriginProtection = False,
allowed_hosts: Sequence[str] | None = None,
allowed_origins: Sequence[str] | None = None,
) -> StarletteWithLifespan:
@@ -511,7 +569,9 @@
routes: Optional list of custom routes
middleware: Optional list of middleware
host_origin_protection: Whether to validate Host and Origin headers
- before requests reach the MCP endpoint.
+ before requests reach the MCP endpoint. Defaults to False for
+ compatibility. "auto" protects localhost-bound servers and explicit
+ host/origin allowlists.
allowed_hosts: Additional hostnames that may appear in the Host header.
allowed_origins: Additional browser origins trusted by the request
guard.
Configure CORS separately when browser JavaScript must read
@@ -576,13 +636,17 @@
server_routes.extend(server._get_additional_http_routes())
# Add middleware
- if host_origin_protection:
+ if host_origin_protection not in (True, False, "auto"):
+ raise ValueError("host_origin_protection must be True, False, or
'auto'.")
+
+ if host_origin_protection is not False:
server_middleware.insert(
0,
Middleware(
HostOriginGuardMiddleware,
allowed_hosts=allowed_hosts,
allowed_origins=allowed_origins,
+ mode="strict" if host_origin_protection is True else "auto",
),
)
if middleware:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/fastmcp_slim-3.4.3/fastmcp/server/mixins/transport.py
new/fastmcp_slim-3.4.4/fastmcp/server/mixins/transport.py
--- old/fastmcp_slim-3.4.3/fastmcp/server/mixins/transport.py 2020-02-02
01:00:00.000000000 +0100
+++ new/fastmcp_slim-3.4.4/fastmcp/server/mixins/transport.py 2020-02-02
01:00:00.000000000 +0100
@@ -19,7 +19,9 @@
import fastmcp
from fastmcp.server.event_store import EventStore
from fastmcp.server.http import (
+ HostOriginProtection,
StarletteWithLifespan,
+ _is_loopback_host,
create_sse_app,
create_streamable_http_app,
)
@@ -48,6 +50,22 @@
return host
+def _resolve_allowed_hosts_for_run(
+ *,
+ host: str,
+ host_origin_protection: HostOriginProtection,
+ allowed_hosts: list[str] | None,
+ configured_allowed_hosts: list[str] | None,
+) -> list[str] | None:
+ if allowed_hosts is not None:
+ return allowed_hosts
+
+ if host_origin_protection == "auto" and _is_loopback_host(host):
+ return [*(configured_allowed_hosts or []), host]
+
+ return configured_allowed_hosts
+
+
class TransportMixin:
"""Mixin providing transport-related methods for FastMCP.
@@ -250,7 +268,7 @@
json_response: bool | None = None,
stateless_http: bool | None = None,
stateless: bool | None = None,
- host_origin_protection: bool | None = None,
+ host_origin_protection: HostOriginProtection | None = None,
allowed_hosts: list[str] | None = None,
allowed_origins: list[str] | None = None,
sockets: list[socket.socket] | None = None,
@@ -269,7 +287,9 @@
stateless_http: Whether to use stateless HTTP (defaults to
settings.stateless_http)
stateless: Alias for stateless_http for CLI consistency
host_origin_protection: Whether to validate Host and Origin headers
- before requests reach the MCP endpoint.
+ before requests reach the MCP endpoint. Defaults to
+ settings.http_host_origin_protection. "auto" protects
+ localhost-bound servers and explicit host/origin allowlists.
allowed_hosts: Additional hostnames that may appear in the Host
header.
allowed_origins: Additional browser origins trusted by the request
guard.
Configure CORS separately when browser JavaScript must read
@@ -290,6 +310,17 @@
host = host if host is not None else fastmcp.settings.host
port = port if port is not None else fastmcp.settings.port
+ resolved_host_origin_protection = (
+ host_origin_protection
+ if host_origin_protection is not None
+ else fastmcp.settings.http_host_origin_protection
+ )
+ resolved_allowed_hosts = _resolve_allowed_hosts_for_run(
+ host=host,
+ host_origin_protection=resolved_host_origin_protection,
+ allowed_hosts=allowed_hosts,
+ configured_allowed_hosts=fastmcp.settings.http_allowed_hosts,
+ )
default_log_level_to_use = (
log_level if log_level is not None else fastmcp.settings.log_level
).lower()
@@ -300,8 +331,8 @@
middleware=middleware,
json_response=json_response,
stateless_http=stateless_http,
- host_origin_protection=host_origin_protection,
- allowed_hosts=allowed_hosts,
+ host_origin_protection=resolved_host_origin_protection,
+ allowed_hosts=resolved_allowed_hosts,
allowed_origins=allowed_origins,
)
@@ -345,7 +376,7 @@
transport: Literal["http", "streamable-http", "sse"] = "http",
event_store: EventStore | None = None,
retry_interval: int | None = None,
- host_origin_protection: bool | None = None,
+ host_origin_protection: HostOriginProtection | None = None,
allowed_hosts: list[str] | None = None,
allowed_origins: list[str] | None = None,
) -> StarletteWithLifespan:
@@ -365,7 +396,9 @@
disconnections. Requires event_store to be set. Only used with
streamable-http transport.
host_origin_protection: Whether to validate Host and Origin headers
- before requests reach the MCP endpoint.
+ before requests reach the MCP endpoint. Defaults to
+ settings.http_host_origin_protection. "auto" protects
+ localhost-bound servers and explicit host/origin allowlists.
allowed_hosts: Additional hostnames that may appear in the Host
header.
allowed_origins: Additional browser origins trusted by the request
guard.
Configure CORS separately when browser JavaScript must read
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fastmcp_slim-3.4.3/fastmcp/settings.py
new/fastmcp_slim-3.4.4/fastmcp/settings.py
--- old/fastmcp_slim-3.4.3/fastmcp/settings.py 2020-02-02 01:00:00.000000000
+0100
+++ new/fastmcp_slim-3.4.4/fastmcp/settings.py 2020-02-02 01:00:00.000000000
+0100
@@ -320,7 +320,7 @@
stateless_http: bool = (
False # If True, uses true stateless mode (new transport per request)
)
- http_host_origin_protection: bool = True
+ http_host_origin_protection: bool | Literal["auto"] = False
http_allowed_hosts: list[str] | None = None
http_allowed_origins: list[str] | None = None