Skip to content

Pin mcp below the release that masks validator refusals - #9

Merged
exploitintel merged 1 commit into
mainfrom
fix/pin-mcp-below-the-validator-masking
Sep 10, 2026
Merged

exploitintel merged 1 commit into
mainfrom
fix/pin-mcp-below-the-validator-masking

Conversation

@exploitintel

Copy link
Copy Markdown
Owner

Restores main to green and, more importantly, stops shipping a degraded package to PyPI.

What broke

Every refusal this server words for itself is raised from a Pydantic WrapValidator - the bounds, the enum listings, the whole-number distinction. server.py:195-205 calls that wording deliberate: "What stays ours is the wording."

mcp 2.1.0 stopped propagating anything raised during argument validation. The SDK docstring for its wrapper is explicit: "nothing from the original reaches the client."

Proved with a minimal probe rather than inferred:

ToolError raised in the tool BODY   -> "Error executing tool X: body: this message should survive"
ToolError raised in a VALIDATOR     -> UnexpectedToolError: "Error executing tool X"

Exception type is irrelevant; the raise site is what matters.

Which versions

Bisected, not guessed:

mcp validator message
2.0.0 survives
2.0.1 survives
2.1.0 masked
2.1.1 masked
2.2.0 masked

So the break is 2.1.0. A <2.2 pin would have looked right and still shipped the bug.

Exposure

The declared range was mcp>=2.0.0,<3, so a fresh pip install eip-mcp has been resolving to a masked build since 2.1.0 shipped. Production on ovh2 is unaffected only by luck: it installed 2.0.0, and a live call still returns limit must be between 1 and 100.

Result

1970 passed, 232 skipped, 0 failed.

Lifting this

The pin is a stopgap. The durable fix is moving the refusals out of validators into the tool bodies, where a ToolError message survives on every version tested, and that is a deliberate change rather than something to fold in here.

Every refusal this server words for itself is raised from a Pydantic
WrapValidator: the bounds, the enum listings, the whole-number distinction.
mcp 2.1.0 stopped propagating anything raised during argument validation, so
all of it reaches the caller as the bare "Error executing tool <name>". The
SDK's own docstring for the wrapper says nothing from the original reaches the
client.

Bisected against a minimal probe rather than assumed: 2.0.0 and 2.0.1 keep the
message, 2.1.0, 2.1.1 and 2.2.0 mask it. The declared range was >=2.0.0,<3, so
a fresh install from PyPI has been resolving to a masked build since 2.1.0
shipped, while ovh2 stayed correct only because it happened to install 2.0.0.

This restores the suite to 1970 passing. Lifting the pin needs the refusals
moved out of validators into the tool bodies, where a ToolError message still
survives on every version tested.
@claude

claude Bot commented Sep 10, 2026

Copy link
Copy Markdown

Reviewed against the read-only MCP client's usual concerns (corpus text escaping into live Markdown/HTML, derived judgment/scores, PoC token leakage, unbounded output, host-validation/transport weakening, scope creep). This diff is a single-line dependency pin in pyproject.toml (mcp>=2.0.0,<3 → mcp>=2.0.0,<2.1) plus an explanatory comment — none of that surface is touched.

Sanity-checked the surrounding claims:

  • No lock file in the repo to drift out of sync with the new pin.
  • requirements-dev.txt and the release/quality workflows don't independently pin or reference mcp, so nothing else needs updating to match.
  • The bisection table in the description (2.0.0/2.0.1 good, 2.1.0+ masked) matches the chosen <2.1 upper bound exactly — the pin isn't over- or under-shooting the known-good range.

No findings. The follow-up mentioned in the description (moving refusals from validators into tool bodies so the pin can eventually be lifted) is correctly scoped out of this PR.

@exploitintel
exploitintel merged commit 834cbd1 into main Sep 10, 2026
4 checks passed
@exploitintel
exploitintel deleted the fix/pin-mcp-below-the-validator-masking branch September 10, 2026 17:35
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