"""M8 MCP 服务入口。 Cherry Studio / Claude Code 通过 stdio 协议调用。 用法: uv run python -m scripts.run_mcp_server # stdio 模式(默认) uv run python -m scripts.run_mcp_server --sse 8765 # HTTP SSE 模式(调试用) Cherry Studio 配置: { "mcpServers": { "a-share-research": { "command": "uv", "args": ["run", "python", "-m", "scripts.run_mcp_server"], "cwd": "/home/pi/news" } } } """ from __future__ import annotations import argparse from pathlib import Path from loguru import logger def _setup_logger() -> None: logger.remove() log_path = Path("logs") / "mcp_server.log" log_path.parent.mkdir(parents=True, exist_ok=True) # MCP stdio 模式下 stderr 会被协议占用,只写文件日志 logger.add( log_path, level="DEBUG", rotation="10 MB", retention=5, encoding="utf-8", enqueue=True, ) def main() -> int: parser = argparse.ArgumentParser(description="A 股 Deep Research MCP 服务") parser.add_argument("--sse", type=int, default=None, help="启动 HTTP SSE 模式在指定端口(调试用)") parser.add_argument("--host", default="0.0.0.0", help="SSE 监听地址") args = parser.parse_args() _setup_logger() logger.info("MCP 服务启动 mode={}", "sse" if args.sse else "stdio") if args.sse: _run_sse(args.host, args.sse) else: _run_stdio() return 0 def _run_stdio() -> None: from mcp_server.tools import mcp # noqa: E402 mcp.run() def _run_sse(host: str, port: int) -> None: from mcp.server.fastmcp import FastMCP # noqa: E402 from mcp_server.tools import ( # noqa: E402 search_company_news, search_industry_news, search_news, search_sentiment_trend, search_stock_events, ) sse_mcp = FastMCP(name="A股DeepResearch", host=host, port=port) sse_mcp.tool()(search_news) sse_mcp.tool()(search_company_news) sse_mcp.tool()(search_industry_news) sse_mcp.tool()(search_stock_events) sse_mcp.tool()(search_sentiment_trend) sse_mcp.run(transport="sse") if __name__ == "__main__": raise SystemExit(main())