Skip to content

Tool definition drift: 124 of 131 definitions changed in v2.0.0 (data + a pinning fix) #3466

Description

@AAtomless

I track how MCP server tool definitions change across releases for an agent security project.

In v2.0.0, 124 of 131 tool definitions changed, with no new capabilities advertised. The count still holds at v2.0.2, since PR #3454 only touches HTTP header validation.

Why it matters to your users:

Teams that pin definition hashes for injection review were forced into a full re-review by this release. Teams that don't pin absorbed 124 changed descriptions into running agents without noticing. Most teams don't know which of those two groups they're in.

I have per-release tables back through v1.14.0, reproduced independently twice, and a two-tier pinning scheme that separates meaningful changes from cosmetic ones so a release like this doesn't force a full re-review.

If useful, I can post both here.

Thanks,
Mike

Activity

  1. Paraphern commented on Oct 10, 2026

    @Paraphern

    Independent confirmation and decomposition. We pin tool contracts (name + description + inputSchema + annotations) via sha-256, diff on update, and grade changes by direction. Running the same comparison on the __toolsnaps__ files at v1.14.0 vs v2.0.0:

    Numbers match: 123 of 131 tools changed (you said 124 - the one-tool difference is likely a formatting boundary in one snap file). 8 unchanged, 10 added, 0 removed.

    But the decomposition matters more than the count. Every single one of the 123 changes is the same thing: an outputSchema was added. The inputSchema, description, and annotations are byte-identical between versions for all 123 tools. This is a Go SDK upgrade artifact (output schema support landed in the SDK), not a semantic change to any tool.

    The 8 unchanged tools are the list/search family (list_branches, list_issues, search_code, etc.) - they didn't get outputSchemas in-place. Instead, 10 new *_output variants were added alongside them (list_branches_output, search_code_output, etc.) with outputSchemas and the same operation. So the list/search tools have both an original (no outputSchema) and an _output variant (with outputSchema) in v2.0.0.

    Why this matters for the pinning scheme you're proposing: a naive hash-pin flags all 123 tools and forces exactly the re-review storm you described. But if the pin grades changes by what actually moved, this entire release is:

    • 0 BREAKING (no inputSchema change, no description rewrite, no annotation flip)
    • 0 LOOSENED (no constraint dropped)
    • 123 NOTATION (outputSchema added, input/description unchanged)
    • 10 NEW (output-variant tools)

    A reviewer seeing "123 NOTATION, 0 BREAKING" clicks through in seconds. A reviewer seeing "123 tools changed" without decomposition spends an afternoon. The grading is what makes pinning survive contact with SDK upgrades.

    For calibration on how common SDK-upgrade waves are: we saw the identical pattern in chrome-devtools-mcp (MCP SDK v2 migration re-serialized all 28 tool schemas - dialect declaration, key order, additionalProperties form - with zero parameter-level edits). Graded, that wave scores 0 BREAKING + 30 NOTATION. Without grading, both releases look like emergencies.

    Happy to share the full per-tool comparison table if useful. We also keep a public corpus of benign/weaponized contract pairs for testing pinning schemes against real attack shapes (description rewrites, schema mutations, sleeper tools): https://github.com/Paraphern/rugsnare

    (Disclosure: I maintain the pinning/diff tool referenced above - open source, zero deps. The 218-finding drift audit across the npm MCP top is its output: https://github.com/Paraphern/rugsnare/blob/main/audits/npm-top-mcp-drift-2026-10.md)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions