fix: allow public host in MCP transport security

This commit is contained in:
2026-09-02 18:38:46 +08:00
parent b482424e79
commit 7b8f855616
+24 -3
View File
@@ -16,8 +16,11 @@ MCP Server Demo — 单服务实例,三 MCP 模组
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
import uvicorn import uvicorn
import os
from urllib.parse import urlparse
from starlette.applications import Starlette from starlette.applications import Starlette
from starlette.routing import Mount from starlette.routing import Mount
from mcp.server.transport_security import TransportSecuritySettings
from auth import close_auth_client from auth import close_auth_client
from modules.crm.tools import crm_server from modules.crm.tools import crm_server
@@ -27,11 +30,29 @@ from modules.crm.db import close_pool as close_crm_pool
from modules.erp.db import close_pool as close_erp_pool from modules.erp.db import close_pool as close_erp_pool
from modules.bexell.db import close_engine as close_bexell_engine from modules.bexell.db import close_engine as close_bexell_engine
# 允许通过反向代理访问时的公网 Host;保留 DNS rebinding protection。
_public_url = os.getenv("MCP_PUBLIC_URL", "http://localhost:8001")
_public_host = urlparse(_public_url).hostname or "localhost"
_transport_security = TransportSecuritySettings(
enable_dns_rebinding_protection=True,
allowed_hosts=[_public_host, "127.0.0.1:*", "localhost:*", "[::1]:*"],
allowed_origins=[f"https://{_public_host}", "http://127.0.0.1:*", "http://localhost:*", "http://[::1]:*"],
)
# 获取各模组的 Starlette ASGI app(streamable_http_path 设为 /mcp, # 获取各模组的 Starlette ASGI app(streamable_http_path 设为 /mcp,
# Mount("/xxx") 会剥离前缀,子 app 看到的路径就是 /mcp) # Mount("/xxx") 会剥离前缀,子 app 看到的路径就是 /mcp)
erp_app = erp_server.streamable_http_app(streamable_http_path="/mcp") erp_app = erp_server.streamable_http_app(
crm_app = crm_server.streamable_http_app(streamable_http_path="/mcp") streamable_http_path="/mcp",
bexell_app = bexell_server.streamable_http_app(streamable_http_path="/mcp") transport_security=_transport_security,
)
crm_app = crm_server.streamable_http_app(
streamable_http_path="/mcp",
transport_security=_transport_security,
)
bexell_app = bexell_server.streamable_http_app(
streamable_http_path="/mcp",
transport_security=_transport_security,
)
@asynccontextmanager @asynccontextmanager