@slbdn/mcp-tester 1.4.3 → 1.5.3

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +49 -0
  3. package/dist/ai/provider.d.ts +145 -0
  4. package/dist/ai/provider.d.ts.map +1 -0
  5. package/dist/ai/provider.js +428 -0
  6. package/dist/ai/provider.js.map +1 -0
  7. package/dist/cli/index.js +214 -14
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/generate-cases.d.ts +113 -0
  10. package/dist/generate-cases.d.ts.map +1 -0
  11. package/dist/generate-cases.js +565 -0
  12. package/dist/generate-cases.js.map +1 -0
  13. package/dist/generate-tests.d.ts +52 -1
  14. package/dist/generate-tests.d.ts.map +1 -1
  15. package/dist/generate-tests.js +208 -81
  16. package/dist/generate-tests.js.map +1 -1
  17. package/dist/index.d.ts +3 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/matchers.d.ts +31 -21
  22. package/dist/matchers.d.ts.map +1 -1
  23. package/dist/matchers.js.map +1 -1
  24. package/dist/templates/full-stack/.github/workflows/test.yml +34 -0
  25. package/dist/templates/full-stack/README.md +73 -0
  26. package/dist/templates/full-stack/examples/mock-server.js +115 -0
  27. package/dist/templates/full-stack/jest.config.js +39 -0
  28. package/dist/templates/full-stack/package.json +31 -0
  29. package/dist/templates/full-stack/scripts/generate-tests.ts +32 -0
  30. package/dist/templates/full-stack/scripts/generate-types.ts +28 -0
  31. package/dist/templates/full-stack/src/server.ts +78 -0
  32. package/dist/templates/full-stack/tests/helpers.ts +29 -0
  33. package/dist/templates/full-stack/tests/parallel.test.ts +44 -0
  34. package/dist/templates/full-stack/tests/server.test.ts +36 -0
  35. package/dist/templates/full-stack/tests/tools.test.ts +61 -0
  36. package/dist/templates/full-stack/tsconfig.json +19 -0
  37. package/dist/templates/minimal-jest/README.md +42 -0
  38. package/dist/templates/minimal-jest/examples/mock-server.js +62 -0
  39. package/dist/templates/minimal-jest/jest.config.js +24 -0
  40. package/dist/templates/minimal-jest/package.json +24 -0
  41. package/dist/templates/minimal-jest/tests/server.test.ts +64 -0
  42. package/dist/templates/minimal-jest/tsconfig.json +19 -0
  43. package/dist/templates/standard-jest/.github/workflows/test.yml +32 -0
  44. package/dist/templates/standard-jest/README.md +44 -0
  45. package/dist/templates/standard-jest/examples/mock-server.js +122 -0
  46. package/dist/templates/standard-jest/jest.config.js +39 -0
  47. package/dist/templates/standard-jest/package.json +27 -0
  48. package/dist/templates/standard-jest/tests/helpers.ts +43 -0
  49. package/dist/templates/standard-jest/tests/prompts.test.ts +37 -0
  50. package/dist/templates/standard-jest/tests/resources.test.ts +37 -0
  51. package/dist/templates/standard-jest/tests/server.test.ts +30 -0
  52. package/dist/templates/standard-jest/tests/tools.test.ts +87 -0
  53. package/dist/templates/standard-jest/tsconfig.json +19 -0
  54. package/docs/advanced.md +424 -0
  55. package/docs/ai-generation.md +211 -0
  56. package/docs/api-reference.md +819 -0
  57. package/docs/cicd.md +289 -0
  58. package/docs/cli.md +225 -0
  59. package/docs/examples.md +300 -0
  60. package/docs/nodejs-compatibility.md +81 -0
  61. package/docs/releases.md +413 -0
  62. package/docs/starter-templates.md +110 -0
  63. package/docs/testing.md +443 -0
  64. package/docs/troubleshooting.md +139 -0
  65. package/jest.d.ts +43 -0
  66. package/package.json +5 -2
