@slbdn/mcp-tester 1.2.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -5,12 +5,119 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [1.4.0] - 2026-07-01
11
+
12
+ ### Added
13
+ - **HTTP and SSE transport support** — connect to remote MCP servers:
14
+ - `StreamableHttpServerConfig` (`transport: 'http'`) — modern MCP Streamable HTTP (POST + SSE GET)
15
+ - `SseServerConfig` (`transport: 'sse'`) — legacy SSE transport
16
+ - `ServerConfig` union type — `StdioServerConfig | StreamableHttpServerConfig | SseServerConfig`
17
+ - `getTransportType()` method — returns `'stdio'`, `'http'`, `'sse'`, or `null`
18
+ - URL auto-detection in CLI (passing a URL as first arg uses HTTP transport)
19
+ - CLI `--transport`, `--url`, `--headers` options on all commands
20
+ - 15 integration tests (Streamable HTTP + SSE) against server-everything
21
+ - 5 CLI HTTP transport tests
22
+ - 14 validation tests for HTTP/SSE configs
23
+
24
+ ### Changed
25
+ - `MCPServerConfig` is now a deprecated alias for `StdioServerConfig` (backward compatible)
26
+ - `start()` accepts the `ServerConfig` discriminated union instead of `MCPServerConfig`
27
+ - CLI commands now accept `[command]` (optional) instead of `<command>` to support HTTP/SSE
28
+
29
+ ## [1.3.0] - 2026-07-01
30
+
31
+ ### Added
32
+ - **TypeScript type generator** (`src/generate-types.ts`) — generate typed `.d.ts` from MCP tool schemas:
33
+ - `generateTypes()` API: connect to server, inspect schemas, emit TypeScript declarations
34
+ - CLI: `npx mcp-tester generate-types node ./server.js -o server.d.ts`
35
+ - Handles: primitives, enums, arrays, nested objects, oneOf/anyOf/allOf, $ref, const
36
+ - Generated types: `{Tool}Args`, `ToolName`, `ToolArgsMap`, `ToolCall`, `ResourceUri`, `PromptCall`
37
+ - 59 tests (12 e2e + 4 options + 43 unit)
38
+ - **Server health checks** — detect zombie processes and monitor server health:
39
+ - `isHealthy()` — sends a lightweight `tools/list` ping, returns `HealthStatus` with latency, PID, message
40
+ - `getServerPid()` — get the server process PID
41
+ - `getLastHealthStatus()` — cached result without re-checking
42
+ - `startHealthMonitor(options)` — periodic health monitoring with `onUnhealthy`/`onRecovery`/`onCheck` callbacks
43
+ - `stopHealthMonitor()` — stop periodic monitoring (also auto-stopped by `client.stop()`)
44
+ - Zombie process detection via `process.kill(pid, 0)`
45
+ - 17 tests (including SIGKILL zombie detection test)
46
+ - **Enhanced mock server** (`src/__tests__/fixtures/mock-server.ts`) — 68 tests:
47
+ - Configurable delays (`defaultDelay`) and random failures (`failureRate`)
48
+ - Input schema validation (`validateSchemas` option)
49
+ - Stateful tools: `counter` (increment/get/reset), `items` (add/list/remove/clear)
50
+ - Transform tool: `upper`/`lower`/`reverse`/`length` operations
51
+ - Custom handlers: `registerToolHandler`, `registerResourceHandler`, `registerPromptHandler`
52
+ - Call history: `getCallHistory`, `getCallCount` for test assertions
53
+ - Streaming support: `setupStream`, `nextStreamChunk`
54
+ - Dynamic registration/removal of tools, resources, prompts
55
+
56
+ ### Changed
57
+ - **CLI version** is now read dynamically from `package.json` (was hardcoded `1.0.0`)
58
+ - Applied safe dependency patches: `@typescript-eslint/*` 8.60.0, `@types/node` 20.19.41, `prettier` 3.8.3, `ts-jest` 29.4.11
59
+ - `npm audit fix` — 0 vulnerabilities (was 11)
60
+
61
+ ### Test Suite
62
+ - **635 tests** (17 suites), up from 491 (14 suites)
63
+ - New: mock server (68), generate-types (59), health checks (17)
64
+
8
65
  ## [1.2.0] - 2026-04-30
9
66
 
10
67
  ### Added
