@effected/mcp 0.11.0 → 0.13.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/testing.d.ts DELETED
@@ -1,490 +0,0 @@
1
- import { Duration, Effect, JsonSchema, Layer, PlatformError, Schema, Scope, Stdio } from "effect";
2
- import { McpProtocol } from "effect/ai";
3
- import { ChildProcess, ChildProcessSpawner } from "effect/process";
4
- declare const McpTestFailure_base: Schema.Class<McpTestFailure, Schema.TaggedStruct<"McpTestFailure", {
5
- /** Which failure occurred; see the list above for which client raises which. */
6
- readonly reason: Schema.Literals<readonly ["StreamEnded", "ServerStopped", "NotJsonRpc", "NotInitialized", "ErrorResponse", "TimedOut"]>;
7
- /** A human-readable description of what went wrong. */
8
- readonly message: Schema.String;
9
- }>, import("effect/Cause").YieldableError>;
10
- /**
11
- * Why an MCP test client could not produce what was asked of it.
12
- *
13
- * @remarks
14
- * Each reason is raised by a specific client, and not every client raises
15
- * every reason:
16
- *
17
- * - `StreamEnded` (`McpProcess`, `McpProbe`): the spawned child's stdout
18
- * ended first, because the child exited. `McpProbe` folds the exit code
19
- * and stderr into the message. `McpProcess.stderrUntil` raises it when
20
- * stderr ends before its predicate holds.
21
- * - `TimedOut` (`McpProcess.stderrUntil`): the predicate did not hold
22
- * within the given timeout. The message carries the stderr seen so far.
23
- * - `NotJsonRpc` (`McpProcess.readUntilResponse`, `McpProbe`): a spawned
24
- * child's stdout line was not a JSON-RPC frame. `McpHarness` never raises
25
- * it: under `strictStdout` a non-JSON-RPC line DIES the pending wait as a
26
- * defect instead, so assert it with `Effect.exit` and `Cause.hasDies`,
27
- * not `catchTag`.
28
- * - `ServerStopped` (`McpHarness`): the in-process server stopped, usually
29
- * because stdin closed while the request was in flight.
30
- * - `NotInitialized` (`McpHarness`): a request other than `initialize` or
31
- * `ping` was made on a stateful revision before `initialize` was sent. The request
32
- * is never written; the server would only have refused it opaquely:
33
- * `-32602 Invalid request metadata` when a stateless adapter is listed
34
- * first, `-32603 Internal error` when only stateful revisions are served.
35
- * - `ErrorResponse` (`McpHarness.listTools`): the server answered with a
36
- * JSON-RPC error where a result was required. Every other request method
37
- * returns the whole response, error included, as data.
38
- *
39
- * @public
40
- */
41
- export declare class McpTestFailure extends McpTestFailure_base {}
42
- /**
43
- * One JSON-RPC 2.0 frame as an MCP test client sees it.
44
- *
45
- * @public
46
- */
47
- interface JsonRpcMessage {
48
- readonly jsonrpc: "2.0";
49
- readonly id?: string | number | null | undefined;
50
- readonly method?: string | undefined;
51
- readonly params?: unknown;
52
- readonly result?: unknown;
53
- readonly error?: unknown;
54
- }
55
- /**
56
- * One entry of a `tools/list` result.
57
- *
58
- * @public
59
- */
60
- interface ServedTool {
61
- readonly name: string;
62
- readonly title?: string | undefined;
63
- readonly description?: string | undefined;
64
- readonly inputSchema: JsonSchema.JsonSchema;
65
- readonly outputSchema?: JsonSchema.JsonSchema | undefined;
66
- readonly annotations?: {
67
- readonly [key: string]: unknown;
68
- } | undefined;
69
- readonly _meta?: {
70
- readonly [key: string]: unknown;
71
- } | undefined;
72
- }
73
- /**
74
- * One entry of a `resources/list` result.
75
- *
76
- * @public
77
- */
78
- interface ServedResource {
79
- readonly uri: string;
80
- readonly name: string;
81
- readonly title?: string | undefined;
82
- readonly description?: string | undefined;
83
- readonly mimeType?: string | undefined;
84
- readonly annotations?: {
85
- readonly [key: string]: unknown;
86
- } | undefined;
87
- readonly size?: number | undefined;
88
- readonly _meta?: {
89
- readonly [key: string]: unknown;
90
- } | undefined;
91
- }
92
- /**
93
- * Options for {@link McpHarness.make}.
94
- *
95
- * @public
96
- */
97
- interface McpHarnessOptions {
98
- /** The revision this client speaks. Defaults to `McpProtocol.v2025_11_25`; a stateless adapter switches to `server/discover` and per-request `_meta`. */
99
- readonly protocol?: McpProtocol.ProtocolAdapter | undefined;
100
- /** The `clientInfo` sent in `initialize` and in stateless `_meta`. */
101
- readonly clientInfo?: {
102
- readonly name: string;
103
- readonly version: string;
104
- } | undefined;
105
- /** Capture the server's console so logs are asserted, not printed. Defaults to `true`. */
106
- readonly captureLogs?: boolean | undefined;
107
- /** Treat any stdout line that is not JSON-RPC as a defect. Defaults to `true`. */
108
- readonly strictStdout?: boolean | undefined;
109
- }
110
- /**
111
- * An in-process MCP client for a real server layer, over queue-backed stdio.
112
- *
113
- * @remarks
114
- * Builds your server with a queue-backed `Stdio.layerTest` that satisfies the
115
- * server's `Stdio` requirement, so tests see the exact served schemas and wire
116
- * results a real client would, with no child and no sockets. Pass the server
117
- * WITHOUT a `Stdio` of its own: a `Stdio` the server provides internally wins,
118
- * and talks to the real terminal. A bundled platform layer such as
119
- * `NodeServices.layer` (`@effect/platform-node`) brings its own `Stdio` along
120
- * with `FileSystem`, `Path`, `ChildProcessSpawner`, `Crypto` and `Terminal` —
121
- * providing it to the server loses `Stdio` the same way, and every wait
122
- * hangs to timeout with no error naming why. Compose the individual layers
123
- * the server needs instead and leave `Stdio` out; this harness supplies it.
124
- *
125
- * The server is built with a fresh layer memo map, never the ambient one, so
126
- * a harness made under another stdio server's `Effect.provide` still serves
127
- * its own. Never pass a server layer that provides a layer the test also
128
- * provides and then reads — `McpHarness.make(server.pipe(Layer.provide(AppLayer)))`
129
- * under `Effect.provide(AppLayer)` builds `AppLayer` twice, so the tools write
130
- * to one instance and the test reads the other. Leave the service in the
131
- * server layer's requirements and provide it once from the test, or build it
132
- * once and pass `Layer.succeed(Tag, value)`.
133
- *
134
- * - Responses are matched by id, so notifications may interleave freely.
135
- * - Every response wait and `awaitOutboundMethod` fails with `ServerStopped`
136
- * when the server stops, and dies when `strictStdout` sees a line that is
137
- * not JSON-RPC. `stop` stops the server at once; `close` ends stdin and lets
138
- * in-flight requests answer first, so only `stop` releases a wait on a
139
- * request that never completes.
140
- * - With `captureLogs`, the server's console is captured: `stderrSoFar`
141
- * holds stderr writes and every log line, and `consoleLogSoFar` holds
142
- * anything that went through `console.log`, which in a real server is
143
- * the wire. Assert it empty.
144
- * - On a stateful revision (the default `2025-11-25`), send `initialize`
145
- * first. `ping` is the exception: the server answers it `{}` before
146
- * initialization, so it is written. Every other request before
147
- * `initialize` fails with `NotInitialized` and is never written: the
148
- * server would only answer an opaque refusal,
149
- * `-32602 Invalid request metadata` when a stateless adapter is listed
150
- * first (as in `McpStdio.protocols`), or `-32603 Internal error` when
151
- * only stateful revisions are served.
152
- *
153
- * @example
154
- * ```ts
155
- * import { McpHarness } from "@effected/mcp/testing";
156
- * import { Effect } from "effect";
157
- *
158
- * // `ServerLayer` is the server's layer, built without its own `Stdio`.
159
- * const program = Effect.gen(function* () {
160
- * const harness = yield* McpHarness.make(ServerLayer);
161
- * yield* harness.initialize;
162
- * const tools = yield* harness.listTools;
163
- * return tools.map((tool) => tool.name);
164
- * }).pipe(Effect.scoped);
165
- * ```
166
- *
167
- * @public
168
- */
169
- export declare class McpHarness {
170
- /** The revision this client speaks. */
171
- readonly protocol: McpProtocol.ProtocolAdapter;
172
- /** `initialize` then `notifications/initialized`; `server/discover` on a stateless revision. Call it first on a stateful revision. */
173
- readonly initialize: Effect.Effect<JsonRpcMessage, McpTestFailure>;
174
- /**
175
- * `initialize` asking for `protocolVersion` instead of the harness's own
176
- * revision, then `notifications/initialized` only when the response
177
- * carries no error. Returns the whole response: assert the negotiated
178
- * `result.protocolVersion`, or the JSON-RPC `error`.
179
- *
180
- * @remarks
181
- * It moves between stateful revisions only. A stateful server never
182
- * refuses a version: it counter-offers its latest stateful revision, so
183
- * asking for an unknown one, or for the stateless `2026-07-28`, comes back
184
- * as `2025-11-25`. On a harness made with a stateless revision the server
185
- * does not serve `initialize` at all, and the response is a JSON-RPC
186
- * `-32601` "Method not found" error, with no `notifications/initialized`
187
- * sent after it.
188
- */
189
- readonly initializeWith: (protocolVersion: string) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
190
- /** `server/discover`. */
191
- readonly discover: Effect.Effect<JsonRpcMessage, McpTestFailure>;
192
- /** Send a request and wait for its response. */
193
- readonly request: (method: string, params?: unknown) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
194
- /** Send a request now; wait for its response later. Fails with `NotInitialized`, sending nothing, on a stateful revision before `initialize` (`ping` excepted). */
195
- readonly startRequest: (method: string, params?: unknown) => Effect.Effect<{
196
- readonly id: number;
197
- readonly response: Effect.Effect<JsonRpcMessage, McpTestFailure>;
198
- }, McpTestFailure>;
199
- /** Send a notification. */
200
- readonly notify: (method: string, params?: unknown) => Effect.Effect<void>;
201
- /** `tools/call`, returning the whole response: a JSON-RPC error is data here. */
202
- readonly callTool: (name: string, args?: unknown) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
203
- /** `tools/list`'s tools; a JSON-RPC error fails with `ErrorResponse`. */
204
- readonly listTools: Effect.Effect<ReadonlyArray<ServedTool>, McpTestFailure>;
205
- /** `resources/list`'s resources; a JSON-RPC error fails with `ErrorResponse`. */
206
- readonly listResources: Effect.Effect<ReadonlyArray<ServedResource>, McpTestFailure>;
207
- /** `resources/read`, returning the whole response. */
208
- readonly readResource: (uri: string) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
209
- /** Write any value as one newline-framed line. Never gated; a raw `initialize` counts as sent. */
210
- readonly sendRaw: (message: unknown) => Effect.Effect<void>;
211
- /** The next server-initiated frame with this method, skipping and keeping others; fails with `ServerStopped` once the server stops. */
212
- readonly awaitOutboundMethod: (method: string) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
213
- /** Every frame written to the server's stdin so far, in order, as the JSON-parsed bytes written (a snapshot the caller's later mutations cannot reach): requests, notifications and `sendRaw` values. */
214
- readonly sentSoFar: Effect.Effect<ReadonlyArray<unknown>>;
215
- /** Everything written to stderr, plus every captured log line. */
216
- readonly stderrSoFar: Effect.Effect<string>;
217
- /**
218
- * Every captured `console.log`, `info` or `debug` call, its arguments joined with a space, each rendered close to
219
- * what the console would show: a string as itself, a value with its own string form as that form (an `Error` as
220
- * `Error: boom`, a number, a date), an array or a plain object as JSON (`{"message":"x"}`, not just `x`).
221
- *
222
- * @remarks
223
- * Rendering never throws inside the server's own call. A value whose string form throws (an object with no
224
- * prototype, a throwing `toString`) and has no JSON falls back to `ErrorText.describe` from `@effected/engine`.
225
- */
226
- readonly consoleLogSoFar: Effect.Effect<ReadonlyArray<string>>;
227
- /**
228
- * End stdin, as a client disconnecting does. The server drains first:
229
- * requests already in flight still answer, and the server stops once they
230
- * have, so a wait on a request that never completes keeps waiting. Use
231
- * {@link McpHarness.stop} to end the server regardless.
232
- */
233
- readonly close: Effect.Effect<void>;
234
- /**
235
- * Interrupt the server without draining, as a client killing the process
236
- * does: every pending response wait and `awaitOutboundMethod` fails with
237
- * `ServerStopped`.
238
- */
239
- readonly stop: Effect.Effect<void>;
240
- private constructor();
241
- /** Build `server` over queue-backed stdio and return a client for it; fails with the layer's own error if it cannot build. */
242
- static readonly make: <ROut, E, R>(server: Layer.Layer<ROut, E, R>, options?: McpHarnessOptions) => Effect.Effect<McpHarness, E, Scope.Scope | Exclude<R, Stdio.Stdio>>;
243
- }
244
- /**
245
- * Options for {@link McpProbe.initialize}.
246
- *
247
- * @public
248
- */
249
- interface McpProbeOptions {
250
- /** Defaults to `McpProtocol.v2025_11_25`; a stateless adapter probes with `server/discover`. */
251
- readonly protocol?: McpProtocol.ProtocolAdapter | undefined;
252
- }
253
- /**
254
- * What {@link McpProbe.initialize} observed.
255
- *
256
- * @public
257
- */
258
- interface McpProbeResult {
259
- /** The id-1 response. A refused handshake is still a response: assert `response.error === undefined`. */
260
- readonly response: JsonRpcMessage;
261
- /** Every raw stdout line, in order. */
262
- readonly stdout: ReadonlyArray<string>;
263
- /** Everything the child wrote to stderr; a clean boot leaves it empty. */
264
- readonly stderr: string;
265
- /** The child's exit code after stdin closed; a clean boot exits 0. */
266
- readonly exitCode: number;
267
- }
268
- /**
269
- * The smallest proof that an installed MCP bin boots: one initialize, a clean
270
- * close, and exit 0.
271
- *
272
- * @remarks
273
- * Stdin stays open until the id-1 response has arrived. Closing it right
274
- * after writing proves nothing against a server that stops at stdin EOF
275
- * without answering what is in flight: it replies nothing and exits 0, so a
276
- * slow boot reads as a pass with no response. The caller asserts `response.error === undefined`, `stderr` is
277
- * empty and `exitCode` is 0; this is the MCP half of a packed-install proof.
278
- * Checking stderr and the exit code alone passes a server that answers
279
- * the handshake with a JSON-RPC error, exits 0 and writes nothing.
280
- *
281
- * - Any stdout line that is not JSON-RPC fails with `NotJsonRpc`, naming the
282
- * line: a server that logs to stdout corrupts the wire, so the probe fails
283
- * rather than skipping the line.
284
- * - A child that exits before responding fails with `StreamEnded`, and the
285
- * message carries its exit code and stderr.
286
- * - A child that ignores stdin EOF never exits, and the probe waits for it.
287
- * Wrap the probe in `Effect.timeout`.
288
- *
289
- * @example
290
- * ```ts
291
- * import { McpProbe } from "@effected/mcp/testing";
292
- * import { Effect } from "effect";
293
- * import { ChildProcess } from "effect/process";
294
- *
295
- * const program = Effect.gen(function* () {
296
- * const probe = yield* McpProbe.initialize(ChildProcess.make(process.execPath, ["./bin/server.js"]));
297
- * // A clean boot: no JSON-RPC error, empty stderr, exit code 0.
298
- * return probe.response.error === undefined && probe.stderr === "" && probe.exitCode === 0;
299
- * });
300
- * // Requires a `ChildProcessSpawner` from the platform layer.
301
- * ```
302
- *
303
- * @public
304
- */
305
- export declare class McpProbe {
306
- private constructor();
307
- /**
308
- * Spawn `command`, send one `initialize` (or `server/discover` on a
309
- * stateless revision) as id 1, wait for its response, close stdin, and
310
- * collect stdout, stderr and the exit code.
311
- */
312
- static readonly initialize: (command: ChildProcess.Command, options?: McpProbeOptions) => Effect.Effect<McpProbeResult, McpTestFailure | PlatformError.PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
313
- }
314
- /**
315
- * Options for {@link McpProcess.stderrUntil}.
316
- *
317
- * @public
318
- */
319
- interface McpProcessStderrUntilOptions {
320
- /**
321
- * How long to wait for the predicate to hold before failing with
322
- * `TimedOut`. Real time: under `it.effect`'s `TestClock` it never fires,
323
- * so a test that waits on stderr runs under `it.live`. Keep it below the
324
- * test runner's own timeout, or the runner kills the test first.
325
- */
326
- readonly timeout: Duration.Input;
327
- }
328
- /**
329
- * A spawned MCP server bin a test writes to while it runs.
330
- *
331
- * @remarks
332
- * Build the command in the test file with `execPath` and an explicit `env`:
333
- * `ChildProcess.make(process.execPath, [bin], { env })`.
334
- *
335
- * - `nextLine` fails with `StreamEnded` when stdout ends, so a child that
336
- * exits early fails the test instead of hanging it.
337
- * - `send` writes one JSON-encoded line; `sendRaw` writes a string or bytes
338
- * exactly as given, for a malformed frame or one frame split across
339
- * writes, even mid-character.
340
- * - `readUntilResponse` reads past interleaved notifications, such as
341
- * `list_changed`, to the matching id and returns what it saw.
342
- * - `closeStdin` is `Queue.end`, never `Queue.shutdown`, so every frame
343
- * already sent is delivered before stdin closes.
344
- * - A request in flight when stdin closes still answers from an Effect
345
- * server, which drains before it exits; a server that does not drain
346
- * drops it, so a portable client reads the response first.
347
- *
348
- * @example
349
- * ```ts
350
- * import { McpProcess } from "@effected/mcp/testing";
351
- * import { Effect } from "effect";
352
- * import { ChildProcess } from "effect/process";
353
- *
354
- * const program = Effect.gen(function* () {
355
- * const child = yield* McpProcess.spawn(ChildProcess.make(process.execPath, ["./bin/server.js"]));
356
- * yield* child.handshake();
357
- * yield* child.send({ jsonrpc: "2.0", id: 2, method: "tools/list" });
358
- * const { response } = yield* child.readUntilResponse(2);
359
- * yield* child.closeStdin;
360
- * return response;
361
- * }).pipe(Effect.scoped);
362
- * // Requires a `ChildProcessSpawner` from the platform layer.
363
- * ```
364
- *
365
- * @public
366
- */
367
- export declare class McpProcess {
368
- /**
369
- * Write one JSON-encoded, newline-framed message to the child's stdin.
370
- *
371
- * @remarks
372
- * Never fails. A frame sent after `closeStdin` is dropped, and a write the
373
- * child can no longer receive fails the stdin pump instead; the next
374
- * `StreamEnded` message names that failure.
375
- */
376
- readonly send: (message: unknown) => Effect.Effect<void>;
377
- /**
378
- * Write `text` to the child's stdin exactly as given: a string as UTF-8,
379
- * bytes unchanged, with no JSON encoding and no newline added.
380
- *
381
- * @remarks
382
- * For frames `send` cannot produce: a line that is not JSON, a blank line,
383
- * or one frame split across several writes, including mid-character by
384
- * passing bytes. Include the `\n` yourself.
385
- * Never fails, on the same terms as `send`.
386
- */
387
- readonly sendRaw: (text: string | Uint8Array) => Effect.Effect<void>;
388
- /** The next non-empty stdout line; fails with `StreamEnded` once stdout ends. */
389
- readonly nextLine: Effect.Effect<string, McpTestFailure>;
390
- /** Read JSON-RPC lines up to and including the response with this id. */
391
- readonly readUntilResponse: (id: string | number) => Effect.Effect<{
392
- readonly response: JsonRpcMessage;
393
- readonly seen: ReadonlyArray<JsonRpcMessage>;
394
- }, McpTestFailure>;
395
- /** `initialize` (id 1) then `notifications/initialized`, or `server/discover` (id 1) on a stateless revision. Use ids of 2 or more for your own requests. */
396
- readonly handshake: (protocol?: McpProtocol.ProtocolAdapter) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
397
- /** End stdin after every frame already sent. */
398
- readonly closeStdin: Effect.Effect<void>;
399
- /** Wait for the child to exit. */
400
- readonly exitCode: Effect.Effect<number, PlatformError.PlatformError>;
401
- /** Everything written to stderr so far. */
402
- readonly stderrSoFar: Effect.Effect<string>;
403
- /**
404
- * Wait until everything written to stderr so far satisfies `predicate`,
405
- * and return that text.
406
- *
407
- * @remarks
408
- * Event-driven: the predicate is checked against the current text at once,
409
- * then again on every chunk the child writes, never on a polling timer.
410
- * Fails with `StreamEnded` when stderr ends (the child exited) without the
411
- * predicate holding, and with `TimedOut` once `options.timeout` passes;
412
- * both messages carry the stderr seen so far. Reach for it whenever a
413
- * report lands on a later tick than the responses a test reads, such as
414
- * `McpGuard`'s `injectCrash: { at: "connected" }` report, instead of
415
- * reading `stderrSoFar` once. `options.timeout` is real time: run the test
416
- * under `it.live`.
417
- */
418
- readonly stderrUntil: (predicate: (stderr: string) => boolean, options: McpProcessStderrUntilOptions) => Effect.Effect<string, McpTestFailure>;
419
- /** Everything written to stderr, once stderr has ended. Waits for the child to exit. */
420
- readonly stderrFinal: Effect.Effect<string>;
421
- private constructor();
422
- /** Spawn `command` for the life of the current scope. */
423
- static readonly spawn: (command: ChildProcess.Command) => Effect.Effect<McpProcess, PlatformError.PlatformError, ChildProcessSpawner.ChildProcessSpawner | Scope.Scope>;
424
- }
425
- /**
426
- * The policy {@link McpToolAudit.check} enforces.
427
- *
428
- * @public
429
- */
430
- interface McpToolAuditPolicy {
431
- /** `"closed"`: every object node rejects unknown keys. `"open"`: none with properties does. `"any"`: not checked. */
432
- readonly input: "open" | "closed" | "any";
433
- /** Every tool must carry a non-empty `title`, top-level or in `annotations.title`. */
434
- readonly requireTitle?: boolean | undefined;
435
- /**
436
- * Every tool must serve an `outputSchema`. The stateful revisions drop a
437
- * non-object one, so check the revision you serve; the violation names
438
- * the likely cause, a union success schema, and `ToolOutputSchema.objectRooted`.
439
- */
440
- readonly requireOutputSchema?: boolean | undefined;
441
- /**
442
- * A served `outputSchema` must be rooted at `type: "object"`. Defaults to
443
- * `true`. Only the stateless revision serves a non-object root, so
444
- * only there does this fire; a union root (`anyOf` or `oneOf`) names
445
- * `ToolOutputSchema.objectRooted` as the fix for a union whose members are
446
- * all objects (a union with a primitive member needs an object envelope
447
- * instead). On a stateful revision the
448
- * same schema is dropped, and `requireOutputSchema` reports it instead.
449
- */
450
- readonly objectRootedOutput?: boolean | undefined;
451
- /** The longest `description` allowed, in UTF-16 code units; a missing description counts as 0. */
452
- readonly maxDescription?: number | undefined;
453
- /** All four MCP annotation hints must be present as booleans. */
454
- readonly requireHints?: boolean | undefined;
455
- }
456
- /**
457
- * A pure sweep over a served `tools/list` that returns every policy
458
- * violation, as `"<tool>: <what>"` strings.
459
- *
460
- * @remarks
461
- * Run it against what a real server serves (`McpHarness.listTools`), not
462
- * against your own schemas: the served document is what a client sees, and
463
- * it differs by protocol revision. The stateless `2026-07-28` adapter passes a
464
- * non-object output through, while the stateful adapters drop it — which is
465
- * why `objectRootedOutput` defaults to `true`.
466
- *
467
- * `"closed"` is only as sound as the walk. It follows `properties`,
468
- * `items`, a schema-valued `additionalProperties`, `prefixItems`, `anyOf`,
469
- * `oneOf` and `$defs`, and merges an `allOf` member's `properties` and
470
- * `additionalProperties: false` onto its node. It does not visit
471
- * `patternProperties` values, an `allOf` member's `items` or
472
- * `additionalProperties` schema, or an `allOf` nested inside another; and
473
- * a key declared in two `allOf` members is last-write-wins. A hand-authored
474
- * or `Tool.dynamic` schema can therefore pass `"closed"` with an open node
475
- * the walk never reached. Core-emitted strict schemas close every node, so
476
- * a strict `Tool.make` tool is reported faithfully.
477
- *
478
- * @public
479
- */
480
- export declare class McpToolAudit {
481
- private constructor();
482
- /**
483
- * Every violation of `policy` across `tools`, as `"<tool>: <what>"`, in
484
- * tool order. Empty means the sweep passed. A duplicate tool name is
485
- * reported under every policy, `input: "any"` included.
486
- */
487
- static readonly check: (tools: ReadonlyArray<ServedTool>, policy: McpToolAuditPolicy) => ReadonlyArray<string>;
488
- }
489
- export type { JsonRpcMessage, McpHarnessOptions, McpProbeOptions, McpProbeResult, McpProcessStderrUntilOptions, McpToolAuditPolicy, ServedResource, ServedTool };
490
- //# sourceMappingURL=testing.d.ts.map
package/testing.js DELETED
@@ -1,7 +0,0 @@
1
- import { McpTestFailure } from "./McpTestFailure.js";
2
- import { McpHarness } from "./McpHarness.js";
3
- import { McpProcess } from "./McpProcess.js";
4
- import { McpProbe } from "./McpProbe.js";
5
- import { McpToolAudit } from "./McpToolAudit.js";
6
-
7
- export { McpHarness, McpProbe, McpProcess, McpTestFailure, McpToolAudit };