news 2026/10/11 18:50:21

mcp-brasil源码深度解析:Async全链路、指数退避重试与BM25工具过滤如何实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
mcp-brasil源码深度解析:Async全链路、指数退避重试与BM25工具过滤如何实现

【免费下载链接】mcp-brasil

MCP Server para 70 APIs públicas brasileiras

项目地址:https://gitcode.com/gh_mirrors/mc/mcp-brasil
点击查看免费下载

mcp-brasil是一个连接 AI 与70+ 巴西政府公开 API的 MCP Server(Model Context Protocol 服务器),覆盖 IBGE、巴西央行、众议院、参议院、透明度门户、DataJud 等权威数据源。对于想读懂它的开发者,本文从源码层面拆解三大核心机制:贯穿全链路的Async 异步架构、应对网络抖动的指数退避重试,以及解决 154+ 工具选择难题的BM25 工具过滤,帮你快速建立对这套项目的整体认知。

👆 上图是 mcp-brasil 的整体架构:上层是 MCP Client(Claude、Cursor、Open WebUI),中间是挂载了数十个 Feature 子服务器的根服务器,底部是分散的政府 API。本文就沿着这张图,把每个关键模块的源码讲透。

项目架构总览:70+ API 如何组织

mcp-brasil 采用"约定优于配置"的插件式设计。每个政府数据源都是一个Feature(功能模块),存放在src/mcp_brasil/data/下,目录结构高度统一:

新增一个数据源时,你不需要手动改根服务器。只要按约定放好文件,注册器就会自动发现并挂载。完整架构文档见 docs/concepts/architecture.md。

核心源码分布:

模块路径职责
根服务器 + 自动注册src/mcp_brasil/server.py发现并挂载所有 Feature
自动注册器src/mcp_brasil/_shared/feature.pyFeatureRegistry扫描挂载
全局配置src/mcp_brasil/settings.py环境变量覆盖的默认值
异步 HTTP 客户端src/mcp_brasil/_shared/http_client.py重试 + 指数退避

Async 全链路:从请求到响应

mcp-brasil 的"全链路"指一次工具调用从入口到出口全程异步,没有任何阻塞点。它由三层协同构成。

共享 HTTP 客户端:lifespan 如何管理连接

传统做法是每个请求临时建一个连接、用完即弃,开销大且浪费。mcp-brasil 用生命周期钩子在服务器启动时创建一个共享的httpx.AsyncClient,所有工具共用它,关闭时再统一释放。

关键在 src/mcp_brasil/_shared/lifespan.py:

@lifespan async def http_lifespan(server: FastMCP[Any]) -> AsyncIterator[dict[str, Any] | None]: client = httpx.AsyncClient( timeout=httpx.Timeout(HTTP_TIMEOUT), headers={"User-Agent": USER_AGENT, "Accept": "application/json"}, follow_redirects=True, ) try: yield {"http_client": client} # 工具通过 ctx.lifespan_context 取用 finally: await client.aclose()

这种"启动时建、关闭时拆"的模式,让连接池、超时、默认头都能全局复用,是 Async 架构的地基。

自动注册:FeatureRegistry 的发现机制

FeatureRegistry通过pkgutil.iter_modules()扫描mcp_brasil/data/下的每个子包,遵循一套约定:

  1. 是带__init__.py的子包;
  2. __init__.py导出一个FEATURE_META(声明名称、描述、是否需鉴权);
  3. server.py导出一个mcp(FastMCP 实例)。

满足条件即被挂载,并以 Feature 名做命名空间前缀(工具名变成ibge_buscar_*)。任一模块校验失败只会被跳过并记录日志,绝不会让整个服务器崩溃——见 src/mcp_brasil/_shared/feature.py。

异步批处理:asyncio.gather 并行执行

当一次任务需要多个相互独立的数据时,mcp-brasil 提供executar_lote工具,把多条查询用asyncio.gather()并行跑完,而不是串行等待。核心在 src/mcp_brasil/_shared/batch.py:

