From f3426e7c6456342318f1ba127fd8dad49c4eb024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=B7=E5=B0=8F=E5=89=8D?= Date: Sat, 17 Jan 2026 18:38:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0ios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mcp_server.py | 128 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 109 insertions(+), 19 deletions(-) diff --git a/mcp_server.py b/mcp_server.py index 321f6adb..446e66e0 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -48,7 +48,7 @@ class ServiceEndpoints: """API服务端点配置""" NEWS_API = "http://222.128.1.157:21891" # 新闻API ROADSHOW_API = "http://222.128.1.157:19800" # 路演API - CONCEPT_API = "http://222.128.1.157:16801" # 概念API V2(concept_api_v2.py,端口16801) + CONCEPT_API = "http://222.128.1.157:16801" # 概念API V4(concept_api_v4.py,端口映射到16801) STOCK_ANALYSIS_API = "http://222.128.1.157:8811" # 涨停分析+研报API MAIN_APP_API = "http://127.0.0.1:5001" # 主应用API(自选股、自选事件等) @@ -315,7 +315,7 @@ TOOLS: List[ToolDefinition] = [ ), ToolDefinition( name="search_concepts", - description="搜索股票概念板块,返回概念详情及相关股票列表。", + description="搜索股票概念板块,支持语义搜索和原因搜索,返回概念详情及相关股票列表。", parameters={ "type": "object", "properties": { @@ -326,6 +326,24 @@ TOOLS: List[ToolDefinition] = [ "trade_date": { "type": "string", "description": "交易日期,格式:YYYY-MM-DD,不传则使用今天" + }, + "filter_lv1": { + "type": "string", + "description": "一级分类过滤,如:'科技'、'消费'、'金融'" + }, + "filter_lv2": { + "type": "string", + "description": "二级分类过滤" + }, + "search_reason": { + "type": "boolean", + "description": "是否同时搜索股票被纳入概念的原因", + "default": False + }, + "include_stock_reasons": { + "type": "boolean", + "description": "是否在返回的股票列表中包含原因", + "default": False } }, "required": ["query"] @@ -333,7 +351,7 @@ TOOLS: List[ToolDefinition] = [ ), ToolDefinition( name="get_concept_details", - description="根据概念ID获取详细信息,包括描述、相关股票、涨跌幅数据等。", + description="根据概念ID获取详细信息,包括描述、insight、相关股票(含关联原因)、涨跌幅数据、层级结构等。", parameters={ "type": "object", "properties": { @@ -351,7 +369,7 @@ TOOLS: List[ToolDefinition] = [ ), ToolDefinition( name="get_stock_concepts", - description="查询指定股票的所有相关概念板块,包括涨跌幅信息。", + description="查询指定股票的所有相关概念板块,包括涨跌幅信息和该股票被纳入概念的原因。", parameters={ "type": "object", "properties": { @@ -364,15 +382,14 @@ TOOLS: List[ToolDefinition] = [ "description": "返回概念数量", "default": 50 }, - "sort_by": { - "type": "string", - "description": "排序方式", - "enum": ["stock_count", "concept_name", "recent"], - "default": "stock_count" - }, "trade_date": { "type": "string", "description": "交易日期,格式:YYYY-MM-DD" + }, + "include_reason": { + "type": "boolean", + "description": "是否返回股票被纳入概念的原因", + "default": True } }, "required": ["stock_code"] @@ -380,7 +397,7 @@ TOOLS: List[ToolDefinition] = [ ), ToolDefinition( name="get_concept_statistics", - description="获取概念板块统计数据,包括涨幅榜、跌幅榜、活跃榜、波动榜、连涨榜。", + description="获取概念板块统计数据,包括涨幅榜、跌幅榜、活跃榜、波动榜、连涨榜。支持按概念类型(叶子/母概念)过滤。", parameters={ "type": "object", "properties": { @@ -400,11 +417,41 @@ TOOLS: List[ToolDefinition] = [ "type": "integer", "description": "最少股票数量过滤", "default": 3 + }, + "concept_type": { + "type": "string", + "description": "概念类型过滤:leaf(叶子概念)、lv1(一级母概念)、lv2(二级母概念)、lv3(三级母概念)", + "enum": ["leaf", "lv1", "lv2", "lv3"], + "default": "leaf" } }, "required": [] } ), + ToolDefinition( + name="search_concepts_by_reason", + description="按股票关联原因搜索概念。可以找到所有reason中提到特定关键词的概念和股票,例如搜索'AI芯片'可以找到所有因AI芯片相关业务被纳入概念的股票。", + parameters={ + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "搜索关键词,会在股票关联原因中搜索" + }, + "size": { + "type": "integer", + "description": "返回结果数量", + "default": 20 + }, + "include_stock_details": { + "type": "boolean", + "description": "是否返回匹配的股票详情(含高亮原因)", + "default": True + } + }, + "required": ["query"] + } + ), ToolDefinition( name="search_limit_up_stocks", description="搜索涨停股票,支持按日期、关键词、板块等条件搜索。包括混合语义搜索。", @@ -1468,8 +1515,9 @@ async def handle_search_roadshows(args: Dict[str, Any]) -> Any: return response.json() async def handle_search_concepts(args: Dict[str, Any]) -> Any: - """处理概念搜索 + """处理概念搜索(适配 concept_api_v4) + 支持语义搜索、层级过滤、原因搜索等 V4 新特性 参数写死:size=12, page=1, sort_by="_score" trade_date 如果没传则使用今天的日期 """ @@ -1485,21 +1533,38 @@ async def handle_search_concepts(args: Dict[str, Any]) -> Any: "sort_by": "_score", # 写死,按相关度排序 "trade_date": trade_date, "search_size": 100, - "use_knn": True + "use_knn": True, + # V4 新增参数 + "search_reason": args.get("search_reason", False), # 是否同时搜索股票原因 + "include_stock_reasons": args.get("include_stock_reasons", False) # 是否在返回的股票列表中包含原因 } + # V4 新增:层级过滤 + if args.get("filter_lv1"): + payload["filter_lv1"] = args["filter_lv1"] + if args.get("filter_lv2"): + payload["filter_lv2"] = args["filter_lv2"] + logger.info(f"[search_concepts] 请求参数: {payload}") response = await HTTP_CLIENT.post(f"{ServiceEndpoints.CONCEPT_API}/search", json=payload) response.raise_for_status() return response.json() async def handle_get_concept_details(args: Dict[str, Any]) -> Any: - """处理概念详情获取""" + """处理概念详情获取(适配 concept_api_v4) + + V4 返回内容包含: + - 概念基本信息(concept_id, concept, description, insight) + - 完整股票列表(含关联原因 reason) + - 层级结构信息(hierarchy: lv1/lv2/lv3) + - 涨跌幅数据(price_info) + """ concept_id = args["concept_id"] params = {} if args.get("trade_date"): params["trade_date"] = args["trade_date"] + logger.info(f"[get_concept_details] 查询概念 {concept_id} 的详情") response = await HTTP_CLIENT.get( f"{ServiceEndpoints.CONCEPT_API}/concept/{concept_id}", params=params @@ -1508,7 +1573,7 @@ async def handle_get_concept_details(args: Dict[str, Any]) -> Any: return response.json() async def handle_get_stock_concepts(args: Dict[str, Any]) -> Any: - """处理股票概念获取""" + """处理股票概念获取(适配 concept_api_v4)""" # 兼容不同的参数名: stock_code, seccode, code stock_code = args.get("stock_code") or args.get("seccode") or args.get("code") if not stock_code: @@ -1516,13 +1581,12 @@ async def handle_get_stock_concepts(args: Dict[str, Any]) -> Any: params = { "size": args.get("size", 50), - "sort_by": args.get("sort_by", "stock_count"), - "include_description": True + "include_reason": args.get("include_reason", True) # V4 新增:返回股票关联原因 } if args.get("trade_date"): params["trade_date"] = args["trade_date"] - logger.info(f"[get_stock_concepts] 查询股票 {stock_code} 的概念") + logger.info(f"[get_stock_concepts] 查询股票 {stock_code} 的概念 (include_reason={params['include_reason']})") response = await HTTP_CLIENT.get( f"{ServiceEndpoints.CONCEPT_API}/stock/{stock_code}/concepts", params=params @@ -1531,7 +1595,10 @@ async def handle_get_stock_concepts(args: Dict[str, Any]) -> Any: return response.json() async def handle_get_concept_statistics(args: Dict[str, Any]) -> Any: - """处理概念统计获取""" + """处理概念统计获取(适配 concept_api_v4) + + V4 新增 concept_type 参数,支持按概念类型过滤统计数据 + """ params = {} if args.get("days"): params["days"] = args["days"] @@ -1541,11 +1608,33 @@ async def handle_get_concept_statistics(args: Dict[str, Any]) -> Any: params["end_date"] = args["end_date"] if args.get("min_stock_count"): params["min_stock_count"] = args["min_stock_count"] + # V4 新增:概念类型过滤 + if args.get("concept_type"): + params["concept_type"] = args["concept_type"] + logger.info(f"[get_concept_statistics] 请求参数: {params}") response = await HTTP_CLIENT.get(f"{ServiceEndpoints.CONCEPT_API}/statistics", params=params) response.raise_for_status() return response.json() +async def handle_search_concepts_by_reason(args: Dict[str, Any]) -> Any: + """按股票关联原因搜索概念(concept_api_v4 新增接口) + + 调用 /search/reason 接口,可以找到所有reason中提到特定关键词的概念和股票 + 例如搜索"AI芯片"可以找到所有因AI芯片相关业务被纳入概念的股票 + """ + payload = { + "query": args["query"], + "size": args.get("size", 20), + "page": 1, # 写死第一页 + "include_stock_details": args.get("include_stock_details", True) + } + + logger.info(f"[search_concepts_by_reason] 请求参数: {payload}") + response = await HTTP_CLIENT.post(f"{ServiceEndpoints.CONCEPT_API}/search/reason", json=payload) + response.raise_for_status() + return response.json() + async def handle_search_limit_up_stocks(args: Dict[str, Any]) -> Any: """处理涨停股票搜索""" payload = { @@ -1835,6 +1924,7 @@ TOOL_HANDLERS = { "get_concept_details": handle_get_concept_details, "get_stock_concepts": handle_get_stock_concepts, "get_concept_statistics": handle_get_concept_statistics, + "search_concepts_by_reason": handle_search_concepts_by_reason, "search_limit_up_stocks": handle_search_limit_up_stocks, "get_daily_stock_analysis": handle_get_daily_stock_analysis, "search_research_reports": handle_search_research_reports,