最新资讯
dev.to 你的 Agent Harness 应具备的 17 项能力 dev.to 离线 AI 记忆中 0.8 余弦阈值为何失效 dev.to Kimi K3.1 Pro 开放权重:自托管 2.8T 模型前的开发者清单 dev.to 如何通过工具调用引导模型以提升 Harness 质量 dev.to AI Agent 审计轨迹不等于对话记录 dev.to 精简 MCP server 工具数量:更少工具、更小影响面,双重收益 dev.to 为什么 git checkout 无法撤销 AI 编码 agent 的改动? wechat AI短剧门槛降降降!实测即梦短剧工作室:剧本分镜预演一条龙,伙伴计划长期护航 dev.to 让模型改写文档前,先量化事实保真度 dev.to 回放 153 个 Claude Code 与 Codex 会话,审计 Agent 的生产影响范围 dev.to 银行 77 意图分类最便宜 LLM:GPT-6.1 Terra 每次成功任务 $0.000727 theinformation.com Chesky的副业:Airbnb向CEO新设AI实验室出售IP
多元动态
登录 注册
智能体 dev.to · @Tim

我测试了 31 个 MCP 服务器的契约合规性,仅 3% 通过

原文 我的收藏

作者用自建故障注入工具 mcp-drill 扫描 31 个流行 MCP 服务器(共 265 个工具,包括 Microsoft Learn、Hugging Face、Cloudflare、DeepWiki),发现仅 3% 声明了能拒绝损坏响应的 outputSchema 契约,56% 完全未声明,42% 的 schema 会验证通过垃圾数据,导致 Agent 难以区分好坏结果。作者提供在线记分卡与 pip 安装方式,并说明其与安全扫描工具 mcp-scan 的差异。

AI推荐理由 作者构建 mcp-drill 故障注入工具,对 31 个流行 MCP 服务器(265 个工具,含 Microsoft Learn、Hugging Face、Cloudflare、DeepWiki)扫描其 outputSchema 契约:仅 3% 声明能拒绝损坏响应,56% 未声明任何契约,42% 的 schema 会通过垃圾数据。该结果对 Agent 工具调用可靠性有直接参考价值,且给出可复现工具与安装方式;但为个人项目自测,样本选择与判定标准未在摘要中详述,结论应视为初步扫描而非行业定论。

80

正文