results = await asyncio.gather(*[_run_one(q) for q in queries])

单个查询失败不会影响其他查询——每个都会返回带错误信息的独立结果,最后拼成 Markdown。这让"对比两个议员的 2023/2024 年开销"这类任务能一次性并发完成。

指数退避重试:让 API 调用更稳健

政府 API 偶尔会抖动(5xx、限流 429、超时)。mcp-brasil 用"只重试可恢复错误 + 指数退避"策略来兜底,核心在 src/mcp_brasil/_shared/http_client.py。

重试哪些错误?_RETRYABLE_STATUS_CODES

代码里用一个冻结集合精确界定"值得重试"的状态码:

_RETRYABLE_STATUS_CODES = frozenset({429, 500, 502, 503, 504})
状态码含义是否重试
429请求过多(限流)✅
500 / 502 / 503 / 504服务器内部/网关/过载/超时✅
404、400 等 4xx客户端错误❌ 直接报错

设计意图很清晰:4xx(除 429)是客户端自己的错,重试也救不了,直接抛错;只有 5xx 和限流这类"暂时性故障"才进入重试循环。

退避公式与 RateLimiter 限流

重试等待时间遵循经典的指数退避公式:

wait = HTTP_BACKOFF_BASE * (2 ** attempt) # 1s → 2s → 4s → 8s ... await asyncio.sleep(wait)

默认值来自 src/mcp_brasil/settings.py:HTTP_MAX_RETRIES=3(共 4 次尝试)、HTTP_BACKOFF_BASE=1.0,且都能用环境变量覆盖。指数增长避免了"雪崩式"地对故障端点反复轰炸,给上游留出恢复时间。

除了对外请求的退避,项目还有一个滑动窗口限流器src/mcp_brasil/_shared/rate_limiter.py,用asyncio.Lock+deque保证并发下的公平性:

limiter = RateLimiter(max_requests=80, period=60.0) async with limiter: await do_request()

当窗口内请求数达到上限时,它会精确算出"最老一条多久过期",然后asyncio.sleep等待——绝不阻塞事件循环,是 Async 友好的限流实现。

BM25 工具过滤:154+ 工具如何精准匹配

mcp-brasil 挂了 70+ 个 API,展开后是154+ 个工具。如果一次性全塞给大模型,会撑爆上下文、也让模型"选择困难"。解决方案是BM25 工具过滤——一种经典的全文检索算法,按相关性给工具打分排序。

为什么需要工具过滤

在 src/mcp_brasil/server.py 里,默认TOOL_SEARCH="bm25"(见 settings.py)。它把list_tools替换成两个更省心的工具:

  • search_tools:按关键词检索,返回Top 10最相关工具;
  • call_tool:用检索结果里挑出来的工具去执行。

模型不再需要"看到全部再挑",而是"先搜到相关的,再调用"。

BM25SearchTransform 工作原理

实现挂在根服务器上,通过 FastMCP 的 Transform 机制动态改写工具列表:

if TOOL_SEARCH == "bm25": from fastmcp.server.transforms.search import BM25SearchTransform mcp.add_transform( BM25SearchTransform( max_results=10, always_visible=_always_visible, ) )

两个设计要点值得注意:

  • max_results=10:只暴露最相关的 10 个,把上下文压力降到最低;
  • always_visible白名单:listar_features、recomendar_tools、planejar_consulta、executar_lote、listar_datasets_disponiveis这 5 个"导航型"元工具永远可见,保证模型任何时候都能"发现工具",不会因为过滤而迷路。

除了 BM25,项目还支持实验性的CodeMode(search+get_tags+get_schemas)与关闭过滤(none)三种模式,用MCP_BRASIL_TOOL_SEARCH一键切换。配套的 LLM 推荐能力(recomendar_tools、planejar_consulta)分别位于 src/mcp_brasil/_shared/discovery.py 与 src/mcp_brasil/_shared/planner.py,可作为 BM25 的补充手段。

总结:三大机制如何协同

