mcp-integration-harness 0.3.0 → 0.4.1
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/README.md +37 -2
- package/dist/coverage.js +11 -11
- package/dist/harness.js +11 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/schema-lint.d.ts +49 -0
- package/dist/schema-lint.js +224 -0
- package/package.json +6 -5
- package/dist/coverage.js.map +0 -1
- package/dist/harness.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loopback.js.map +0 -1
- package/dist/wait.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# mcp-integration-harness
|
|
2
2
|
|
|
3
|
+
<!-- badges: start -->
|
|
4
|
+
|
|
5
|
+
[](https://github.com/ni-c/mcp-integration-harness/actions/workflows/ci.yml)
|
|
6
|
+
<a href="https://socket.dev/npm/package/mcp-integration-harness"><img src="https://socket.dev/api/badge/npm/package/mcp-integration-harness" alt="Socket supply-chain report" height="20"></a>
|
|
7
|
+
<br>
|
|
3
8
|
[](https://www.npmjs.com/package/mcp-integration-harness)
|
|
4
|
-
[](https://github.com/sponsors/ni-c)
|
|
10
|
+
<!-- badges: end -->
|
|
6
11
|
|
|
7
12
|
Run your built [Model Context Protocol](https://modelcontextprotocol.io) server
|
|
8
13
|
as a real process, against a real backend in Docker, and fail the build unless
|
|
@@ -103,6 +108,34 @@ depending on who asked. A list is `{ items: [...] }`.
|
|
|
103
108
|
|
|
104
109
|
Exemptions are a `Record<tool, reason>` and rot in the same three directions.
|
|
105
110
|
|
|
111
|
+
## `expectPortableToolSchemas`
|
|
112
|
+
|
|
113
|
+
Whether the schemas a server advertises are ones every client can read.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const { tools } = await harness.client.listTools();
|
|
117
|
+
expectPortableToolSchemas(tools);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Four spellings are legal JSON Schema and still get a tool refused or silently
|
|
121
|
+
stripped by some MCP clients:
|
|
122
|
+
|
|
123
|
+
| Written as | Comes from | Write instead |
|
|
124
|
+
| ---------------------------- | ------------------------------------ | --------------------------------------- |
|
|
125
|
+
| `"additionalProperties": {}` | `z.looseObject`, `.catchall()` | `.meta({ additionalProperties: true })` |
|
|
126
|
+
| `"anything": {}` | `z.unknown()`, `z.any()` | the type the value really has |
|
|
127
|
+
| `"type": ["string", "null"]` | `z.string().nullable()` from zod 4.5 | `.describe()` **before** `.nullable()` |
|
|
128
|
+
| `"$ref": "https://…"` | a hand-written schema | inline it, or `#/$defs/…` |
|
|
129
|
+
|
|
130
|
+
All four are spellings rather than contracts: each has an equivalent form that
|
|
131
|
+
says the same thing to a validator. Which is why this check takes no exemption
|
|
132
|
+
map — a reason could only ever read "not fixed yet".
|
|
133
|
+
|
|
134
|
+
It runs against the schema **as it goes on the wire**, which is the only place
|
|
135
|
+
it can run: zod emitted `anyOf` for a nullable string up to 4.4 and a `type`
|
|
136
|
+
array from 4.5 on, so the same source produces a portable schema or a
|
|
137
|
+
non-portable one depending on a patch release of a dependency.
|
|
138
|
+
|
|
106
139
|
## `assertLoopback`
|
|
107
140
|
|
|
108
141
|
The guard that matters more than the tests it protects.
|
|
@@ -144,6 +177,8 @@ would otherwise run your suite as you. Those names are blanked explicitly.
|
|
|
144
177
|
| `toolCoverage` | The same comparison without asserting, for printing the numbers |
|
|
145
178
|
| `expectEveryToolDeclaresOutputSchema` | Every advertised tool declares an output schema with an object root |
|
|
146
179
|
| `outputSchemaCoverage` | The same comparison without asserting |
|
|
180
|
+
| `expectPortableToolSchemas` | Every advertised schema avoids the four spellings clients mishandle |
|
|
181
|
+
| `schemaPortability` | The same lint without asserting, returning the findings |
|
|
147
182
|
| `assertLoopback(url)` | Throws unless the URL is on this machine |
|
|
148
183
|
| `waitForHttp(url, opts)` | Polls until an HTTP backend is ready, and says what the last attempt got |
|
|
149
184
|
| `waitForTcp(host, port)` | The same for a backend that is not HTTP — IMAP, SMTP — optionally on a greeting |
|
package/dist/coverage.js
CHANGED
|
@@ -9,13 +9,13 @@ export function toolCoverage(harness, allTools, skipped) {
|
|
|
9
9
|
const catalogue = new Set(allTools);
|
|
10
10
|
const reasons = Object.keys(skipped);
|
|
11
11
|
return {
|
|
12
|
-
called: [...harness.called].
|
|
13
|
-
skipped: reasons.
|
|
12
|
+
called: [...harness.called].toSorted(),
|
|
13
|
+
skipped: reasons.toSorted(),
|
|
14
14
|
missing: allTools
|
|
15
15
|
.filter((tool) => !harness.called.has(tool) && !(tool in skipped))
|
|
16
|
-
.
|
|
17
|
-
staleReasons: reasons.filter((tool) => harness.called.has(tool)).
|
|
18
|
-
unknownReasons: reasons.filter((tool) => !catalogue.has(tool)).
|
|
16
|
+
.toSorted(),
|
|
17
|
+
staleReasons: reasons.filter((tool) => harness.called.has(tool)).toSorted(),
|
|
18
|
+
unknownReasons: reasons.filter((tool) => !catalogue.has(tool)).toSorted(),
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
@@ -72,21 +72,21 @@ export function outputSchemaCoverage(tools, exempt = {}) {
|
|
|
72
72
|
const reasons = Object.keys(exempt);
|
|
73
73
|
const withSchema = tools.filter((tool) => tool.outputSchema !== undefined);
|
|
74
74
|
return {
|
|
75
|
-
declared: withSchema.map((tool) => tool.name).
|
|
76
|
-
exempt: reasons.
|
|
75
|
+
declared: withSchema.map((tool) => tool.name).toSorted(),
|
|
76
|
+
exempt: reasons.toSorted(),
|
|
77
77
|
missing: tools
|
|
78
78
|
.filter((tool) => tool.outputSchema === undefined && !(tool.name in exempt))
|
|
79
79
|
.map((tool) => tool.name)
|
|
80
|
-
.
|
|
80
|
+
.toSorted(),
|
|
81
81
|
staleReasons: withSchema
|
|
82
82
|
.filter((tool) => tool.name in exempt)
|
|
83
83
|
.map((tool) => tool.name)
|
|
84
|
-
.
|
|
85
|
-
unknownReasons: reasons.filter((name) => !names.has(name)).
|
|
84
|
+
.toSorted(),
|
|
85
|
+
unknownReasons: reasons.filter((name) => !names.has(name)).toSorted(),
|
|
86
86
|
nonObjectRoot: withSchema
|
|
87
87
|
.filter((tool) => !hasObjectRoot(tool.outputSchema))
|
|
88
88
|
.map((tool) => tool.name)
|
|
89
|
-
.
|
|
89
|
+
.toSorted(),
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
/**
|
package/dist/harness.js
CHANGED
|
@@ -51,9 +51,15 @@ export async function startServer(options) {
|
|
|
51
51
|
// any hook a client can install. Such a line without a trailing newline
|
|
52
52
|
// corrupts the next real message instead, which surfaces as a request
|
|
53
53
|
// timeout — see the hint in the failure below.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
//
|
|
55
|
+
// The SDK's `Client` exposes this as a plain property — it is neither an
|
|
56
|
+
// `EventTarget` nor an `EventEmitter`, so there is no listener API to
|
|
57
|
+
// prefer. `Object.assign` installs the one handler the property can hold.
|
|
58
|
+
Object.assign(client, {
|
|
59
|
+
onerror: (error) => {
|
|
60
|
+
protocolErrors.push(error);
|
|
61
|
+
},
|
|
62
|
+
});
|
|
57
63
|
const transport = new StdioClientTransport({
|
|
58
64
|
command: process.execPath,
|
|
59
65
|
args: [entry],
|
|
@@ -87,7 +93,7 @@ export async function startServer(options) {
|
|
|
87
93
|
// refused credential — is sitting in the stderr just captured. Without this
|
|
88
94
|
// the most common first failure of a new suite is also the least legible.
|
|
89
95
|
throw new Error(`mcp-integration-harness: ${process.execPath} ${entry} did not start.\n` +
|
|
90
|
-
`${String(error)}\n\nIts stderr:\n${errors.join('') || '(nothing)'}
|
|
96
|
+
`${String(error)}\n\nIts stderr:\n${errors.join('') || '(nothing)'}`, { cause: error });
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
99
|
* The call itself: coverage bookkeeping, the transport, the framing check.
|
|
@@ -118,7 +124,7 @@ export async function startServer(options) {
|
|
|
118
124
|
'If that stderr is empty and this was a timeout, suspect stdout: a ' +
|
|
119
125
|
'write there without a trailing newline is prepended to the next ' +
|
|
120
126
|
'JSON-RPC message, and the reply is discarded inside the read buffer ' +
|
|
121
|
-
'where no hook can see it. stdout belongs to the transport.');
|
|
127
|
+
'where no hook can see it. stdout belongs to the transport.', { cause: error });
|
|
122
128
|
}
|
|
123
129
|
assertFramingIntact(`calling ${name}`);
|
|
124
130
|
return result;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { startServer, tokenOf, type CallOptions, type ElicitBehaviour, type LiveHarness, type StartServerOptions, type ToolResult, } from './harness.js';
|
|
2
2
|
export { expectEveryToolDeclaresOutputSchema, expectEveryToolExercised, outputSchemaCoverage, toolCoverage, type AdvertisedTool, type CoverageReport, type OutputSchemaReport, type SkipReasons, } from './coverage.js';
|
|
3
|
+
export { expectPortableToolSchemas, schemaPortability, type SchemaBearingTool, type SchemaFinding, type SchemaLintRule, } from './schema-lint.js';
|
|
3
4
|
export { assertLoopback, assertLoopbackHost } from './loopback.js';
|
|
4
5
|
export { waitForHttp, waitForTcp, type TcpWaitOptions, type WaitOptions, } from './wait.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { startServer, tokenOf, } from './harness.js';
|
|
2
2
|
export { expectEveryToolDeclaresOutputSchema, expectEveryToolExercised, outputSchemaCoverage, toolCoverage, } from './coverage.js';
|
|
3
|
+
export { expectPortableToolSchemas, schemaPortability, } from './schema-lint.js';
|
|
3
4
|
export { assertLoopback, assertLoopbackHost } from './loopback.js';
|
|
4
5
|
export { waitForHttp, waitForTcp, } from './wait.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portability rules for the JSON Schemas a server advertises.
|
|
3
|
+
*
|
|
4
|
+
* A schema can be perfectly legal JSON Schema and still be refused or
|
|
5
|
+
* mishandled by a client, and the four rules below are the ones this family of
|
|
6
|
+
* servers has actually walked into. All four are spellings rather than
|
|
7
|
+
* contracts: each has an equivalent form that says the same thing to a
|
|
8
|
+
* validator and survives the trip to every client.
|
|
9
|
+
*
|
|
10
|
+
* The checks run against the schema as it goes out on the wire, which is the
|
|
11
|
+
* only place they can run. Zod is what writes that schema here, and what it
|
|
12
|
+
* writes changes between its own releases: `z.string().nullable()` emitted
|
|
13
|
+
* `anyOf` up to zod 4.4 and a `"type": ["string", "null"]` array from 4.5 on.
|
|
14
|
+
* A source-level rule would have missed that; a wire-level one cannot.
|
|
15
|
+
*/
|
|
16
|
+
/** Which spelling a finding is about. */
|
|
17
|
+
export type SchemaLintRule = 'untyped-schema' | 'boolean-schema' | 'type-union' | 'remote-ref';
|
|
18
|
+
export interface SchemaFinding {
|
|
19
|
+
rule: SchemaLintRule;
|
|
20
|
+
/** The tool whose schema carries it. */
|
|
21
|
+
tool: string;
|
|
22
|
+
/** `inputSchema` or `outputSchema`, plus the path inside it. */
|
|
23
|
+
path: string;
|
|
24
|
+
/** What is wrong, and what to write instead. */
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
/** One entry of `tools/list`, as much of it as this check reads. */
|
|
28
|
+
export interface SchemaBearingTool {
|
|
29
|
+
name: string;
|
|
30
|
+
inputSchema?: unknown;
|
|
31
|
+
outputSchema?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Lints the advertised schemas, without asserting.
|
|
35
|
+
*
|
|
36
|
+
* Separate from the assertion for the reason {@link toolCoverage} is: the count
|
|
37
|
+
* is worth a line in a CI log on a green run too.
|
|
38
|
+
*/
|
|
39
|
+
export declare function schemaPortability(tools: readonly SchemaBearingTool[]): SchemaFinding[];
|
|
40
|
+
/**
|
|
41
|
+
* Fails unless every advertised schema is one every client can read.
|
|
42
|
+
*
|
|
43
|
+
* No exemption map, unlike the checks in `coverage.ts`. Those excuse what a
|
|
44
|
+
* *backend* cannot provide, which is a fact about the world and needs writing
|
|
45
|
+
* down. There is nothing to excuse here: every finding has an equivalent
|
|
46
|
+
* spelling that says the same thing, so a reason could only ever read "not
|
|
47
|
+
* fixed yet".
|
|
48
|
+
*/
|
|
49
|
+
export declare function expectPortableToolSchemas(tools: readonly SchemaBearingTool[]): void;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portability rules for the JSON Schemas a server advertises.
|
|
3
|
+
*
|
|
4
|
+
* A schema can be perfectly legal JSON Schema and still be refused or
|
|
5
|
+
* mishandled by a client, and the four rules below are the ones this family of
|
|
6
|
+
* servers has actually walked into. All four are spellings rather than
|
|
7
|
+
* contracts: each has an equivalent form that says the same thing to a
|
|
8
|
+
* validator and survives the trip to every client.
|
|
9
|
+
*
|
|
10
|
+
* The checks run against the schema as it goes out on the wire, which is the
|
|
11
|
+
* only place they can run. Zod is what writes that schema here, and what it
|
|
12
|
+
* writes changes between its own releases: `z.string().nullable()` emitted
|
|
13
|
+
* `anyOf` up to zod 4.4 and a `"type": ["string", "null"]` array from 4.5 on.
|
|
14
|
+
* A source-level rule would have missed that; a wire-level one cannot.
|
|
15
|
+
*/
|
|
16
|
+
/** Keywords that constrain the instance. Anything else only annotates it. */
|
|
17
|
+
const CONSTRAINING_KEYWORDS = new Set([
|
|
18
|
+
// Assertions
|
|
19
|
+
'type',
|
|
20
|
+
'enum',
|
|
21
|
+
'const',
|
|
22
|
+
'multipleOf',
|
|
23
|
+
'maximum',
|
|
24
|
+
'exclusiveMaximum',
|
|
25
|
+
'minimum',
|
|
26
|
+
'exclusiveMinimum',
|
|
27
|
+
'maxLength',
|
|
28
|
+
'minLength',
|
|
29
|
+
'pattern',
|
|
30
|
+
'maxItems',
|
|
31
|
+
'minItems',
|
|
32
|
+
'uniqueItems',
|
|
33
|
+
'maxContains',
|
|
34
|
+
'minContains',
|
|
35
|
+
'maxProperties',
|
|
36
|
+
'minProperties',
|
|
37
|
+
'required',
|
|
38
|
+
'dependentRequired',
|
|
39
|
+
'format',
|
|
40
|
+
'contentEncoding',
|
|
41
|
+
'contentMediaType',
|
|
42
|
+
'contentSchema',
|
|
43
|
+
// Applicators
|
|
44
|
+
'items',
|
|
45
|
+
'prefixItems',
|
|
46
|
+
'contains',
|
|
47
|
+
'additionalItems',
|
|
48
|
+
'unevaluatedItems',
|
|
49
|
+
'properties',
|
|
50
|
+
'patternProperties',
|
|
51
|
+
'additionalProperties',
|
|
52
|
+
'propertyNames',
|
|
53
|
+
'unevaluatedProperties',
|
|
54
|
+
'dependentSchemas',
|
|
55
|
+
'allOf',
|
|
56
|
+
'anyOf',
|
|
57
|
+
'oneOf',
|
|
58
|
+
'not',
|
|
59
|
+
// References
|
|
60
|
+
'$ref',
|
|
61
|
+
'$dynamicRef',
|
|
62
|
+
'$recursiveRef',
|
|
63
|
+
]);
|
|
64
|
+
/**
|
|
65
|
+
* Keywords whose value may be a bare boolean without anyone minding.
|
|
66
|
+
*
|
|
67
|
+
* `"additionalProperties": true` is the ordinary way to write an open object
|
|
68
|
+
* and every client reads it. A bare `true` anywhere a schema *object* is
|
|
69
|
+
* expected is a different matter.
|
|
70
|
+
*/
|
|
71
|
+
const BOOLEAN_VALUED_KEYWORDS = new Set([
|
|
72
|
+
'additionalProperties',
|
|
73
|
+
'unevaluatedProperties',
|
|
74
|
+
'additionalItems',
|
|
75
|
+
'unevaluatedItems',
|
|
76
|
+
]);
|
|
77
|
+
const SUBSCHEMA_KEYWORDS = [
|
|
78
|
+
'items',
|
|
79
|
+
'contains',
|
|
80
|
+
'not',
|
|
81
|
+
'propertyNames',
|
|
82
|
+
'if',
|
|
83
|
+
'then',
|
|
84
|
+
'else',
|
|
85
|
+
'additionalProperties',
|
|
86
|
+
'unevaluatedProperties',
|
|
87
|
+
'additionalItems',
|
|
88
|
+
'unevaluatedItems',
|
|
89
|
+
'contentSchema',
|
|
90
|
+
];
|
|
91
|
+
const SUBSCHEMA_ARRAY_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'];
|
|
92
|
+
const SUBSCHEMA_MAP_KEYWORDS = [
|
|
93
|
+
'properties',
|
|
94
|
+
'patternProperties',
|
|
95
|
+
'dependentSchemas',
|
|
96
|
+
'dependencies',
|
|
97
|
+
'$defs',
|
|
98
|
+
'definitions',
|
|
99
|
+
];
|
|
100
|
+
const JSON_SCHEMA_TYPES = new Set([
|
|
101
|
+
'null',
|
|
102
|
+
'boolean',
|
|
103
|
+
'object',
|
|
104
|
+
'array',
|
|
105
|
+
'number',
|
|
106
|
+
'string',
|
|
107
|
+
'integer',
|
|
108
|
+
]);
|
|
109
|
+
/** Guards against a `$ref` cycle turning the walk into a hang. */
|
|
110
|
+
const MAX_DEPTH = 64;
|
|
111
|
+
function isRecord(value) {
|
|
112
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
113
|
+
}
|
|
114
|
+
function constrainsInstance(node) {
|
|
115
|
+
if (Object.keys(node).some((key) => CONSTRAINING_KEYWORDS.has(key))) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
// `if` alone constrains nothing; with a branch beside it, it does.
|
|
119
|
+
return 'if' in node && ('then' in node || 'else' in node);
|
|
120
|
+
}
|
|
121
|
+
function isPlainTypeUnion(type) {
|
|
122
|
+
if (!Array.isArray(type) || type.length === 0)
|
|
123
|
+
return false;
|
|
124
|
+
return type.every((entry) => typeof entry === 'string' && JSON_SCHEMA_TYPES.has(entry));
|
|
125
|
+
}
|
|
126
|
+
function walk(node, path, keyword, depth, emit) {
|
|
127
|
+
if (depth > MAX_DEPTH)
|
|
128
|
+
return;
|
|
129
|
+
if (typeof node === 'boolean') {
|
|
130
|
+
if (keyword !== undefined && BOOLEAN_VALUED_KEYWORDS.has(keyword))
|
|
131
|
+
return;
|
|
132
|
+
emit('boolean-schema', path, `bare \`${String(node)}\` where a schema object is expected. Write ` +
|
|
133
|
+
(node
|
|
134
|
+
? 'the object form — `{}` under `not`, or the type the value really has.'
|
|
135
|
+
: '`{"not": {}}`; deleting the entry allows the property instead of forbidding it.'));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!isRecord(node))
|
|
139
|
+
return;
|
|
140
|
+
if (isPlainTypeUnion(node.type)) {
|
|
141
|
+
emit('type-union', path, `\`type\` is an array (${JSON.stringify(node.type)}). Several clients ` +
|
|
142
|
+
'read `type` as a single string and drop the constraint or refuse the ' +
|
|
143
|
+
'tool. Split it into `anyOf` branches — in zod, put `.describe()` on ' +
|
|
144
|
+
'the inner type *before* `.nullable()`, which stops it folding the two ' +
|
|
145
|
+
'into one `type` array.');
|
|
146
|
+
}
|
|
147
|
+
const ref = node.$ref;
|
|
148
|
+
if (typeof ref === 'string' && ref !== '' && !ref.startsWith('#')) {
|
|
149
|
+
emit('remote-ref', path, `\`$ref\` points outside this document (\`${ref}\`). Clients do not ` +
|
|
150
|
+
'fetch remote schemas. Inline it, or move it into `$defs`.');
|
|
151
|
+
}
|
|
152
|
+
if (!constrainsInstance(node) && keyword !== 'not') {
|
|
153
|
+
emit('untyped-schema', path, 'no validation keyword at all, so this accepts any value — the object ' +
|
|
154
|
+
'spelling of a bare `true`, which some clients refuse or mishandle. ' +
|
|
155
|
+
'In zod: `.meta({ additionalProperties: true })` on a `looseObject` or ' +
|
|
156
|
+
'a `catchall`, and the real type instead of `z.unknown()`.');
|
|
157
|
+
}
|
|
158
|
+
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
159
|
+
const map = node[key];
|
|
160
|
+
if (!isRecord(map))
|
|
161
|
+
continue;
|
|
162
|
+
for (const [name, child] of Object.entries(map)) {
|
|
163
|
+
walk(child, `${path}.${key}.${name}`, key, depth + 1, emit);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const key of SUBSCHEMA_ARRAY_KEYWORDS) {
|
|
167
|
+
const list = node[key];
|
|
168
|
+
if (!Array.isArray(list))
|
|
169
|
+
continue;
|
|
170
|
+
list.forEach((child, index) => {
|
|
171
|
+
walk(child, `${path}.${key}[${index}]`, key, depth + 1, emit);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
for (const key of SUBSCHEMA_KEYWORDS) {
|
|
175
|
+
if (!(key in node))
|
|
176
|
+
continue;
|
|
177
|
+
const child = node[key];
|
|
178
|
+
if (key === 'items' && Array.isArray(child)) {
|
|
179
|
+
child.forEach((entry, index) => {
|
|
180
|
+
walk(entry, `${path}.${key}[${index}]`, key, depth + 1, emit);
|
|
181
|
+
});
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
walk(child, `${path}.${key}`, key, depth + 1, emit);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Lints the advertised schemas, without asserting.
|
|
189
|
+
*
|
|
190
|
+
* Separate from the assertion for the reason {@link toolCoverage} is: the count
|
|
191
|
+
* is worth a line in a CI log on a green run too.
|
|
192
|
+
*/
|
|
193
|
+
export function schemaPortability(tools) {
|
|
194
|
+
const findings = [];
|
|
195
|
+
for (const tool of tools) {
|
|
196
|
+
for (const kind of ['inputSchema', 'outputSchema']) {
|
|
197
|
+
const schema = tool[kind];
|
|
198
|
+
if (schema === undefined)
|
|
199
|
+
continue;
|
|
200
|
+
walk(schema, kind, undefined, 0, (rule, path, message) => {
|
|
201
|
+
findings.push({ rule, tool: tool.name, path, message });
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return findings;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Fails unless every advertised schema is one every client can read.
|
|
209
|
+
*
|
|
210
|
+
* No exemption map, unlike the checks in `coverage.ts`. Those excuse what a
|
|
211
|
+
* *backend* cannot provide, which is a fact about the world and needs writing
|
|
212
|
+
* down. There is nothing to excuse here: every finding has an equivalent
|
|
213
|
+
* spelling that says the same thing, so a reason could only ever read "not
|
|
214
|
+
* fixed yet".
|
|
215
|
+
*/
|
|
216
|
+
export function expectPortableToolSchemas(tools) {
|
|
217
|
+
const findings = schemaPortability(tools);
|
|
218
|
+
if (findings.length === 0)
|
|
219
|
+
return;
|
|
220
|
+
const lines = findings.map((finding) => ` ${finding.tool} — ${finding.path}: ${finding.message}`);
|
|
221
|
+
throw new Error(`${findings.length} schema portability problem(s) across ` +
|
|
222
|
+
`${tools.length} tool(s):\n\n${lines.join('\n\n')}`);
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=schema-lint.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-integration-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Drive an MCP server over real stdio against a real backend, and prove every tool was exercised",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
|
-
"dist"
|
|
33
|
+
"dist",
|
|
34
|
+
"!dist/**/*.map"
|
|
34
35
|
],
|
|
35
36
|
"engines": {
|
|
36
37
|
"node": ">=22"
|
|
@@ -55,12 +56,12 @@
|
|
|
55
56
|
"@modelcontextprotocol/core": "^2.0.0",
|
|
56
57
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
57
58
|
"@types/node": "^26.2.0",
|
|
58
|
-
"@vitest/coverage-v8": "
|
|
59
|
-
"mcp-approval": "^0.
|
|
59
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
60
|
+
"mcp-approval": "^0.8.2",
|
|
60
61
|
"oxlint": "^1.80.0",
|
|
61
62
|
"prettier": "^3.6.0",
|
|
62
63
|
"typescript": "^7.0.2",
|
|
63
|
-
"vitest": "^
|
|
64
|
+
"vitest": "^5.0.0",
|
|
64
65
|
"zod": "^4.4.3"
|
|
65
66
|
}
|
|
66
67
|
}
|
package/dist/coverage.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
package/dist/harness.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,OAAO,GAMR,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mCAAmC,EACnC,wBAAwB,EACxB,oBAAoB,EACpB,YAAY,GAKb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EACL,WAAW,EACX,UAAU,GAGX,MAAM,WAAW,CAAC"}
|
package/dist/loopback.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loopback.js","sourceRoot":"","sources":["../src/loopback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,gDAAgD,IAAI,qBAAqB;YACvE,wEAAwE;YACxE,uEAAuE;YACvE,+BAA+B,CAClC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,qDAAqD,GAAG,iBAAiB;YACvE,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,wEAAwE;QACxE,2EAA2E;QAC3E,qEAAqE;QACrE,6EAA6E;QAC7E,MAAM,IAAI,KAAK,CACb,qDAAqD,GAAG,aAAa;YACnE,oEAAoE;YACpE,qEAAqE,CACxE,CAAC;IACJ,CAAC;IACD,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
|
package/dist/wait.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"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"}
|