68
+ - **Visual test reports** — HTML test report auto-generated on every `npm test` run:
69
+ - Uses `jest-html-reporters` with collapsible test trees, timing, failure details
70
+ - Report saved to `reports/test-report.html`
71
+ - CI uploads report as artifact (14-day retention)
72
+ - Open locally: `open reports/test-report.html`
73
+ - **Property-based tests** (`src/__tests__/property-based.test.ts`) — 73 tests using fast-check:
74
+ - 44 validation tests: reject/accept all input types, error code invariants
75
+ - 17 masking tests: idempotency, completeness, secret detection, length bounds
76
+ - 12 generate-tests tests: no-throw, serializability, schema priority, nested arrays
77
+ - Fixed flaky `fc.double()` producing NaN/Infinity → use `fc.integer()` for numeric fields
78
+ - **Enhanced mock server** (`src/__tests__/fixtures/mock-server.ts`) — 68 tests:
79
+ - Configurable delays (`defaultDelay`) and random failures (`failureRate`)
80
+ - Input schema validation (`validateSchemas` option)
81
+ - Stateful tools: `counter` (increment/get/reset), `items` (add/list/remove/clear)
82
+ - Transform tool: `upper`/`lower`/`reverse`/`length` operations
83
+ - Custom handlers: `registerToolHandler`, `registerResourceHandler`, `registerPromptHandler`
84
+ - Call history: `getCallHistory`, `getCallCount` for test assertions
85
+ - Streaming support: `setupStream`, `nextStreamChunk`
86
+ - Dynamic registration/removal of tools, resources, prompts
87
+ - **TypeScript type generator** (`src/generate-types.ts`) — generate typed `.d.ts` from MCP tool schemas:
88
+ - `generateTypes()` API: connect to server, inspect schemas, emit TypeScript declarations
89
+ - CLI: `npx mcp-tester generate-types node ./server.js -o server.d.ts`
90
+ - Handles: primitives, enums, arrays, nested objects, oneOf/anyOf/allOf, $ref, const
91
+ - Generated types: `{Tool}Args`, `ToolName`, `ToolArgsMap`, `ToolCall`, `ResourceUri`, `PromptCall`
92
+ - 59 tests (12 e2e + 4 options + 43 unit)
93
+ - **Server health checks** — detect zombie processes and monitor server health:
94
+ - `isHealthy()` — sends a lightweight `tools/list` ping, returns `HealthStatus` with latency, PID, message
95
+ - `getServerPid()` — get the server process PID
96
+ - `getLastHealthStatus()` — cached result without re-checking
97
+ - `startHealthMonitor(options)` — periodic health monitoring with `onUnhealthy`/`onRecovery`/`onCheck` callbacks
98
+ - `stopHealthMonitor()` — stop periodic monitoring (also auto-stopped by `client.stop()`)
99
+ - Zombie process detection via `process.kill(pid, 0)`
100
+ - 17 tests (including SIGKILL zombie detection test)
101
+ - **Test code generator** (`src/generate-tests.ts`) — generate a complete test file from MCP server inspection:
102
+ - CLI: `mcp-tester generate node ./server.js -o server.test.ts` (alias: `gen`)
103
+ - API: `generateTests({ command, args, framework, ... })`
104
+ - Generates lifecycle tests, tool call tests with sample args from JSON Schema, resource read tests, prompt tests
105
+ - Options: `--framework jest|vitest`, `--output <file>`, `--description <name>`, `--no-tools`, `--no-resources`, `--no-prompts`, `--no-matchers`
106
+ - Sample arguments derived from JSON Schema: types, enums, defaults, examples
107
+ - 21 tests in `generate-tests.test.ts`
108
+ - **Input validation** (`src/utils/validation.ts`) — all MCPClient methods validate inputs before execution:
109
+ - `start()`: validates command (required string), args (string array), env (string values), startupDelay (non-negative number)
110
+ - `callTool()`: validates name (required string), arguments (object), timeout (positive number), retries (non-negative number)
111
+ - `readResource()`: validates URI (required non-empty string)
112
+ - `getPrompt()`: validates name (required string), args (string values)
113
+ - `requestSampling()`: validates messages (non-empty array)
114
+ - Constructor: validates timeout (positive), retries/retryDelay/startupDelay (non-negative), name/version (string)
115
+ - Validation runs before connection checks — invalid args throw `MCPClientError`, not `MCPNotStartedError`
116
+ - 91 tests in `validation.test.ts`
11
117
  - **Code coverage comments on PRs** — GitHub Actions workflow now posts a coverage table as a sticky comment on every pull request (statements/branches/functions/lines with thresholds)
