@slbdn/mcp-tester 1.5.4 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/releases.md CHANGED
@@ -1,413 +1,156 @@
1
1
  # Release Guide
2
2
 
3
- This guide explains how to create and publish new releases of MCP Tester.
3
+ How to create and publish a new release of `mcp-tester`. The release tool (`npm run release`) does the version bump, CHANGELOG promotion, commit, and tag in one command — and runs a strict pre-flight that catches every issue we've shipped broken before (audit failures, npm 11 lockfile traps, dangling local tags, empty `[Unreleased]`).
4
4
 
5
- ## Prerequisites
5
+ ## Prerequisites (one-time)
6
6
 
7
- 1. **NPM Token Setup**
8
- - Go to [npmjs.com](https://www.npmjs.com/settings/tokens)
9
- - Create a new automation token
10
- - Add it to GitHub repository secrets as `NPM_TOKEN`
11
- - Navigate to: Repository Settings → Secrets and variables → Actions
12
- - Click "New repository secret"
13
- - Name: `NPM_TOKEN`
14
- - Value: Your npm automation token
7
+ 1. **NPM Token**
8
+ - Go to <https://www.npmjs.com/settings/tokens> and create an **Automation** token.
9
+ - Add it to the repository as the secret `NPM_TOKEN` (Settings → Secrets and variables → Actions → New repository secret).
10
+ 2. **GitHub Actions** — `GITHUB_TOKEN` is automatic; `release.yml` already has `contents: write` for releases and `id-token: write` for provenance (if enabled).
11
+ 3. **Local git** — `git push` permission for `main` and tags. The release script never pushes; you do that after the script finishes.
15
12
 
16
- 2. **GitHub Token**
17
- - The `GITHUB_TOKEN` is automatically provided by GitHub Actions
18
- - Ensure the workflow has permission to create releases (already configured)
19
-
20
- ## Release Process
21
-
22
- ### Option 1: Quick Release (Recommended)
23
-
24
- Use this for routine releases (patch, minor, or major version bumps):
25
-
26
- ```bash
27
- # For patch release (1.0.0 → 1.0.1)
28
- npm run release:patch
29
-
30
- # For minor release (1.0.0 → 1.1.0)
31
- npm run release:minor
32
-
33
- # For major release (1.0.0 → 2.0.0)
34
- npm run release:major
35
-
36
- # For prerelease (1.0.0 → 1.0.1-beta.0)
37
- npm run release:prerelease
38
- ```
39
-
40
- Then commit and create tag:
41
-
42
- ```bash
43
- # Commit the version bump and CHANGELOG updates
44
- npm run release:commit
45
-
46
- # Create and push the tag
47
- git tag v$(node -p "require('./package.json').version")
48
- git push origin main --tags
49
- ```
50
-
51
- The release workflow will automatically:
52
- - ✅ Verify version matches tag
53
- - ✅ Run tests across Node.js versions (20, 22)
54
- - ✅ Build the project
55
- - ✅ Run security audits
56
- - ✅ Publish to npm
57
- - ✅ Create GitHub release with notes from CHANGELOG
58
- - ✅ Upload coverage to Codecov
59
-
60
- ### Option 2: Manual Release
61
-
62
- For full control over the release process:
13
+ ## The release process
63
14
 
64
15
  ```bash
65
- # 1. Update version in package.json
66
- npm version patch # or minor, major, prerelease
67
-
68
- # 2. Update CHANGELOG.md
69
- # - Move items from [Unreleased] to new version section
70
- # - Add date to version header: ## [1.0.1] - 2025-01-20
71
- # - Keep [Unreleased] section for next changes
72
-
73
- # 3. Verify tests pass
74
- npm test
16
+ # 1. Make sure your tree is ready:
17
+ # - the [Unreleased] section of CHANGELOG.md has the entries you want to ship
18
+ # - everything you want in the release is committed and pushed
19
+ git push origin main
75
20
 
76
- # 4. Build project
77
- npm run build
21
+ # 2. Run the release script (add --dry-run first if you want a no-write preview)
22
+ npm run release -- minor
23
+ # alias scripts: release:patch, release:minor, release:major, release:prerelease
78
24
 
79
- # 5. Commit changes
80
- git add package.json CHANGELOG.md
81
- git commit -m "chore: release v1.0.1"
82
-
83
- # 6. Create and push tag
84
- git tag v1.0.1
85
- git push origin main --tags
25
+ # 3. The script prints the push command when it succeeds:
26
+ # git push origin main --tags
27
+ # Run that. release.yml takes over from there.
86
28
  ```
87
29
 
88
- ### Option 3: Custom Version
30
+ The script:
89
31
 
90
- To set a specific version:
32
+ 1. Runs a strict pre-flight (next section). If anything is off, it exits 1 with an actionable message and writes nothing.
33
+ 2. Bumps the version in `package.json` and the two `version` lines in `package-lock.json` (direct JSON edit — **never** `npm version`, which has produced lockfile churn in the past).
34
+ 3. Promotes `## [Unreleased]` to `## [<version>] - <today>` in `CHANGELOG.md`, byte-for-byte preserving the rest.
35
+ 4. Verifies the resulting `git diff` is exactly the 3 expected files with the expected line counts.
36
+ 5. Creates the commit `chore: release <version>` and a lightweight tag `v<version>`.
37
+ 6. Prints the push handoff.
91
38
 
92
- ```bash
93
- # Set specific version
94
- npm version 1.2.3
95
-
96
- # Update CHANGELOG.md manually
97
- # ... edit CHANGELOG.md ...
98
-
99
- # Commit
100
- git add package.json CHANGELOG.md
101
- git commit -m "chore: release v1.2.3"
102
-
103
- # Create tag and push
104
- git tag v1.2.3
105
- git push origin main --tags
106
- ```
107
-
108
- ## Version Numbering
109
-
110
- Follow [Semantic Versioning](https://semver.org/):
111
-
112
- - **MAJOR** (X.0.0): Breaking changes or major features
113
- - Example: 1.0.0 → 2.0.0
114
- - Use when: API changes that break compatibility
115
-
116
- - **MINOR** (0.X.0): New features, backward compatible
117
- - Example: 1.0.0 → 1.1.0
118
- - Use when: Adding new features without breaking changes
119
-
120
- - **PATCH** (0.0.X): Bug fixes
121
- - Example: 1.0.0 → 1.0.1
122
- - Use when: Fixing bugs without adding features
123
-
124
- - **PRERELEASE** (0.0.0-X): Pre-release versions
125
- - Example: 1.0.0 → 1.1.0-alpha.1
126
- - Use when: Testing unreleased features
127
-
128
- ## Pre-Release Checklist
129
-
130
- Before creating a release:
131
-
132
- ### 1. Update CHANGELOG.md
133
- ```markdown
134
- ## [1.0.1] - 2025-01-20
135
-
136
- ### Added
137
- - New feature X
138
-
139
- ### Fixed
140
- - Bug Y fixed
141
-
142
- ### Changed
143
- - Updated dependency Z
144
-
145
- ## [Unreleased]
146
-
147
- ### Added
148
- - Next feature A (stays here)
149
- ```
39
+ Nothing is pushed, nothing is published. You can inspect the commit with `git show`, the diff with `git show v<version>`, and the tag with `git tag -l`. If anything looks wrong, abort the release with `git reset --hard HEAD~1 && git tag -d v<version>`.
150
40
 
151
- ### 2. Run Tests
152
- ```bash
153
- npm test
154
- npm run test:coverage
155
- ```
41
+ ## The pre-flight gates (P1–P8)
156
42
 
157
- ### 3. Verify Build
158
- ```bash
159
- npm run build
160
- npm run lint
161
- npm run format:check
162
- ```
43
+ Each gate maps to a real incident. If any fails, the script exits 1 with the failing gate, why it failed, and the manual command to re-run for the real error output.
163
44
 
164
- ### 4. Check Dependencies
165
- ```bash
166
- npm audit
167
- npm outdated
168
- ```
45
+ | Gate | Checks | Incident it would have caught |
46
+ |---|---|---|
47
+ | **P1** | Working tree is clean | (always; you can't cut a release on dirty code) |
48
+ | **P2** | `HEAD` is at the tip of `origin/main` (no unpushed, no unpulled commits) | The 1.6.0 fold — release tag lived on unpushed commits |
49
+ | **P3** | Every local `v*` tag exists on `origin` (peeks `^{commit}` to match the remote's peeled entry) | Same — would have caught `v1.5.5` as dangling before publish |
50
+ | **P4** | Lockfile is installable by `npm@10` (run in a temp dir; CI's npm) | The 1.5.1 + 1.6.0 emnapi trap — `npm audit fix` under npm 11 has twice produced locks npm 10 cannot install |
51
+ | **P5** | `npm@10 audit --audit-level=high` exits 0 | 1.5.0 publish failure (SDK OAuth + proxy-addr) |
52
+ | **P6** | Full local gates: `build`, `lint`, `format:check`, `test:browser`, `test`, `test:coverage`, `test:package` | Surfaces anything `release.yml` will run, locally, in ~6 min |
53
+ | **P7** | New version `N` is strictly greater than published `P`; no local tag `v{N}`; not on the registry | Re-releasing the same version; double-tagging |
54
+ | **P8** | `## [Unreleased]` exists in `CHANGELOG.md` and contains at least one content line | The v1.5.5 fold — release with nothing in it |
169
55
 
170
- ### 5. Review Documentation
171
- - [ ] README.md is up to date
172
- - [ ] CHANGELOG.md includes all changes
173
- - [ ] Examples work correctly
174
- - [ ] API documentation is accurate
56
+ Use `npm run release -- <bump> --dry-run` to run every gate and print the planned version / date / diff preview without writing anything.
175
57
 
176
- ### 6. Verify Version
177
- ```bash
178
- npm version patch # This updates package.json
179
- cat package.json | grep version
180
- ```
58
+ ## How the CI publish works (so you know what to expect)
181
59
 
182
- ## Release Workflow
60
+ Pushing `main` + the new `v<x.y.z>` tag triggers `.github/workflows/release.yml`, which:
183
61
 
184
- When you push a version tag (e.g., `v1.0.1`), the release workflow:
62
+ 1. **Verifies** the tag version matches `package.json` (refuses to publish a misaligned tag).
63
+ 2. **Runs gates on Node 20 / npm 10** — `npm ci`, `npm audit --audit-level=high` (hard gate), `build`, `lint`, `format:check`, `test`, `coverage`.
64
+ 3. **Publishes** to npm with provenance, creates the GitHub release from the CHANGELOG section that was just promoted, uploads coverage to Codecov.
65
+ 4. **Verifies** the install from the registry. This job now waits up to 10 minutes for the version to become visible (npm is eventually consistent) and retries the install (see commit `24fee8d`).
185
66
 
186
- 1. **Trigger**: Starts automatically on tag push
187
- 2. **Verify**: Confirms tag version matches package.json
188
- 3. **Test**: Runs all tests across Node.js 20, 22
189
- 4. **Build**: Compiles TypeScript to JavaScript
190
- 5. **Audit**: Runs security audits
191
- 6. **Lint**: Checks code quality
192
- 7. **Publish**: Publishes package to npm registry
193
- 8. **Release**: Creates GitHub release with CHANGELOG notes
194
- 9. **Verify**: Verifies package can be installed from npm
67
+ If step 2 fails after the tag is pushed, fix the issue and cut a **new** release with the script — do not rewrite the tag, do not re-run the workflow.
195
68
 
196
- ## Monitoring Release Progress
69
+ ## Versioning
197
70
 
198
- After pushing the tag:
71
+ [Semantic Versioning](https://semver.org/):
199
72
 
200
- 1. Go to: `https://github.com/islobodan/mcp-tester/actions`
201
- 2. Click on the "Release" workflow run
202
- 3. Monitor the progress through each step
73
+ - **MAJOR** — breaking API change. Use sparingly.
74
+ - **MINOR** — new capability, backward compatible (browser support, new transport, new matcher).
75
+ - **PATCH** — bug fix, no public surface change (workflow fix, lockfile bump, doc fix).
76
+ - **PRERELEASE** — opt-in / experimental. The script supports `npm run release -- prerelease` and follows npm's `npm version prerelease` rules: `1.6.0` → `1.6.1-0`, `1.6.1-0` → `1.6.1-1`, `1.6.1-beta.0` → `1.6.1-beta.1`.
203
77
 
204
- Expected duration: ~5-8 minutes
78
+ ## Manual fallback (discouraged)
205
79
 
206
- ## Post-Release
80
+ If the release script can't run for some reason (e.g. you need to do a post-incident hotfix on a fresh clone with no network), the manual equivalent is:
207
81
 
208
- ### 1. Verify on npm
209
82
  ```bash
210
- # Check if package is available
211
- npm view @slbdn/mcp-tester
212
-
213
- # Install and test
214
- npm install @slbdn/mcp-tester@latest
83
+ # 1. Edit package.json "version" and the two version lines in package-lock.json
84
+ # (top-level + packages[""].version). Do NOT run `npm version` — it rewrites
85
+ # the lockfile through npm's own machinery and has produced churn before.
86
+ # 2. Promote CHANGELOG.md by hand: `## [Unreleased]` → `## [N] - YYYY-MM-DD`.
87
+ # 3. Commit and tag.
88
+ git add package.json package-lock.json CHANGELOG.md
89
+ git commit -m "chore: release N"
90
+ git tag vN
91
+ git push origin main --tags
215
92
  ```
216
93
 
217
- ### 2. Verify GitHub Release
218
- - Go to: `https://github.com/islobodan/mcp-tester/releases`
219
- - Check release notes are correct
220
- - Verify release assets are attached
221
-
222
- ### 3. Update Documentation
223
- - Update README.md if needed
224
- - Update examples if API changed
225
- - Update AGENTS.md with new features
226
-
227
- ### 4. Announce Release
228
- - Create GitHub Discussion
229
- - Post issue about the release
230
- - Update project documentation
94
+ If the script's pre-flight then fails on the *next* release, it's usually P4 (lockfile) — fix with `npx -y npm@10 install` (not `npm audit fix` under npm 11).
231
95
 
232
96
  ## Troubleshooting
233
97
 
234
- ### Release Workflow Failed
98
+ ### Pre-flight says "tree is not clean"
235
99
 
236
- **Check:**
237
- 1. Version tag format (must be `vX.Y.Z`)
238
- 2. Version matches package.json exactly
239
- 3. Tests are passing locally
240
- 4. NPM_TOKEN is set correctly
100
+ Commit, stash, or unstage the listed files. The script refuses to operate on a dirty tree because the `git diff --numstat` self-check needs a stable baseline.
241
101
 
242
- **Fix:**
243
- ```bash
244
- # Delete and recreate tag
245
- git tag -d v1.0.1
246
- git push origin :refs/tags/v1.0.1
102
+ ### Pre-flight says "HEAD is N commit(s) ahead of origin/main"
247
103
 
248
- # Fix issues, then recreate
249
- git tag v1.0.1
250
- git push origin v1.0.1
251
- ```
104
+ You have local commits that aren't pushed. Either push them (`git push origin main`) and re-run, or reset them if you don't want them. The 1.5.5 fold was exactly this scenario.
252
105
 
253
- ### NPM Publish Failed
106
+ ### Pre-flight P4 fails ("lockfile not installable by npm 10")
254
107
 
255
- **Check:**
256
- 1. NPM_TOKEN has publish permissions
257
- 2. Package name is not already taken
258
- 3. Version doesn't already exist on npm
108
+ `npm@10 ci --dry-run` returned non-zero in the temp dir. The most common cause is `npm audit fix` having been run under npm 11. Fix:
259
109
 
260
- **Fix:**
261
110
  ```bash
262
- # Verify token
263
- npm whoami
264
-
265
- # Check if version exists
266
- npm view @slbdn/mcp-tester@1.0.1
267
-
268
- # If version exists, increment it
269
- npm version patch
270
- git commit package.json -m "chore: increment version"
271
- git tag v1.0.2
272
- git push origin v1.0.2
111
+ npx -y npm@10 install # regenerate lock under npm 10
112
+ # OR (if you actually want audit fixes)
113
+ npx -y npm@10 audit fix
273
114
  ```
274
115
 
275
- ### GitHub Release Not Created
116
+ Then re-run the release script. See `docs/troubleshooting.md` for the full emnapi history.
276
117
 
277
- **Check:**
278
- 1. GITHUB_TOKEN has write permissions
279
- 2. Workflow has permission to create releases
280
- 3. Tag format is correct
118
+ ### Pre-flight P5 fails (audit)
281
119
 
282
- **Fix:**
283
- - Manually create release from GitHub UI
284
- - Or delete tag and push again
120
+ Same command `release.yml` will run. Run `npx -y npm@10 audit` to see what; bump or replace the offending dependency. If the advisory is in a transitive dep behind a dev-only package, the right fix is to bump the parent (e.g. `ts-jest` was the path that brought in `handlebars` for 1.6.0).
285
121
 
286
- ### Tests Failing in CI
122
+ ### Pre-flight P8 fails ("nothing to release — [Unreleased] is empty")
287
123
 
288
- **Check:**
289
- 1. All tests pass locally
290
- 2. Node.js version compatibility
291
- 3. Dependencies are installed correctly
124
+ Add entries to `CHANGELOG.md` under `## [Unreleased]`, or skip this release. The script refuses to cut a release with an empty changelog because that's exactly the shape of the v1.5.5 fold.
292
125
 
293
- **Fix:**
294
- ```bash
295
- # Clean and reinstall
296
- rm -rf node_modules package-lock.json
297
- npm install
126
+ ### Resume after an interrupted run
298
127
 
299
- # Run tests
300
- npm test
301
- ```
128
+ If the script died between the commit and the tag (e.g. lost connection), the next run detects the state — `package.json` is bumped, `CHANGELOG.md` has the new section, HEAD is `chore: release <N>`, but the tag is missing — and just creates the missing tag. Resume detection itself is a cheap local shape check (no network); the full pre-flight still runs in resume mode, with two deliberate exceptions: P2 (HEAD is necessarily ahead of `origin/main` — the release commit is about to be pushed) and P8 (the changelog is already promoted — that is the resume signal). `N > published P` is still verified in P7, and the release steps never re-run the bump/promotion (which is not idempotent).
302
129
 
303
- ## Rollback Procedure
130
+ ### `release.yml` verify job fails
304
131
 
305
- If you need to rollback a release:
132
+ `release.yml`'s verify job now waits up to 10 minutes for npm to propagate and retries the install (commit `24fee8d`). If it still fails, the package genuinely is not installable — check the workflow logs and treat as a real failure.
306
133
 
307
- ### 1. Yank NPM Version
308
- ```bash
309
- npm deprecate @slbdn/mcp-tester@1.0.1 "Release rollback due to bug"
310
- ```
134
+ ### Tag exists locally but you want to redo the release
311
135
 
312
- ### 2. Delete GitHub Release
313
- 1. Go to repository releases page
314
- 2. Edit or delete the release
315
- 3. Delete the tag if needed
316
-
317
- ### 3. Create Hotfix
318
136
  ```bash
319
- # Create hotfix branch
320
- git checkout -b hotfix/issue
321
-
322
- # Fix issue
323
- git commit -am "fix: critical bug"
324
-
325
- # Bump version
326
- npm version patch
327
-
328
- # Release
329
- git tag v1.0.2
330
- git push origin v1.0.2
331
- ```
332
-
333
- ## Best Practices
334
-
335
- 1. **Update CHANGELOG First**
336
- - Always update CHANGELOG.md before version bump
337
- - Include all changes in the release
338
- - Reference issues/PRs if helpful
339
-
340
- 2. **Test Before Release**
341
- - Run all tests locally
342
- - Build the project
343
- - Install and test locally
344
-
345
- 3. **Use Semantic Versioning**
346
- - MAJOR: Breaking changes
347
- - MINOR: New features
348
- - PATCH: Bug fixes
349
-
350
- 4. **Tag Naming**
351
- - Always use `v` prefix: `v1.0.1`
352
- - Follow semver format: `vX.Y.Z`
353
-
354
- 5. **Review Before Pushing**
355
- - Check CHANGELOG is complete
356
- - Verify version is correct
357
- - Confirm tests pass
358
-
359
- 6. **Monitor Release**
360
- - Watch GitHub Actions workflow
361
- - Check npm publication
362
- - Verify GitHub release creation
363
-
364
- 7. **Document Breaking Changes**
365
- - Clearly document breaking changes in CHANGELOG
366
- - Add migration guide if needed
367
- - Update examples to use new API
368
-
369
- ## Example: Complete Release Workflow
370
-
371
- ```bash
372
- # 1. Update CHANGELOG.md
373
- # Edit CHANGELOG.md, move items from [Unreleased] to new version
374
-
375
- # 2. Bump version (patch release)
376
- npm run release:patch
377
-
378
- # 3. Verify tests pass
379
- npm test
380
-
381
- # 4. Build project
382
- npm run build
383
-
384
- # 5. Commit changes
385
- npm run release:commit
386
-
387
- # 6. Create and push tag
388
- VERSION=$(node -p "require('./package.json').version")
389
- git tag v$VERSION
390
- git push origin main --tags
391
-
392
- # 7. Monitor release at:
393
- # https://github.com/islobodan/mcp-tester/actions
137
+ git tag -d vX.Y.Z
138
+ git reset --hard HEAD~1 # undo the release commit
139
+ # re-run: npm run release -- patch
394
140
  ```
395
141
 
396
- ## Additional Resources
142
+ Never push a deletion of a published tag without first unpublishing or deprecating that version on npm.
397
143
 
398
- - [Semantic Versioning](https://semver.org/)
399
- - [npm Publishing](https://docs.npmjs.com/cli/publish)
400
- - [GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)
401
- - [GitHub Actions](https://docs.github.com/en/actions)
144
+ ## Best practices
402
145
 
403
- ## Support
146
+ 1. **Keep `[Unreleased]` flowing.** Add changelog entries with the code change, not in a separate prep step. The script's P8 gate makes this a hard requirement.
147
+ 2. **Push before you release.** The script's P2 + P3 gates enforce this; respect them.
148
+ 3. **One tag per push.** Two tag pushes launch two concurrent `release.yml` runs that both `npm publish`; npm `latest` will land on whichever finishes last (potentially the older one). If you accidentally cut two, see [docs/troubleshooting.md](./troubleshooting.md).
149
+ 4. **Use `--dry-run` on the first cut of a new release line** to sanity-check what would happen without writing anything.
150
+ 5. **Never run `npm version` against this repo's lockfile.** Use the script (which does direct JSON edits + a diff self-check) or the manual fallback.
404
151
 
405
- If you encounter issues with releases:
152
+ ## See also
406
153
 
407
- 1. Check GitHub Actions logs for detailed error messages
408
- 2. Review this guide's troubleshooting section
409
- 3. Open an issue on GitHub with:
410
- - Version being released
411
- - Error messages
412
- - Steps taken
413
- - Expected vs actual behavior
154
+ - [`docs/plans/release-automation.md`](./plans/release-automation.md) — the implementation spec, including the incident log that justifies every gate.
155
+ - [`docs/troubleshooting.md`](./troubleshooting.md) — common failures and how to fix them.
156
+ - [`CHANGELOG.md`](../CHANGELOG.md) — the changelog the script promotes.
package/docs/testing.md CHANGED
@@ -8,6 +8,7 @@ Guide to writing and running tests with MCP Tester.
8
8
  npm test # Run all tests
9
9
  npm run test:watch # Watch mode (auto-rerun on changes)
10
10
  npm run test:coverage # Run with coverage report
11
+ npm run test:browser # Bundle-check the browser build (esbuild)
11
12
  npm run lint # Lint code
12
13
  ```
13
14
 
@@ -20,6 +21,8 @@ src/__tests__/
20
21
  ├── advanced.test.ts # Sampling, elicitation
21
22
  ├── real-server.test.ts # Integration tests (stdio transport)
22
23
  ├── everything-server.test.ts # Full integration (server-everything)
24
+ ├── http-transport.test.ts # Streamable HTTP / SSE transport
25
+ ├── websocket-transport.test.ts # WebSocket transport (in-process double)
23
26
  ├── cli.test.ts # CLI tool tests
24
27
  └── fixtures/
25
28
  └── mock-server.ts # In-memory mock MCP server
@@ -114,8 +114,8 @@ Coverage thresholds: **80%** for branches, functions, lines, and statements.
114
114
 
115
115
  ## Known Limitations
116
116
 
117
- - Supports **stdio**, **Streamable HTTP**, and **SSE** transports
118
- - Designed for **Node.js** servers (other runtimes may need adjustments)
117
+ - Supports **stdio**, **Streamable HTTP**, **SSE**, and **WebSocket** transports
118
+ - Node.js by default; the HTTP/SSE/WebSocket transports also run in browsers and edge runtimes (see [Browser Support](./browser.md))
119
119
  - Mock server has configurable delays, failures, stateful tools, and validation
120
120
 
121
121
  ## Vitest
@@ -137,3 +137,24 @@ If you get TypeScript errors with custom matchers, make sure your `tsconfig.json
137
137
  "include": ["node_modules/@slbdn/mcp-tester/vitest.d.ts"]
138
138
  }
139
139
  ```
140
+
141
+ ## Browser and Edge Runtimes
142
+
143
+ **"Module not found: node:child_process" / "cross-spawn" in a browser build**
144
+ Your bundler is not honouring the `browser` field. Ensure it targets `browser`
145
+ (Webpack `target: 'web'`, Vite `build.target` not `ssr`, esbuild
146
+ `platform: 'browser'`). The repo's `npm run test:browser` script is a minimal
147
+ reference. Do not import `@slbdn/mcp-tester/dist/...` deep paths — import the
148
+ package root so the browser entry point is selected.
149
+
150
+ **"WebSocket is not defined" (Node.js)**
151
+ The WebSocket transport needs a global `WebSocket`. Node.js 22+ provides one;
152
+ on older versions enable it with `--experimental-websocket` or set a polyfill
153
+ such as `ws` on `globalThis`.
154
+
155
+ **CORS errors against a remote MCP server**
156
+ The server must allow your origin and, for Streamable HTTP, the
157
+ `mcp-session-id` header. This is a browser/network constraint — configure the
158
+ server, not the client.
159
+
160
+ See [Browser Support](./browser.md) for the full matrix.
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@slbdn/mcp-tester",
3
- "version": "1.5.4",
3
+ "version": "1.7.0",
4
4
  "description": "Minimal MCP client implementation for CI/CD testing of MCP servers",
5
5
  "main": "dist/index.js",
6
+ "browser": {
7
+ "./dist/index.js": "./dist/browser.js",
8
+ "./dist/utils/stdio-transport.js": false
9
+ },
6
10
  "types": "dist/index.d.ts",
7
11
  "type": "module",
8
12
  "sideEffects": false,
@@ -24,6 +28,7 @@
24
28
  "test:watch": "jest --watch",
25
29
  "test:coverage": "jest --coverage",
26
30
  "test:package": "node scripts/smoke-test-package.mjs",
31
+ "test:browser": "node scripts/check-browser-bundle.mjs",
27
32
  "benchmark": "tsx src/__tests__/benchmarks.ts",
28
33
  "lint": "eslint src --ext .ts",
29
34
  "format": "prettier --write \"src/**/*.ts\"",
@@ -31,11 +36,12 @@
31
36
  "audit": "npm audit",
32
37
  "audit:fix": "npm audit fix",
33
38
  "prepublishOnly": "npm run build && npm run docs",
34
- "release:patch": "npm version patch && npm run build",
35
- "release:minor": "npm version minor && npm run build",
36
- "release:major": "npm version major && npm run build",
37
- "release:prerelease": "npm version prerelease && npm run build",
38
- "release:commit": "git add package.json CHANGELOG.md && git commit -m \"chore: release $(node -p \"require('./package.json').version\")\"",
39
+ "release": "node scripts/release.mjs",
40
+ "release:patch": "node scripts/release.mjs patch",
41
+ "release:minor": "node scripts/release.mjs minor",
42
+ "release:major": "node scripts/release.mjs major",
43
+ "release:prerelease": "node scripts/release.mjs prerelease",
44
+ "test:release": "node --test scripts/release.test.mjs",
39
45
  "prepare": "husky || true"
40
46
  },
41
47
  "bin": {
@@ -77,6 +83,7 @@
77
83
  "@types/node": "^20.19.41",
78
84
  "@typescript-eslint/eslint-plugin": "^8.60.0",
79
85
  "@typescript-eslint/parser": "^8.60.0",
86
+ "esbuild": "^0.28.2",
80
87
  "eslint": "^8.56.0",
81
88
  "fast-check": "^4.8.0",
82
89
  "husky": "^9.1.7",