From 3233e3fea4ae38ea673538ad53e015f2b8234b2d Mon Sep 17 00:00:00 2001 From: beare <945412026@qq.com> Date: Fri, 1 May 2026 22:05:53 +0800 Subject: [PATCH] feat: add score parameter to news search functions - Introduced a new optional `score` parameter in the `search_news` method of `NewsAPIClient` to filter results based on AI score. - Updated `search_news_advanced` function to include a `min_score` parameter for advanced filtering. - Modified `get_high_score_news` to utilize the new score filtering, improving the ability to retrieve high-scoring news articles. --- src/opennews_mcp/api_client.py | 3 +++ src/opennews_mcp/tools/news.py | 16 +++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/opennews_mcp/api_client.py b/src/opennews_mcp/api_client.py index c843776..066345c 100644 --- a/src/opennews_mcp/api_client.py +++ b/src/opennews_mcp/api_client.py @@ -140,6 +140,7 @@ class NewsAPIClient: query: Optional[str] = None, engine_types: Optional[dict[str, list[str]]] = None, has_coin: bool = False, + score: Optional[int] = None, limit: int = 20, page: int = 1, ) -> dict: @@ -153,6 +154,8 @@ class NewsAPIClient: body["engineTypes"] = engine_types if has_coin: body["hasCoin"] = has_coin + if score is not None: + body["score"] = score resp = await self._request("POST", f"{self.base_url}/open/news_search", json=body) return resp.json() diff --git a/src/opennews_mcp/tools/news.py b/src/opennews_mcp/tools/news.py index cbc51dc..d1de67a 100644 --- a/src/opennews_mcp/tools/news.py +++ b/src/opennews_mcp/tools/news.py @@ -163,6 +163,7 @@ async def search_news_advanced( keyword: str = "", engine_types: str = "", has_coin: bool = False, + min_score: int = 0, limit: int = 10, ) -> dict: """Advanced news search with multiple filters. @@ -175,6 +176,7 @@ async def search_news_advanced( keyword: Optional search keyword. engine_types: Engine type filter in format "type1:cat1,cat2;type2:cat3" (e.g. "news:Bloomberg,Reuters;listing:;prediction:"). has_coin: If true, only return news that have associated coins. + min_score: Minimum AI score threshold (default 0, range 0-100). limit: Maximum results (default 10, max 100). """ if (err := require_token()): @@ -199,6 +201,7 @@ async def search_news_advanced( result = await api.search_news( coins=coin_list, query=keyword or None, engine_types=engine_types_dict, has_coin=has_coin, + score=min_score if min_score > 0 else None, limit=limit, page=1, ) data = result.get("data", [])[:limit] @@ -226,20 +229,15 @@ async def get_high_score_news(ctx: Context, min_score: int = 70, limit: int = 10 api = ctx.request_context.lifespan_context.api limit = clamp_limit(limit) try: - fetch_limit = min(limit * 3, MAX_ROWS) - result = await api.search_news(limit=fetch_limit, page=1) - raw = result.get("data", []) - - filtered = [it for it in raw - if (it.get("aiRating") or {}).get("score", 0) >= min_score] - filtered.sort( + result = await api.search_news(score=min_score, limit=limit, page=1) + data = result.get("data", []) + data.sort( key=lambda x: (x.get("aiRating") or {}).get("score", 0), reverse=True, ) - data = filtered[:limit] return make_serializable({ "success": True, "min_score": min_score, - "data": data, "count": len(data), + "data": data[:limit], "count": len(data[:limit]), "total": result.get("total", 0), }) except Exception as e: return {"success": False, "error": str(e) or repr(e)}