Skip to content

build(deps): pin mcp to 2.1.0 so an SDK minor cannot land unreviewed - #503

Merged
GiulioDER merged 2 commits into
masterfrom
claude/ci-failures-5e23f9
Aug 25, 2026
Merged

build(deps): pin mcp to 2.1.0 so an SDK minor cannot land unreviewed#503
GiulioDER merged 2 commits into
masterfrom
claude/ci-failures-5e23f9

Conversation

@GiulioDER

Copy link
Copy Markdown
Owner

What this does and why

mcp was declared >=2,<3, so 2.1.0 arrived on its own. It redacts a tool exception's message
unless the exception derives from the SDK's ToolError, so the refusal raised by
recall_mcp.limits.RateLimited reached clients as a bare Error executing tool recall_search
instead of its retry guidance.

The three assertions in tests/test_rate_limit_http.py caught it, but only after it had broken
master three times
(#497, #498, #499). #501 fixed the code by giving RateLimited the ToolError
base. This fixes the reason it landed unreviewed at all.

uv.lock prevented none of it: CI installs with pip install -e, which ignores the lock, so the
lock read 2.0.0 throughout while CI resolved 2.1.0. The lock constrains uv sync and nothing else.

Pinned at 2.1.0 rather than reverting to 2.0.0 because 2.1.0 is what master is currently green on,
so the pin freezes a state with a full CI run behind it. All three sites that the file's own comment
says must move together are pinned: the mcp, dev and desktop extras.

A second commit corrects a comment in .github/workflows/ci.yml. The floor job resolves
lowest-direct, so an exact pin makes mcp's floor degenerate: lowest and newest become one version
and that job no longer proves anything about the MCP API surface. Its comment still claimed a
mcp>=2 floor was exercised. That same comment already records being burned by a false floor claim
once (pgvector>=0.3), and concludes a floor nothing resolves at "is documentation, not a
constraint, and it is documentation that was false".

docs/PRODUCTION.md and CHANGELOG.md also name mcp>=2,<3 and are deliberately left alone:
both are release notes for 0.5.1 describing what that release did, which is still true.

Two calls worth reviewing

  • No Dependabot ignore rule was added. Dependabot will now open a PR whenever a new mcp ships.
    That visible PR is the reviewed bump this pin exists to force, and
    tests/test_dependabot_ignores_match_pins.py argues for exactly that tradeoff, preferring a
    self-announcing PR to silence.
  • A hard == in published metadata constrains consumers. Concretely, semgrep pins
    mcp==1.23.3, so recall[mcp] and semgrep can no longer share an environment. semgrep is not a
    dependency of this repo, so CI is unaffected, but downstream users combining recall with another
    MCP-consuming package will hit this class of conflict. The alternative shape is a range in package
    metadata plus an exact pin in a constraints file, which would require CI to stop using
    pip install -e before it constrains anything.

Area touched

MCP server (dependency metadata and CI configuration only; no runtime code changed).

Checklist

  • ruff check . passes
  • pytest passes against a real pgvector database. Targeted rather than the full suite, since
    no runtime code changed: tests/test_rate_limit_http.py 4 passed; the MCP surface
    (test_auth, test_limits, test_mcp_*, test_server_env_validation) 378 passed,
    1 skipped
    ; test_dependabot_ignores_match_pins plus both citation gates 73 passed.
    All run with mcp==2.1.0 actually installed. The full suite is left to CI.
  • Dependency changed: uv lock was run, uv.lock is included, and uv lock --check passes
    locally. The only movement is mcp and mcp-types, 2.0.0 to 2.1.0.
  • The test that would fail without this change already exists and is the reason this was found:
    tests/test_rate_limit_http.py asserts on the client-visible refusal text, not on an internal
    flag, so it fails exactly when the SDK stops surfacing the message.
  • No published number changes.
  • No calibration, retrieval-quality or trust-layer impact, so make eval was not re-run.

Evaluation impact

No retrieval or trust-layer impact. This changes dependency metadata and one CI comment only.

🤖 Generated with Claude Code

gde00555-spec and others added 2 commits August 25, 2026 15:30
`mcp>=2,<3` let 2.1.0 arrive on its own. It redacts a tool exception's
message unless the exception derives from the SDK's `ToolError`, so the
refusal raised by `recall_mcp.limits.RateLimited` reached clients as a bare
"Error executing tool recall_search" rather than its retry guidance. The
three assertions in tests/test_rate_limit_http.py caught it, but only after
it had broken master three times (#497, #498, #499).

`uv.lock` did not prevent any of that: CI installs with `pip install -e`,
which ignores the lock, so the lock said 2.0.0 throughout while CI resolved
2.1.0. Pin the three declaration sites that must move together (`mcp`,
`dev`, `desktop`) and relock, so a version change is a reviewed diff with a
CI run behind it instead of a silent resolution.

RateLimited keeps its ToolError base regardless; the pin controls when a new
SDK arrives, not whether the code survives it.

Verified against mcp 2.1.0 locally: tests/test_rate_limit_http.py 4 passed,
and the MCP surface (auth, limits, test_mcp_*, server env) 378 passed,
1 skipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The `floor` job installs with `--resolution lowest-direct`, so pinning `mcp`
at an exact version makes its floor degenerate: lowest and newest are now the
same single version and that job no longer proves anything about the MCP API
surface. Its comment still claimed a `mcp>=2` floor was being exercised.

This repository has already been bitten by exactly this: the same comment
records `pgvector>=0.3` naming versions where `import recall.store` raises,
and concludes that a floor nothing resolves at "is documentation, not a
constraint, and it is documentation that was false". Leaving the MCP half
stale would have reproduced that.

docs/PRODUCTION.md and CHANGELOG.md also name `mcp>=2,<3`, and both are left
alone on purpose: they are release notes for 0.5.1 and describe what that
release did, which is still true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@GiulioDER
GiulioDER merged commit 59d4add into master Aug 25, 2026
13 checks passed
@GiulioDER
GiulioDER deleted the claude/ci-failures-5e23f9 branch August 25, 2026 14:38
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.

2 participants