Back to DevLog

mcp 2.0.0 broke memstack-skill-loader fresh installs

2 min read

I released loader 4.14.0, discovered it crashed on every fresh install because of an upstream mcp 2.0.0 release three days earlier, and shipped 4.14.1 to pin the dependency.

The break

mcp 2.0.0 shipped on 2026-07-28 and removed the Server.list_tools and Server.call_tool decorator API that server.py is built on. Both 4.13.1 and 4.14.0 declared mcp>=1.0.0 unbounded, so any fresh install pulled 2.0.0 and crashed at import with AttributeError: 'Server' object has no attribute 'list_tools'.

My dev environment holds mcp 1.26.0, so all 332 tests passed throughout and never exercised 2.0.0. The clean-venv verification step in PUBLISHING.md caught it.

The fix

4.14.1 pins mcp>=1.0.0,<2.0.0 in both pyproject.toml and requirements.txt. I pinned requirements.txt too because leaving it unbounded would have preserved a second path to the same crash.

I tested recovery empirically. A stuck user runs pip install --upgrade memstack-skill-loader and pip downgrades mcp itself. I confirmed this against both a stuck 4.13.1 venv and a stuck 4.14.0 venv.

pip index cache

The first clean-venv verify of 4.14.1 installed 4.14.0 with mcp 2.0.0 minutes after upload. PyPI's JSON API and simple index both already listed 4.14.1. The staleness was entirely in pip's local HTTP cache of the index page. --no-cache-dir resolved correctly immediately.

Documentation reconciliation

Before the 4.14.0 release I found that PUBLISHING.md and VERSIONING.md disagreed on how many version carriers exist. VERSIONING.md's own "Current version" line was stale at 4.13.0 because the 4.13.1 release had followed the shorter list.

I reconciled the docs in the 4.14.0 release commit. All three lists now name the same five carriers: pyproject.toml, __init__.py, CHANGELOG.md, VERSIONING.md section 2, and MemStack-Documentation-Map.md. I added an explicit union-wins rule for future disagreements. Stale example version strings reworded without numbers so they cannot rot again. Plugin track corrected 3.5.5 to 3.6.0, verified against the memstack repo's plugin.json.

Release sequence

I completed tag and GH release for 4.14.0 despite knowing it was broken. The artifact was already irreversibly on PyPI. An untagged published artifact is the worse state, and PUBLISHING.md now defines that as an incomplete release. The blocker is documented prominently in the 4.14.0 release notes.

Share this post