diff --git a/mcp_docx_server.py b/mcp_docx_server.py index 84ca583..dba952b 100644 --- a/mcp_docx_server.py +++ b/mcp_docx_server.py @@ -63,6 +63,13 @@ mcp = FastMCP( transport_security=transport_security, ) +# 全局变量:存储服务器配置 +_server_config = { + "host": None, + "port": None, + "transport": None, +} + def _is_url(path: str) -> bool: """简单判断一个字符串是否为 HTTP/HTTPS URL。""" @@ -97,18 +104,40 @@ def _download_to_temp(url: str, suffix: str = ".tmp") -> 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/ - - 最终 URL = MCP_OUTPUT_BASE_URL.rstrip('/') + '/' + 文件名 + - 如果设置了 MCP_OUTPUT_BASE_URL: 使用该 URL 作为基础 + - 否则在 http 模式下: http://host:port/download/{filename} + - stdio 模式下: 返回 None """ + # 优先使用环境变量 base = os.getenv("MCP_OUTPUT_BASE_URL") - if not base: - return None + if base: + filename = os.path.basename(abs_output_path) + return base.rstrip("/") + "/" + filename - filename = os.path.basename(abs_output_path) - 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: @@ -306,7 +335,7 @@ async def upload_handler(request: Request): "success": False, "message": f"文件上传失败: {str(e)}" }, status_code=500) -@mcp.custom_route("/download", methods=["GET"]) +@mcp.custom_route("/download/{filename}", methods=["GET"]) async def download_handler(request: Request): """处理文件下载""" try: @@ -362,6 +391,11 @@ if __name__ == "__main__": args = parser.parse_args() if args.transport == "http": + # 保存服务器配置到全局变量 + _server_config["host"] = args.host + _server_config["port"] = args.port + _server_config["transport"] = "http" + # 启动 MCP 服务器(会自动集成到 uvicorn) mcp.settings.host = args.host mcp.settings.port = args.port @@ -373,5 +407,6 @@ if __name__ == "__main__": mcp.run(transport="streamable-http") else: # 本地 stdio 模式 + _server_config["transport"] = "stdio" print("🚀 MCP stdio 模式启动中(本地使用)") mcp.run(transport="stdio")