news 2026/9/12 16:55:15

Envoy MCP HTTP 过滤器新增 server/discover、subscriptions/listen 与 tasks/* 方法组:方法分组与 params.taskId 提取实现解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Envoy MCP HTTP 过滤器新增 server/discover、subscriptions/listen 与 tasks/* 方法组:方法分组与 params.taskId 提取实现解析

Envoy MCP HTTP 过滤器新增 server/discover、subscriptions/listen 与 tasks/* 方法组:方法分组与 params.taskId 提取实现解析

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

本篇技术指南基于 Envoy 开源仓库中 changelogs/current/new_features/mcp__new_method_groups.rst 这一变更记录展开。该变更向 Envoy 的 MCP(Model Context Protocol)HTTP 过滤器新增了server/discoversubscriptions/listentasks/*三组方法的识别能力,并在 MCP JSON 解析器中支持从请求体中提取params.taskId字段。读完本文,你将掌握这些新增方法组的默认提取规则、内置分组(discovery/subscription/task)的实现位置,以及如何通过ParserConfig自定义分组元数据、如何借助Mcp-Name请求头免解析提取任务标识,从而把 MCP 流量中的方法属性接入动态元数据与路由决策。

变更内容总览

原始变更记录全文仅一句话,但背后对应着一整条实现链路:

Added support forserver/discover,subscriptions/listen, andtasks/*method groups, and support for extractingparams.taskIdin MCP JSON parser.

拆解为三部分能力:

  1. 方法识别:MCP JSON 解析器新增识别server/discover(服务器发现)、subscriptions/listen(订阅监听)两个具体方法,以及tasks/gettasks/updatetasks/cancel三个任务类方法(即tasks/*)。
  2. 方法分组:在 MCP 过滤器内置的方法分组(method group)分类中,新增discoverysubscriptiontask三个组,用于将方法归类到动态元数据。
  3. 字段提取:为tasks/*方法新增默认提取路径params.taskId,解析器会在流式解析 JSON-RPC 请求体时把任务 ID 写入元数据,并可映射到Mcp-Name请求头。

这些能力全部落在 MCP HTTP 过滤器(扩展名envoy.filters.http.mcp)内部,核心实现在 source/extensions/filters/http/mcp/mcp_json_parser.cc 与 source/extensions/filters/http/mcp/mcp_json_parser.h,方法常量定义在 source/extensions/filters/common/mcp/constants.h。

背景:MCP 过滤器如何处理 JSON-RPC 流量

MCP(Model Context Protocol)基于 JSON-RPC 2.0 通信。Envoy 的 MCP 过滤器在不解码完整请求的前提下,对流经的 HTTP 请求体做流式 JSON 解析(底层使用ProtobufUtil::converter::JsonStreamParser,见 mcp_json_parser.cc),从中提取jsonrpcmethodid等核心字段以及各方法特有的业务字段,并把结果写入请求动态元数据(dynamic metadata)或过滤器状态(filter state),供路由选择、日志、追踪等下游环节使用。

解析器将每个方法需要提取的字段建模为“提取规则”(AttributeExtractionRule),规则以点分隔的 JSON 路径表示,例如params.nameparams.uri。方法名与提取规则的默认绑定关系在McpParserConfig::initializeDefaults()中集中注册(mcp_json_parser.cc),本次变更正是在这份默认注册表中扩展了新的方法条目。

新增方法组:discovery、subscription、task

方法常量与分组常量

方法名与分组名的常量均定义于 source/extensions/filters/common/mcp/constants.h:

  • 方法常量(Methods命名空间,constants.h):
    • SERVER_DISCOVER = "server/discover"
    • SUBSCRIPTIONS_LISTEN = "subscriptions/listen"
    • TASKS_GET = "tasks/get"TASKS_UPDATE = "tasks/update"TASKS_CANCEL = "tasks/cancel"
  • 分组常量(MethodGroups命名空间,constants.h):
    • DISCOVERY = "discovery"
    • SUBSCRIPTION = "subscription"
    • TASK = "task"

加上此前已有的lifecycletoolresourcepromptnotificationloggingsamplingcompletionunknown,内置分组一共 12 个。

内置分组判定逻辑

方法到分组的映射由McpParserConfig::getBuiltInMethodGroup()实现(mcp_json_parser.cc),本次新增的三段逻辑非常直观:

// Discovery methods if (method == SERVER_DISCOVER) { return std::string(DISCOVERY); } // Subscription methods if (method == SUBSCRIPTIONS_LISTEN) { return std::string(SUBSCRIPTION); } // Task methods if (method == TASKS_GET || method == TASKS_UPDATE || method == TASKS_CANCEL) { return std::string(TASK); }

方法判定顺序为:lifecycle → discovery → subscription → task → tool → resource → prompt → logging → sampling → completion → 以notifications/前缀匹配的通用通知 →unknownnotifications/*走前缀匹配(mcp_json_parser.cc),其余均为精确匹配。

分组如何进入动态元数据

分组值由 MCP 过滤器在解析完成后写入动态元数据。关键代码在 source/extensions/filters/http/mcp/mcp_filter.cc:

const ParserConfig& active_parser_config = parserConfig(); const std::string& group_metadata_key = active_parser_config.groupMetadataKey(); if (!group_metadata_key.empty()) { std::string method_group = active_parser_config.getMethodGroup(effective_method); (*metadata.mutable_fields())[group_metadata_key].set_string_value(method_group); }

也就是说:只有在配置中显式设置了group_metadata_key时,分组才会写入动态元数据;该 key 默认为空,即默认不启用分组输出。用户可以在ParserConfig.methods[]中为具体方法覆盖分组名(MethodConfig.group),覆盖优先级高于内置分组(精确匹配优先,见 mcp_json_parser.cc)。proto 定义参见 api/envoy/extensions/filters/http/mcp/v3/mcp.proto。

新增提取路径:params.taskId

默认提取规则注册

tasks/*三个方法统一提取params.taskId,在initializeDefaults()中注册(mcp_json_parser.cc):

// Tasks. addMethodConfig(Methods::TASKS_GET, {AttributeExtractionRule(std::string(Paths::PARAMS_TASK_ID))}); addMethodConfig(Methods::TASKS_UPDATE, {AttributeExtractionRule(std::string(Paths::PARAMS_TASK_ID))}); addMethodConfig(Methods::TASKS_CANCEL, {AttributeExtractionRule(std::string(Paths::PARAMS_TASK_ID))});

路径常量PARAMS_TASK_ID = "params.taskId"定义在 constants.h。因此一个形如下面的tasks/get请求,解析后动态元数据的params.taskId会被填充为task-123

{ "jsonrpc": "2.0", "method": "tasks/get", "params": { "taskId": "task-123" }, "id": 123 }

taskId 与 Mcp-Name 请求头的关系

McpParserConfig::getNameAttributePath()返回“方法对应的命名属性路径”,即该方法的标识符在 JSON 中的位置(mcp_json_parser.cc):

if (method == TASKS_GET || method == TASKS_UPDATE || method == TASKS_CANCEL) { return std::string(PARAMS_TASK_ID); }

其他方法的对应关系为:tools/callprompts/getparams.nameresources/readparams.uri;其余方法返回空。这个映射有两个用途:

  1. HEADERS 提取模式:当Mcp.attribute_source配置为HEADERS时,过滤器直接信任Mcp-MethodMcp-Name请求头,将头部值写入元数据,避免解析请求体(mcp_filter.cc)。此时tasks/get携带Mcp-Name: task-123即可免解析获得params.taskId = task-123
  2. VERIFY 模式:以头部为准,并校验解析出的 body 值与头部一致(proto 注释见 mcp.proto)。

关于三个tasks/*方法与Mcp-Name头配合的行为,在 test/extensions/filters/http/mcp/mcp_filter_test.cc 等测试中有覆盖:请求头{"mcp-method": "tasks/get", "mcp-name": "task-123"}会产出元数据method="tasks/get"params.taskId="task-123"

提取规则同样适用于用户自定义覆盖

用户可在ParserConfig.methods[].extraction_rules[]中为任意方法(包括本批新增方法)自定义提取路径,规则以点分隔路径形式给出,例如params.taskIdparams.name。方法级配置会合并到内置规则之上:方法特有提取规则全部视为必选字段,而params._meta始终作为可选字段追加(见buildMethodRequirements(),mcp_json_parser.cc)。

源码级实现要点:流式提取如何命中新路径

新增方法之所以“开箱即用”,得益于McpFieldExtractor的路径匹配机制:

  • 解析器在收到顶层method字段后即确定method_,并调用updateActiveTargetPaths()预计算当前方法的目标路径集合(mcp_json_parser.cc)。
  • 每个 JSON 字段渲染时通过isPathInteresting()判定是否值得暂存:支持“目标路径的祖先/前缀”“目标路径的后代”两类模糊匹配(mcp_json_parser.cc),因此即使解析器尚未读完整段 JSON,也能增量判断params.taskId是否属于目标。
  • 根对象闭合后调用finalizeExtraction():先复制jsonrpcmethodid等始终提取字段,再按方法复制专属字段,最后校验必选字段是否齐全(mcp_json_parser.cc)。缺失必选字段会被记录在missing_required_fields_中并输出 debug 日志(mcp_json_parser.cc)。

同时,McpFieldExtractor在解析过程中维护has_jsonrpc_has_method_has_result_has_error_等状态来判定消息是否为合法 MCP 请求或 JSON-RPC 响应(mcp_json_parser.h),新增方法无需额外处理即可参与这些校验。

测试验证:新增方法的覆盖情况

仓库为本次变更提供了完整的单测覆盖,可直接作为行为规范参考:

  • test/extensions/filters/http/mcp/mcp_json_parser_test.cc:
    • ServerDiscoverExtraction:验证server/discover被识别为合法 MCP 请求且getMethod()返回SERVER_DISCOVER
    • SubscriptionsListenExtraction:验证subscriptions/listen的识别。
    • TasksGetExtraction/TasksUpdateExtraction/TasksCancelExtraction:分别验证tasks/gettasks/updatetasks/cancel的识别,并断言parser_->getNestedValue("params.taskId")提取出task-123/task-456/task-789
    • 另见该文件第 1572-1574 行:getNameAttributePath("tasks/get"|"tasks/update"|"tasks/cancel")均断言返回params.taskId
  • test/extensions/filters/http/mcp/mcp_filter_test.cc:覆盖了设置group_metadata_key后,内置分组(如tool)与用户自定义分组(custom_override_groupcustom_tools)写入动态元数据的完整链路。

典型配置示例

将方法分组与任务 ID 接入动态元数据的最小配置(HTTP 过滤器级):

http_filters: - name: envoy.filters.http.mcp typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.mcp.v3.Mcp traffic_mode: PASS_THROUGH parser_config: group_metadata_key: method_group # 启用分组输出,写入动态元数据 methods: - method: tasks/get # 覆盖 tasks/get 的分组(可选) group: my_task_group extraction_rules: - path: params.taskId # 默认已内置,可自定义增补
  • group_metadata_key:非空时,过滤器将方法分组名(如discoverysubscriptiontask)写入该 key;为空则禁用分组输出(默认)。
  • methods[].group:为空时使用内置分类(getBuiltInMethodGroup),非空时精确覆盖。
  • extraction_rules[].path:点分隔 JSON 路径,方法特有规则会被视为必选字段。

若希望免解析请求体、直接通过请求头获取方法名与任务 ID,可将attribute_source设为HEADERS,此时客户端需携带Mcp-Method: tasks/getMcp-Name: task-123(两者对应的 HTTP 头名见 constants.h)。注意头部提取只覆盖methodMcp-Name所代表的命名属性,其他自定义提取规则仍需解析 body(mcp.proto)。

适用前提与限制

  • 本文所述方法常量、分组名与默认提取规则均以当前仓库(main分支开发状态)为准;proto 文件顶部标注了work_in_progress = true(mcp.proto),说明该过滤器仍在演进中,升级 Envoy 版本后应以对应版本的 API 文档为准。
  • server/discoversubscriptions/listen属于较新的 MCP 规范方法,本文不涉及具体版本规范内容,仅聚焦 Envoy 侧的分组与提取实现。
  • 分组值只有在配置了group_metadata_key时才会进入动态元数据;未配置时,新增方法组仅影响解析器的内部字段需求计算,不产生可见元数据。

综上,mcp__new_method_groups.rst这条看似简短的变更记录,在 Envoy 源码中对应着从方法常量、内置分组、默认提取规则到动态元数据写入、请求头映射与单测覆盖的一整套实现,读者可沿着 constants.h、mcp_json_parser.cc、mcp_filter.cc 与对应测试文件逐层深入。

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

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

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

光模块固晶机伺服选型与精度实现原理

1. 光模块固晶机为什么非得用三菱伺服?——从贴装精度的物理极限说起光模块固晶机不是普通贴片机,它干的是把几百微米见方的激光芯片、PD探测器、透镜阵列,以0.5μm的重复定位精度,精准“种”在陶瓷基板或硅光载板上的活。这个精度…

作者头像 李华