@@ -0,0 +1,300 @@
1
+ # Examples
2
+
3
+ Practical code examples for common MCP Tester use cases.
4
+
5
+ ## Example MCP Servers
6
+
7
+ The `examples/` directory includes ready-to-run MCP servers for testing and learning:
8
+
9
+ | Server | Description |
10
+ |--------|-------------|
11
+ | `mock-server.js` | Basic server with echo, add, delay, error_tool + 2 resources + 2 prompts |
12
+ | `simple-server.ts` | Minimal TypeScript server — greet tool, version resource, welcome prompt |
13
+ | `stateful-server.ts` | Server with mutable state — counter (increment/get/reset) and todo list (add/list/complete) |
14
+
15
+ Run any server standalone:
16
+
17
+ ```bash
18
+ # JavaScript (no build needed)
19
+ node examples/mock-server.js
20
+
21
+ # TypeScript (uses tsx)
22
+ npx tsx examples/simple-server.ts
23
+ npx tsx examples/stateful-server.ts
24
+ ```
25
+
26
+ Test against them:
27
+
28
+ ```bash
29
+ npx @slbdn/mcp-tester test -- node --loader tsx examples/simple-server.ts
30
+ ```
31
+
32
+ ## Basic Tool Testing
33
+
34
+ ```typescript
35
+ import { MCPClient } from '@slbdn/mcp-tester';
36
+
37
+ async function testTool() {
38
+ const client = new MCPClient();
39
+
40
+ try {
41
+ await client.start({
42
+ command: 'node',
43
+ args: ['./my-server.js'],
44
+ });
45
+
46
+ const tools = await client.listTools();
47
+ console.log(`Found ${tools.length} tools`);
48
+
49
+ for (const tool of tools) {
50
+ console.log(`\nTesting: ${tool.name}`);
51
+ const result = await client.callTool({
52
+ name: tool.name,
53
+ arguments: {},
54
+ });
55
+ console.log(`Result: ${result.content[0]?.text}`);
56
+ }
57
+ } finally {
58
+ await client.stop();
59
+ }
60
+ }
61
+
62
+ testTool();
63
+ ```
64
+
65
+ ## Resource Reading
66
+
67
+ ```typescript
68
+ import { MCPClient } from '@slbdn/mcp-tester';
69
+
70
+ async function readConfiguration() {
71
+ const client = new MCPClient();
72
+
73
+ try {
74
+ await client.start({
75
+ command: 'node',
76
+ args: ['./config-server.js'],
77
+ });
78
+
79
+ const resources = await client.listResources();
80
+ console.log('Available resources:', resources.map(r => r.uri));
81
+
82
+ const settings = await client.readResource('config://settings');
83
+ console.log('Settings:', JSON.parse(settings.contents[0].text as string));
84
+ } finally {
85
+ await client.stop();
86
+ }
87
+ }
88
+
89
+ readConfiguration();
90
+ ```
91
+
92
+ ## Using Prompts
93
+
94
+ ```typescript
95
+ import { MCPClient } from '@slbdn/mcp-tester';
96
+
97
+ async function usePrompt() {
98
+ const client = new MCPClient();
99
+
100
+ try {
101
+ await client.start({
102
+ command: 'node',
103
+ args: ['./prompt-server.js'],
104
+ });
105
+
106
+ const prompt = await client.getPrompt('greet', { name: 'World' });
107
+ console.log('Generated message:', prompt.messages[0].content.text);
108
+ } finally {
109
+ await client.stop();
110
+ }
111
+ }
112
+
113
+ usePrompt();
114
+ ```
115
+
116
+ ## Complete Jest Test Suite
117
+
118
+ ```typescript
119
+ import { MCPClient, setupJestMatchers } from '@slbdn/mcp-tester';
120
+ import { beforeAll, beforeEach, afterEach, describe, it, expect } from '@jest/globals';
121
+
122
+ beforeAll(() => setupJestMatchers());
123
+
124
+ describe('My MCP Server', () => {
125
+ let client: MCPClient;
126
+
127
+ beforeEach(async () => {
128
+ client = new MCPClient();
129
+ await client.start({ command: 'node', args: ['./server.js'] });
130
+ });
131
+
132
+ afterEach(async () => {
133
+ if (client.isConnected()) await client.stop();
134
+ });
135
+
136
+ it('should have expected tools', async () => {
137
+ const tools = await client.listTools();
138
+ expect(tools).toHaveTool('echo');
139
+ expect(tools).toHaveToolCount(5);
140
+ });
141
+
142
+ it('should call tool and check result', async () => {
143
+ const result = await client.callTool({
144
+ name: 'calculate',
145
+ arguments: { operation: 'add', values: [10, 20] },
146
+ });
147
+ expect(result).toReturnText('30');
148
+ });
149
+
150
+ it('should handle errors', async () => {
151
+ const result = await client.callTool({
152
+ name: 'fail-tool',
153
+ arguments: {},
154
+ });
155
+ expect(result).toReturnError();
156
+ });
157
+ });
158
+ ```
159
+
160
+ ## Complete Vitest Test Suite
161
+
162
+ ```typescript
163
+ import { MCPClient, setupVitestMatchers } from '@slbdn/mcp-tester';
164
+ import { beforeAll, beforeEach, afterEach, describe, it, expect } from 'vitest';
165
+ // /// <reference types="@slbdn/mcp-tester/vitest" />
166
+
167
+ beforeAll(() => setupVitestMatchers());
168
+
169
+ describe('My MCP Server', () => {
170
+ let client: MCPClient;
171
+
172
+ beforeEach(async () => {
173
+ client = new MCPClient();
174
+ await client.start({ command: 'node', args: ['./server.js'] });
175
+ });
176
+
177
+ afterEach(async () => {
178
+ if (client.isConnected()) await client.stop();
179
+ });
180
+
181
+ it('should have expected tools', async () => {
182
+ const tools = await client.listTools();
183
+ expect(tools).toHaveTool('echo');
184
+ expect(tools).toHaveToolCount(5);
185
+ });
186
+
187
+ it('should call tool and check result', async () => {
188
+ const result = await client.callTool({
189
+ name: 'calculate',
190
+ arguments: { operation: 'add', values: [10, 20] },
191
+ });
192
+ expect(result).toReturnText('30');
193
+ });
194
+ });
195
+ ```
196
+
197
+ ## Using Assert Utilities (Any Test Runner)
198
+
199
+ ```typescript
200
+ import { MCPClient, assert } from '@slbdn/mcp-tester';
201
+
202
+ async function runTest(name: string, fn: () => Promise<void>) {
203
+ try {
204
+ await fn();
205
+ console.log(`✓ ${name}`);
206
+ } catch (error) {
207
+ console.error(`✗ ${name}: ${error instanceof Error ? error.message : error}`);
208
+ }
209
+ }
210
+
211
+ const client = new MCPClient();
212
+ await client.start({ command: 'node', args: ['./server.js'] });
213
+
214
+ await runTest('echo returns correct text', async () => {
215
+ const result = await client.callTool({ name: 'echo', arguments: { message: 'hello' } });
216
+ assert.toolTextEquals(result, 'Echo: hello');
217
+ assert.toolTextContains(result, 'hello');
218
+ assert.toolIsOk(result);
219
+ });
220
+
221
+ await runTest('add computes sum', async () => {
222
+ const result = await client.callTool({ name: 'add', arguments: { a: 3, b: 7 } });
223
+ assert.toolTextContains(result, '10');
224
+ });
225
+
226
+ await runTest('config is valid JSON', async () => {
227
+ const result = await client.readResource('config://settings');
228
+ assert.resourceHasContent(result);
229
+ assert.resourceTextContains(result, 'setting1');
230
+ });
231
+
232
+ await client.stop();
233
+ ```
234
+
235
+ ## Running the Examples
236
+
237
+ ```bash
238
+ # Basic functionality test
239
+ npx tsx examples/basic-test.ts
240
+
241
+ # Full capabilities test
242
+ npx tsx examples/full-test.ts
243
+
244
+ # Jest matchers example
245
+ npx tsx examples/jest-matchers-example.ts
246
+
247
+ # Assert utilities example
248
+ npx tsx examples/assert-example.ts
249
+
250
+ # Test against a real MCP server (server-everything)
251
+ npx tsx examples/everything-server-test.ts
252
+
253
+ # Test stateful server patterns
254
+ npx tsx examples/stateful-server-test.ts
255
+
256
+ # Run mock server standalone (for manual testing)
257
+ node examples/mock-server.js
258
+
259
+ # Run simple TypeScript server (for learning)
260
+ npx tsx examples/simple-server.ts
261
+
262
+ # Run stateful server (counter + todos)
263
+ npx tsx examples/stateful-server.ts
264
+ ```
265
+
266
+ ## Generating TypeScript Types
267
+
268
+ Connect to any MCP server and generate typed `.d.ts` declarations:
269
+
270
+ ```typescript
271
+ import { generateTypes } from '@slbdn/mcp-tester';
272
+ import { writeFileSync } from 'fs';
273
+
274
+ const types = await generateTypes({
275
+ command: 'node',
276
+ args: ['./my-server.js'],
277
+ });
278
+
279
+ writeFileSync('my-server-types.d.ts', types);
280
+ ```
281
+
282
+ Or use the CLI:
283
+
284
+ ```bash
285
+ npx @slbdn/mcp-tester generate-types node ./server.js -o server.d.ts
286
+ ```
287
+
288
+ Then use the generated types for type-safe tool calls:
289
+
290
+ ```typescript
291
+ import type { ToolArgsMap, ToolCall } from './server.d.ts';
292
+
293
+ // TypeScript knows the exact arguments shape
294
+ const result = await client.callTool({
295
+ name: 'add',
296
+ arguments: { a: 1, b: 2 } as ToolArgsMap['add'],
297
+ });
298
+ ```
299
+
300
+ **Supported schema features:** primitives, enums, arrays, nested objects, `oneOf`/`anyOf`/`allOf`, `$ref`, `const`, optional fields, JSDoc descriptions.
@@ -0,0 +1,81 @@
1
+ # Node.js Compatibility
2
+
3
+ ## Supported Versions
4
+
5
+ | Node.js Version | Status | Notes |
6
+ |----------------|--------|-------|
7
+ | 18.x | ⚠️ Not Supported | ESM limitations — upgrade recommended |
8
+ | 20.x (LTS) | ✅ Fully Supported | **Recommended** (minimum required version) |
9
+ | 21.x | ✅ Fully Supported | Latest stable |
10
+ | 22.x+ | ✅ Compatible | Tested, works |
11
+
12
+ ## Requirements
13
+
14
+ - **Node.js** >= 20
15
+ - **npm** >= 9
16
+ - ES2022 Modules (ESM)
17
+ - Async/await support
18
+
19
+ The `package.json` enforces the minimum version:
20
+
21
+ ```json
22
+ {
23
+ "engines": {
24
+ "node": ">=20"
25
+ }
26
+ }
27
+ ```
28
+
29
+ ## TypeScript Compatibility
30
+
31
+ Targets TypeScript 5.3+ with ES2022 output.
32
+
33
+ ## Platform Support
34
+
35
+ - ✅ macOS (Intel & Apple Silicon)
36
+ - ✅ Linux (Ubuntu, Debian, CentOS, Alpine)
37
+ - ✅ Windows 10/11 (via WSL or native Node.js)
38
+
39
+ ## CI/CD Version Specification
40
+
41
+ **GitHub Actions:**
42
+ ```yaml
43
+ - uses: actions/setup-node@v5
44
+ with:
45
+ node-version: '20'
46
+ ```
47
+
48
+ **CircleCI:**
49
+ ```yaml
50
+ docker:
51
+ - image: cimg/node:20.11.0
52
+ ```
53
+
54
+ **Jenkins:**
55
+ ```groovy
56
+ tools {
57
+ nodejs 'Node.js 20.11.0'
58
+ }
59
+ ```
60
+
61
+ ## Upgrading Node.js
62
+
63
+ **Using nvm:**
64
+ ```bash
65
+ nvm install 20
66
+ nvm use 20
67
+ nvm alias default 20
68
+ ```
69
+
70
+ **Using n:**
71
+ ```bash
72
+ n 20
73
+ ```
74
+
75
+ ## Known Issues
76
+
77
+ | Version | Issue | Workaround |
78
+ |---------|-------|------------|
79
+ | < 18 | Not supported | Upgrade to 18+ |
80
+ | 18.0–18.16 | Potential ESM issues | Use 18.17+ |
81
+ | Any | Memory limits for large ops | Increase `--max-old-space-size` |