Skip to content

Commit bd67be3

Browse files
committed
add batch testing and analysis prompt on codemod
1 parent 3d43f78 commit bd67be3

15 files changed

Lines changed: 1402 additions & 147 deletions

File tree

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ pnpm-lock.yaml
1212
# Ignore generated files
1313
src/spec.types.ts
1414

15+
# Batch test cloned repos and results
16+
packages/codemod/batch-test/repos
17+
packages/codemod/batch-test/results
18+
1519
# Quickstart examples uses 2-space indent to match ecosystem conventions
1620
examples/client-quickstart/
1721
examples/server-quickstart/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
repos/
2+
results/
3+
tarballs/
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Codemod Batch Test: Analysis
2+
3+
## Context
4+
5+
The MCP TypeScript SDK is migrating from a single v1 package (`@modelcontextprotocol/sdk`) to a multi-package v2 architecture (`@modelcontextprotocol/client`, `/server`, `/core`, `/node`, `/express`). This involves renamed APIs, restructured context objects, removed modules, and
6+
new import paths.
7+
8+
The `@modelcontextprotocol/codemod` package automates the mechanical parts of this migration. It runs 9 ordered AST transforms via ts-morph: import path rewrites, symbol renames, McpServer API restructuring, handler registration changes, context property remapping, and more. It
9+
also updates `package.json` to swap v1 deps for v2.
10+
11+
The **batch test** runs this codemod against a curated list of real-world repos that use the v1 SDK. For each repo it:
12+
13+
1. Clones and installs
14+
2. Runs baseline checks (typecheck, build, test, lint) to confirm the repo is healthy before migration
15+
3. Runs the codemod
16+
4. Re-installs (package.json was updated with v2 deps)
17+
5. Re-runs the same checks
18+
19+
The goal is to find issues in the codemod itself — incorrect transforms, missing transforms, or gaps — so we can fix them.
20+
21+
## Instructions
22+
23+
1. Build the codemod:
24+
25+
```
26+
pnpm --filter @modelcontextprotocol/codemod build
27+
```
28+
29+
2. Run the batch test:
30+
31+
```
32+
pnpm --filter @modelcontextprotocol/codemod batch-test
33+
```
34+
35+
3. Read `packages/codemod/batch-test/results/summary.json` for the overview. Note which repos have `postCodemodClean: false` and which check types have new errors.
36+
37+
4. For each repo with new errors, read its `packages/codemod/batch-test/results/<repo-slug>/report.json`. Compare `baseline` vs `postCodemod` for each check — only errors that appear in `postCodemod` but not in `baseline` are codemod-introduced.
38+
39+
5. Also review the `codemod.diagnostics` array in each report — these are warnings the codemod itself emitted about patterns it couldn't fully handle.
40+
41+
6. For each codemod-introduced error, look at the actual source file in the cloned repo (`packages/codemod/batch-test/repos/<repo-slug>/...`) to understand what the codemod produced and what it should have produced.
42+
43+
7. Categorize each finding using the categories below, then produce the output described in the Output Format section.
44+
45+
## Error Categories
46+
47+
| Category | Meaning | What to do |
48+
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
49+
| `codemod-bug` | A transform produced incorrect output — the code it generated is wrong | Identify which transform is responsible and what the correct output should be. This is a bug to fix in the codemod. |
50+
| `missing-transform` | The codemod left v1 code untouched that it should have migrated | Identify the v1 pattern and which existing transform should handle it, or whether a new transform is needed. |
51+
| `manual-migration` | The error is expected — the migration guide documents this as requiring human judgment (e.g., removed APIs, architectural changes) | Verify the codemod emitted a diagnostic for it. If not, add one. |
52+
| `repo-specific` | An unusual pattern unique to this repo that isn't worth handling in the codemod | Note it briefly but don't suggest codemod changes. |
53+
54+
## Output Format
55+
56+
### Summary
57+
58+
- Repos tested: X
59+
- Repos clean after codemod: Y
60+
- Repos with new errors: Z
61+
- Total codemod-introduced errors: N
62+
63+
### Findings by Category
64+
65+
#### Codemod Bugs
66+
67+
| Repo | File:Line | Error | Transform | Root Cause | Correct Output |
68+
| ---- | --------- | ----- | --------- | ---------- | -------------- |
69+
70+
#### Missing Transforms
71+
72+
| Repo | File:Line | Error | v1 Pattern | Suggested Fix |
73+
| ---- | --------- | ----- | ---------- | ------------- |
74+
75+
#### Manual Migration (expected)
76+
77+
| Repo | File:Line | Error | Has Diagnostic? | Migration Guide Reference |
78+
| ---- | --------- | ----- | --------------- | ------------------------- |
79+
80+
#### Repo-Specific
81+
82+
| Repo | File:Line | Error | Why Not Worth Handling |
83+
| ---- | --------- | ----- | ---------------------- |
84+
85+
### Priority Fixes
86+
87+
List the top 3-5 codemod improvements that would fix the most repos, ordered by impact (number of repos affected). For each, state: what to change, in which transform, and how many repos it would fix.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[
2+
{
3+
"repo": "KKonstantinov/mcp-servers-fork",
4+
"ref": "feature/upgrade-zod-v4",
5+
"packages": [
6+
{
7+
"dir": "src/everything",
8+
"sourceDir": ".",
9+
"checks": {
10+
"typecheck": "npx tsc --noEmit",
11+
"build": "npm run build",
12+
"test": "npm run test",
13+
"lint": "npm run prettier:check"
14+
}
15+
}
16+
]
17+
},
18+
{
19+
"repo": "modelcontextprotocol/inspector",
20+
"ref": "main",
21+
"packages": [
22+
{
23+
"dir": "client",
24+
"sourceDir": "src",
25+
"checks": {
26+
"typecheck": "npx tsc --noEmit",
27+
"build": "npm run build",
28+
"test": "npm run test",
29+
"lint": "npm run lint"
30+
}
31+
},
32+
{
33+
"dir": "server",
34+
"sourceDir": "src",
35+
"checks": {
36+
"typecheck": "npx tsc --noEmit",
37+
"build": "npm run build",
38+
"test": null,
39+
"lint": null
40+
}
41+
}
42+
]
43+
}
44+
]

packages/codemod/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"lint": "eslint src/ && prettier --ignore-path ../../.prettierignore --check .",
4444
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
4545
"check": "pnpm run typecheck && pnpm run lint",
46+
"batch-test": "tsx src/bin/batchTest.ts",
47+
"batch-test:clean": "rm -rf batch-test/repos batch-test/results batch-test/tarballs",
4648
"test": "vitest run",
4749
"test:watch": "vitest"
4850
},

packages/codemod/scripts/generateSpecSchemaMap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if (!authMatch) throw new Error('Could not find authSchemas in specTypeSchema.ts
1919

2020
const authSchemas = [...authMatch[1]!.matchAll(/(\w+Schema)/g)].map(m => m[1]!);
2121

22-
const allSchemas = [...protocolSchemas, ...authSchemas].sort();
22+
const allSchemas = [...protocolSchemas, ...authSchemas].toSorted();
2323

2424
const entries = allSchemas.map((s, i) => ` '${s}'${i < allSchemas.length - 1 ? ',' : ''}`).join('\n');
2525

0 commit comments

Comments
 (0)