@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,565 @@
1
+ /**
2
+ * Edge-case engine — derives intelligent test cases from tool JSON Schemas.
3
+ *
4
+ * Two sources of cases:
5
+ * 1. Deterministic rules over `inputSchema` ({@link suggestEdgeCases}) — always
6
+ * available, no network, no API key.
7
+ * 2. AI-suggested cases (see `src/ai/provider.ts`) — validated against the
8
+ * same schemas before use.
9
+ *
10
+ * Both produce {@link GeneratedCase} records: plain data, never code. The
11
+ * emitter in `generate-tests.ts` renders them, so LLM output can never become
12
+ * arbitrary code in a generated test file.
13
+ *
14
+ * @module generate-cases
15
+ */
16
+ /**
17
+ * Generate sample arguments from a JSON Schema property.
18
+ */
19
+ export function generateSampleValue(schema) {
20
+ const type = schema.type;
21
+ const examples = schema.examples;
22
+ const enumValues = schema['enum'];
23
+ if (enumValues && enumValues.length > 0)
24
+ return enumValues[0];
25
+ if (examples && examples.length > 0)
26
+ return examples[0];
27
+ if (schema.default !== undefined)
28
+ return schema.default;
29
+ switch (type) {
30
+ case 'string':
31
+ return schema.description
32
+ ? `example-${String(schema.description).toLowerCase().replace(/\s+/g, '-')}`
33
+ : 'example';
34
+ case 'number':
35
+ case 'integer': {
36
+ // Keep the sample inside [minimum, maximum] so base arguments remain
37
+ // valid for bounded schemas (42 would break every derived case).
38
+ let value = 42;
39
+ const min = schema.minimum;
40
+ const max = schema.maximum;
41
+ if (typeof max === 'number' && value > max)
42
+ value = max;
43
+ if (typeof min === 'number' && value < min)
44
+ value = min;
45
+ return value;
46
+ }
47
+ case 'boolean':
48
+ return true;
49
+ case 'array': {
50
+ // Honor minItems so base arguments satisfy the schema.
51
+ const minItems = typeof schema.minItems === 'number' ? Math.max(schema.minItems, 1) : 1;
52
+ const itemSchema = schema.items;
53
+ return Array.from({ length: minItems }, () => itemSchema ? generateSampleValue(itemSchema) : 'example');
54
+ }
55
+ case 'object':
56
+ return {};
57
+ default:
58
+ return 'example';
59
+ }
60
+ }
61
+ /**
62
+ * Generate valid sample arguments from a tool's input schema.
63
+ */
64
+ export function generateToolArgs(tool) {
65
+ const schema = tool.inputSchema;
66
+ if (!schema || !schema.properties)
67
+ return {};
68
+ const args = {};
69
+ const props = schema.properties;
70
+ const required = new Set(schema.required || []);
71
+ // Generate values for all required fields, and optional ones with defaults
72
+ for (const [key, propSchema] of Object.entries(props)) {
73
+ if (required.has(key) || propSchema.default !== undefined) {
74
+ args[key] = generateSampleValue(propSchema);
75
+ }
76
+ }
77
+ // If no required fields, generate at least one so the test is useful
78
+ if (Object.keys(args).length === 0 && Object.keys(props).length > 0) {
79
+ const firstKey = Object.keys(props)[0];
80
+ args[firstKey] = generateSampleValue(props[firstKey]);
81
+ }
82
+ return args;
83
+ }
84
+ /** JSON type name for a JS value, aligned with JSON Schema type keywords. */
85
+ function jsonTypeOf(value) {
86
+ if (value === null)
87
+ return 'null';
88
+ if (Array.isArray(value))
89
+ return 'array';
90
+ if (Number.isInteger(value))
91
+ return 'integer';
92
+ if (typeof value === 'number')
93
+ return 'number';
94
+ return typeof value; // 'string' | 'boolean' | 'object'
95
+ }
96
+ /** Does `value` satisfy the schema's `type` keyword (integer ⊂ number)? */
97
+ function typeMatches(value, expected) {
98
+ if (expected === undefined)
99
+ return true;
100
+ const actual = jsonTypeOf(value);
101
+ const types = Array.isArray(expected) ? expected : [expected];
102
+ return types.some((t) => t === actual || (t === 'number' && actual === 'integer'));
103
+ }
104
+ /**
105
+ * Lightweight validation of `args` against a tool's `inputSchema`.
106
+ *
107
+ * Checks top-level properties only (required, type, enum, min/maxLength,
108
+ * minimum/maximum, minItems, maxItems, uniqueItems, pattern, additionalProperties).
109
+ * Nested schemas are not traversed — the AI layer uses this as a sanity
110
+ * gate, not a full validator.
111
+ *
112
+ * @returns `null` when the args are acceptable, otherwise a human-readable
113
+ * reason why they are not.
114
+ */
115
+ export function validateArgsAgainstSchema(args, schema) {
116
+ if (!schema || typeof schema !== 'object')
117
+ return null;
118
+ const props = schema.properties ?? {};
119
+ const required = schema.required ?? [];
120
+ const additional = schema.additionalProperties;
121
+ for (const key of required) {
122
+ if (!(key in args))
123
+ return `missing required property "${key}"`;
124
+ }
125
+ for (const [key, value] of Object.entries(args)) {
126
+ const prop = props[key];
127
+ if (!prop) {
128
+ if (additional === false) {
129
+ return `unknown property "${key}" (additionalProperties is false)`;
130
+ }
131
+ if (additional && typeof additional === 'object') {
132
+ // additionalProperties as a schema: extra values must satisfy it.
133
+ const reason = validateValueAgainstSchema(value, additional);
134
+ if (reason)
135
+ return `unknown property "${key}" violates additionalProperties: ${reason}`;
136
+ }
137
+ continue;
138
+ }
139
+ if (!typeMatches(value, prop.type)) {
140
+ return `property "${key}" should be ${String(prop.type)}, got ${jsonTypeOf(value)}`;
141
+ }
142
+ const enumValues = prop['enum'];
143
+ if (enumValues && !enumValues.includes(value)) {
144
+ return `property "${key}" must be one of ${JSON.stringify(enumValues)}`;
145
+ }
146
+ if (typeof value === 'string') {
147
+ if (typeof prop.minLength === 'number' && value.length < prop.minLength) {
148
+ return `property "${key}" is shorter than minLength ${prop.minLength}`;
149
+ }
150
+ if (typeof prop.maxLength === 'number' && value.length > prop.maxLength) {
151
+ return `property "${key}" is longer than maxLength ${prop.maxLength}`;
152
+ }
153
+ if (typeof prop.pattern === 'string') {
154
+ try {
155
+ if (!new RegExp(prop.pattern).test(value)) {
156
+ return `property "${key}" does not match pattern /${prop.pattern}/`;
157
+ }
158
+ }
159
+ catch {
160
+ // Invalid regex in schema — ignore rather than rejecting every case.
161
+ }
162
+ }
163
+ }
164
+ if (typeof value === 'number') {
165
+ if (typeof prop.minimum === 'number' && value < prop.minimum) {
166
+ return `property "${key}" is below minimum ${prop.minimum}`;
167
+ }
168
+ if (typeof prop.maximum === 'number' && value > prop.maximum) {
169
+ return `property "${key}" is above maximum ${prop.maximum}`;
170
+ }
171
+ if (typeof prop.exclusiveMinimum === 'number' && value <= prop.exclusiveMinimum) {
172
+ return `property "${key}" must be > ${prop.exclusiveMinimum} (exclusive)`;
173
+ }
174
+ if (typeof prop.exclusiveMaximum === 'number' && value >= prop.exclusiveMaximum) {
175
+ return `property "${key}" must be < ${prop.exclusiveMaximum} (exclusive)`;
176
+ }
177
+ }
178
+ if (Array.isArray(value)) {
179
+ if (typeof prop.minItems === 'number' && value.length < prop.minItems) {
180
+ return `property "${key}" has fewer than minItems ${prop.minItems}`;
181
+ }
182
+ if (typeof prop.maxItems === 'number' && value.length > prop.maxItems) {
183
+ return `property "${key}" has more than maxItems ${prop.maxItems}`;
184
+ }
185
+ if (prop.uniqueItems === true && hasDuplicates(value)) {
186
+ return `property "${key}" has duplicate items (uniqueItems is true)`;
187
+ }
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+ /** Does `arr` contain any value that appears more than once? */
193
+ function hasDuplicates(arr) {
194
+ const seen = new Set();
195
+ for (const v of arr) {
196
+ // JSON-key the value so objects compare structurally.
197
+ const k = JSON.stringify(v);
198
+ if (seen.has(k))
199
+ return true;
200
+ seen.add(k);
201
+ }
202
+ return false;
203
+ }
204
+ /**
205
+ * Validate a single value against a JSON Schema fragment (no `required` /
206
+ * `properties` — just the constraint keywords applicable to one value).
207
+ * Returns `null` when the value is acceptable.
208
+ */
209
+ function validateValueAgainstSchema(value, schema) {
210
+ if (schema.type && !typeMatches(value, schema.type)) {
211
+ return `type ${String(schema.type)} expected, got ${jsonTypeOf(value)}`;
212
+ }
213
+ const enumValues = schema['enum'];
214
+ if (enumValues && !enumValues.includes(value)) {
215
+ return `must be one of ${JSON.stringify(enumValues)}`;
216
+ }
217
+ if (typeof value === 'string') {
218
+ if (typeof schema.minLength === 'number' && value.length < schema.minLength) {
219
+ return `shorter than minLength ${schema.minLength}`;
220
+ }
221
+ if (typeof schema.maxLength === 'number' && value.length > schema.maxLength) {
222
+ return `longer than maxLength ${schema.maxLength}`;
223
+ }
224
+ if (typeof schema.pattern === 'string') {
225
+ try {
226
+ if (!new RegExp(schema.pattern).test(value)) {
227
+ return `does not match pattern /${schema.pattern}/`;
228
+ }
229
+ }
230
+ catch {
231
+ // Invalid regex in schema — ignore rather than rejecting every case.
232
+ }
233
+ }
234
+ }
235
+ if (typeof value === 'number') {
236
+ if (typeof schema.minimum === 'number' && value < schema.minimum) {
237
+ return `below minimum ${schema.minimum}`;
238
+ }
239
+ if (typeof schema.maximum === 'number' && value > schema.maximum) {
240
+ return `above maximum ${schema.maximum}`;
241
+ }
242
+ if (typeof schema.exclusiveMinimum === 'number' && value <= schema.exclusiveMinimum) {
243
+ return `must be > ${schema.exclusiveMinimum} (exclusive)`;
244
+ }
245
+ if (typeof schema.exclusiveMaximum === 'number' && value >= schema.exclusiveMaximum) {
246
+ return `must be < ${schema.exclusiveMaximum} (exclusive)`;
247
+ }
248
+ }
249
+ if (Array.isArray(value)) {
250
+ if (typeof schema.minItems === 'number' && value.length < schema.minItems) {
251
+ return `has fewer than minItems ${schema.minItems}`;
252
+ }
253
+ if (typeof schema.maxItems === 'number' && value.length > schema.maxItems) {
254
+ return `has more than maxItems ${schema.maxItems}`;
255
+ }
256
+ if (schema.uniqueItems === true && hasDuplicates(value)) {
257
+ return `has duplicate items (uniqueItems is true)`;
258
+ }
259
+ }
260
+ return null;
261
+ }
262
+ /** Sentinel value used to violate string enums and string constraints. */
263
+ const INVALID_STRING = '__mcp_tester_invalid__';
264
+ /**
265
+ * Pick a printable string that does NOT match `pattern`, so the
266
+ * not-matching-pattern case genuinely violates it.
267
+ *
268
+ * @returns A violating string, or `undefined` when the pattern is invalid or
269
+ * matches every candidate (e.g. `.*`), in which case the caller must skip
270
+ * the case rather than emit a bogus `error` expectation.
271
+ */
272
+ function violatingStringForPattern(pattern) {
273
+ let re;
274
+ try {
275
+ re = new RegExp(pattern);
276
+ }
277
+ catch {
278
+ // Invalid regex: the pattern can never be enforced by the server either.
279
+ return undefined;
280
+ }
281
+ return [INVALID_STRING, '!!!', '@@@', ' ', '0', 'Z'].find((c) => !re.test(c));
282
+ }
283
+ /**
284
+ * Choose a value guaranteed to violate an `additionalProperties` sub-schema,
285
+ * or `undefined` when no single value can be guaranteed to violate it (e.g. a
286
+ * `type` union). The value's JSON type is picked to mismatch the schema:
287
+ * numeric schemas get a string, everything else gets a number.
288
+ */
289
+ function additionalPropsViolatingValue(ap) {
290
+ const type = ap.type;
291
+ if (type === 'number' || type === 'integer')
292
+ return 'not-a-number';
293
+ // string | boolean | array | object | null all reject the number 12345.
294
+ if (typeof type === 'string')
295
+ return 12345;
296
+ // A union accepts multiple JSON types; no single value is guaranteed wrong.
297
+ if (Array.isArray(type))
298
+ return undefined;
299
+ // No `type` keyword: infer the intended type from constraint keywords.
300
+ if (typeof ap.minLength === 'number' ||
301
+ typeof ap.maxLength === 'number' ||
302
+ typeof ap.pattern === 'string') {
303
+ return 12345;
304
+ }
305
+ if (typeof ap.minimum === 'number' ||
306
+ typeof ap.maximum === 'number' ||
307
+ typeof ap.exclusiveMinimum === 'number' ||
308
+ typeof ap.exclusiveMaximum === 'number') {
309
+ return 'not-a-number';
310
+ }
311
+ return undefined;
312
+ }
313
+ /**
314
+ * Derive deterministic edge cases for one tool from its `inputSchema`.
315
+ *
316
+ * Rules (each emitted only when the schema actually constrains it):
317
+ * - `required` — omit each required property → error
318
+ * - `enum` — a value outside the enum → error
319
+ * - `min-length` / `max-length` — boundary and one-past-the-bound strings
320
+ * - `pattern` — a string that doesn't match the regex → error
321
+ * - `bounds` — number/integer at `minimum`/`maximum` and one past (also
322
+ * handles `exclusiveMinimum` / `exclusiveMaximum`)
323
+ * - `type` — a value of the wrong JSON type → error
324
+ * - `min-items` / `max-items` — array under `minItems` or over `maxItems` → error
325
+ * - `unique-items` — array with duplicates → error
326
+ * - `additional-properties` — unknown property → error (`false` or schema form)
327
+ *
328
+ * @returns One or more cases; may be empty for schemas with no constraints.
329
+ */
330
+ export function suggestEdgeCases(tool) {
331
+ const schema = tool.inputSchema;
332
+ if (!schema || !schema.properties)
333
+ return [];
334
+ const props = schema.properties;
335
+ const required = new Set(schema.required || []);
336
+ const base = generateToolArgs(tool);
337
+ const cases = [];
338
+ const withArgs = (mutate, title, expectation, rationale, source) => {
339
+ const args = { ...base };
340
+ mutate(args);
341
+ cases.push({ tool: tool.name, title, args, expectation, rationale, source });
342
+ };
343
+ // Property metadata lookups
344
+ const stringProps = Object.entries(props).filter(([, p]) => p.type === 'string');
345
+ const numberProps = Object.entries(props).filter(([, p]) => p.type === 'number' || p.type === 'integer');
346
+ const arrayProps = Object.entries(props).filter(([, p]) => p.type === 'array');
347
+ // rule:required — omit each required property
348
+ for (const key of required) {
349
+ if (!(key in props))
350
+ continue;
351
+ withArgs((args) => delete args[key], `rejects call without required "${key}"`, 'error', `"${key}" is required; the server should reject its absence`, 'rule:required');
352
+ }
353
+ // rule:enum — a value outside the enum
354
+ for (const [key, prop] of Object.entries(props)) {
355
+ const enumValues = prop['enum'];
356
+ if (!enumValues || enumValues.length === 0)
357
+ continue;
358
+ let invalid;
359
+ if (typeof enumValues[0] === 'string') {
360
+ invalid = enumValues.includes(INVALID_STRING) ? undefined : INVALID_STRING;
361
+ }
362
+ else if (typeof enumValues[0] === 'number') {
363
+ const max = Math.max(...enumValues.filter((v) => typeof v === 'number'));
364
+ invalid = Number.isFinite(max) ? max + 1 : undefined;
365
+ }
366
+ if (invalid === undefined)
367
+ continue;
368
+ withArgs((args) => {
369
+ args[key] = invalid;
370
+ }, `rejects "${key}" outside enum (not in [${enumValues.map(String).join(', ')}])`, 'error', `"${key}" is constrained to enum ${JSON.stringify(enumValues)}`, 'rule:enum');
371
+ }
372
+ // rule:min-length / rule:max-length — string boundaries
373
+ for (const [key, prop] of stringProps) {
374
+ const minLength = prop.minLength;
375
+ const maxLength = prop.maxLength;
376
+ if (typeof minLength === 'number' && minLength > 0) {
377
+ withArgs((args) => {
378
+ args[key] = 'x'.repeat(Math.max(minLength - 1, 0));
379
+ }, `rejects "${key}" shorter than minLength ${minLength}`, 'error', `"${key}" requires at least ${minLength} character(s)`, 'rule:min-length');
380
+ }
381
+ if (typeof maxLength === 'number') {
382
+ withArgs((args) => {
383
+ args[key] = 'x'.repeat(maxLength + 1);
384
+ }, `behavior of "${key}" longer than maxLength ${maxLength}`, 'observe', `"${key}" allows at most ${maxLength} characters — one past the bound`, 'rule:max-length');
385
+ }
386
+ if (typeof prop.pattern === 'string') {
387
+ const violating = violatingStringForPattern(prop.pattern);
388
+ // Skip patterns that accept every candidate (e.g. `.*`); otherwise the
389
+ // "error" case would actually succeed against a conforming server.
390
+ if (violating !== undefined) {
391
+ withArgs((args) => {
392
+ args[key] = violating;
393
+ }, `rejects "${key}" not matching pattern /${prop.pattern}/`, 'error', `"${key}" is constrained to pattern /${prop.pattern}/`, 'rule:pattern');
394
+ }
395
+ }
396
+ }
397
+ // rule:bounds — number boundaries
398
+ for (const [key, prop] of numberProps) {
399
+ const minimum = prop.minimum;
400
+ const maximum = prop.maximum;
401
+ const exclusiveMinimum = prop.exclusiveMinimum;
402
+ const exclusiveMaximum = prop.exclusiveMaximum;
403
+ if (typeof minimum === 'number') {
404
+ withArgs((args) => {
405
+ args[key] = minimum - 1;
406
+ }, `rejects "${key}" below minimum ${minimum}`, 'error', `"${key}" must be >= ${minimum}`, 'rule:bounds');
407
+ }
408
+ if (typeof maximum === 'number') {
409
+ withArgs((args) => {
410
+ args[key] = maximum + 1;
411
+ }, `rejects "${key}" above maximum ${maximum}`, 'error', `"${key}" must be <= ${maximum}`, 'rule:bounds');
412
+ }
413
+ if (typeof exclusiveMinimum === 'number') {
414
+ withArgs((args) => {
415
+ args[key] = exclusiveMinimum;
416
+ }, `rejects "${key}" equal to exclusiveMinimum ${exclusiveMinimum}`, 'error', `"${key}" must be > ${exclusiveMinimum}`, 'rule:bounds');
417
+ }
418
+ if (typeof exclusiveMaximum === 'number') {
419
+ withArgs((args) => {
420
+ args[key] = exclusiveMaximum;
421
+ }, `rejects "${key}" equal to exclusiveMaximum ${exclusiveMaximum}`, 'error', `"${key}" must be < ${exclusiveMaximum}`, 'rule:bounds');
422
+ }
423
+ }
424
+ // rule:type — wrong JSON type for each required property
425
+ for (const [key, prop] of Object.entries(props)) {
426
+ if (!required.has(key))
427
+ continue;
428
+ const expected = prop.type;
429
+ let wrong;
430
+ switch (expected) {
431
+ case 'string':
432
+ wrong = 12345;
433
+ break;
434
+ case 'number':
435
+ case 'integer':
436
+ wrong = 'not-a-number';
437
+ break;
438
+ case 'boolean':
439
+ wrong = 'not-a-boolean';
440
+ break;
441
+ case 'array':
442
+ wrong = 'not-an-array';
443
+ break;
444
+ case 'object':
445
+ wrong = 'not-an-object';
446
+ break;
447
+ default:
448
+ continue;
449
+ }
450
+ withArgs((args) => {
451
+ args[key] = wrong;
452
+ }, `rejects wrong type for "${key}" (expected ${expected})`, 'error', `"${key}" is typed "${expected}"; a wrongly-typed (${jsonTypeOf(wrong)}) value should be rejected`, 'rule:type');
453
+ }
454
+ // rule:min-items / rule:max-items / rule:unique-items — array boundaries
455
+ for (const [key, prop] of arrayProps) {
456
+ const minItems = prop.minItems;
457
+ const maxItems = prop.maxItems;
458
+ const uniqueItems = prop.uniqueItems === true;
459
+ if (typeof minItems === 'number' && minItems > 0) {
460
+ withArgs((args) => {
461
+ args[key] = [];
462
+ }, `rejects "${key}" with fewer than minItems ${minItems}`, 'error', `"${key}" requires at least ${minItems} item(s)`, 'rule:min-items');
463
+ }
464
+ if (typeof maxItems === 'number') {
465
+ const target = Math.max(maxItems + 1, 1);
466
+ const itemSchema = prop.items ?? {};
467
+ withArgs((args) => {
468
+ args[key] = Array.from({ length: target }, () => 'unique' in itemSchema || itemSchema.type ? generateSampleValue(itemSchema) : 'example');
469
+ }, `rejects "${key}" with more than maxItems ${maxItems}`, 'error', `"${key}" allows at most ${maxItems} item(s)`, 'rule:max-items');
470
+ }
471
+ if (uniqueItems) {
472
+ const itemSchema = prop.items ?? {};
473
+ const sample = generateSampleValue(itemSchema);
474
+ withArgs((args) => {
475
+ args[key] = [sample, sample];
476
+ }, `rejects "${key}" with duplicate items (uniqueItems: true)`, 'error', `"${key}" requires unique items; a list with duplicates should be rejected`, 'rule:unique-items');
477
+ }
478
+ }
479
+ // rule:additional-properties — unknown property
480
+ // Two cases: additionalProperties: false (anything extra is rejected), or
481
+ // additionalProperties as a schema (extras must satisfy that schema).
482
+ if (schema.additionalProperties === false) {
483
+ withArgs((args) => {
484
+ args['__mcp_tester_unknown__'] = true;
485
+ }, 'rejects an unknown property (additionalProperties: false)', 'error', 'schema sets additionalProperties: false; unknown keys should be rejected', 'rule:additional-properties');
486
+ }
487
+ else if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {
488
+ const ap = schema.additionalProperties;
489
+ const violating = additionalPropsViolatingValue(ap);
490
+ if (violating !== undefined) {
491
+ withArgs((args) => {
492
+ args['__mcp_tester_unknown__'] = violating;
493
+ }, `rejects an unknown property that violates additionalProperties schema`, 'error', `schema restricts additional properties; an extra value that violates it should be rejected`, 'rule:additional-properties-schema');
494
+ }
495
+ }
496
+ return cases;
497
+ }
498
+ /**
499
+ * Derive deterministic edge cases for a set of tools.
500
+ */
501
+ export function suggestEdgeCasesForTools(tools) {
502
+ return tools.flatMap((tool) => suggestEdgeCases(tool));
503
+ }
504
+ /**
505
+ * Stable identity for a case. Two cases collide when they target the same
506
+ * tool with semantically equal args. Object keys are sorted so that
507
+ * `{a:1,b:2}` and `{b:2,a:1}` are treated as the same case.
508
+ */
509
+ export function caseKey(c) {
510
+ return `${c.tool}::${stableStringify(c.args)}`;
511
+ }
512
+ /** JSON.stringify with object keys sorted, so order doesn't change identity. */
513
+ function stableStringify(value) {
514
+ if (value === null || typeof value !== 'object')
515
+ return JSON.stringify(value);
516
+ if (Array.isArray(value)) {
517
+ return `[${value.map(stableStringify).join(',')}]`;
518
+ }
519
+ const keys = Object.keys(value).sort();
520
+ const entries = keys.map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`);
521
+ return `{${entries.join(',')}}`;
522
+ }
523
+ /**
524
+ * Merge case lists, dropping later duplicates (same tool + args) and cases
525
+ * whose args fail schema validation.
526
+ *
527
+ * Only `success` cases are validated: `error` and `observe` cases intentionally
528
+ * probe invalid input (a rejected tool call, or server-defined behaviour just
529
+ * past a bound), so requiring them to satisfy the schema would discard the
530
+ * rules engine's own output.
531
+ *
532
+ * @returns Accepted cases plus the number of rejected ones (for logging).
533
+ */
534
+ export function mergeAndValidateCases(groups, schemas) {
535
+ const seen = new Set();
536
+ const cases = [];
537
+ const rejected = [];
538
+ for (const group of groups) {
539
+ for (const c of group) {
540
+ const key = caseKey(c);
541
+ if (seen.has(key))
542
+ continue;
543
+ const schema = schemas.get(c.tool)?.inputSchema;
544
+ if (schema) {
545
+ // Only success cases must satisfy the schema; error/observe cases
546
+ // deliberately violate it.
547
+ if (c.expectation === 'success') {
548
+ const reason = validateArgsAgainstSchema(c.args, schema);
549
+ if (reason) {
550
+ rejected.push({ c, reason });
551
+ continue;
552
+ }
553
+ }
554
+ }
555
+ else if (!schemas.has(c.tool)) {
556
+ rejected.push({ c, reason: `unknown tool "${c.tool}"` });
557
+ continue;
558
+ }
559
+ seen.add(key);
560
+ cases.push(c);
561
+ }
562
+ }
563
+ return { cases, rejected };
564
+ }
565
+ //# sourceMappingURL=generate-cases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-cases.js","sourceRoot":"","sources":["../src/generate-cases.ts"],"names":[],"mappings":"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"}