output url构建为完整的url

This commit is contained in:
2026-02-27 16:01:02 +08:00
parent afe9a54e3c
commit a9e3f284f2

View File

@@ -63,6 +63,13 @@ mcp = FastMCP(
transport_security=transport_security, transport_security=transport_security,
) )
# 全局变量:存储服务器配置
_server_config = {
"host": None,
"port": None,
"transport": None,
}
def _is_url(path: str) -> bool: def _is_url(path: str) -> bool:
"""简单判断一个字符串是否为 HTTP/HTTPS URL。""" """简单判断一个字符串是否为 HTTP/HTTPS URL。"""
@@ -97,19 +104,41 @@ def _download_to_temp(url: str, suffix: str = ".tmp") -> str:
def _build_output_url(abs_output_path: str) -> Optional[str]: def _build_output_url(abs_output_path: str) -> Optional[str]:
""" """
根据环境变量 MCP_OUTPUT_BASE_URL 构造输出文件的 URL。 构造输出文件的下载 URL。
优先使用环境变量 MCP_OUTPUT_BASE_URL否则根据服务器配置自动构建。
约定: 约定:
- MCP_OUTPUT_BASE_URL 形如: http://host:port/files/ - 如果设置了 MCP_OUTPUT_BASE_URL: 使用该 URL 作为基础
- 最终 URL = MCP_OUTPUT_BASE_URL.rstrip('/') + '/' + 文件名 - 否则在 http 模式下: http://host:port/download/{filename}
- stdio 模式下: 返回 None
""" """
# 优先使用环境变量
base = os.getenv("MCP_OUTPUT_BASE_URL") base = os.getenv("MCP_OUTPUT_BASE_URL")
if not base: if base:
return None
filename = os.path.basename(abs_output_path) filename = os.path.basename(abs_output_path)
return base.rstrip("/") + "/" + filename return base.rstrip("/") + "/" + filename
# 如果是 http 模式,自动构建下载 URL
if _server_config["transport"] == "http":
host = _server_config["host"]
port = _server_config["port"]
filename = os.path.basename(abs_output_path)
# 如果 host 是 0.0.0.0,尝试使用更具体的地址
if host == "0.0.0.0":
# 优先使用环境变量指定的公网地址
public_host = os.getenv("MCP_PUBLIC_HOST")
if public_host:
host = public_host
else:
# 默认使用 localhost
host = "localhost"
return f"http://{host}:{port}/download/{filename}"
return None
def _get_upload_dir() -> str: def _get_upload_dir() -> str:
""" """
@@ -306,7 +335,7 @@ async def upload_handler(request: Request):
"success": False, "success": False,
"message": f"文件上传失败: {str(e)}" "message": f"文件上传失败: {str(e)}"
}, status_code=500) }, status_code=500)
@mcp.custom_route("/download", methods=["GET"]) @mcp.custom_route("/download/{filename}", methods=["GET"])
async def download_handler(request: Request): async def download_handler(request: Request):
"""处理文件下载""" """处理文件下载"""
try: try:
@@ -362,6 +391,11 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
if args.transport == "http": if args.transport == "http":
# 保存服务器配置到全局变量
_server_config["host"] = args.host
_server_config["port"] = args.port
_server_config["transport"] = "http"
# 启动 MCP 服务器(会自动集成到 uvicorn # 启动 MCP 服务器(会自动集成到 uvicorn
mcp.settings.host = args.host mcp.settings.host = args.host
mcp.settings.port = args.port mcp.settings.port = args.port
@@ -373,5 +407,6 @@ if __name__ == "__main__":
mcp.run(transport="streamable-http") mcp.run(transport="streamable-http")
else: else:
# 本地 stdio 模式 # 本地 stdio 模式
_server_config["transport"] = "stdio"
print("🚀 MCP stdio 模式启动中(本地使用)") print("🚀 MCP stdio 模式启动中(本地使用)")
mcp.run(transport="stdio") mcp.run(transport="stdio")