Decision taken 2026-08-07: re-narrow mcp from >=1.27,<3.0 back to >=1.27,<2.0. Filed so the decision is durable rather than living in a session transcript, and sequenced behind #338 because both touch uv.lock.
The concrete finding
pyproject.toml currently states the constraint and its justification in the same block, and they disagree with each other:
# Cap at <2.0 so a deliberate review happens before adopting
# any new major release. Bump the lower bound when verifying a
# newer release; bump the upper bound only after auditing the
# _compat shim against the new internals.
# 1.27.2 audited 2026-05-31: ...
"mcp>=1.27,<3.0",
The comment says <2.0. The pin says <3.0. #316 widened the constraint and left the rationale untouched, so the file now documents a guard it no longer has.
Why the guard exists
src/hive/_compat.py monkey-patches private attributes on mcp.shared.session.RequestResponder — _completed, _on_complete, _entered, _cancel_scope, respond. Private internals carry no compatibility promise across a major release. The narrow cap existed precisely so that adopting mcp 2.x required a human to audit the shim first.
<3.0 admits the entire 2.x line — the exact major boundary the original cap was written to exclude. The shim is self-gated and degrades quietly if the symbols vanish, which is a real mitigation but the wrong one to rely on: quiet degradation means the cancel-race crash returns without a failing build to announce it.
Scope
Sequencing
Blocked on #338 merging. That PR rewrites uv.lock for the cryptography 50 bump; its diff does not touch the mcp specifier line, so the conflict risk is modest, but regenerating the same lock from two branches invites avoidable churn.
Refs #316, #127, #336.
Decision taken 2026-08-07: re-narrow
mcpfrom>=1.27,<3.0back to>=1.27,<2.0. Filed so the decision is durable rather than living in a session transcript, and sequenced behind #338 because both touchuv.lock.The concrete finding
pyproject.tomlcurrently states the constraint and its justification in the same block, and they disagree with each other:The comment says
<2.0. The pin says<3.0. #316 widened the constraint and left the rationale untouched, so the file now documents a guard it no longer has.Why the guard exists
src/hive/_compat.pymonkey-patches private attributes onmcp.shared.session.RequestResponder—_completed,_on_complete,_entered,_cancel_scope,respond. Private internals carry no compatibility promise across a major release. The narrow cap existed precisely so that adoptingmcp2.x required a human to audit the shim first.<3.0admits the entire 2.x line — the exact major boundary the original cap was written to exclude. The shim is self-gated and degrades quietly if the symbols vanish, which is a real mitigation but the wrong one to rely on: quiet degradation means the cancel-race crash returns without a failing build to announce it.Scope
pyproject.toml:mcp>=1.27,<3.0->mcp>=1.27,<2.0.uv.lockfor the narrowed specifier. Noteuv.lockalready records>=1.27,<3.0, so the two currently agree and no pre-existing drift is being carried.Sequencing
Blocked on #338 merging. That PR rewrites
uv.lockfor thecryptography50 bump; its diff does not touch themcpspecifier line, so the conflict risk is modest, but regenerating the same lock from two branches invites avoidable churn.Refs #316, #127, #336.