mcp-brasil 用一套克制而成熟的设计,把一个"多 API 聚合服务"做稳了:

  1. Async 全链路——lifespan共享客户端 +asyncio.gather并行,全程无阻塞;
  2. 指数退避重试—— 只重试 429/5xx,退避公式给上游留恢复时间,滑动窗口限流防雪崩;
  3. BM25 工具过滤—— Top 10 检索 + 元工具白名单,让 154+ 工具不再"难选"。

想深入更多细节,可直接阅读 docs/concepts/architecture.md 与 docs/guide/development.md。这套"自动注册 + 异步 + 稳健重试 + 智能检索"的组合,也为其他多数据源 MCP 项目提供了不错的参考范本。

【免费下载链接】mcp-brasil

MCP Server para 70 APIs públicas brasileiras

项目地址:https://gitcode.com/gh_mirrors/mc/mcp-brasil
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 18:47:41

OpenSSL EC_POINT_mul 详解:椭圆曲线点乘的核心 API

1. 函数概述 EC_POINT_mul 是 OpenSSL 密码学库中椭圆曲线(Elliptic Curve, EC)算法体系里最核心的计算函数之一。它的主要作用是在椭圆曲线上进行点乘运算(标量乘法,Scalar Multiplication)。 2. 函数原型与定义 在 OpenSSL 的 <openssl/ec.h> 头文件中,定义如…

作者头像 李华
网站建设 2026/10/11 18:43:26

JIRA Scrum敏捷项目管理:看板搭建与Sprint执行全流程

简介&#xff1a;基于JIRA的敏捷开发项目管理是一份面向项目经理、Scrum Master及开发团队成员的实操型文档&#xff0c;系统讲解如何借助JIRA落地Scrum增量迭代流程。内容围绕Scrum的角色分工&#xff08;产品负责人、Scrum Master、开发测试团队&#xff09;与五步开发法展开…

作者头像 李华
网站建设 2026/10/11 18:40:16

双目视觉深度感知与三维重建:从相机标定到点云生成的完整工程实战

简介&#xff1a;这套基于双目摄像头的立体视觉深度感知与三维重建算法系统&#xff0c;面向计算机视觉学习者、机器人导航与自动驾驶领域开发者&#xff0c;完整覆盖从相机标定、立体匹配、视差计算&#xff0c;到深度图生成、点云重建&#xff0c;再到目标检测与跟踪的算法链…

作者头像 李华
网站建设 2026/10/11 18:35:53

农作物病虫害识别毕设避坑指南:从数据清洗到模型训练全解析

简介&#xff1a;面向高校毕业设计及课程项目的深度学习应用资料包&#xff0c;围绕常见农作物病虫害识别任务&#xff0c;提供从图像数据收集、视觉显著性处理、卷积神经网络构建到系统部署的完整方案&#xff0c;尤其适合计算机视觉、智慧农业方向的学生用于课题研究、代码复…

作者头像 李华
网站建设 2026/10/11 18:34:34

ARP欺骗全解析:原理、攻击流程与三层防御方案

1. ARP欺骗是什么&#xff1f;先看链路层的“认门牌”过程局域网里真正决定数据包去哪个网卡的不是IP&#xff0c;而是MAC地址。IP相当于门牌号&#xff0c;MAC才是门牌对应的那栋房。两台设备要通信&#xff0c;先通过ARP&#xff08;Address Resolution Protocol&#xff0c;…

作者头像 李华
网站建设 2026/10/11 18:28:57

ComfyUI+Wan2.2文生视频实战:显存优化与参数配方全解析

简介&#xff1a;一份基于 ComfyUI/Wan2.2 RapidAIOMega 的二次元文生视频配置包&#xff0c;面向刚入门 ComfyUI 或想快速产出二次元风格视频的创作者。核心内容为可直接导入 ComfyUI 的 JSON 工作流文件&#xff0c;内部已预置采样器、模型加载等基础节点&#xff0c;省去从零…

作者头像 李华