@effected/mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/McpGuard.js +121 -0
- package/McpHarness.js +40 -4
- package/McpStdio.js +10 -3
- package/McpTestFailure.js +3 -2
- package/McpToolAudit.js +5 -2
- package/McpToolkit.js +129 -10
- package/README.md +126 -6
- package/ToolFailure.js +7 -1
- package/ToolOutputSchema.js +66 -0
- package/ToolRefusal.js +42 -0
- package/guard.d.ts +157 -0
- package/guard.js +3 -0
- package/index.d.ts +242 -6
- package/index.js +3 -1
- package/internal/guardLaunch.js +14 -0
- package/package.json +6 -1
- package/testing.d.ts +39 -6
package/testing.d.ts
CHANGED
|
@@ -25,8 +25,9 @@ declare const McpTestFailure_base: Schema.Class<McpTestFailure, Schema.TaggedStr
|
|
|
25
25
|
* because stdin closed while the request was in flight.
|
|
26
26
|
* - `NotInitialized` (`McpHarness`): a request other than `initialize` was
|
|
27
27
|
* made on a stateful revision before `initialize` was sent. The request
|
|
28
|
-
* is never written; the server would only have refused it
|
|
29
|
-
*
|
|
28
|
+
* is never written; the server would only have refused it opaquely:
|
|
29
|
+
* `-32602 Invalid request metadata` when a stateless adapter is listed
|
|
30
|
+
* first, `-32603 Internal error` when only stateful revisions are served.
|
|
30
31
|
* - `ErrorResponse` (`McpHarness.listTools`): the server answered with a
|
|
31
32
|
* JSON-RPC error where a result was required. Every other request method
|
|
32
33
|
* returns the whole response, error included, as data.
|
|
@@ -140,8 +141,10 @@ interface McpHarnessOptions {
|
|
|
140
141
|
* the wire. Assert it empty.
|
|
141
142
|
* - On a stateful revision (the default `2025-11-25`), send `initialize`
|
|
142
143
|
* first. Every other request before it fails with `NotInitialized` and
|
|
143
|
-
* is never written: the server would only answer an
|
|
144
|
-
*
|
|
144
|
+
* is never written, `ping` included: the server would only answer an
|
|
145
|
+
* opaque refusal, `-32602 Invalid request metadata` when a stateless
|
|
146
|
+
* adapter is listed first (as in `McpStdio.protocols`), or
|
|
147
|
+
* `-32603 Internal error` when only stateful revisions are served.
|
|
145
148
|
*
|
|
146
149
|
* @public
|
|
147
150
|
*/
|
|
@@ -150,6 +153,22 @@ export declare class McpHarness {
|
|
|
150
153
|
readonly protocol: McpProtocol.ProtocolAdapter;
|
|
151
154
|
/** `initialize` then `notifications/initialized`; `server/discover` on a stateless revision. Call it first on a stateful revision. */
|
|
152
155
|
readonly initialize: Effect.Effect<JsonRpcMessage, McpTestFailure>;
|
|
156
|
+
/**
|
|
157
|
+
* `initialize` asking for `protocolVersion` instead of the harness's own
|
|
158
|
+
* revision, then `notifications/initialized` only when the response
|
|
159
|
+
* carries no error. Returns the whole response: assert the negotiated
|
|
160
|
+
* `result.protocolVersion`, or the JSON-RPC `error`.
|
|
161
|
+
*
|
|
162
|
+
* @remarks
|
|
163
|
+
* It moves between stateful revisions only. A stateful server never
|
|
164
|
+
* refuses a version: it counter-offers its latest stateful revision, so
|
|
165
|
+
* asking for an unknown one, or for the stateless `2026-07-28`, comes back
|
|
166
|
+
* as `2025-11-25`. On a harness made with a stateless revision the server
|
|
167
|
+
* does not serve `initialize` at all, and the response is a JSON-RPC
|
|
168
|
+
* `-32601` "Method not found" error, with no `notifications/initialized`
|
|
169
|
+
* sent after it.
|
|
170
|
+
*/
|
|
171
|
+
readonly initializeWith: (protocolVersion: string) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
|
|
153
172
|
/** `server/discover`. */
|
|
154
173
|
readonly discover: Effect.Effect<JsonRpcMessage, McpTestFailure>;
|
|
155
174
|
/** Send a request and wait for its response. */
|
|
@@ -173,6 +192,8 @@ export declare class McpHarness {
|
|
|
173
192
|
readonly sendRaw: (message: unknown) => Effect.Effect<void>;
|
|
174
193
|
/** The next server-initiated frame with this method, skipping and keeping others; fails with `ServerStopped` once the server stops. */
|
|
175
194
|
readonly awaitOutboundMethod: (method: string) => Effect.Effect<JsonRpcMessage, McpTestFailure>;
|
|
195
|
+
/** 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. */
|
|
196
|
+
readonly sentSoFar: Effect.Effect<ReadonlyArray<unknown>>;
|
|
176
197
|
/** Everything written to stderr, plus every captured log line. */
|
|
177
198
|
readonly stderrSoFar: Effect.Effect<string>;
|
|
178
199
|
/** Every captured `console.log`, `info` or `debug` call. */
|
|
@@ -318,9 +339,21 @@ interface McpToolAuditPolicy {
|
|
|
318
339
|
readonly input: "open" | "closed" | "any";
|
|
319
340
|
/** Every tool must carry a non-empty `title`, top-level or in `annotations.title`. */
|
|
320
341
|
readonly requireTitle?: boolean | undefined;
|
|
321
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* Every tool must serve an `outputSchema`. The stateful revisions drop a
|
|
344
|
+
* non-object one, so check the revision you serve; the violation names
|
|
345
|
+
* the likely cause, a union success schema, and `ToolOutputSchema.objectRooted`.
|
|
346
|
+
*/
|
|
322
347
|
readonly requireOutputSchema?: boolean | undefined;
|
|
323
|
-
/**
|
|
348
|
+
/**
|
|
349
|
+
* A served `outputSchema` must be rooted at `type: "object"`. Defaults to
|
|
350
|
+
* `true` (D10). Only the stateless revision serves a non-object root, so
|
|
351
|
+
* only there does this fire; a union root (`anyOf` or `oneOf`) names
|
|
352
|
+
* `ToolOutputSchema.objectRooted` as the fix for a union whose members are
|
|
353
|
+
* all objects (a union with a primitive member needs an object envelope
|
|
354
|
+
* instead). On a stateful revision the
|
|
355
|
+
* same schema is dropped, and `requireOutputSchema` reports it instead.
|
|
356
|
+
*/
|
|
324
357
|
readonly objectRootedOutput?: boolean | undefined;
|
|
325
358
|
/** The longest `description` allowed, in UTF-16 code units; a missing description counts as 0. */
|
|
326
359
|
readonly maxDescription?: number | undefined;
|