MCP has outputSchema so agents can validate tool results. But does the schema actually reject a wrong answer? I built mcp-drill -- a fault-injection harness that speaks MCP -- and scanned 31 popular servers (265 tools) including Microsoft Learn, Hugging Face, Cloudflare, DeepWiki. Result: only 3% declare a contract that would reject a corrupted response. 56% declare nothing, 42% declare a schema that happily validates garbage. Your agent cannot tell a bad result from a good one. Live scorecard: timurrakhmatullin86.github.io/mcp-drill Install: pip install mcp-drill[scan] How this differs from security scanning: vs mcp-scan Why I built this MCP is JSON-RPC over stdio / Streamable HTTP with bidirectional notifications. Normal HTTP chaos tools don't speak it. And even when you test an MCP server, you usually test your agent, not whether the server's contract protects you. Real failures I kept hitting: A tool returns a well-formed but truncated payload mid-stream -- agent acts on half a JSON. A fetch tool returns {"result": "ok"} with status 200 even when the tool name is wrong -- how does the agent know it failed? A server declares outputSchema: {type: "object"} -- great, it validates any object, including a corrupted one. Zero protection. I wanted one command to answer: if I corrupt the response but keep its type, does your schema catch it? And separately: if I send you garbage input, do you tell me with a proper error? So I built mcp-drill: Fault injection proxy -- mcp-drill wrap --faults timeout,corrupt,truncate,malformed -- npx ... -- sits between client and server, perturbs responses deterministically (seed-able). Model-free scorecard -- mcp-drill scan -- npx ... or mcp-drill scan --url https://... -- no LLM, deterministic, reproducible. Every number is a property of the server. What I measured (no LLM involved) For each server, mcp-drill does the MCP handshake, lists tools, then runs fixed probes: Output-contract coverage -- % of tools that declare an outputSchema at all. Output-contract enforceability -- of those that declare one, % whose schema rejects a corrupted-but-well-typed payload. Corruption: keep structure + type, replace every leaf with mcp-drill-corruption / -999999999 / out-of-range. If it still validates -> vacuous. If it rejects -> enforceable. This is an outcome test, not style policing. Error conformance -- 3 probes: unknown method, unknown tool, missing required args. Classified as jsonrpc_error / tool_error (good) vs accepted / timeout / crash (bad). Repro: pip install -e ".[scan]" && python studies/pilot/run_pilot.py studies/pilot/servers.json -- commits server list + raw results.json. Full methodology: METHODOLOGY.md The headline number 31 servers, 265 tools -- 3% enforceable. Tier Share Count Meaning No schema 56% 148/265 Nothing to validate against Vacuous schema 42% 110/265 Corrupted payload still validates -- zero protection Enforceable 3% 7/265 Schema rejects the corrupted payload Notable: SDK-auto-wrapped (x-fastmcp-wrap-result): 10 tools -- the default from the dominant MCP Python SDK (FastMCP) wraps a return as {"result": string} and calls it a contract. It's vacuous by construction. Error handling: 30/31 servers handle bad input correctly -- the error path is healthy. The success path is not. The number is stable: 3% at 18 servers -> 3% at 22 -> 2% at 26 -> 3% at 31 (including remote marquee servers). Not a small-sample artefact. Some highlights: Server Tools Enforceable Notes git-mcp-server 28 18% Best of the bunch huggingface (remote) 8 12% Only marquee with enforceable schemas filesystem 14 7% Best reference server everything 13 0% Reference server, 100% vacuous microsoft-learn (remote) 3 0% Name-brand doesn't help deepwiki (remote) 3 0% 100% vacuous playwright 23 0% No schemas at all desktop-commander 26 0% No schemas at all Why this matters for agents Agents increasingly act on a tool result without a human in the loop: tool A's output becomes tool B's input. The only automatic guard is: did the transport succeed + did the payload match outputSchema? If the schema is vacuous, nothing guards a well-typed but wrong result, and the agent proceeds on bad data. This is not what security scanners (like mcp-scan) catch. Those ask "can this server be abused to do something evil?" We ask "can this server be trusted when it returns a result?" See the VS page. And coverage is a vanity metric here. Auto-generated schemas (FastMCP infers from return type hints) raise coverage toward 100% while enforceability stays near 0% -- a vacuous default inherited by every server that doesn't override it. The gap widens as tooling improves, unless schemas add value-level constraints (enum, pattern, format, bounds). Try it on your own server # install pip install "mcp-drill[scan]" # or without install uvx mcp-drill scan -- --help # local stdio server mcp-drill scan -- npx -y @modelcontextprotocol/server-filesystem /tmp # remote Streamable HTTP mcp-drill scan --url https://mcp.deepwiki.com/mcp # JSON output for CI mcp-drill scan --json -- npx -y @modelcontextprotocol/server-filesystem /tmp > mcp-drill.json # badge (shields.io endpoint) mcp-drill scan --badge --url https://mcp.deepwiki.com/mcp > badge.json # fault injection proxy mcp-drill wrap --faults timeout,truncate -- npx -y @modelcontextprotocol/server-everything Enter fullscreen mode Exit fullscreen mode Gate in CI -- GitHub Action (no LLM, no API key): - uses: TimurRakhmatullin86/mcp-drill@v0 with: server: 'npx -y @modelcontextprotocol/server-filesystem /tmp' min-error-handling: '0.9' Enter fullscreen mode Exit fullscreen mode What to do about it If you build an MCP server: declare outputSchemas that constrain values, not just shapes. Add enum / pattern / format / numeric bounds where semantics allow. additionalProperties: false helps, but alone it's not enough -- a corrupted string is still a string. Test with mcp-drill scan --json in CI and gate on it. If you consume MCP tools: don't rely on outputSchema presence as safety. Validate semantically downstream or use mcp-drill wrap to exercise your agent's failure paths before prod. If you review MCP proposals: coverage will trend to 100% as generators spread. Ask for enforceability. GitHub repo -- Apache-2.0, telemetry off, Python 3.10+. Live scorecard. PRs and issues welcome -- especially if your server scores differently and you think the harness is wrong. Method is model-free and deterministic -- every number is a property of the server, not of whatever agent called it. The tool is the methodology, and it is released.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容