12
118
  - **Dedicated `coverage` CI job** — runs on single Node.js version (faster than matrix), generates `coverage-summary.json`, uploads to Codecov v4
13
119
  - **`coverageReporters`** in `jest.config.js` — added `json-summary` reporter for CI coverage data extraction
120
+ - **VS Code snippets** (`.vscode/mcp-tester.code-snippets`) — 15 snippets for MCP test patterns (type `mcp` prefix)
14
121
 
15
122
  ### Changed
16
123
  - **Per-file coverage thresholds** updated for new files (`masking.ts`, `logger.ts`) and actual coverage numbers
@@ -20,6 +127,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
127
  - **docs/testing.md** — updated coverage thresholds (was "80%", now per-file table)
21
128
  - **AGENTS.md** — updated test count, coverage stats, CI job descriptions, file listing
22
129
  - Fixed flaky `delay` test (100ms → 90ms tolerance for timing variance)
130
+ - **Updated test count**: 491 (was 306)
23
131
 
24
132
  ## [1.1.0] - 2026-04-23
25
133
 
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![npm downloads](https://img.shields.io/npm/dm/@slbdn/mcp-tester)](https://www.npmjs.com/package/@slbdn/mcp-tester)
9
9
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
- [![Test Status](https://img.shields.io/badge/tests-306%20passing-brightgreen)](https://github.com/islobodan/mcp-tester/actions/workflows/test.yml)
11
+ [![Test Status](https://img.shields.io/badge/tests-669%20passing-brightgreen)](https://github.com/islobodan/mcp-tester/actions/workflows/test.yml)
12
12
  [![Coverage](https://img.shields.io/badge/coverage-68%2F61%2F60%2F68-brightgreen)](https://github.com/islobodan/mcp-tester/actions/workflows/test.yml) <!-- statements/branches/functions/lines -->
13
13
 
14
14
  A production-ready MCP (Model Context Protocol) client for **automated testing** of MCP servers with Jest.
@@ -50,7 +50,7 @@ No more manual clicking through inspectors — write real tests, run them in CI,
50
50
  │ │ │ MCPTimeoutError │ MCPConnectionError │ ... │ │ │
51
51
  │ │ └──────────────────────┬───────────────────────────────┘ │ │
52
52
  │ └─────────────────────────┼─────────────────────────────────────┘ │
53
- │ │ stdio (JSON-RPC) │
53
+ │ │ stdio, HTTP, SSE │
54
54
  │ ┌─────────────────────────▼─────────────────────────────────────┐ │
55
55
  │ │ MCP Server (child process) │ │
56
56
  │ │ ┌────────┐ ┌───────────┐ ┌──────────┐ ┌────────────┐ │ │
@@ -60,9 +60,9 @@ No more manual clicking through inspectors — write real tests, run them in CI,
60
60
  └─────────────────────────────────────────────────────────────────────┘
61
61
  ```
62
62
 
63
- **Data flow**: Your test calls `MCPClient` → which sends JSON-RPC over stdio → to the MCP server process → server responds → `MCPClient` returns typed results → your assertion validates them.
63
+ **Data flow**: Your test calls `MCPClient` → which sends JSON-RPC over stdio/HTTP/SSE → to the MCP server → server responds → `MCPClient` returns typed results → your assertion validates them.
64
64
 
65
- **Key design**: `MCPClient` manages the server lifecycle (spawn/kill) and protocol handling. Your tests never deal with the transport layer directly.
65
+ **Key design**: `MCPClient` manages the server lifecycle (spawn/kill for stdio, connect/disconnect for HTTP/SSE) and protocol handling. Your tests never deal with the transport layer directly.
66
66
 
67
67
  ## Why MCP Tester?
68
68
 
@@ -84,10 +84,22 @@ No more manual clicking through inspectors — write real tests, run them in CI,
84
84
  | Branches | 61% |
85
85
  | Functions | 60% |
86
86
  | Lines | 68% |
87
- | Tests | 306 passing |
87
+ | Tests | 669 passing |
88
88
 
89
89
  Per-file coverage thresholds are set in `jest.config.js` to catch regressions while avoiding CI noise. Run `npm run test:coverage` to see the full breakdown by file. PRs automatically receive a coverage comment via GitHub Actions.
90
90
 
91
+ ## Test Reports
92
+
93
+ Every `npm test` run auto-generates an HTML test report:
94
+
95
+ ```bash
96
+ npm test # generates reports/test-report.html
97
+ open reports/test-report.html # macOS
98
+ xdg-open reports/test-report.html # Linux
99
+ ```
100
+
101
+ The report includes collapsible test trees, timing per test, and failure details with stack traces. CI uploads reports as artifacts (14-day retention).
102
+
91
103
  ## Install
92
104
 
93
105
  ```bash
@@ -124,6 +136,22 @@ const result = await client.callTool({
124
136
  await client.stop();
125
137
  ```
126
138
 
139
+ ### Connect via HTTP
140
+
141
+ ```typescript
142
+ // Streamable HTTP transport (recommended for remote servers)
143
+ await client.start({
144
+ transport: 'http',
145
+ url: 'https://api.example.com/mcp',
146
+ });
147
+
148
+ // Legacy SSE transport
149
+ await client.start({
150
+ transport: 'sse',
151
+ url: 'http://localhost:3000/sse',
152
+ });
153
+ ```
154
+
127
155
  ### Test with Jest
128
156
 
129
157
  ```typescript
@@ -173,12 +201,90 @@ npx @slbdn/mcp-tester list-tools node ./server.js --json
173
201
  # Call a tool
174
202
  npx @slbdn/mcp-tester call-tool echo node ./server.js --params '{"message":"Hello"}'
175
203
 
176
- # Short aliases: lt, ct, rr, gp
204
+ # Generate test file from server inspection
205
+ npx @slbdn/mcp-tester generate node ./server.js -o server.test.ts
206
+ npx @slbdn/mcp-tester gen node ./server.js --framework vitest --no-resources
207
+
208
+ # Short aliases: lt, ct, rr, gp, gen
177
209
  npx @slbdn/mcp-tester lt node ./server.js
178
210
  ```
179
211
 
180
212
  See [CLI Reference](./docs/cli.md) for all commands and options.
181
213
 
214
+ ### Generate Test Files
215
+
216
+ Connect to any MCP server and generate a ready-to-run test file:
217
+
218
+ ```bash
219
+ # Generate Jest test file
220
+ npx @slbdn/mcp-tester generate node ./server.js -o server.test.ts
221
+
222
+ # Generate Vitest test file
223
+ npx @slbdn/mcp-tester gen node ./server.js --framework vitest
224
+
225
+ # Skip specific sections
226
+ npx @slbdn/mcp-tester generate node ./server.js --no-resources --no-prompts -o tools-only.test.ts
227
+ ```
228
+
229
+ Or use the API:
230
+
231
+ ```typescript
232
+ import { generateTests } from '@slbdn/mcp-tester';
233
+
234
+ const code = await generateTests({
235
+ command: 'node',
236
+ args: ['./server.js'],
237
+ framework: 'jest',
238
+ description: 'My Server Tests',
239
+ });
240
+
241
+ fs.writeFileSync('server.test.ts', code);
242
+ ```
243
+
244
+ The generator connects to the server, inspects all tools/resources/prompts, and generates:
245
+ - Connection and lifecycle tests
246
+ - Tool call tests with **sample arguments derived from JSON Schema**
247
+ - Resource read tests
248
+ - Prompt tests with sample arguments
249
+ - Proper `beforeEach`/`afterEach` cleanup
250
+
251
+ ### Generate TypeScript Types
252
+
253
+ Connect to any MCP server and generate typed `.d.ts` declarations from tool schemas:
254
+
255
+ ```bash
256
+ # Generate TypeScript types
257
+ npx @slbdn/mcp-tester generate-types node ./server.js -o server.d.ts
258
+ ```
259
+
260
+ Or use the API:
261
+
262
+ ```typescript
263
+ import { generateTypes } from '@slbdn/mcp-tester';
264
+ import { writeFileSync } from 'fs';
265
+
266
+ const types = await generateTypes({
267
+ command: 'node',
268
+ args: ['./server.js'],
269
+ });
270
+
271
+ writeFileSync('server.d.ts', types);
272
+ ```
273
+
274
+ This produces typed interfaces you can use for type-safe tool calls:
275
+
276
+ ```typescript
277
+ import type { ToolArgsMap } from './server.d.ts';
278
+
279
+ // TypeScript knows: { a: number; b: number }
280
+ const result = await client.callTool({
281
+ name: 'add',
282
+ arguments: { a: 1, b: 2 } as ToolArgsMap['add'],
283
+ });
284
+ ```
285
+
286
+ Supports: primitives, enums, nested objects, arrays, `oneOf`/`anyOf`/`allOf`, `$ref`, `const`.
287
+
182
288
  ## Speed Up Your Tests with Parallel Execution
183
289
 
184
290
  MCP Tester is built for concurrency. Fire off multiple tool calls at once — no waiting in line:
@@ -216,6 +322,10 @@ No extra config needed. Just `Promise.all` and go.
216
322
  | `start(config)` | `Promise<void>` | Connect to an MCP server |
217
323
  | `stop()` | `Promise<void>` | Disconnect and clean up |
218
324
  | `isConnected()` | `boolean` | Check connection state |
325
+ | `isHealthy()` | `Promise<HealthStatus>` | Check server health and responsiveness |
326
+ | `getServerPid()` | `number | null` | Get server process PID |
327
+ | `startHealthMonitor(opts)` | `void` | Start periodic health monitoring |
328
+ | `stopHealthMonitor()` | `void` | Stop health monitoring |
219
329
  | `listTools()` | `Promise<Tool[]>` | List available tools |
220
330
  | `callTool(options)` | `Promise<CallToolResult>` | Call a tool with arguments |
221
331
  | `listResources()` | `Promise<Resource[]>` | List available resources |
@@ -228,6 +338,25 @@ No extra config needed. Just `Promise.all` and go.
228
338
 
229
339
  See [API Reference](./docs/api-reference.md) for full details including types, options, and error classes.
230
340
 
341
+ ## Server Health Checks
342
+
343
+ Detect crashed servers and zombie processes during long test runs:
344
+
345
+ ```typescript
346
+ // One-time check
347
+ const health = await client.isHealthy();
348
+ console.log(`Healthy: ${health.healthy}, PID: ${health.pid}, latency: ${health.latencyMs}ms`);
349
+
350
+ // Periodic monitoring
351
+ client.startHealthMonitor({
352
+ interval: 3000,
353
+ onUnhealthy: (status) => console.error('Server down:', status.message),
354
+ onRecovery: (status) => console.log('Server recovered!'),
355
+ });
356
+ ```
357
+
358
+ Health checks detect zombie processes (killed/crashed but `isConnected()` still returns `true`) using `process.kill(pid, 0)`.
359
+
231
360
  ## Custom Jest Matchers
232
361
 
233
362
  Built-in matchers so your assertions read like English:
@@ -390,7 +519,7 @@ mcp-tester/
390
519
  npm install # Install dependencies
391
520
  npm run build # Compile TypeScript
392
521
  npm run dev # Watch mode — auto-rebuild on source changes
393
- npm test # Run tests (306 tests)
522
+ npm test # Run tests (auto-generates reports/test-report.html)
394
523
  npm run lint # Lint code
395
524
  npm run format # Format with Prettier
396
525
  ```
@@ -476,6 +605,30 @@ prettyPrint({ apiKey: 'sk-proj-abc123...', count: 42 });
476
605
 
477
606
  See [Troubleshooting Guide](./docs/troubleshooting.md) for more details.
478
607
 
608
+ ## VS Code Snippets
609
+
610
+ Type `mcp` in any TypeScript file to get started — 15 built-in snippets:
611
+
612
+ | Prefix | Inserts |
613
+ |--------|--------|
614
+ | `mcp-test` | Full test suite with lifecycle setup |
615
+ | `mcp-tool` | Tool call test + assertion |
616
+ | `mcp-resource` | Resource read test |
617
+ | `mcp-prompt` | Prompt get test |
618
+ | `mcp-client` | `new MCPClient()` + `start()` |
619
+ | `mcp-client-opts` | Client with timeout, retries, log level |
620
+ | `mcp-error` | Error handling test (`rejects.toThrow`) |
621
+ | `mcp-parallel` | `Promise.all` parallel tool calls |
622
+ | `mcp-list-tools` | List tools + `toHaveTool` assertion |
623
+ | `mcp-list-resources` | List resources + `toHaveResource` assertion |
624
+ | `mcp-list-prompts` | List prompts + `toHavePrompt` assertion |
625
+ | `mcp-assert-text` | `assert.toolTextEquals()` |
626
+ | `mcp-assert-json` | `assert.toolJsonEquals()` |
627
+ | `mcp-notifications` | Notification handler setup |
628
+ | `mcp-import` / `mcp-import-full` | Import statements |
629
+
630
+ Snippets are in `.vscode/mcp-tester.code-snippets` — works out of the box when you open the project in VS Code.
631
+
479
632
  ## Contributing
480
633
 
481
634
  1. Fork the repository