Skip to content

fix(source-read): reject raw MCP argument coercion before IO - #6963

Merged
loopx-agent merged 1 commit into
mainfrom
codex/bot-public-reader-mcp-20261020
Oct 20, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/bot-public-reader-mcp-20261020

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

FastMCP converts boolean, numeric-string and float offsets before the reader's strict validation, and converts the string "null" into an absent digest. Image indices have the same conversion gap. Validate the original MCP arguments before SDK conversion, reuse the existing text/index predicates, and retain the public tool schemas, sanitized results and default-off host admission.

Regression tests run a real MCP client against the production registration. They cover rejected raw parameters before observation IO, valid URL-only and explicit-null initial reads, digest-pinned Unicode continuation, changed-source rejection, image pixels and private URL rejection. The documentation now states the raw JSON contract.

Validation: 104 focused source tests and 104 independently installed-wheel tests passed; the new negative tests fail on the unmodified baseline (13 failed, 8 passed). A real isolated stdio MCP provider rejected nine coercible inputs, joined an immutable 106,488-byte public source, rejected a stale digest and rejected a private URL. Source and installed-wheel stdio MCP probes passed. Six direct and eleven selected repository premerge checks passed; the exact reviewed head received a published author-owned COMMENTED review. Full Bot qualification remains separate.

Scope: three existing reader/test/documentation files; one shared image-index predicate, no new provider, configuration, permissions or session state.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机

使用隔离 Chat 阅读公开来源的 Agent,会在工具请求参数类型错误时遇到此问题。例如 offset=false 被 SDK 转成零,字符串 "null" 被转成空摘要;旧入口继续读取,修复后在读取前返回明确拒绝,合法续读照常执行。真实 MCP 请求已证明非法参数无法进入观察 IO,合法请求的结构、完整正文续读和错误摘要拒绝保持。本次不改变读取权限、个人 MCP、会话或安装开关,也不宣称完整 Bot 验收完成。原运行服务尚需安装采用和独立验收;完整社区黄金集、隐私及恢复资格仍单独保留。

这里的 SDK 是 MCP 工具调用适配层。原有 helper 的严格类型检查运行得太晚:它接到的已经是转换后的合法值。继续增加 helper 单测或只把类型注解改成严格整数,均不能证明字符串摘要不会被预处理成空值。实际调用路径已重现问题,所以不修会继续产生错误读取或省略原请求的摘要核对。

改动思路

原始类型属于现有读取器的入口不变量,应在 SDK 转换前执行;复用既有校验和 FastMCP 结果转换即可,无需另建服务器或参数状态。本 PR 只修同一个可选公开读取器的原始参数校验、真实客户端回归和文档。

入口仍由原 native Chat 的 host 开关决定。启用后,原始 JSON 请求先进入本地 FastMCP 子类;文本参数走既有 _text_page_parameters,图片索引走从旧函数提取的 _image_index。通过后才调用 SDK 原分发器,继续复用现有工具注册、输出 schema、文本结构和图片内容转换。拒绝发生在 worker、网络和锁之前,合法请求则保留原锁与超时流程。没有增加同步字段、持久状态、第二套服务器或新配置。

具体改动

按改动前的 docs/integrations/public-source-reader.md 判断,规格修订是 13813cfb7d83c393c9e0912161fe9c2a05542272。原文没有编号,这里用局部评审标签映射:RAW-PARAMETERS 已实现原始参数拒绝;BOUNDED-READ 保留匿名 HTTPS、分页摘要与资源限制;HOST-ADMISSION 保留 operator 控制和默认关闭;QUALIFICATION 保留安装采用与整套 Bot 准出的独立要求。没有用这次新增文档反过来定义验收目标。

关键代码讲解

  1. main / PublicSourceServer.call_tool 在 SDK 转换前检查原值。false、true、数字字符串、浮点 offset 和字符串 "null" 不能再变成合法参数。错误仍使用原有脱敏结果,合法参数进入继承的 SDK 分发,不重写结果协议。
  2. _image_index 保留原来的精确整数与范围规则,由直接图片函数和 MCP 入口共同调用。这样既覆盖相同的 SDK 转换问题,也避免日后在两个位置修改索引政策。
  3. 现有测试文件增加真实 MCP ClientSession,经生产 main() 注册进入实际 tools/call 分发。21 个非法参数实例在未修复基线得到 13 failed / 8 passed;修复后源码和独立安装 wheel 各 104 passed。另以真实隔离 stdio MCP 和 worker,验证九个转换负例、106,488 字节固定公开来源完整拼接、错误摘要无正文及私有 URL 拒绝。

我还以相同实际 MCP 客户端对照不可变 base 与 head:两个工具 schema、五种合法或拒绝响应以及合法繁忙响应逐字段相同;三个转换反例仅在基线进入模拟 IO。host admission 文件字节未改,三个有效配置的关闭路径输出相同。六项直接、十一项选中 premerge 检查通过。按当前策略未读取或等待 GitHub CI。

对主干的风险

最强的反例仍是“内部 helper 测试通过,外层 SDK 已经改写输入”。本次回归捕获生产注册并运行真实 SDK 客户端,模拟边界只位于观察 IO;另有真实 stdio 与公开 HTTPS worker 补足传输路径。它没有证明付费模型理解了所有错误,也不证明业务恢复完成。参数非法时现在优先返回拒绝,合法调用被占用时仍返回原繁忙结果,这是明确的入口语义。

维护风险集中在以后升级 SDK 时注册钩子的变化,因此依赖锁定和真实入口测试需要一起保留。没有改变四兆字节、十万字符、三十秒、DNS/TLS 或 SVG 边界。构建初次遇到旧前端 bundle 和缺失本地 build 模块,按标准前端构建与 uv 打包恢复;测试目录的一次错误调用也保留为失败记录,没有取消断言或放宽门禁。有效资格来自重建后真实安装的 wheel 导入、测试及 MCP 回读。

语义与 CI 对齐

复用原有读取错误、参数 schema 和校验词汇;子类只在 provider 内部生效,不新增共享语义注册项。premerge 的语义漂移与分层检查通过。原会话、历史、权限和默认关闭路径不受本次 diff 修改;既有调用者可以继续按整数偏移与摘要续读,错误输入由客户端纠正。

我的整体评价

APPROVE,限 exact head 945a8b3c1f4ee69c843b630316ac77b5c8aa81dd。长程执行路径保持,用户体验改善为错误请求明确拒绝且合法任务不增加交互轮次;没有测得费用、吞吐或全局模型收益。该边界可用且与现有 IO owner 一致,保留 FastMCP 转换比另建服务器更小,抽取索引规则也消除了重复校验。

这是一项 justified_increment:合并及安装资格与原运行服务采用分别核验,完整 Bot 准出仍等待独立证据。本评审没有核实的阻塞发现;原公开读取器的宿主开关、两个工具名、有效响应和读取限制保持。后续 SDK 升级必须继续运行真实注册测试,不能退回 helper-only 验证。

English verdict: APPROVE for exact head 945a8b3c1f4ee69c843b630316ac77b5c8aa81dd. Raw MCP values are checked before SDK coercion using the existing provider predicates. Real base/head ClientSession parity, 104 source and 104 installed-wheel tests, isolated stdio probes and repository premerge passed. Installed Bot adoption and complete Bot qualification remain separate. This author-owned COMMENTED review is not formal GitHub approval.

@loopx-agent
loopx-agent merged commit 01a81c1 into main Oct 20, 2026
21 of 36 checks passed
@loopx-agent
loopx-agent deleted the codex/bot-public-reader-mcp-20261020 branch October 20, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant