@slbdn/mcp-tester 1.4.3 → 1.5.4
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 +59 -0
- package/README.md +78 -26
- package/dist/ai/provider.d.ts +145 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +428 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/cli/index.js +214 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/generate-cases.d.ts +113 -0
- package/dist/generate-cases.d.ts.map +1 -0
- package/dist/generate-cases.js +565 -0
- package/dist/generate-cases.js.map +1 -0
- package/dist/generate-tests.d.ts +52 -1
- package/dist/generate-tests.d.ts.map +1 -1
- package/dist/generate-tests.js +208 -81
- package/dist/generate-tests.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/matchers.d.ts +31 -21
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js.map +1 -1
- package/dist/templates/full-stack/.github/workflows/test.yml +34 -0
- package/dist/templates/full-stack/README.md +73 -0
- package/dist/templates/full-stack/examples/mock-server.js +115 -0
- package/dist/templates/full-stack/jest.config.js +39 -0
- package/dist/templates/full-stack/package.json +31 -0
- package/dist/templates/full-stack/scripts/generate-tests.ts +32 -0
- package/dist/templates/full-stack/scripts/generate-types.ts +28 -0
- package/dist/templates/full-stack/src/server.ts +78 -0
- package/dist/templates/full-stack/tests/helpers.ts +29 -0
- package/dist/templates/full-stack/tests/parallel.test.ts +44 -0
- package/dist/templates/full-stack/tests/server.test.ts +36 -0
- package/dist/templates/full-stack/tests/tools.test.ts +61 -0
- package/dist/templates/full-stack/tsconfig.json +19 -0
- package/dist/templates/minimal-jest/README.md +42 -0
- package/dist/templates/minimal-jest/examples/mock-server.js +62 -0
- package/dist/templates/minimal-jest/jest.config.js +24 -0
- package/dist/templates/minimal-jest/package.json +24 -0
- package/dist/templates/minimal-jest/tests/server.test.ts +64 -0
- package/dist/templates/minimal-jest/tsconfig.json +19 -0
- package/dist/templates/standard-jest/.github/workflows/test.yml +32 -0
- package/dist/templates/standard-jest/README.md +44 -0
- package/dist/templates/standard-jest/examples/mock-server.js +122 -0
- package/dist/templates/standard-jest/jest.config.js +39 -0
- package/dist/templates/standard-jest/package.json +27 -0
- package/dist/templates/standard-jest/tests/helpers.ts +43 -0
- package/dist/templates/standard-jest/tests/prompts.test.ts +37 -0
- package/dist/templates/standard-jest/tests/resources.test.ts +37 -0
- package/dist/templates/standard-jest/tests/server.test.ts +30 -0
- package/dist/templates/standard-jest/tests/tools.test.ts +87 -0
- package/dist/templates/standard-jest/tsconfig.json +19 -0
- package/docs/advanced.md +424 -0
- package/docs/ai-generation.md +211 -0
- package/docs/api-reference.md +819 -0
- package/docs/cicd.md +289 -0
- package/docs/cli.md +225 -0
- package/docs/examples.md +300 -0
- package/docs/nodejs-compatibility.md +81 -0
- package/docs/releases.md +413 -0
- package/docs/starter-templates.md +110 -0
- package/docs/testing.md +443 -0
- package/docs/troubleshooting.md +139 -0
- package/jest.d.ts +43 -0
- package/package.json +5 -2
package/docs/examples.md
ADDED
|
@@ -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` |
|