Files
modelcontextprotocol--pytho…/scripts/codemod-batch-test
Max Isbey ecafdc78d6 Re-scope the codemod to run-on-v2 minimalism
The goal is that migrated v1 code runs on v2 on its legacy paths, not
that it adopts v2 idioms. Applying that bar:

- Leave e.error.code / .message / .data chains alone: v2's MCPError
  keeps a typed .error ErrorData, so the v1 spelling runs and
  type-checks unchanged. The except-binding tracking goes with it.
- Rewrite one-argument McpError(...) calls to MCPError.from_error_data(...)
  instead of flattening the inline ErrorData: the user's expression is
  kept as written and the non-inline form no longer needs a marker.
- Convert v1 positional arguments on the lowlevel Server constructor to
  keywords (v2 is keyword-only after name but kept v1's names and order),
  pinned against the installed signature by a new ratchet test.
- Reword every marker message that pointed at replaced internals or at
  the successor of the removed experimental tasks API; state removals
  plainly instead of steering users onto new surfaces.
- Teach the batch harness that a reportArgumentType error naming a
  detonating argument type (timedelta, AnyUrl) is a real break, never
  v2 strictness drift, and ignore stale work/ directories.
2026-07-01 12:38:23 +00:00
..

Codemod batch test

Runs the mcp-codemod v1 -> v2 migration against real, pinned repositories and audits the result with pyright, to find silent misses the unit tests and the in-repo example corpus cannot.

How it works

For each repository in repos.json:

  1. Clone the pinned commit (shallow).
  2. Run the codemod (sources and dependency files) over a copy.
  3. Type-check the pristine clone against an environment holding the latest v1 SDK, and the migrated copy against this workspace's v2 environment, with identical pyright settings.
  4. Diff the two error sets. Errors only on the migrated side are the migration surface; baseline noise (the repo's own issues, missing third-party stubs) appears on both sides and cancels out.
  5. Correlate each new error with the inserted # mcp-codemod: markers.

The codemod's contract is that the markers are the complete list of remaining manual work, so every new error should sit on or next to a marker. A new error with no nearby marker is a silent miss -- those are printed, written to work/results/<slug>.json, and make the run exit 1.

Usage

From the repository root (the v1 environment is created on first run):

uv run --frozen python scripts/codemod-batch-test/run.py            # all repos
uv run --frozen python scripts/codemod-batch-test/run.py --repo mcp-obsidian
uv run --frozen python scripts/codemod-batch-test/run.py --fresh    # re-clone

Adding a repository

Add an entry to repos.json with a pinned sha (never a branch), an include list when only part of the repository uses the SDK (empty means the whole tree), and a one-line note. Prefer repositories that depend on the mcp package directly; servers built on the external FastMCP library exercise that library's surface, not this SDK's.