@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
|
@@ -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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"}
|