@slbdn/mcp-tester 1.0.2 → 1.2.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 +83 -79
- package/README.md +333 -1406
- package/dist/assert.d.ts +75 -0
- package/dist/assert.d.ts.map +1 -0
- package/dist/assert.js +250 -0
- package/dist/assert.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +311 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client/MCPClient.d.ts +316 -0
- package/dist/client/MCPClient.d.ts.map +1 -1
- package/dist/client/MCPClient.js +270 -28
- package/dist/client/MCPClient.js.map +1 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -1
- package/dist/index.js.map +1 -1
- package/dist/matchers.d.ts +262 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +527 -0
- package/dist/matchers.js.map +1 -0
- package/dist/utils/errors.d.ts +80 -4
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +123 -6
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/logger.d.ts +88 -4
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +131 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/masking.d.ts +66 -0
- package/dist/utils/masking.d.ts.map +1 -0
- package/dist/utils/masking.js +171 -0
- package/dist/utils/masking.js.map +1 -0
- package/package.json +34 -5
- package/vitest.d.ts +51 -0
package/dist/matchers.js
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { AssertionError } from './assert.js';
|
|
2
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
3
|
+
function extractTextFromContent(result) {
|
|
4
|
+
const item = result.content[0];
|
|
5
|
+
return item && 'text' in item ? item.text : undefined;
|
|
6
|
+
}
|
|
7
|
+
function formatList(items) {
|
|
8
|
+
return items.length > 0 ? items.join(', ') : '(none)';
|
|
9
|
+
}
|
|
10
|
+
// ─── Collection Matchers ────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Check if a tool with the given name exists in the tools array.
|
|
13
|
+
* Works with `.not` for negation.
|
|
14
|
+
*
|
|
15
|
+
* expect(tools).toHaveTool('echo');
|
|
16
|
+
* expect(tools).not.toHaveTool('deprecated_tool');
|
|
17
|
+
*/
|
|
18
|
+
export const toHaveTool = (received, toolName) => {
|
|
19
|
+
const hasTool = received.some((tool) => tool.name === toolName);
|
|
20
|
+
return {
|
|
21
|
+
pass: hasTool,
|
|
22
|
+
message: () => hasTool
|
|
23
|
+
? `Expected tools to NOT have "${toolName}"`
|
|
24
|
+
: `Expected tools to have "${toolName}", found: ${formatList(received.map((t) => t.name))}`,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Check if a resource with the given URI exists.
|
|
29
|
+
*
|
|
30
|
+
* expect(resources).toHaveResource('config://settings');
|
|
31
|
+
*/
|
|
32
|
+
export const toHaveResource = (received, uri) => {
|
|
33
|
+
const hasResource = received.some((resource) => resource.uri === uri);
|
|
34
|
+
return {
|
|
35
|
+
pass: hasResource,
|
|
36
|
+
message: () => hasResource
|
|
37
|
+
? `Expected resources to NOT have "${uri}"`
|
|
38
|
+
: `Expected resources to have "${uri}", found: ${formatList(received.map((r) => r.uri))}`,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Check if a prompt with the given name exists.
|
|
43
|
+
*
|
|
44
|
+
* expect(prompts).toHavePrompt('greet');
|
|
45
|
+
*/
|
|
46
|
+
export const toHavePrompt = (received, promptName) => {
|
|
47
|
+
const hasPrompt = received.some((prompt) => prompt.name === promptName);
|
|
48
|
+
return {
|
|
49
|
+
pass: hasPrompt,
|
|
50
|
+
message: () => hasPrompt
|
|
51
|
+
? `Expected prompts to NOT have "${promptName}"`
|
|
52
|
+
: `Expected prompts to have "${promptName}", found: ${formatList(received.map((p) => p.name))}`,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Check if a tool exists and has an input schema.
|
|
57
|
+
*
|
|
58
|
+
* expect(tools).toHaveToolWithSchema('echo');
|
|
59
|
+
*/
|
|
60
|
+
export const toHaveToolWithSchema = (received, toolName) => {
|
|
61
|
+
const tool = received.find((t) => t.name === toolName);
|
|
62
|
+
if (!tool) {
|
|
63
|
+
return {
|
|
64
|
+
pass: false,
|
|
65
|
+
message: () => `Expected tools to have "${toolName}", found: ${formatList(received.map((t) => t.name))}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const hasSchema = !!tool.inputSchema;
|
|
69
|
+
return {
|
|
70
|
+
pass: hasSchema,
|
|
71
|
+
message: () => hasSchema
|
|
72
|
+
? `Expected tool "${toolName}" to NOT have input schema`
|
|
73
|
+
: `Expected tool "${toolName}" to have input schema`,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Check that the tools array has exactly `count` items.
|
|
78
|
+
*
|
|
79
|
+
* expect(tools).toHaveToolCount(5);
|
|
80
|
+
*/
|
|
81
|
+
export const toHaveToolCount = (received, count) => {
|
|
82
|
+
const actual = received.length;
|
|
83
|
+
return {
|
|
84
|
+
pass: actual === count,
|
|
85
|
+
message: () => actual === count
|
|
86
|
+
? `Expected tools to NOT have exactly ${count} items`
|
|
87
|
+
: `Expected tools to have ${count} items, but found ${actual}: ${formatList(received.map((t) => t.name))}`,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Check that the resources array has exactly `count` items.
|
|
92
|
+
*
|
|
93
|
+
* expect(resources).toHaveResourceCount(3);
|
|
94
|
+
*/
|
|
95
|
+
export const toHaveResourceCount = (received, count) => {
|
|
96
|
+
const actual = received.length;
|
|
97
|
+
return {
|
|
98
|
+
pass: actual === count,
|
|
99
|
+
message: () => actual === count
|
|
100
|
+
? `Expected resources to NOT have exactly ${count} items`
|
|
101
|
+
: `Expected resources to have ${count} items, but found ${actual}: ${formatList(received.map((r) => r.uri))}`,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Check that the prompts array has exactly `count` items.
|
|
106
|
+
*
|
|
107
|
+
* expect(prompts).toHavePromptCount(2);
|
|
108
|
+
*/
|
|
109
|
+
export const toHavePromptCount = (received, count) => {
|
|
110
|
+
const actual = received.length;
|
|
111
|
+
return {
|
|
112
|
+
pass: actual === count,
|
|
113
|
+
message: () => actual === count
|
|
114
|
+
? `Expected prompts to NOT have exactly ${count} items`
|
|
115
|
+
: `Expected prompts to have ${count} items, but found ${actual}: ${formatList(received.map((p) => p.name))}`,
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Check if a resource with the given display name exists.
|
|
120
|
+
*
|
|
121
|
+
* expect(resources).toHaveResourceByName('Settings');
|
|
122
|
+
*/
|
|
123
|
+
export const toHaveResourceByName = (received, name) => {
|
|
124
|
+
const hasResource = received.some((resource) => resource.name === name);
|
|
125
|
+
return {
|
|
126
|
+
pass: hasResource,
|
|
127
|
+
message: () => hasResource
|
|
128
|
+
? `Expected resources to NOT have "${name}"`
|
|
129
|
+
: `Expected resources to have "${name}", found: ${formatList(received.map((r) => r.name))}`,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Check if a prompt exists and has defined arguments (is parameterized).
|
|
134
|
+
*
|
|
135
|
+
* expect(prompts).toHavePromptWithArgs('greet');
|
|
136
|
+
*/
|
|
137
|
+
export const toHavePromptWithArgs = (received, promptName) => {
|
|
138
|
+
const prompt = received.find((p) => p.name === promptName);
|
|
139
|
+
if (!prompt) {
|
|
140
|
+
return {
|
|
141
|
+
pass: false,
|
|
142
|
+
message: () => `Expected prompts to have "${promptName}", found: ${formatList(received.map((p) => p.name))}`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const hasArgs = !!(prompt.arguments && prompt.arguments.length > 0);
|
|
146
|
+
return {
|
|
147
|
+
pass: hasArgs,
|
|
148
|
+
message: () => hasArgs
|
|
149
|
+
? `Expected prompt "${promptName}" to NOT have arguments`
|
|
150
|
+
: `Expected prompt "${promptName}" to have arguments, but it has none`,
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
// ─── Tool Result Matchers ───────────────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Check that a tool result has text content.
|
|
156
|
+
* Optionally check that the text equals an exact string.
|
|
157
|
+
*
|
|
158
|
+
* expect(result).toReturnText(); // has any text
|
|
159
|
+
* expect(result).toReturnText('Hello World'); // text equals exactly
|
|
160
|
+
*/
|
|
161
|
+
export const toReturnText = (received, expected) => {
|
|
162
|
+
const text = extractTextFromContent(received);
|
|
163
|
+
if (text === undefined) {
|
|
164
|
+
return {
|
|
165
|
+
pass: false,
|
|
166
|
+
message: () => `Expected tool result to have text content, but got: ${JSON.stringify(received.content[0]?.type ?? 'empty')}`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (expected === undefined) {
|
|
170
|
+
return {
|
|
171
|
+
pass: true,
|
|
172
|
+
message: () => `Expected tool result to NOT have text content, but got: "${text}"`,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const matches = text === expected;
|
|
176
|
+
return {
|
|
177
|
+
pass: matches,
|
|
178
|
+
message: () => matches
|
|
179
|
+
? `Expected tool text to NOT equal "${expected}"`
|
|
180
|
+
: `Expected tool text to equal "${expected}", but got: "${text}"`,
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Check that a tool result's text contains a substring.
|
|
185
|
+
*
|
|
186
|
+
* expect(result).toReturnTextContaining('hello');
|
|
187
|
+
*/
|
|
188
|
+
export const toReturnTextContaining = (received, substring) => {
|
|
189
|
+
const text = extractTextFromContent(received);
|
|
190
|
+
if (text === undefined) {
|
|
191
|
+
return {
|
|
192
|
+
pass: false,
|
|
193
|
+
message: () => `Expected tool result to contain "${substring}", but result has no text content`,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const contains = text.includes(substring);
|
|
197
|
+
return {
|
|
198
|
+
pass: contains,
|
|
199
|
+
message: () => contains
|
|
200
|
+
? `Expected tool text to NOT contain "${substring}"`
|
|
201
|
+
: `Expected tool text to contain "${substring}", but got: "${text}"`,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Check that a tool result indicates an error (isError flag or "error" in text).
|
|
206
|
+
*
|
|
207
|
+
* expect(result).toReturnError();
|
|
208
|
+
*/
|
|
209
|
+
export const toReturnError = (received) => {
|
|
210
|
+
const isError = received.isError ||
|
|
211
|
+
(extractTextFromContent(received)?.toLowerCase().includes('error') ?? false);
|
|
212
|
+
return {
|
|
213
|
+
pass: isError,
|
|
214
|
+
message: () => isError
|
|
215
|
+
? `Expected tool result to NOT be an error`
|
|
216
|
+
: `Expected tool result to be an error, but it succeeded`,
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Check that a tool result indicates success (no error).
|
|
221
|
+
*
|
|
222
|
+
* expect(result).toReturnOk();
|
|
223
|
+
*/
|
|
224
|
+
export const toReturnOk = (received) => {
|
|
225
|
+
const isError = received.isError ||
|
|
226
|
+
(extractTextFromContent(received)?.toLowerCase().includes('error') ?? false);
|
|
227
|
+
return {
|
|
228
|
+
pass: !isError,
|
|
229
|
+
message: () => !isError
|
|
230
|
+
? `Expected tool result to be an error, but it succeeded`
|
|
231
|
+
: `Expected tool result to be successful, but got error: ${extractTextFromContent(received) ?? '(no text)'}`,
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Parse tool result text as JSON and deep-compare to expected object.
|
|
236
|
+
*
|
|
237
|
+
* expect(result).toReturnJson({ status: 'ok', count: 5 });
|
|
238
|
+
*/
|
|
239
|
+
export const toReturnJson = (received, expected) => {
|
|
240
|
+
const text = extractTextFromContent(received);
|
|
241
|
+
if (text === undefined) {
|
|
242
|
+
return {
|
|
243
|
+
pass: false,
|
|
244
|
+
message: () => `Expected tool result to contain JSON, but result has no text content`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
let parsed;
|
|
248
|
+
try {
|
|
249
|
+
parsed = JSON.parse(text);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return {
|
|
253
|
+
pass: false,
|
|
254
|
+
message: () => `Expected tool result to be valid JSON, but got: "${text.substring(0, 100)}${text.length > 100 ? '...' : ''}"`,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const matches = JSON.stringify(parsed) === JSON.stringify(expected);
|
|
258
|
+
return {
|
|
259
|
+
pass: matches,
|
|
260
|
+
message: () => matches
|
|
261
|
+
? `Expected tool JSON to NOT equal ${JSON.stringify(expected)}`
|
|
262
|
+
: `Expected tool JSON to equal:\n ${JSON.stringify(expected)}\n\nReceived:\n ${JSON.stringify(parsed)}`,
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Check that a tool result has exactly `count` content items.
|
|
267
|
+
*
|
|
268
|
+
* expect(result).toReturnContentCount(2); // e.g. text + image
|
|
269
|
+
*/
|
|
270
|
+
export const toReturnContentCount = (received, count) => {
|
|
271
|
+
const actual = received.content.length;
|
|
272
|
+
return {
|
|
273
|
+
pass: actual === count,
|
|
274
|
+
message: () => actual === count
|
|
275
|
+
? `Expected tool result to NOT have ${count} content items`
|
|
276
|
+
: `Expected tool result to have ${count} content items, but found ${actual}`,
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Check that a tool result contains at least one image content item.
|
|
281
|
+
*
|
|
282
|
+
* expect(result).toReturnImage();
|
|
283
|
+
*/
|
|
284
|
+
export const toReturnImage = (received) => {
|
|
285
|
+
const hasImage = received.content.some((item) => 'type' in item && item.type === 'image');
|
|
286
|
+
const types = received.content.map((c) => ('type' in c ? c.type : 'embedded')).join(', ');
|
|
287
|
+
return {
|
|
288
|
+
pass: hasImage,
|
|
289
|
+
message: () => hasImage
|
|
290
|
+
? `Expected tool result to NOT contain an image`
|
|
291
|
+
: `Expected tool result to contain an image, but found types: ${types}`,
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
// ─── Resource Result Matchers ────────────────────────────────────────────────
|
|
295
|
+
/**
|
|
296
|
+
* Check that a resource result has text content.
|
|
297
|
+
* Optionally check that the text equals an exact string.
|
|
298
|
+
*
|
|
299
|
+
* expect(result).toReturnResourceText(); // has any text
|
|
300
|
+
* expect(result).toReturnResourceText('expected'); // text equals exactly
|
|
301
|
+
*/
|
|
302
|
+
export const toReturnResourceText = (received, expected) => {
|
|
303
|
+
const item = received.contents[0];
|
|
304
|
+
if (!item || !('text' in item)) {
|
|
305
|
+
return {
|
|
306
|
+
pass: false,
|
|
307
|
+
message: () => 'Expected resource result to have text content',
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
const text = item.text;
|
|
311
|
+
if (expected === undefined) {
|
|
312
|
+
return {
|
|
313
|
+
pass: true,
|
|
314
|
+
message: () => `Expected resource result to NOT have text content, but got: "${text.substring(0, 50)}"`,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const matches = text === expected;
|
|
318
|
+
return {
|
|
319
|
+
pass: matches,
|
|
320
|
+
message: () => matches
|
|
321
|
+
? `Expected resource text to NOT equal "${expected}"`
|
|
322
|
+
: `Expected resource text to equal "${expected}", but got: "${text}"`,
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Check that a resource result's text contains a substring.
|
|
327
|
+
*
|
|
328
|
+
* expect(result).toReturnResourceTextContaining('connection');
|
|
329
|
+
*/
|
|
330
|
+
export const toReturnResourceTextContaining = (received, substring) => {
|
|
331
|
+
const item = received.contents[0];
|
|
332
|
+
if (!item || !('text' in item)) {
|
|
333
|
+
return {
|
|
334
|
+
pass: false,
|
|
335
|
+
message: () => `Expected resource text to contain "${substring}", but result has no text content`,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const text = item.text;
|
|
339
|
+
const contains = text.includes(substring);
|
|
340
|
+
return {
|
|
341
|
+
pass: contains,
|
|
342
|
+
message: () => contains
|
|
343
|
+
? `Expected resource text to NOT contain "${substring}"`
|
|
344
|
+
: `Expected resource text to contain "${substring}", but got: "${text.substring(0, 100)}${text.length > 100 ? '...' : ''}"`,
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
// ─── Prompt Result Matchers ─────────────────────────────────────────────────
|
|
348
|
+
/**
|
|
349
|
+
* Check that a prompt result's first message text contains a substring.
|
|
350
|
+
*
|
|
351
|
+
* expect(result).toReturnPromptTextContaining('Alice');
|
|
352
|
+
*/
|
|
353
|
+
export const toReturnPromptTextContaining = (received, substring) => {
|
|
354
|
+
const item = received.messages[0]?.content;
|
|
355
|
+
if (!item || !('text' in item)) {
|
|
356
|
+
return {
|
|
357
|
+
pass: false,
|
|
358
|
+
message: () => `Expected prompt message to contain "${substring}", but result has no text content`,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
const text = item.text;
|
|
362
|
+
const contains = text.includes(substring);
|
|
363
|
+
return {
|
|
364
|
+
pass: contains,
|
|
365
|
+
message: () => contains
|
|
366
|
+
? `Expected prompt text to NOT contain "${substring}"`
|
|
367
|
+
: `Expected prompt text to contain "${substring}", but got: "${text}"`,
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Check that a prompt result has exactly `count` messages.
|
|
372
|
+
*
|
|
373
|
+
* expect(result).toReturnPromptMessageCount(2);
|
|
374
|
+
*/
|
|
375
|
+
export const toReturnPromptMessageCount = (received, count) => {
|
|
376
|
+
const actual = received.messages.length;
|
|
377
|
+
return {
|
|
378
|
+
pass: actual === count,
|
|
379
|
+
message: () => actual === count
|
|
380
|
+
? `Expected prompt to NOT have ${count} messages`
|
|
381
|
+
: `Expected prompt to have ${count} messages, but found ${actual}`,
|
|
382
|
+
};
|
|
383
|
+
};
|
|
384
|
+
// ─── Setup ──────────────────────────────────────────────────────────────────
|
|
385
|
+
/**
|
|
386
|
+
* Register all custom matchers with Jest.
|
|
387
|
+
* Call once in test setup:
|
|
388
|
+
*
|
|
389
|
+
* import { setupJestMatchers } from '@slbdn/mcp-tester';
|
|
390
|
+
* beforeAll(() => setupJestMatchers());
|
|
391
|
+
*
|
|
392
|
+
* Or add to jest.setup.js for global availability.
|
|
393
|
+
*
|
|
394
|
+
* Also works as `setupCustomMatchers()` (alias kept for backward compat).
|
|
395
|
+
*/
|
|
396
|
+
export const setupJestMatchers = () => {
|
|
397
|
+
expect.extend({
|
|
398
|
+
// Collection
|
|
399
|
+
toHaveTool,
|
|
400
|
+
toHaveResource,
|
|
401
|
+
toHavePrompt,
|
|
402
|
+
toHaveToolWithSchema,
|
|
403
|
+
toHaveToolCount,
|
|
404
|
+
toHaveResourceCount,
|
|
405
|
+
toHavePromptCount,
|
|
406
|
+
toHaveResourceByName,
|
|
407
|
+
toHavePromptWithArgs,
|
|
408
|
+
// Tool results
|
|
409
|
+
toReturnText,
|
|
410
|
+
toReturnTextContaining,
|
|
411
|
+
toReturnError,
|
|
412
|
+
toReturnOk,
|
|
413
|
+
toReturnJson,
|
|
414
|
+
toReturnContentCount,
|
|
415
|
+
toReturnImage,
|
|
416
|
+
// Resource results
|
|
417
|
+
toReturnResourceText,
|
|
418
|
+
toReturnResourceTextContaining,
|
|
419
|
+
// Prompt results
|
|
420
|
+
toReturnPromptTextContaining,
|
|
421
|
+
toReturnPromptMessageCount,
|
|
422
|
+
});
|
|
423
|
+
};
|
|
424
|
+
/** @deprecated Use setupJestMatchers() instead */
|
|
425
|
+
export const setupCustomMatchers = setupJestMatchers;
|
|
426
|
+
/**
|
|
427
|
+
* Register all custom matchers with Vitest.
|
|
428
|
+
* Call once in test setup:
|
|
429
|
+
*
|
|
430
|
+
* import { setupVitestMatchers } from '@slbdn/mcp-tester';
|
|
431
|
+
* import { beforeAll } from 'vitest';
|
|
432
|
+
* beforeAll(() => setupVitestMatchers());
|
|
433
|
+
*/
|
|
434
|
+
export const setupVitestMatchers = () => {
|
|
435
|
+
// Vitest's expect.extend is compatible with Jest's format
|
|
436
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
437
|
+
const vitestExpect = globalThis.expect;
|
|
438
|
+
if (!vitestExpect || typeof vitestExpect.extend !== 'function') {
|
|
439
|
+
throw new Error('setupVitestMatchers() must be called in a Vitest environment. ' +
|
|
440
|
+
'Make sure vitest is imported before calling this.');
|
|
441
|
+
}
|
|
442
|
+
vitestExpect.extend({
|
|
443
|
+
// Collection
|
|
444
|
+
toHaveTool,
|
|
445
|
+
toHaveResource,
|
|
446
|
+
toHavePrompt,
|
|
447
|
+
toHaveToolWithSchema,
|
|
448
|
+
toHaveToolCount,
|
|
449
|
+
toHaveResourceCount,
|
|
450
|
+
toHavePromptCount,
|
|
451
|
+
toHaveResourceByName,
|
|
452
|
+
toHavePromptWithArgs,
|
|
453
|
+
// Tool results
|
|
454
|
+
toReturnText,
|
|
455
|
+
toReturnTextContaining,
|
|
456
|
+
toReturnError,
|
|
457
|
+
toReturnOk,
|
|
458
|
+
toReturnJson,
|
|
459
|
+
toReturnContentCount,
|
|
460
|
+
toReturnImage,
|
|
461
|
+
// Resource results
|
|
462
|
+
toReturnResourceText,
|
|
463
|
+
toReturnResourceTextContaining,
|
|
464
|
+
// Prompt results
|
|
465
|
+
toReturnPromptTextContaining,
|
|
466
|
+
toReturnPromptMessageCount,
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
// Auto-setup for Jest environments (no-op outside Jest)
|
|
470
|
+
if (typeof expect !== 'undefined' && typeof expect.extend === 'function') {
|
|
471
|
+
setupJestMatchers();
|
|
472
|
+
}
|
|
473
|
+
// ─── Standalone Assertion Wrappers ──────────────────────────────────────────
|
|
474
|
+
// Thin wrappers that throw AssertionError — usable outside Jest with any test runner.
|
|
475
|
+
/**
|
|
476
|
+
* Assert that a tool result has text content (optionally matching exactly).
|
|
477
|
+
* Works with any test runner — throws AssertionError on failure.
|
|
478
|
+
*/
|
|
479
|
+
export function assertToolText(result, expected, msg) {
|
|
480
|
+
const text = extractTextFromContent(result);
|
|
481
|
+
if (text === undefined)
|
|
482
|
+
throw new AssertionError(msg ?? 'Expected tool result to have text content');
|
|
483
|
+
if (expected !== undefined && text !== expected) {
|
|
484
|
+
throw new AssertionError(msg ?? `Expected tool text "${expected}", got "${text}"`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Assert that a tool result text contains a substring.
|
|
489
|
+
* Works with any test runner — throws AssertionError on failure.
|
|
490
|
+
*/
|
|
491
|
+
export function assertToolTextContains(result, substring, msg) {
|
|
492
|
+
const text = extractTextFromContent(result);
|
|
493
|
+
if (text === undefined)
|
|
494
|
+
throw new AssertionError(msg ?? 'Expected tool result to have text content');
|
|
495
|
+
if (!text.includes(substring)) {
|
|
496
|
+
throw new AssertionError(msg ?? `Expected tool text to contain "${substring}", got: "${text}"`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Assert that tools list contains a tool with the given name.
|
|
501
|
+
* Works with any test runner — throws AssertionError on failure.
|
|
502
|
+
*/
|
|
503
|
+
export function assertHasTool(tools, name, msg) {
|
|
504
|
+
if (!tools.some((t) => t.name === name)) {
|
|
505
|
+
throw new AssertionError(msg ?? `Expected tools to have "${name}", found: ${formatList(tools.map((t) => t.name))}`);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Assert that resources list contains a resource with the given URI.
|
|
510
|
+
* Works with any test runner — throws AssertionError on failure.
|
|
511
|
+
*/
|
|
512
|
+
export function assertHasResource(resources, uri, msg) {
|
|
513
|
+
if (!resources.some((r) => r.uri === uri)) {
|
|
514
|
+
throw new AssertionError(msg ??
|
|
515
|
+
`Expected resources to have "${uri}", found: ${formatList(resources.map((r) => r.uri))}`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Assert that prompts list contains a prompt with the given name.
|
|
520
|
+
* Works with any test runner — throws AssertionError on failure.
|
|
521
|
+
*/
|
|
522
|
+
export function assertHasPrompt(prompts, name, msg) {
|
|
523
|
+
if (!prompts.some((p) => p.name === name)) {
|
|
524
|
+
throw new AssertionError(msg ?? `Expected prompts to have "${name}", found: ${formatList(prompts.map((p) => p.name))}`);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=matchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchers.js","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -1,21 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for MCPClient operations.
|
|
3
|
+
*
|
|
4
|
+
* All errors include a descriptive message, error code, and proper stack trace.
|
|
5
|
+
* Timeout and connection errors include actionable suggestions for debugging.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* try {
|
|
10
|
+
* await client.callTool({ name: 'invalid-tool', arguments: {} });
|
|
11
|
+
* } catch (error) {
|
|
12
|
+
* if (error instanceof MCPServerError) {
|
|
13
|
+
* console.error(`Server error: ${error.message}`);
|
|
14
|
+
* console.error(`Operation: ${error.operation}`);
|
|
15
|
+
* } else if (error instanceof MCPTimeoutError) {
|
|
16
|
+
* console.error(`Timeout after ${error.timeout}ms on ${error.operation}`);
|
|
17
|
+
* console.error(`Suggestions: ${error.suggestions.join(', ')}`);
|
|
18
|
+
* } else if (error instanceof MCPConnectionError) {
|
|
19
|
+
* console.error(`Connection failed: ${error.message}`);
|
|
20
|
+
* console.error(`Command: ${error.command}`);
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Base error class for all MCP client errors.
|
|
27
|
+
*/
|
|
1
28
|
export declare class MCPClientError extends Error {
|
|
29
|
+
/** Error code for programmatic error handling. */
|
|
2
30
|
readonly code: string;
|
|
3
31
|
constructor(message: string, code?: string);
|
|
4
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Error thrown when a request times out.
|
|
35
|
+
*
|
|
36
|
+
* Includes the operation that timed out, the timeout value, and
|
|
37
|
+
* actionable suggestions for resolving the timeout.
|
|
38
|
+
*/
|
|
5
39
|
export declare class MCPTimeoutError extends MCPClientError {
|
|
40
|
+
/** The timeout value in milliseconds. */
|
|
6
41
|
readonly timeout: number;
|
|
7
|
-
|
|
42
|
+
/** The operation that timed out (e.g., "Call tool echo", "List tools"). */
|
|
43
|
+
readonly operation: string;
|
|
44
|
+
/** Actionable suggestions for resolving the timeout. */
|
|
45
|
+
readonly suggestions: string[];
|
|
46
|
+
constructor(message: string, timeout: number, operation?: string, suggestions?: string[]);
|
|
47
|
+
/**
|
|
48
|
+
* Generate default suggestions based on timeout value.
|
|
49
|
+
*/
|
|
50
|
+
private static defaultSuggestions;
|
|
8
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when the client fails to connect to the MCP server.
|
|
54
|
+
*
|
|
55
|
+
* Includes the server command and actionable suggestions for resolving
|
|
56
|
+
* connection failures.
|
|
57
|
+
*/
|
|
9
58
|
export declare class MCPConnectionError extends MCPClientError {
|
|
10
|
-
|
|
59
|
+
/** The command that was used to start the server. */
|
|
60
|
+
readonly command: string;
|
|
61
|
+
/** Actionable suggestions for resolving the connection failure. */
|
|
62
|
+
readonly suggestions: string[];
|
|
63
|
+
constructor(message: string, command?: string, suggestions?: string[]);
|
|
64
|
+
/**
|
|
65
|
+
* Generate default suggestions based on the server command.
|
|
66
|
+
*/
|
|
67
|
+
private static defaultSuggestions;
|
|
11
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Error thrown when a client method is called before start().
|
|
71
|
+
*
|
|
72
|
+
* Includes which method was called to help identify the issue.
|
|
73
|
+
*/
|
|
12
74
|
export declare class MCPNotStartedError extends MCPClientError {
|
|
13
|
-
|
|
75
|
+
/** The method that was called on the unstarted client. */
|
|
76
|
+
readonly method: string;
|
|
77
|
+
constructor(method?: string);
|
|
14
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Error thrown when start() is called on an already-started client.
|
|
81
|
+
*/
|
|
15
82
|
export declare class MCPAlreadyStartedError extends MCPClientError {
|
|
16
83
|
constructor();
|
|
17
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Error thrown when the MCP server returns an error response.
|
|
87
|
+
*
|
|
88
|
+
* Includes the operation that failed and the server error code if available.
|
|
89
|
+
*/
|
|
18
90
|
export declare class MCPServerError extends MCPClientError {
|
|
19
|
-
|
|
91
|
+
/** The operation that failed (e.g., "Call tool echo", "Read resource config://settings"). */
|
|
92
|
+
readonly operation: string;
|
|
93
|
+
/** The MCP error code from the server response, if available. */
|
|
94
|
+
readonly serverCode?: number | string;
|
|
95
|
+
constructor(message: string, operation?: string, serverCode?: number | string);
|
|
20
96
|
}
|
|
21
97
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAA2B;CAM/D;AAED,qBAAa,eAAgB,SAAQ,cAAc;IACjD,SAAgB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,kDAAkD;IAClD,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAA2B;CAM/D;AAED;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,cAAc;IACjD,yCAAyC;IACzC,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC,2EAA2E;IAC3E,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC,wDAAwD;IACxD,SAAgB,WAAW,EAAE,MAAM,EAAE,CAAC;gBAE1B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE;IASxF;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAoBlC;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,qDAAqD;IACrD,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC,mEAAmE;IACnE,SAAgB,WAAW,EAAE,MAAM,EAAE,CAAC;gBAE1B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE;IAQrE;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;CA0BlC;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,0DAA0D;IAC1D,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEnB,MAAM,CAAC,EAAE,MAAM;CAU5B;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,cAAc;;CASzD;AAED;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,cAAc;IAChD,6FAA6F;IAC7F,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC,iEAAiE;IACjE,SAAgB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;gBAEjC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;CAO9E"}
|