@orkestrel/mcp 0.0.19 → 0.0.21

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.
@@ -56,11 +56,11 @@ var MCP_HEADER_MISMATCH = -32020;
56
56
  *
57
57
  * @remarks
58
58
  * The GENERIC code for the whole condition, not one capability's code. This server answers
59
- * it in two places — a `tools/call` that needs `elicitation`, and a `tasks/*` request whose
60
- * client never declared `io.modelcontextprotocol/tasks` — and the two are told apart by
59
+ * it in more than one place — a `tools/call` that needs `elicitation`, and a `tasks/*` request
60
+ * whose client never declared `io.modelcontextprotocol/tasks` — and they are told apart by
61
61
  * `error.data.requiredCapabilities` alone (`{ elicitation: {} }` against
62
- * `{ extensions: { 'io.modelcontextprotocol/tasks': {} } }`). They are two instances of one
63
- * condition, so a second numeral would describe the same fact twice. The Tasks extension's
62
+ * `{ extensions: { 'io.modelcontextprotocol/tasks': {} } }`). They are instances of the same
63
+ * condition, so a separate numeral would describe the same fact twice. The Tasks extension's
64
64
  * own draft prose still shows `-32003` in examples; the dated core schema fixes this code,
65
65
  * and the dated schema is what a peer implements against.
66
66
  */
@@ -147,20 +147,18 @@ var DEFAULT_MCP_CLIENT_VERSION = "1.0.0";
147
147
  * is unset — a request the remote server does not answer within it rejects.
148
148
  */
149
149
  var DEFAULT_MCP_REQUEST_TIMEOUT = 3e4;
150
- /** The maximum discovery-probe deadline used when a client deadline is configured. */
151
- var DEFAULT_MCP_PROBE_TIMEOUT = 50;
152
150
  //#endregion
153
151
  //#region src/core/errors.ts
154
152
  /**
155
- * A remote Model Context Protocol JSON-RPC error, preserving its machine-readable
156
- * numeric code and optional structured context.
153
+ * A Model Context Protocol error preserving its machine-readable numeric code and
154
+ * optional structured context.
157
155
  *
158
156
  * @remarks
159
- * {@link MCPClient} throws this error only for a remote JSON-RPC `error` response.
160
- * Local lifecycle and transport conditions such as disconnects and request timeouts
161
- * remain plain `Error`s. `context` carries the response's optional `error.data`
162
- * unchanged and is `undefined` when the peer omitted it. This includes the modern
163
- * reserved paths: `-32020` carries no context, `-32021` may carry
157
+ * {@link MCPClient} throws this error for a remote JSON-RPC `error` response and for a
158
+ * locally detected protocol incompatibility. Local lifecycle and transport conditions such
159
+ * as disconnects and request timeouts remain plain `Error`s. For a remote response, `context`
160
+ * carries the optional `error.data` unchanged and is `undefined` when the peer omitted it.
161
+ * This includes the modern reserved paths: `-32020` carries no context, `-32021` may carry
164
162
  * `requiredCapabilities`, and `-32022` carries the peer's `supported` revisions and
165
163
  * `requested` revision for negotiation recovery.
166
164
  *
@@ -179,7 +177,7 @@ var MCPError = class extends Error {
179
177
  code;
180
178
  context;
181
179
  /**
182
- * Create a remote MCP protocol error.
180
+ * Creates an MCP protocol error.
183
181
  *
184
182
  * @param message - The human-readable JSON-RPC error message
185
183
  * @param code - The machine-readable numeric JSON-RPC error code
@@ -192,7 +190,7 @@ var MCPError = class extends Error {
192
190
  }
193
191
  };
194
192
  /**
195
- * Determine whether an unknown value is an {@link MCPError}.
193
+ * Determines whether an unknown value is an {@link MCPError}.
196
194
  *
197
195
  * @param value - The unknown value to inspect
198
196
  * @returns `true` only when the value is an `MCPError`
@@ -213,7 +211,7 @@ function isMCPError(value) {
213
211
  //#endregion
214
212
  //#region src/core/inferers.ts
215
213
  /**
216
- * Infer the wire era for an MCP protocol revision.
214
+ * Infers the wire era for an MCP protocol revision.
217
215
  *
218
216
  * @param version - The protocol revision to classify
219
217
  * @returns `'modern'` for `2026-07-28`, `'legacy'` for either supported legacy
@@ -228,7 +226,7 @@ function inferEra(version) {
228
226
  }
229
227
  }
230
228
  /**
231
- * Infer the newest supported protocol revision present in a peer's offer.
229
+ * Infers the newest supported protocol revision present in a peer's offer.
232
230
  *
233
231
  * @param offered - The protocol revisions offered by the peer
234
232
  * @returns The newest locally supported offered revision, or `undefined`
@@ -237,12 +235,12 @@ function inferVersion(offered) {
237
235
  for (const version of SUPPORTED_PROTOCOL_VERSIONS) if (offered.includes(version)) return version;
238
236
  }
239
237
  /**
240
- * Infer the protocol version an outbound message announces itself with — the ONE
238
+ * Infers the protocol version an outbound message announces itself with — the ONE
241
239
  * projection every HTTP client transport stamps `mcp-protocol-version` from.
242
240
  *
243
241
  * @remarks
244
242
  * This is deliberately the SAME read the server's own expectation performs
245
- * ({@link import('@src/server').inferHeaderIssue}): a modern request's reserved
243
+ * ({@link import('@orkestrel/mcp/server').inferHeaderIssue}): a modern request's reserved
246
244
  * `_meta` version, accepted whenever it is a string. It is NOT
247
245
  * {@link import('./parsers.js').parseRequestContext}, and the difference is the whole
248
246
  * point. That parser answers a different question — is the modern metadata WELL FORMED —
@@ -255,7 +253,7 @@ function inferVersion(offered) {
255
253
  * `initialize` handshake the transport captured, not from the message.
256
254
  *
257
255
  * Header NAMES stay with the transports that own the wire (see `constants.ts`); core owns
258
- * the value this projection derives, which is the part the two faces disagreed about.
256
+ * the value this projection derives, which is the part the browser and Node faces disagreed about.
259
257
  *
260
258
  * @param message - The outbound message about to be written
261
259
  * @returns The version to announce, or `undefined` when the message announces none
@@ -273,7 +271,7 @@ function inferRequestVersion(message) {
273
271
  //#endregion
274
272
  //#region src/core/cloners.ts
275
273
  /**
276
- * Snapshot one bounded exact JSON value together with its canonical wire serialization.
274
+ * Snapshots one bounded exact JSON value together with its canonical wire serialization.
277
275
  *
278
276
  * The returned value is an owned, deeply frozen graph reconstructed from the canonical text;
279
277
  * the frozen tuple shares no mutable structure with the input. Invalid exact-JSON shapes,
@@ -303,10 +301,10 @@ function snapshotJSON(value, limits) {
303
301
  return Object.freeze(snapshot);
304
302
  }
305
303
  /**
306
- * Snapshot one exact Tool result and the canonical wire text of a defined success value.
304
+ * Snapshots one exact Tool result and the canonical wire text of a defined success value.
307
305
  *
308
- * A success must have exactly four own enumerable data properties: `id`, `name`, `success: true`,
309
- * and `value`. A failure must instead have exactly `id`, `name`, `success: false`, and a string
306
+ * A success must have exactly the own enumerable data properties `id`, `name`,
307
+ * `success: true`, and `value`. A failure must instead have exactly `id`, `name`, `success: false`, and a string
310
308
  * `error`. The returned result and tuple are frozen. Only a defined success value crosses the
311
309
  * bounded JSON ownership seam; it becomes an owned deeply frozen value and receives canonical
312
310
  * text. Value-less successes and failures pair with `undefined` text. Non-records, symbol keys,
@@ -381,11 +379,11 @@ function snapshotToolResult(value, limits) {
381
379
  //#endregion
382
380
  //#region src/core/parsers.ts
383
381
  /**
384
- * Narrow an already-parsed value to a {@link JSONRPCMessage}, or `undefined` when
382
+ * Narrows an already-parsed value to a {@link JSONRPCMessage}, or `undefined` when
385
383
  * it is not one.
386
384
  *
387
385
  * @remarks
388
- * Total (§14) — a non-message returns `undefined`, never throws. The input must
386
+ * Total — a non-message returns `undefined`, never throws. The input must
389
387
  * ALREADY be `JSON.parse`d: the raw-string parse (which can throw on malformed
390
388
  * JSON) happens in `MCPServer.handle` inside a try/catch that maps a parse failure
391
389
  * to a `-32700` response.
@@ -399,7 +397,7 @@ function snapshotToolResult(value, limits) {
399
397
  * result. Identity is not preserved and is not promised.
400
398
  *
401
399
  * The parser's sound partner is the COMPOSITE `isJSONRPCMessage(value) &&
402
- * isBoundedJSON(value, limits)`, and against it both halves of the §15 soundness law
400
+ * isBoundedJSON(value, limits)`, and against it both halves of the soundness law
403
401
  * hold by construction:
404
402
  *
405
403
  * - Every non-`undefined` result satisfies {@link isJSONRPCMessage}, because the guard
@@ -435,7 +433,7 @@ function parseJSONRPCMessage(value, limits = {
435
433
  return snapshot !== void 0 && isJSONRPCMessage(snapshot[0]) ? snapshot[0] : void 0;
436
434
  }
437
435
  /**
438
- * Parse the reserved modern request metadata into an {@link MCPRequestContext}.
436
+ * Parses the reserved modern request metadata into an {@link MCPRequestContext}.
439
437
  *
440
438
  * @remarks
441
439
  * This is the validity step after {@link isModernRequest}: a defined result can
@@ -485,7 +483,7 @@ function parseRequestContext(value, limits = {
485
483
  }
486
484
  }
487
485
  /**
488
- * Parse the opened value carried by an opaque `requestState` continuation.
486
+ * Parses the opened value carried by an opaque `requestState` continuation.
489
487
  *
490
488
  * @remarks
491
489
  * This parser does not open the opaque continuation carrier; the configured
@@ -543,7 +541,69 @@ function parseMCPInputState(value) {
543
541
  //#endregion
544
542
  //#region src/core/helpers.ts
545
543
  /**
546
- * Deterministically serialize one exact JSON value within explicit bounds.
544
+ * Determines whether a client capability record declares form-mode elicitation.
545
+ *
546
+ * @remarks
547
+ * The protocol's empty `elicitation` object is the implicit form-only declaration.
548
+ * A non-empty declaration must carry a record-valued `form` member; URL-only support
549
+ * does not authorize a form request. Total over hostile input.
550
+ *
551
+ * @param value - The client capability record to inspect
552
+ * @returns `true` when form-mode elicitation is declared
553
+ *
554
+ * @example
555
+ * ```ts
556
+ * isFormElicitationSupported({ elicitation: {} }) // true — implicit form mode
557
+ * isFormElicitationSupported({ elicitation: { url: {} } }) // false
558
+ * ```
559
+ */
560
+ function isFormElicitationSupported(value) {
561
+ const owned = attempt(() => cloneJSONRecord(value));
562
+ if (!owned.success) return false;
563
+ try {
564
+ const elicitation = owned.value["elicitation"];
565
+ if (!isRecord(elicitation)) return false;
566
+ if (isRecord(elicitation["form"])) return true;
567
+ return Object.keys(elicitation).length === 0;
568
+ } catch {
569
+ return false;
570
+ }
571
+ }
572
+ /**
573
+ * Determines whether a client capability record declares the draft Tasks extension.
574
+ *
575
+ * @remarks
576
+ * The declaration lives at `extensions['io.modelcontextprotocol/tasks']` and its value is
577
+ * an empty object, so this is a PRESENCE check: the extension defines no options, and a
578
+ * server that read one would be reading a field no client can meaningfully set. The value
579
+ * must still be a record, because that is the shape the capability record declares — a
580
+ * `true` or a string there is a client speaking a different protocol, not a shorthand.
581
+ *
582
+ * A client declares this PER REQUEST. Nothing here consults a session, because the modern
583
+ * revision is stateless and a capability declared once at connect time says nothing about
584
+ * the request in hand. Total over hostile input.
585
+ *
586
+ * @param value - The client capability record to inspect
587
+ * @returns `true` when the tasks extension is declared
588
+ *
589
+ * @example
590
+ * ```ts
591
+ * isTaskSupported({ extensions: { 'io.modelcontextprotocol/tasks': {} } }) // true
592
+ * isTaskSupported({ extensions: {} }) // false — the key is the declaration
593
+ * ```
594
+ */
595
+ function isTaskSupported(value) {
596
+ const owned = attempt(() => cloneJSONRecord(value));
597
+ if (!owned.success) return false;
598
+ try {
599
+ const extensions = owned.value["extensions"];
600
+ return isRecord(extensions) && isRecord(extensions["io.modelcontextprotocol/tasks"]);
601
+ } catch {
602
+ return false;
603
+ }
604
+ }
605
+ /**
606
+ * Serializes one exact JSON value deterministically within explicit bounds.
547
607
  *
548
608
  * @param value - The unknown value to validate and serialize
549
609
  * @param limits - Serialized byte, key, and depth limits
@@ -762,7 +822,7 @@ function serializeJSON(value, limits) {
762
822
  return serialized.success ? serialized.value : void 0;
763
823
  }
764
824
  /**
765
- * Compute a lowercase host-neutral SHA-256 digest of one bounded canonical JSON value.
825
+ * Computes a lowercase host-neutral SHA-256 digest of one bounded canonical JSON value.
766
826
  *
767
827
  * @param value - The unknown value to validate and digest
768
828
  * @param limits - Serialized byte, key, and depth limits
@@ -775,7 +835,7 @@ async function digestJSON(value, limits) {
775
835
  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
776
836
  }
777
837
  /**
778
- * Build one official progress notification for the original request stream.
838
+ * Builds one official progress notification for the original request stream.
779
839
  *
780
840
  * @param token - The request's original opaque progress token
781
841
  * @param progress - The finite progress payload
@@ -794,7 +854,7 @@ function buildProgressNotification(token, progress) {
794
854
  };
795
855
  }
796
856
  /**
797
- * Build one official cancellation notification for a request already sent.
857
+ * Builds one official cancellation notification for a request already sent.
798
858
  *
799
859
  * @remarks
800
860
  * `requestId` and `reason` are WIRE SPELLINGS carried verbatim from the dated schema's
@@ -832,15 +892,15 @@ function buildCancelledNotification(id, reason) {
832
892
  };
833
893
  }
834
894
  /**
835
- * Determine whether one method may answer with a given modern `resultType`.
895
+ * Determines whether one method may answer with a given modern `resultType`.
836
896
  *
837
897
  * @remarks
838
- * The dated protocol lets a `tools/call` answer three ways — it COMPLETED, it became a
898
+ * The dated protocol lets a `tools/call` answer in more than one way — it COMPLETED, it became a
839
899
  * durable task, or it needs another round trip — while every other method this client
840
900
  * issues has exactly one legal answer. So the arm a peer chose is only meaningful beside
841
901
  * the method it answers, and this is the one place that pairing is decided.
842
902
  *
843
- * The rule is deliberately a WHITELIST: an unrecognized `resultType` is refused for every
903
+ * The rule is deliberately closed: an unrecognized `resultType` is refused for every
844
904
  * method, including `tools/call`. A client that carried an arm it cannot name would hand
845
905
  * its caller a value whose meaning it invented.
846
906
  *
@@ -861,7 +921,7 @@ function matchesResultType(method, resultType) {
861
921
  return resultType === "task" || resultType === "input_required";
862
922
  }
863
923
  /**
864
- * Concatenate an MCP tool-call result's text content blocks into one string.
924
+ * Concatenates an MCP tool-call result's text content blocks into one string.
865
925
  *
866
926
  * @remarks
867
927
  * The inverse of a server splitting a value into text block(s), and TOTAL: a non-record
@@ -885,12 +945,12 @@ function extractContentText(result) {
885
945
  return parts.join("\n");
886
946
  }
887
947
  /**
888
- * Narrow one `tools/call` answer to the arm the peer chose.
948
+ * Narrows one `tools/call` answer to the arm the peer chose.
889
949
  *
890
950
  * @remarks
891
- * The three arms {@link matchesResultType} admits are the whole space this sees, because a
951
+ * The arms {@link matchesResultType} admits are the whole space this sees, because a
892
952
  * `resultType` the client cannot name is refused at correlation. What is left is validating
893
- * the two arms the protocol gives a shape to, and deriving the tool's value from the one it
953
+ * the arms the protocol gives a shape to, and deriving the tool's value from the one it
894
954
  * does not:
895
955
  *
896
956
  * - A peer's `structuredContent` is PREFERRED over the content blocks, because it is the
@@ -938,7 +998,7 @@ function buildCallOutcome(name, result) {
938
998
  });
939
999
  }
940
1000
  /**
941
- * Build the canonical Tool call for one validated MCP `tools/call` request.
1001
+ * Builds the canonical Tool call for one validated MCP `tools/call` request.
942
1002
  *
943
1003
  * @param request - The original MCP request
944
1004
  * @param caller - Optional consumer-asserted caller context
@@ -957,7 +1017,7 @@ function buildToolCall(request, caller, args) {
957
1017
  };
958
1018
  }
959
1019
  /**
960
- * Build a JSON-RPC success {@link JSONRPCResultResponse} — the `id` echoed, the
1020
+ * Builds a JSON-RPC success {@link JSONRPCResultResponse} — the `id` echoed, the
961
1021
  * method's value as `result`.
962
1022
  *
963
1023
  * @remarks
@@ -976,7 +1036,7 @@ function buildJSONRPCResult(id, result) {
976
1036
  };
977
1037
  }
978
1038
  /**
979
- * Build a JSON-RPC error {@link JSONRPCErrorResponse} — the `id` echoed, the failure
1039
+ * Builds a JSON-RPC error {@link JSONRPCErrorResponse} — the `id` echoed, the failure
980
1040
  * as an `error` object.
981
1041
  *
982
1042
  * @remarks
@@ -1005,7 +1065,7 @@ function buildJSONRPCError(id, code, message, data) {
1005
1065
  };
1006
1066
  }
1007
1067
  /**
1008
- * Resolve the caller-facing dispatch options into the options a dispatched method
1068
+ * Resolves the caller-facing dispatch options into the options a dispatched method
1009
1069
  * receives.
1010
1070
  *
1011
1071
  * @remarks
@@ -1039,7 +1099,7 @@ function buildMethodOptions(options, lifetime) {
1039
1099
  };
1040
1100
  }
1041
1101
  /**
1042
- * Map a {@link ToolManagerInterface}'s definitions to MCP `tools/list` descriptors
1102
+ * Maps a {@link ToolManagerInterface}'s definitions to MCP `tools/list` descriptors
1043
1103
  * — renaming `parameters` to the wire's `inputSchema`.
1044
1104
  *
1045
1105
  * @remarks
@@ -1082,7 +1142,7 @@ function buildModernResult(result, identity, ttl, scope) {
1082
1142
  };
1083
1143
  }
1084
1144
  /**
1085
- * Intersect a requested subscription filter with the notification families a server supports.
1145
+ * Intersects a requested subscription filter with the notification families a server supports.
1086
1146
  *
1087
1147
  * @param requested - The notification families requested by the client
1088
1148
  * @param supported - The notification families the server can actually produce
@@ -1102,7 +1162,7 @@ function buildSubscriptionFilter(requested, supported) {
1102
1162
  };
1103
1163
  }
1104
1164
  /**
1105
- * Determine whether a produced notification belongs to an honoured subscription filter.
1165
+ * Determines whether a produced notification belongs to an honoured subscription filter.
1106
1166
  *
1107
1167
  * @param notification - The server notification offered by the configured producer
1108
1168
  * @param filter - The filter acknowledged to the client
@@ -1117,7 +1177,7 @@ function matchesSubscriptionNotification(notification, filter) {
1117
1177
  return typeof uri === "string" && filter.resourceSubscriptions?.includes(uri) === true;
1118
1178
  }
1119
1179
  /**
1120
- * Stamp a subscription notification with the request id reserved for its held-open stream.
1180
+ * Stamps a subscription notification with the request id reserved for its held-open stream.
1121
1181
  *
1122
1182
  * @param notification - The notification to copy and stamp
1123
1183
  * @param id - The `subscriptions/listen` request id
@@ -1138,7 +1198,7 @@ function stampSubscriptionNotification(notification, id) {
1138
1198
  };
1139
1199
  }
1140
1200
  /**
1141
- * Build the first notification carrying a subscription id for a listen request.
1201
+ * Builds the first notification carrying a subscription id for a listen request.
1142
1202
  *
1143
1203
  * @param notifications - The exact notification filter the server will honour
1144
1204
  * @param id - The `subscriptions/listen` request id
@@ -1152,7 +1212,7 @@ function buildSubscriptionAcknowledgement(notifications, id) {
1152
1212
  }, id);
1153
1213
  }
1154
1214
  /**
1155
- * Build the terminating response for a subscription source that closes gracefully.
1215
+ * Builds the terminating response for a subscription source that closes gracefully.
1156
1216
  *
1157
1217
  * @param id - The `subscriptions/listen` request id
1158
1218
  * @param identity - The server identity included by the modern result stamping site
@@ -1162,7 +1222,7 @@ function buildSubscriptionResult(id, identity) {
1162
1222
  return buildJSONRPCResult(id, buildModernResult({ _meta: { [MCP_META_SUBSCRIPTION]: id } }, identity));
1163
1223
  }
1164
1224
  /**
1165
- * Build the mandatory modern `server/discover` result.
1225
+ * Builds the mandatory modern `server/discover` result.
1166
1226
  *
1167
1227
  * @remarks
1168
1228
  * `capabilities.resources` and `capabilities.prompts` appear only for servers with their
@@ -1194,7 +1254,7 @@ function buildDiscoverResult(options) {
1194
1254
  }, options.identity, options.cache?.ttl ?? 6e4, options.cache?.scope);
1195
1255
  }
1196
1256
  /**
1197
- * Build the MCP `initialize` result — the negotiated protocol version, the
1257
+ * Builds the MCP `initialize` result — the negotiated protocol version, the
1198
1258
  * advertised capabilities, and the server identity.
1199
1259
  *
1200
1260
  * @remarks
@@ -1221,7 +1281,7 @@ function buildInitializeResult(name, version, requested) {
1221
1281
  };
1222
1282
  }
1223
1283
  /**
1224
- * Decode one raw inbound message within an explicit bound — the decode a binder performs
1284
+ * Decodes one raw inbound message within an explicit bound — the decode a binder performs
1225
1285
  * before it hands the string on.
1226
1286
  *
1227
1287
  * @remarks
@@ -1229,14 +1289,14 @@ function buildInitializeResult(name, version, requested) {
1229
1289
  * `JSON.parse`d at all: a decoder that parses before it measures has already spent the work
1230
1290
  * the bound exists to refuse. A message over the bound, malformed JSON, and a well-formed
1231
1291
  * value that is not a JSON-RPC message are one answer — `undefined` — because a binder does
1232
- * exactly the same thing with all three: nothing, and let
1292
+ * exactly the same thing with each of them: nothing, and let
1233
1293
  * {@link import('./types.js').MCPServerInterface.handle} produce the wire refusal from the
1234
1294
  * same bound.
1235
1295
  *
1236
- * Total (§14) — never throws, whatever the input.
1296
+ * Total — never throws, whatever the input.
1237
1297
  *
1238
1298
  * @param message - The raw inbound JSON-RPC message string
1239
- * @param limits - The byte and depth bounds to decode within (the server's own, via `limit`)
1299
+ * @param limits - The byte and depth bounds to decode within (the server's own, from `limit`)
1240
1300
  * @returns The decoded message, or `undefined` when it is over the bound or is not one
1241
1301
  *
1242
1302
  * @example
@@ -1250,7 +1310,7 @@ function decodeBoundedMessage(message, limits) {
1250
1310
  return parsed.success ? parseJSONRPCMessage(parsed.value, limits) : void 0;
1251
1311
  }
1252
1312
  /**
1253
- * Read the request id an inbound `notifications/cancelled` names — the inverse of
1313
+ * Reads the request id an inbound `notifications/cancelled` names — the inverse of
1254
1314
  * {@link buildCancelledNotification}.
1255
1315
  *
1256
1316
  * @remarks
@@ -1258,7 +1318,7 @@ function decodeBoundedMessage(message, limits) {
1258
1318
  * real {@link JSONRPCId}: `null` is not one, and neither is an absent member, so a
1259
1319
  * malformed frame reads as "cancels nothing" rather than as an error. Anything that is not a
1260
1320
  * `notifications/cancelled` notification — a response, a request that happens to use the
1261
- * method name, another notification — reads the same way. Total (§14).
1321
+ * method name, another notification — reads the same way. Total.
1262
1322
  *
1263
1323
  * @param message - The decoded inbound message to read
1264
1324
  * @returns The id of the request being cancelled, or `undefined` when the message cancels nothing
@@ -1274,7 +1334,7 @@ function readCancelledId(message) {
1274
1334
  return isJSONRPCId(requested) ? requested : void 0;
1275
1335
  }
1276
1336
  /**
1277
- * Pump a controlled serialized exchange onto a transport — every notification in order, then
1337
+ * Pumps a controlled serialized exchange onto a transport — every notification in order, then
1278
1338
  * the terminating response — and END the exchange however the pump leaves.
1279
1339
  *
1280
1340
  * @remarks
@@ -1319,9 +1379,9 @@ async function sendStream(stream, transport) {
1319
1379
  }
1320
1380
  }
1321
1381
  /**
1322
- * Pipe an {@link MCPTransportInterface} into an {@link MCPDispatcherInterface} — every
1382
+ * Pipes an {@link MCPTransportInterface} into an {@link MCPDispatcherInterface} — every
1323
1383
  * inbound message runs through `server.handle`, and a defined reply is written back
1324
- * via `transport.send`.
1384
+ * through `transport.send`.
1325
1385
  *
1326
1386
  * @remarks
1327
1387
  * `server.handle` already turns a malformed message into a serialized `-32700` /
@@ -1342,7 +1402,7 @@ async function sendStream(stream, transport) {
1342
1402
  * **This binder OWNS every exchange it starts, and ends each one on every exit.** It holds one
1343
1403
  * `AbortController` per live request, keyed by the request's id and deleted whenever that
1344
1404
  * request leaves — normally, by a throw, or by cancellation — and it supplies that signal to
1345
- * `handle` as {@link import('./types.js').MCPDispatchOptions}. Three consequences follow.
1405
+ * `handle` as {@link import('./types.js').MCPDispatchOptions}. These consequences follow.
1346
1406
  * An inbound `notifications/cancelled` ABORTS the request it names, which is how the message-
1347
1407
  * based cancellation path reaches a tool on the carriers that have one (stdio, WebSocket,
1348
1408
  * `MessagePort`); a cancelled request writes NO response, because a peer that asked for a call
@@ -1415,7 +1475,7 @@ function bindServer(server, transport) {
1415
1475
  };
1416
1476
  }
1417
1477
  /**
1418
- * Pipe an {@link MCPTransportInterface} into an {@link MCPClientInterface} — every
1478
+ * Pipes an {@link MCPTransportInterface} into an {@link MCPClientInterface} — every
1419
1479
  * inbound message is decoded and delivered onto the client's OWN transport
1420
1480
  * (`client.transport.emitter`'s `message` / `close` events), resolving/rejecting the
1421
1481
  * client's correlated pending requests exactly as a direct reply would.
@@ -1429,7 +1489,7 @@ function bindServer(server, transport) {
1429
1489
  * this binder then completes the inbound half by decoding each message and pushing it
1430
1490
  * onto `client.transport.emitter` (an {@link import('@orkestrel/emitter').EmitterInterface}
1431
1491
  * exposes `emit`, so no client modification is needed). A malformed / non-JSON-RPC
1432
- * inbound message is DROPPED (§14, total — never throws); a delivery fault is routed to
1492
+ * inbound message is DROPPED (total — never throws); a delivery fault is routed to
1433
1493
  * `client.transport.emitter`'s `error` event (never rethrown). The returned unbind
1434
1494
  * DETACHES this binder (further inbound messages and the transport's `closed` signal are
1435
1495
  * ignored) WITHOUT closing the transport.
@@ -1447,7 +1507,7 @@ function bindServer(server, transport) {
1447
1507
  * itself when a caller's `signal` aborts, on a carrier declaring `duplex`. Adding a registry
1448
1508
  * here would be a second correlation table for ids the client is already correlating, and two
1449
1509
  * tables for one fact drift. The one obligation this binder does carry is delivery: a
1450
- * malformed / non-JSON-RPC inbound message is DROPPED (§14, total — never throws).
1510
+ * malformed / non-JSON-RPC inbound message is DROPPED (total — never throws).
1451
1511
  *
1452
1512
  * @param client - The transport-agnostic client whose transport to deliver messages onto
1453
1513
  * @param transport - The duplex channel to pipe the client over
@@ -1497,11 +1557,11 @@ function bindClient(client, transport) {
1497
1557
  }
1498
1558
  //#endregion
1499
1559
  //#region src/core/validators.ts
1500
- /** Determine whether a value is an exact finite JSON object. */
1560
+ /** Determines whether a value is an exact finite JSON object. */
1501
1561
  function isJSONObject(value) {
1502
1562
  return attempt(() => cloneJSONRecord(value)).success;
1503
1563
  }
1504
- /** Determine whether a string follows the dated MCP `_meta` key grammar. */
1564
+ /** Determines whether a string follows the dated MCP `_meta` key grammar. */
1505
1565
  function isMCPMetaKey(value) {
1506
1566
  if (!isString(value)) return false;
1507
1567
  const slash = value.indexOf("/");
@@ -1514,24 +1574,24 @@ function isMCPMetaKey(value) {
1514
1574
  }
1515
1575
  return name.length === 0 || /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(name);
1516
1576
  }
1517
- /** Determine whether a value is exact finite MCP metadata with valid keys. */
1577
+ /** Determines whether a value is exact finite MCP metadata with valid keys. */
1518
1578
  function isMCPMetaObject(value) {
1519
1579
  const owned = attempt(() => cloneJSONRecord(value));
1520
1580
  return owned.success && Object.keys(owned.value).every((key) => isMCPMetaKey(key));
1521
1581
  }
1522
- /** Determine whether a value is exact result metadata with a valid reserved server identity. */
1582
+ /** Determines whether a value is exact result metadata with a valid reserved server identity. */
1523
1583
  function isMCPResultMetaObject(value) {
1524
1584
  const owned = attempt(() => cloneJSONRecord(value));
1525
1585
  if (!owned.success || !Object.keys(owned.value).every((key) => isMCPMetaKey(key))) return false;
1526
1586
  const identity = owned.value[MCP_META_SERVER];
1527
1587
  return isUndefined(identity) || isMCPIdentity(identity);
1528
1588
  }
1529
- /** Determine whether a value is one dated MCP logging level. */
1589
+ /** Determines whether a value is one dated MCP logging level. */
1530
1590
  function isMCPLoggingLevel(value) {
1531
1591
  return value === "debug" || value === "info" || value === "notice" || value === "warning" || value === "error" || value === "critical" || value === "alert" || value === "emergency";
1532
1592
  }
1533
1593
  /**
1534
- * Determine whether a value is standard padded base64 as required by JSON Schema `byte` format.
1594
+ * Determines whether a value is standard padded base64 as required by JSON Schema `byte` format.
1535
1595
  *
1536
1596
  * @param value - The unknown value to inspect
1537
1597
  * @returns Whether the value is an empty or completely padded standard base64 encoding
@@ -1540,7 +1600,7 @@ function isStandardBase64(value) {
1540
1600
  return isString(value) && /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
1541
1601
  }
1542
1602
  /**
1543
- * Determine whether a value is one absolute URI under RFC 3986 syntax.
1603
+ * Determines whether a value is one absolute URI under RFC 3986 syntax.
1544
1604
  *
1545
1605
  * @remarks
1546
1606
  * This host-neutral syntax guard does not resolve, normalize, decode, fetch, or apply a
@@ -1629,7 +1689,7 @@ function isAbsoluteURI(value) {
1629
1689
  return /^[A-Za-z0-9\-._~!$&'()*+,;=%]*$/.test(host);
1630
1690
  }
1631
1691
  /**
1632
- * Determine whether a value is one RFC 3339 `full-date` naming a real calendar day.
1692
+ * Determines whether a value is one RFC 3339 `full-date` naming a real calendar day.
1633
1693
  *
1634
1694
  * @remarks
1635
1695
  * RFC 3339 §5.6 defines `date-mday` as `01-28`, `29`, `30`, or `31` BASED ON the month and
@@ -1664,7 +1724,7 @@ function isRFC3339Date(value) {
1664
1724
  return day <= (month === 4 || month === 6 || month === 9 || month === 11 ? 30 : 31);
1665
1725
  }
1666
1726
  /**
1667
- * Determine whether a value is one RFC 3339 `date-time` naming a real calendar day.
1727
+ * Determines whether a value is one RFC 3339 `date-time` naming a real calendar day.
1668
1728
  *
1669
1729
  * @remarks
1670
1730
  * The `full-date` half is {@link isRFC3339Date}, so an impossible day is refused here for
@@ -1691,7 +1751,7 @@ function isRFC3339DateTime(value) {
1691
1751
  return matched !== null && isRFC3339Date(matched[1]);
1692
1752
  }
1693
1753
  /**
1694
- * Determine whether a value is one exact finite MCP progress payload.
1754
+ * Determines whether a value is one exact finite MCP progress payload.
1695
1755
  *
1696
1756
  * @param value - The unknown value to inspect
1697
1757
  * @returns Whether required progress and optional total/message fields match the dated schema
@@ -1710,7 +1770,7 @@ function isMCPProgress(value) {
1710
1770
  }
1711
1771
  }
1712
1772
  /**
1713
- * Determine whether a value carries valid dated-schema MCP content annotations.
1773
+ * Determines whether a value carries valid dated-schema MCP content annotations.
1714
1774
  *
1715
1775
  * @param value - The unknown value to inspect
1716
1776
  * @returns Whether the value is valid MCP annotations
@@ -1731,7 +1791,7 @@ function isMCPAnnotations(value) {
1731
1791
  }
1732
1792
  }
1733
1793
  /**
1734
- * Determine whether a value is one exact dated-schema MCP icon.
1794
+ * Determines whether a value is one exact dated-schema MCP icon.
1735
1795
  *
1736
1796
  * @param value - The unknown value to inspect
1737
1797
  * @returns Whether the value is a valid MCP icon
@@ -1750,7 +1810,7 @@ function isMCPIcon(value) {
1750
1810
  return false;
1751
1811
  }
1752
1812
  }
1753
- /** Determine whether a value is one complete dated MCP implementation identity. */
1813
+ /** Determines whether a value is one complete dated MCP implementation identity. */
1754
1814
  function isMCPIdentity(value) {
1755
1815
  const owned = attempt(() => cloneJSONRecord(value));
1756
1816
  if (!owned.success) return false;
@@ -1766,7 +1826,7 @@ function isMCPIdentity(value) {
1766
1826
  return false;
1767
1827
  }
1768
1828
  }
1769
- /** Determine whether a value is one exact open dated client-capability declaration. */
1829
+ /** Determines whether a value is one exact open dated client-capability declaration. */
1770
1830
  function isMCPClientCapabilities(value) {
1771
1831
  const owned = attempt(() => cloneJSONRecord(value));
1772
1832
  if (!owned.success) return false;
@@ -1796,7 +1856,7 @@ function isMCPClientCapabilities(value) {
1796
1856
  return false;
1797
1857
  }
1798
1858
  }
1799
- /** Determine whether a value is one exact open dated server-capability declaration. */
1859
+ /** Determines whether a value is one exact open dated server-capability declaration. */
1800
1860
  function isMCPServerCapabilities(value) {
1801
1861
  const owned = attempt(() => cloneJSONRecord(value));
1802
1862
  if (!owned.success) return false;
@@ -1822,7 +1882,7 @@ function isMCPServerCapabilities(value) {
1822
1882
  }
1823
1883
  }
1824
1884
  /**
1825
- * Determine whether a value is embedded textual MCP resource contents.
1885
+ * Determines whether a value is embedded textual MCP resource contents.
1826
1886
  *
1827
1887
  * @param value - The unknown value to inspect
1828
1888
  * @returns Whether the value is embedded textual resource contents
@@ -1841,7 +1901,7 @@ function isMCPTextResource(value) {
1841
1901
  }
1842
1902
  }
1843
1903
  /**
1844
- * Determine whether a value is embedded blob MCP resource contents.
1904
+ * Determines whether a value is embedded blob MCP resource contents.
1845
1905
  *
1846
1906
  * @param value - The unknown value to inspect
1847
1907
  * @returns Whether the value is embedded blob resource contents
@@ -1860,7 +1920,7 @@ function isMCPBlobResource(value) {
1860
1920
  }
1861
1921
  }
1862
1922
  /**
1863
- * Determine whether a value is one `resources/list` descriptor.
1923
+ * Determines whether a value is one `resources/list` descriptor.
1864
1924
  *
1865
1925
  * @param value - The unknown value to inspect
1866
1926
  * @returns Whether the value is a valid resource descriptor
@@ -1878,7 +1938,7 @@ function isMCPResource(value) {
1878
1938
  }
1879
1939
  }
1880
1940
  /**
1881
- * Determine whether a value is one resource-template descriptor.
1941
+ * Determines whether a value is one resource-template descriptor.
1882
1942
  *
1883
1943
  * @remarks
1884
1944
  * This guard validates the descriptor shape. Template expansion and the RFC 6570 feature
@@ -1899,7 +1959,7 @@ function isMCPResourceTemplate(value) {
1899
1959
  }
1900
1960
  }
1901
1961
  /**
1902
- * Determine whether a value is structurally discriminated resource contents.
1962
+ * Determines whether a value is structurally discriminated resource contents.
1903
1963
  *
1904
1964
  * @param value - The unknown value to inspect
1905
1965
  * @returns Whether exactly one of `text` and `blob` is present and valid
@@ -1913,7 +1973,7 @@ function isMCPResourceContents(value) {
1913
1973
  return text ? isMCPTextResource(resource) : isMCPBlobResource(resource);
1914
1974
  }
1915
1975
  /**
1916
- * Determine whether a value carries the shared optional pagination cursor.
1976
+ * Determines whether a value carries the shared optional pagination cursor.
1917
1977
  *
1918
1978
  * @param value - The unknown value to inspect
1919
1979
  * @returns Whether a present `cursor` is a string
@@ -1923,7 +1983,7 @@ function isMCPPaginationParams(value) {
1923
1983
  return owned.success && (isUndefined(owned.value["cursor"]) || isString(owned.value["cursor"]));
1924
1984
  }
1925
1985
  /**
1926
- * Determine whether a value is one consumer-owned resource page.
1986
+ * Determines whether a value is one consumer-owned resource page.
1927
1987
  *
1928
1988
  * @param value - The unknown value to inspect
1929
1989
  * @returns Whether the resources and optional following cursor are valid
@@ -1936,7 +1996,7 @@ function isMCPResourcePage(value) {
1936
1996
  return Array.isArray(resources) && resources.every((resource) => isMCPResource(resource)) && (isUndefined(cursor) || isString(cursor));
1937
1997
  }
1938
1998
  /**
1939
- * Determine whether a value is one consumer-owned resource-template page.
1999
+ * Determines whether a value is one consumer-owned resource-template page.
1940
2000
  *
1941
2001
  * @param value - The unknown value to inspect
1942
2002
  * @returns Whether the templates and optional following cursor are valid
@@ -1949,7 +2009,7 @@ function isMCPResourceTemplatePage(value) {
1949
2009
  return Array.isArray(templates) && templates.every((template) => isMCPResourceTemplate(template)) && (isUndefined(cursor) || isString(cursor));
1950
2010
  }
1951
2011
  /**
1952
- * Determine whether a value is a string-valued MCP argument record.
2012
+ * Determines whether a value is a string-valued MCP argument record.
1953
2013
  *
1954
2014
  * @param value - The unknown value to inspect
1955
2015
  * @returns Whether every own argument value is a string
@@ -1959,7 +2019,7 @@ function isMCPStringArguments(value) {
1959
2019
  return owned.success && Object.values(owned.value).every((argument) => isString(argument));
1960
2020
  }
1961
2021
  /**
1962
- * Determine whether a value is one prompt argument descriptor.
2022
+ * Determines whether a value is one prompt argument descriptor.
1963
2023
  *
1964
2024
  * @param value - The unknown value to inspect
1965
2025
  * @returns Whether the prompt argument descriptor is valid
@@ -1971,7 +2031,7 @@ function isMCPPromptArgument(value) {
1971
2031
  return isString(argument["name"]) && (isUndefined(argument["title"]) || isString(argument["title"])) && (isUndefined(argument["description"]) || isString(argument["description"])) && (isUndefined(argument["required"]) || isBoolean(argument["required"]));
1972
2032
  }
1973
2033
  /**
1974
- * Determine whether a value is one `prompts/list` descriptor.
2034
+ * Determines whether a value is one `prompts/list` descriptor.
1975
2035
  *
1976
2036
  * @param value - The unknown value to inspect
1977
2037
  * @returns Whether the prompt descriptor is valid
@@ -1985,7 +2045,7 @@ function isMCPPrompt(value) {
1985
2045
  return isString(prompt["name"]) && (isUndefined(prompt["title"]) || isString(prompt["title"])) && (isUndefined(prompt["description"]) || isString(prompt["description"])) && (isUndefined(argumentsValue) || Array.isArray(argumentsValue) && argumentsValue.every((argument) => isMCPPromptArgument(argument))) && (isUndefined(icons) || Array.isArray(icons) && icons.every((icon) => isMCPIcon(icon))) && (isUndefined(prompt["_meta"]) || isMCPMetaObject(prompt["_meta"]));
1986
2046
  }
1987
2047
  /**
1988
- * Determine whether a value is one prompt message with existing rich content.
2048
+ * Determines whether a value is one prompt message with existing rich content.
1989
2049
  *
1990
2050
  * @param value - The unknown value to inspect
1991
2051
  * @returns Whether the role and content are valid
@@ -1995,7 +2055,7 @@ function isMCPPromptMessage(value) {
1995
2055
  return owned.success && (owned.value["role"] === "user" || owned.value["role"] === "assistant") && isMCPContent(owned.value["content"]);
1996
2056
  }
1997
2057
  /**
1998
- * Determine whether a value is one consumer-owned prompt page.
2058
+ * Determines whether a value is one consumer-owned prompt page.
1999
2059
  *
2000
2060
  * @param value - The unknown value to inspect
2001
2061
  * @returns Whether the prompts and optional following cursor are valid
@@ -2008,7 +2068,7 @@ function isMCPPromptPage(value) {
2008
2068
  return Array.isArray(prompts) && prompts.every((prompt) => isMCPPrompt(prompt)) && (isUndefined(cursor) || isString(cursor));
2009
2069
  }
2010
2070
  /**
2011
- * Determine whether a value is one complete `prompts/get` result.
2071
+ * Determines whether a value is one complete `prompts/get` result.
2012
2072
  *
2013
2073
  * @param value - The unknown value to inspect
2014
2074
  * @returns Whether the prompt result and all messages are valid
@@ -2021,7 +2081,7 @@ function isMCPPromptGetResult(value) {
2021
2081
  return result["resultType"] === "complete" && (isUndefined(result["description"]) || isString(result["description"])) && Array.isArray(messages) && messages.every((message) => isMCPPromptMessage(message)) && (isUndefined(result["_meta"]) || isMCPResultMetaObject(result["_meta"]));
2022
2082
  }
2023
2083
  /**
2024
- * Determine whether a value is a prompt or resource-template completion reference.
2084
+ * Determines whether a value is a prompt or resource-template completion reference.
2025
2085
  *
2026
2086
  * @param value - The unknown value to inspect
2027
2087
  * @returns Whether the discriminated reference is valid
@@ -2033,7 +2093,7 @@ function isMCPCompletionReference(value) {
2033
2093
  return reference["type"] === "ref/prompt" ? isString(reference["name"]) : reference["type"] === "ref/resource" && isString(reference["uri"]);
2034
2094
  }
2035
2095
  /**
2036
- * Determine whether a value is one `completion/complete` parameter object.
2096
+ * Determines whether a value is one `completion/complete` parameter object.
2037
2097
  *
2038
2098
  * @param value - The unknown value to inspect
2039
2099
  * @returns Whether its reference, fragment, and optional string context are valid
@@ -2052,7 +2112,7 @@ function isMCPCompletionParams(value) {
2052
2112
  return isMCPCompletionReference(params["ref"]) && isString(argument.value["name"]) && isString(argument.value["value"]);
2053
2113
  }
2054
2114
  /**
2055
- * Determine whether a value is one host-produced completion candidate set.
2115
+ * Determines whether a value is one host-produced completion candidate set.
2056
2116
  *
2057
2117
  * @param value - The unknown value to inspect
2058
2118
  * @returns Whether its candidates and optional result facts are valid
@@ -2066,7 +2126,7 @@ function isMCPCompletion(value) {
2066
2126
  return Array.isArray(values) && values.every((candidate) => isString(candidate)) && (isUndefined(total) || isInteger(total) && total >= 0) && (isUndefined(completion["hasMore"]) || isBoolean(completion["hasMore"]));
2067
2127
  }
2068
2128
  /**
2069
- * Determine whether a value is one complete, capped `completion/complete` result.
2129
+ * Determines whether a value is one complete, capped `completion/complete` result.
2070
2130
  *
2071
2131
  * @param value - The unknown value to inspect
2072
2132
  * @returns Whether the result is complete and carries at most 100 candidates
@@ -2078,7 +2138,7 @@ function isMCPCompletionResult(value) {
2078
2138
  return isMCPCompletion(completion) && completion.values.length <= 100 && (isUndefined(owned.value["_meta"]) || isMCPResultMetaObject(owned.value["_meta"]));
2079
2139
  }
2080
2140
  /**
2081
- * Determine whether a value is one exact dated-schema MCP tool content block.
2141
+ * Determines whether a value is one exact dated-schema MCP tool content block.
2082
2142
  *
2083
2143
  * @param value - The unknown value to inspect
2084
2144
  * @returns Whether the value is valid MCP content
@@ -2110,7 +2170,7 @@ function isMCPContent(value) {
2110
2170
  }
2111
2171
  }
2112
2172
  /**
2113
- * Determine whether a value is one modern MCP result.
2173
+ * Determines whether a value is one modern MCP result.
2114
2174
  *
2115
2175
  * @remarks
2116
2176
  * The open contract's guard: a record carrying a string `resultType` and, when
@@ -2140,7 +2200,7 @@ function isMCPResult(value) {
2140
2200
  return isUndefined(metadata) || isMCPResultMetaObject(metadata);
2141
2201
  }
2142
2202
  /**
2143
- * Determine whether a value is one legacy-era MCP result.
2203
+ * Determines whether a value is one legacy-era MCP result.
2144
2204
  *
2145
2205
  * @remarks
2146
2206
  * The legacy revision has no result discriminator, so the absence of `resultType` is
@@ -2161,7 +2221,7 @@ function isMCPLegacyResult(value) {
2161
2221
  return owned.success && !Object.hasOwn(owned.value, "resultType");
2162
2222
  }
2163
2223
  /**
2164
- * Determine whether a value is a complete modern MCP tool result.
2224
+ * Determines whether a value is a complete modern MCP tool result.
2165
2225
  *
2166
2226
  * @param value - The unknown value to inspect
2167
2227
  * @returns Whether the value is a complete MCP call result
@@ -2181,7 +2241,7 @@ function isMCPCallResult(value) {
2181
2241
  }
2182
2242
  }
2183
2243
  /**
2184
- * Determine whether a value is a modern MCP task-creation result.
2244
+ * Determines whether a value is a modern MCP task-creation result.
2185
2245
  *
2186
2246
  * @remarks
2187
2247
  * The runtime enforcement of {@link MCPTaskManagerInterface.start}'s declared return
@@ -2215,7 +2275,7 @@ function isMCPTaskResult(value) {
2215
2275
  }
2216
2276
  }
2217
2277
  /**
2218
- * Determine whether a value is one of the extension's five task lifecycle states.
2278
+ * Determines whether a value is one of the extension's task lifecycle states.
2219
2279
  *
2220
2280
  * @param value - The unknown value to inspect
2221
2281
  * @returns Whether the value is an {@link MCPTaskStatus}
@@ -2230,7 +2290,7 @@ function isMCPTaskStatus(value) {
2230
2290
  return value === "working" || value === "input_required" || value === "completed" || value === "failed" || value === "cancelled";
2231
2291
  }
2232
2292
  /**
2233
- * Determine whether a value is one durable task's full snapshot.
2293
+ * Determines whether a value is one durable task's full snapshot.
2234
2294
  *
2235
2295
  * @remarks
2236
2296
  * The runtime enforcement of {@link MCPTaskManagerInterface.task}'s declared return shape,
@@ -2273,7 +2333,7 @@ function isMCPTaskDetail(value) {
2273
2333
  }
2274
2334
  }
2275
2335
  /**
2276
- * Determine whether a value is a string within a UTF-8 byte bound.
2336
+ * Determines whether a value is a string within a UTF-8 byte bound.
2277
2337
  *
2278
2338
  * @param value - The unknown value to inspect
2279
2339
  * @param bytes - The maximum accepted encoded bytes
@@ -2304,7 +2364,7 @@ function isBoundedString(value, bytes) {
2304
2364
  return true;
2305
2365
  }
2306
2366
  /**
2307
- * Determine whether a value is bounded, cycle-free exact JSON.
2367
+ * Determines whether a value is bounded, cycle-free exact JSON.
2308
2368
  *
2309
2369
  * @remarks
2310
2370
  * Traversal is iterative, ancestor-aware, and contained by {@link attempt}; deep input,
@@ -2324,7 +2384,7 @@ function isBoundedJSON(value, limits) {
2324
2384
  return serializeJSON(value, limits) !== void 0;
2325
2385
  }
2326
2386
  /**
2327
- * Determine whether a value is a valid JSON-RPC correlation id — a string or a
2387
+ * Determines whether a value is a valid JSON-RPC correlation id — a string or a
2328
2388
  * finite integer.
2329
2389
  *
2330
2390
  * @remarks
@@ -2332,7 +2392,7 @@ function isBoundedJSON(value, limits) {
2332
2392
  * absence is what makes a call a notification) and `null` is not one either (MCP
2333
2393
  * omits an unreadable id rather than nulling it). A runtime numeric id must be a
2334
2394
  * finite integer; an empty string is a legal id, because the dated schema imposes
2335
- * no minimum length. Total (§14): any other input returns `false`.
2395
+ * no minimum length. Total: any other input returns `false`.
2336
2396
  *
2337
2397
  * @param value - The already-parsed value to test
2338
2398
  * @returns `true` when `value` is a string or a finite integer
@@ -2350,7 +2410,7 @@ function isJSONRPCId(value) {
2350
2410
  return isString(value) || isInteger(value);
2351
2411
  }
2352
2412
  /**
2353
- * Determine whether a value is a supported {@link MCPVersion}.
2413
+ * Determines whether a value is a supported {@link MCPVersion}.
2354
2414
  *
2355
2415
  * @param value - The unknown value to inspect
2356
2416
  * @returns `true` when the value is one of {@link SUPPORTED_PROTOCOL_VERSIONS}
@@ -2359,7 +2419,7 @@ function isMCPVersion(value) {
2359
2419
  return isString(value) && SUPPORTED_PROTOCOL_VERSIONS.some((version) => version === value);
2360
2420
  }
2361
2421
  /**
2362
- * Determine whether a value is an MCP {@link MCPSubscriptionFilter}.
2422
+ * Determines whether a value is an MCP {@link MCPSubscriptionFilter}.
2363
2423
  *
2364
2424
  * @remarks
2365
2425
  * Every filter field is optional. Boolean notification families accept only booleans, and
@@ -2384,69 +2444,7 @@ function isMCPSubscriptionFilter(value) {
2384
2444
  return isUndefined(subscriptions) || arrayOf(isString)(subscriptions);
2385
2445
  }
2386
2446
  /**
2387
- * Determine whether a client capability record declares form-mode elicitation.
2388
- *
2389
- * @remarks
2390
- * The protocol's empty `elicitation` object is the implicit form-only declaration.
2391
- * A non-empty declaration must carry a record-valued `form` member; URL-only support
2392
- * does not authorize a form request. Total over hostile input.
2393
- *
2394
- * @param value - The client capability record to inspect
2395
- * @returns `true` when form-mode elicitation is declared
2396
- *
2397
- * @example
2398
- * ```ts
2399
- * isFormElicitationSupported({ elicitation: {} }) // true — implicit form mode
2400
- * isFormElicitationSupported({ elicitation: { url: {} } }) // false
2401
- * ```
2402
- */
2403
- function isFormElicitationSupported(value) {
2404
- const owned = attempt(() => cloneJSONRecord(value));
2405
- if (!owned.success) return false;
2406
- try {
2407
- const elicitation = owned.value["elicitation"];
2408
- if (!isRecord(elicitation)) return false;
2409
- if (isRecord(elicitation["form"])) return true;
2410
- return Object.keys(elicitation).length === 0;
2411
- } catch {
2412
- return false;
2413
- }
2414
- }
2415
- /**
2416
- * Determine whether a client capability record declares the draft Tasks extension.
2417
- *
2418
- * @remarks
2419
- * The declaration lives at `extensions['io.modelcontextprotocol/tasks']` and its value is
2420
- * an empty object, so this is a PRESENCE check: the extension defines no options, and a
2421
- * server that read one would be reading a field no client can meaningfully set. The value
2422
- * must still be a record, because that is the shape the capability record declares — a
2423
- * `true` or a string there is a client speaking a different protocol, not a shorthand.
2424
- *
2425
- * A client declares this PER REQUEST. Nothing here consults a session, because the modern
2426
- * revision is stateless and a capability declared once at connect time says nothing about
2427
- * the request in hand. Total over hostile input.
2428
- *
2429
- * @param value - The client capability record to inspect
2430
- * @returns `true` when the tasks extension is declared
2431
- *
2432
- * @example
2433
- * ```ts
2434
- * isTaskSupported({ extensions: { 'io.modelcontextprotocol/tasks': {} } }) // true
2435
- * isTaskSupported({ extensions: {} }) // false — the key is the declaration
2436
- * ```
2437
- */
2438
- function isTaskSupported(value) {
2439
- const owned = attempt(() => cloneJSONRecord(value));
2440
- if (!owned.success) return false;
2441
- try {
2442
- const extensions = owned.value["extensions"];
2443
- return isRecord(extensions) && isRecord(extensions["io.modelcontextprotocol/tasks"]);
2444
- } catch {
2445
- return false;
2446
- }
2447
- }
2448
- /**
2449
- * Determine whether a value is one restricted primitive form-elicitation schema.
2447
+ * Determines whether a value is one restricted primitive form-elicitation schema.
2450
2448
  *
2451
2449
  * @param value - The unknown value to inspect
2452
2450
  * @returns `true` for a supported boolean, numeric, string, or string-array schema
@@ -2502,7 +2500,7 @@ function isMCPElicitFieldSchema(value) {
2502
2500
  }
2503
2501
  }
2504
2502
  /**
2505
- * Determine whether a value is the restricted top-level object schema a form elicitation issues.
2503
+ * Determines whether a value is the restricted top-level object schema a form elicitation issues.
2506
2504
  *
2507
2505
  * @remarks
2508
2506
  * The schema half of {@link isMCPElicitForm}, exported on its own because the issued schema
@@ -2536,7 +2534,7 @@ function isMCPElicitSchema(value) {
2536
2534
  }
2537
2535
  }
2538
2536
  /**
2539
- * Determine whether a value is a form-mode elicitation parameter object.
2537
+ * Determines whether a value is a form-mode elicitation parameter object.
2540
2538
  *
2541
2539
  * @param value - The unknown value to inspect
2542
2540
  * @returns `true` when `value` has the restricted form elicitation shape
@@ -2562,7 +2560,7 @@ function isMCPElicitForm(value) {
2562
2560
  }
2563
2561
  }
2564
2562
  /**
2565
- * Determine whether a value is a URL-mode elicitation parameter object.
2563
+ * Determines whether a value is a URL-mode elicitation parameter object.
2566
2564
  *
2567
2565
  * @param value - The unknown value to inspect
2568
2566
  * @returns `true` when `value` has the URL elicitation shape
@@ -2583,7 +2581,7 @@ function isMCPElicitURL(value) {
2583
2581
  }
2584
2582
  }
2585
2583
  /**
2586
- * Determine whether a value is an embedded `elicitation/create` request.
2584
+ * Determines whether a value is an embedded `elicitation/create` request.
2587
2585
  *
2588
2586
  * @param value - The unknown value to inspect
2589
2587
  * @returns `true` when `value` is a form- or URL-mode elicitation request
@@ -2608,7 +2606,7 @@ function isMCPElicitRequest(value) {
2608
2606
  }
2609
2607
  }
2610
2608
  /**
2611
- * Determine whether a value is one legal embedded multi-round-trip request.
2609
+ * Determines whether a value is one legal embedded multi-round-trip request.
2612
2610
  *
2613
2611
  * @param value - The unknown value to inspect
2614
2612
  * @returns `true` for elicitation, deprecated sampling, or deprecated roots requests
@@ -2632,7 +2630,7 @@ function isMCPInputRequest(value) {
2632
2630
  }
2633
2631
  }
2634
2632
  /**
2635
- * Determine whether a value is a server-keyed map of embedded input requests.
2633
+ * Determines whether a value is a server-keyed map of embedded input requests.
2636
2634
  *
2637
2635
  * @param value - The unknown value to inspect
2638
2636
  * @returns `true` when every own value is a legal {@link MCPInputRequest}
@@ -2652,7 +2650,7 @@ function isMCPInputRequestMap(value) {
2652
2650
  }
2653
2651
  }
2654
2652
  /**
2655
- * Determine whether a value is one elicitation response.
2653
+ * Determines whether a value is one elicitation response.
2656
2654
  *
2657
2655
  * @param value - The unknown value to inspect
2658
2656
  * @returns `true` when action/content have the protocol shape
@@ -2679,7 +2677,7 @@ function isMCPElicitResult(value) {
2679
2677
  }
2680
2678
  }
2681
2679
  /**
2682
- * Determine whether accepted elicitation content satisfies the exact schema that was issued.
2680
+ * Determines whether accepted elicitation content satisfies the exact schema that was issued.
2683
2681
  *
2684
2682
  * @remarks
2685
2683
  * {@link isMCPElicitResult} says a response has the SHAPE of a response; this says the
@@ -2701,7 +2699,7 @@ function isMCPElicitResult(value) {
2701
2699
  * that answers more than it was asked is not refused for it. A `schema` that is not itself a
2702
2700
  * valid {@link MCPElicitSchema} admits NOTHING — an unenforceable schema is never a permissive
2703
2701
  * one — which is why `schema` is accepted as `unknown` and checked rather than trusted. Total
2704
- * (§14) over hostile content and hostile schemas alike.
2702
+ * over hostile content and hostile schemas alike.
2705
2703
  *
2706
2704
  * @param value - The accepted response content to check
2707
2705
  * @param schema - The exact {@link MCPElicitSchema} that was issued with the elicitation
@@ -2786,7 +2784,7 @@ function isElicitContent(value, schema) {
2786
2784
  }
2787
2785
  }
2788
2786
  /**
2789
- * Determine whether a value is an MCP input-required result.
2787
+ * Determines whether a value is an MCP input-required result.
2790
2788
  *
2791
2789
  * @remarks
2792
2790
  * Enforces the at-least-one-of rule at runtime: `inputRequests`, `requestState`, or
@@ -2819,15 +2817,15 @@ function isMCPInputResult(value) {
2819
2817
  }
2820
2818
  }
2821
2819
  /**
2822
- * Determine whether a parsed value is a {@link JSONRPCRequest}.
2820
+ * Determines whether a parsed value is a {@link JSONRPCRequest}.
2823
2821
  *
2824
2822
  * @remarks
2825
2823
  * A request is a record with `jsonrpc === '2.0'`, a string `method`, and an `id`
2826
2824
  * that {@link isJSONRPCId} accepts. An id-less call is NOT a request — it is a
2827
2825
  * {@link JSONRPCNotification}, which {@link isJSONRPCNotification} answers for. The
2828
- * two guards are mutually exclusive on every input: this one requires a valid `id`
2826
+ * guards are mutually exclusive on every input: this one requires a valid `id`
2829
2827
  * value, that one requires no own `id` member at all. `params`, when present, must
2830
- * be a record. Total (§14): any other input returns `false`.
2828
+ * be a record. Total: any other input returns `false`.
2831
2829
  *
2832
2830
  * @param value - The already-parsed value to test
2833
2831
  * @returns `true` when `value` is a valid JSON-RPC request
@@ -2849,12 +2847,12 @@ function isJSONRPCRequest(value) {
2849
2847
  return isUndefined(params) || isRecord(params);
2850
2848
  }
2851
2849
  /**
2852
- * Determine whether a parsed value is a {@link JSONRPCNotification}.
2850
+ * Determines whether a parsed value is a {@link JSONRPCNotification}.
2853
2851
  *
2854
2852
  * @remarks
2855
2853
  * A notification is a request-shaped call carrying NO `id` member — the protocol
2856
2854
  * forbids one, because nothing answers a notification. `params`, when present, must
2857
- * be a record. Total (§14): any other input returns `false`.
2855
+ * be a record. Total: any other input returns `false`.
2858
2856
  *
2859
2857
  * @param value - The already-parsed value to test
2860
2858
  * @returns `true` when `value` is a valid JSON-RPC notification
@@ -2875,12 +2873,12 @@ function isJSONRPCNotification(value) {
2875
2873
  return isUndefined(params) || isRecord(params);
2876
2874
  }
2877
2875
  /**
2878
- * Determine whether a parsed value is a {@link JSONRPCInvocation} — a request or a
2876
+ * Determines whether a parsed value is a {@link JSONRPCInvocation} — a request or a
2879
2877
  * notification.
2880
2878
  *
2881
2879
  * @remarks
2882
2880
  * The union of {@link isJSONRPCRequest} and {@link isJSONRPCNotification}, which are
2883
- * mutually exclusive, so a positive answer names exactly one arm. Total (§14).
2881
+ * mutually exclusive, so a positive answer names exactly one arm. Total.
2884
2882
  *
2885
2883
  * @param value - The already-parsed value to test
2886
2884
  * @returns `true` when `value` is a valid JSON-RPC request or notification
@@ -2889,7 +2887,7 @@ function isJSONRPCInvocation(value) {
2889
2887
  return isJSONRPCRequest(value) || isJSONRPCNotification(value);
2890
2888
  }
2891
2889
  /**
2892
- * Determine whether a parsed value is a {@link JSONRPCResultResponse} — the success
2890
+ * Determines whether a parsed value is a {@link JSONRPCResultResponse} — the success
2893
2891
  * arm of a response.
2894
2892
  *
2895
2893
  * @remarks
@@ -2898,7 +2896,7 @@ function isJSONRPCInvocation(value) {
2898
2896
  * which is what makes this guard and {@link isJSONRPCErrorResponse} mutually
2899
2897
  * exclusive on every input. `result` itself must be an object: either a modern
2900
2898
  * {@link isMCPResult} or a legacy {@link isMCPLegacyResult}, never a bare primitive.
2901
- * Total (§14).
2899
+ * Total.
2902
2900
  *
2903
2901
  * @param value - The already-parsed value to test
2904
2902
  * @returns `true` when `value` is a valid JSON-RPC result response
@@ -2919,22 +2917,22 @@ function isJSONRPCResultResponse(value) {
2919
2917
  return isMCPResult(result) || isMCPLegacyResult(result);
2920
2918
  }
2921
2919
  /**
2922
- * Determine whether a value is one JSON-RPC `error` member.
2920
+ * Determines whether a value is one JSON-RPC `error` member.
2923
2921
  *
2924
2922
  * @remarks
2925
2923
  * The failure OBJECT, not the envelope carrying it — the shape a failed response owns
2926
2924
  * under `error`, and the shape a `failed` {@link MCPTaskDetail} owns under the same name,
2927
- * which is why it is one guard rather than the same three checks written twice.
2925
+ * which is why it is one guard rather than the same checks written twice.
2928
2926
  *
2929
2927
  * It is deliberately STRUCTURAL rather than exact-JSON: `data` is declared `unknown`, so
2930
2928
  * requiring the whole object to survive a JSON clone would refuse a legal error that
2931
2929
  * carried a non-JSON payload. Both callers here hand it an already-owned value.
2932
2930
  *
2933
- * That choice is why the two key reads are guarded. Every sibling guard clones first, and a
2931
+ * That choice is why the key reads are guarded. Every sibling guard clones first, and a
2934
2932
  * clone reads each key once behind a boundary that already owns totality; this one is the
2935
2933
  * family's only DIRECT reader, so it meets `code` and `message` exactly as the value defines
2936
2934
  * them — including as accessors that throw. Reading a named key off an unowned value is
2937
- * itself the hostile step, and it is bounded here rather than allowed to escape. Total (§14).
2935
+ * itself the hostile step, and it is bounded here rather than allowed to escape. Total.
2938
2936
  *
2939
2937
  * @param value - The already-parsed value to test
2940
2938
  * @returns `true` when `value` carries an integer `code` and a string `message`
@@ -2951,14 +2949,14 @@ function isJSONRPCError(value) {
2951
2949
  return read.success && read.value;
2952
2950
  }
2953
2951
  /**
2954
- * Determine whether a parsed value is a {@link JSONRPCErrorResponse} — the failure
2952
+ * Determines whether a parsed value is a {@link JSONRPCErrorResponse} — the failure
2955
2953
  * arm of a response.
2956
2954
  *
2957
2955
  * @remarks
2958
2956
  * `id` is OPTIONAL here and only here: a peer that could not read the failed
2959
2957
  * request's id OMITS the member rather than sending `null`, so an absent `id` is
2960
2958
  * valid and a `null` one is not. The envelope must own an `error` and must NOT own a
2961
- * `result`. `error` carries an integer `code` and a string `message`. Total (§14).
2959
+ * `result`. `error` carries an integer `code` and a string `message`. Total.
2962
2960
  *
2963
2961
  * @param value - The already-parsed value to test
2964
2962
  * @returns `true` when `value` is a valid JSON-RPC error response
@@ -2979,10 +2977,10 @@ function isJSONRPCErrorResponse(value) {
2979
2977
  return isJSONRPCError(response["error"]);
2980
2978
  }
2981
2979
  /**
2982
- * Determine whether a parsed value is a {@link JSONRPCResponse}.
2980
+ * Determines whether a parsed value is a {@link JSONRPCResponse}.
2983
2981
  *
2984
2982
  * @remarks
2985
- * The union of the two mutually exclusive arms. Total (§14).
2983
+ * The union of the mutually exclusive arms. Total.
2986
2984
  *
2987
2985
  * @param value - The already-parsed value to test
2988
2986
  * @returns `true` when `value` is a valid JSON-RPC response
@@ -2991,11 +2989,11 @@ function isJSONRPCResponse(value) {
2991
2989
  return isJSONRPCResultResponse(value) || isJSONRPCErrorResponse(value);
2992
2990
  }
2993
2991
  /**
2994
- * Determine whether a parsed value is a {@link JSONRPCMessage} — an invocation or a
2992
+ * Determines whether a parsed value is a {@link JSONRPCMessage} — an invocation or a
2995
2993
  * response.
2996
2994
  *
2997
2995
  * @remarks
2998
- * The union of {@link isJSONRPCInvocation} and {@link isJSONRPCResponse}. Total (§14).
2996
+ * The union of {@link isJSONRPCInvocation} and {@link isJSONRPCResponse}. Total.
2999
2997
  *
3000
2998
  * @param value - The already-parsed value to test
3001
2999
  * @returns `true` when `value` is a valid JSON-RPC message
@@ -3004,7 +3002,7 @@ function isJSONRPCMessage(value) {
3004
3002
  return isJSONRPCInvocation(value) || isJSONRPCResponse(value);
3005
3003
  }
3006
3004
  /**
3007
- * Determine whether a parsed value is an MCP `initialize` invocation.
3005
+ * Determines whether a parsed value is an MCP `initialize` invocation.
3008
3006
  *
3009
3007
  * @param value - The already-parsed value to test
3010
3008
  * @returns `true` when `value` is a valid `initialize` request or notification
@@ -3020,7 +3018,7 @@ function isInitializeRequest(value) {
3020
3018
  return owned.success && isJSONRPCInvocation(owned.value) && owned.value["method"] === "initialize";
3021
3019
  }
3022
3020
  /**
3023
- * Determine whether a JSON-RPC invocation uses the modern per-request MCP wire shape.
3021
+ * Determines whether a JSON-RPC invocation uses the modern per-request MCP wire shape.
3024
3022
  *
3025
3023
  * @remarks
3026
3024
  * Presence routes and validity answers: this guard checks only that
@@ -3111,7 +3109,7 @@ var MCPProgressReporter = class {
3111
3109
  #last;
3112
3110
  #stopped = false;
3113
3111
  /**
3114
- * Create one non-durable progress slot for an active request.
3112
+ * Creates one non-durable progress slot for an active request.
3115
3113
  *
3116
3114
  * @param token - The opaque progress token copied into each notification
3117
3115
  * @param limits - The byte, key, and depth bounds applied to every progress payload
@@ -3126,7 +3124,7 @@ var MCPProgressReporter = class {
3126
3124
  else signal.addEventListener("abort", this.#listener, { once: true });
3127
3125
  }
3128
3126
  /**
3129
- * Publish one bounded, strictly increasing progress value and await its consumption.
3127
+ * Publishes one bounded, strictly increasing progress value and awaits its consumption.
3130
3128
  *
3131
3129
  * @param progress - The progress payload to own and hand to the serial consumer
3132
3130
  * @returns A promise resolving after {@link take} consumes the item
@@ -3147,7 +3145,7 @@ var MCPProgressReporter = class {
3147
3145
  await consumed.promise;
3148
3146
  }
3149
3147
  /**
3150
- * Take the next progress notification, waiting for the single producer slot when empty.
3148
+ * Takes the next progress notification, waiting for the single producer slot when empty.
3151
3149
  *
3152
3150
  * @returns The official progress notification carrying the original token
3153
3151
  * @throws When the reporter stops or another consumer already has a pending take
@@ -3171,7 +3169,7 @@ var MCPProgressReporter = class {
3171
3169
  return buildProgressNotification(this.#token, progress);
3172
3170
  }
3173
3171
  /**
3174
- * Permanently stop the reporter, reject pending work, and detach its abort listener.
3172
+ * Stops the reporter permanently, rejects pending work, and detaches its abort listener.
3175
3173
  *
3176
3174
  * Repeated calls are idempotent. No queued or replayable progress survives the first call.
3177
3175
  *
@@ -3213,10 +3211,10 @@ var MCPProgressReporter = class {
3213
3211
  * cleanup to the producer — so a cooperating producer is woken rather than waited on —
3214
3212
  * contains every promise the producer settles late, and makes every closure path idempotent.
3215
3213
  *
3216
- * The three closures are deliberately different answers: the source's own return is the
3214
+ * The closures are deliberately different answers: the source's own return is the
3217
3215
  * terminal RESPONSE, `return(value)` is the consumer saying it has the answer already, and
3218
- * {@link stop} is an owner saying there will be no answer at all. Only the first is a
3219
- * message a peer ever sees.
3216
+ * {@link stop} is an owner saying there will be no answer at all. Only the source's own
3217
+ * return is a message a peer ever sees.
3220
3218
  *
3221
3219
  * A producer's own resource cleanup remains the producer's: JavaScript cannot settle work a
3222
3220
  * generator is suspended inside, so the signal is how an uncooperative producer is asked to
@@ -3249,7 +3247,7 @@ var MCPStreamController = class {
3249
3247
  #error;
3250
3248
  #closed = false;
3251
3249
  /**
3252
- * Control one produced stream for the lifetime of one request.
3250
+ * Controls one produced stream for the lifetime of one request.
3253
3251
  *
3254
3252
  * @param source - The produced held-open result whose cancellation this controller owns
3255
3253
  * @param signal - The request signal every closure settles against; its abort ends the exchange
@@ -3264,7 +3262,7 @@ var MCPStreamController = class {
3264
3262
  else signal.addEventListener("abort", this.#listener, { once: true });
3265
3263
  }
3266
3264
  /**
3267
- * Read the next message, or the terminating response that ends the exchange.
3265
+ * Reads the next message, or the terminating response that ends the exchange.
3268
3266
  *
3269
3267
  * @remarks
3270
3268
  * At most one read is outstanding against the source at a time, and a rival read is
@@ -3299,7 +3297,7 @@ var MCPStreamController = class {
3299
3297
  };
3300
3298
  }
3301
3299
  /**
3302
- * End the exchange because the consumer already has its answer.
3300
+ * Ends the exchange because the consumer already has its answer.
3303
3301
  *
3304
3302
  * @param value - The terminal the consumer is ending on
3305
3303
  * @returns That terminal as the iteration's `return`
@@ -3313,7 +3311,7 @@ var MCPStreamController = class {
3313
3311
  };
3314
3312
  }
3315
3313
  /**
3316
- * End the exchange with a failure the consumer is raising.
3314
+ * Ends the exchange with a failure the consumer is raising.
3317
3315
  *
3318
3316
  * @param error - The failure to end the exchange with
3319
3317
  * @returns Never — the returned promise always rejects
@@ -3324,7 +3322,7 @@ var MCPStreamController = class {
3324
3322
  throw error;
3325
3323
  }
3326
3324
  /**
3327
- * End the exchange permanently, with no terminal response.
3325
+ * Ends the exchange permanently, with no terminal response.
3328
3326
  *
3329
3327
  * @remarks
3330
3328
  * Idempotent, and the operation an owner that is not the consumer uses: a transport whose
@@ -3339,7 +3337,7 @@ var MCPStreamController = class {
3339
3337
  if (!this.#closed) this.#fail(this.#closure.signal.reason);
3340
3338
  }
3341
3339
  /**
3342
- * End the exchange when the scope that owns it exits.
3340
+ * Ends the exchange when the scope that owns it exits.
3343
3341
  *
3344
3342
  * @remarks
3345
3343
  * {@link stop} under the name a `finally` calls it by, so a pump discharges its ownership
@@ -3352,7 +3350,7 @@ var MCPStreamController = class {
3352
3350
  this.stop();
3353
3351
  }
3354
3352
  /**
3355
- * Iterate this exchange — the controller is its own iterator.
3353
+ * Iterates this exchange — the controller is its own iterator.
3356
3354
  *
3357
3355
  * @returns This controller
3358
3356
  */
@@ -3441,7 +3439,7 @@ var MCPStreamController = class {
3441
3439
  var MCPTextStreamController = class {
3442
3440
  #stream;
3443
3441
  /**
3444
- * Mirror one controlled typed exchange as its serialized sequence.
3442
+ * Mirrors one controlled typed exchange as its serialized sequence.
3445
3443
  *
3446
3444
  * @param stream - The controlled typed stream this face serializes and delegates into
3447
3445
  */
@@ -3449,7 +3447,7 @@ var MCPTextStreamController = class {
3449
3447
  this.#stream = stream;
3450
3448
  }
3451
3449
  /**
3452
- * Read the next serialized message, or the serialized terminating response.
3450
+ * Reads the next serialized message, or the serialized terminating response.
3453
3451
  *
3454
3452
  * @returns The next message as a string, or the terminal as the iteration's `return`
3455
3453
  * @throws Whatever ended the typed exchange, unserialized — an abort is not a message
@@ -3466,7 +3464,7 @@ var MCPTextStreamController = class {
3466
3464
  };
3467
3465
  }
3468
3466
  /**
3469
- * End the exchange because the consumer already has its answer.
3467
+ * Ends the exchange because the consumer already has its answer.
3470
3468
  *
3471
3469
  * @remarks
3472
3470
  * The typed exchange ends with no terminal, because a string is not a
@@ -3485,7 +3483,7 @@ var MCPTextStreamController = class {
3485
3483
  };
3486
3484
  }
3487
3485
  /**
3488
- * End the exchange with a failure the consumer is raising.
3486
+ * Ends the exchange with a failure the consumer is raising.
3489
3487
  *
3490
3488
  * @param error - The failure to end the exchange with
3491
3489
  * @returns Never — the returned promise always rejects
@@ -3496,7 +3494,7 @@ var MCPTextStreamController = class {
3496
3494
  throw error;
3497
3495
  }
3498
3496
  /**
3499
- * End the typed exchange permanently, with no terminal response.
3497
+ * Ends the typed exchange permanently, with no terminal response.
3500
3498
  *
3501
3499
  * @returns Nothing
3502
3500
  */
@@ -3504,7 +3502,7 @@ var MCPTextStreamController = class {
3504
3502
  this.#stream.stop();
3505
3503
  }
3506
3504
  /**
3507
- * End the typed exchange when the scope that owns this face exits.
3505
+ * Ends the typed exchange when the scope that owns this face exits.
3508
3506
  *
3509
3507
  * @remarks
3510
3508
  * Delegates downward exactly as {@link stop} does — disposing the serialized arm is
@@ -3516,7 +3514,7 @@ var MCPTextStreamController = class {
3516
3514
  this.#stream.stop();
3517
3515
  }
3518
3516
  /**
3519
- * Iterate this exchange — the controller is its own iterator.
3517
+ * Iterates this exchange — the controller is its own iterator.
3520
3518
  *
3521
3519
  * @returns This controller
3522
3520
  */
@@ -3527,7 +3525,7 @@ var MCPTextStreamController = class {
3527
3525
  //#endregion
3528
3526
  //#region src/core/MCPLegacy.ts
3529
3527
  /**
3530
- * Translate the fixed legacy method set onto one modern dispatcher.
3528
+ * Translates the fixed legacy method set onto one modern dispatcher.
3531
3529
  *
3532
3530
  * @remarks
3533
3531
  * This decorator owns no execution engine or result normalizer. Modern invocations
@@ -3538,7 +3536,7 @@ var MCPTextStreamController = class {
3538
3536
  var MCPLegacy = class {
3539
3537
  #options;
3540
3538
  /**
3541
- * Create a legacy decorator.
3539
+ * Creates a legacy decorator.
3542
3540
  *
3543
3541
  * @param options - The sole dispatcher and legacy handshake identity
3544
3542
  */
@@ -3647,7 +3645,7 @@ var MCPLegacy = class {
3647
3645
  * requests over a live {@link ToolManagerInterface}, with NO transport coupling.
3648
3646
  *
3649
3647
  * @remarks
3650
- * - **Two entry points.** `dispatch(invocation)` runs an already-parsed invocation and
3648
+ * - **`dispatch` and `handle`.** `dispatch(invocation)` runs an already-parsed invocation and
3651
3649
  * resolves a {@link JSONRPCResponse} for a request — or `undefined` for a
3652
3650
  * {@link JSONRPCNotification}, which carries no `id` and is answered by nothing.
3653
3651
  * `handle(message)` is the string boundary: it
@@ -3663,8 +3661,8 @@ var MCPLegacy = class {
3663
3661
  * every dispatch: the same path a later method or a consumer's own takes, with an
3664
3662
  * unregistered method still answering `-32601`.
3665
3663
  * - **Provider-agnostic.** Imports only core siblings — JSON-RPC + the tool registry,
3666
- * no HTTP, no model. Wire fields are narrowed via the contracts guards (no `as`).
3667
- * - **Observable (§13).** The owned `emitter` fires `request` at the top of every
3664
+ * no HTTP, no model. Wire fields are narrowed with the contract guards (no `as`).
3665
+ * - **Observable.** The owned `emitter` fires `request` at the top of every
3668
3666
  * dispatch; the emitter isolates a listener throw and routes it to its `error` handler
3669
3667
  * (the `error` option), so a listener throw can never escape the dispatch.
3670
3668
  *
@@ -3785,6 +3783,11 @@ var MCPServer = class {
3785
3783
  }
3786
3784
  async #modern(request, options) {
3787
3785
  const id = request.id;
3786
+ const method = request.method;
3787
+ if (!isModernRequest(request)) {
3788
+ if (this.#methods.method(method) === void 0) return buildJSONRPCError(id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${method}`);
3789
+ return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: request declares no protocol version");
3790
+ }
3788
3791
  const context = parseRequestContext(request, {
3789
3792
  bytes: this.#limits.message,
3790
3793
  depth: this.#limits.depth
@@ -4313,7 +4316,7 @@ var MCPServer = class {
4313
4316
  //#endregion
4314
4317
  //#region src/core/MCPTaskClient.ts
4315
4318
  /**
4316
- * The CLIENT half of the draft Tasks extension — the three `tasks/*` methods over one
4319
+ * The CLIENT half of the draft Tasks extension — the `tasks/*` methods over one
4317
4320
  * correlated-request door, exposed as an {@link import('./types.js').MCPClientInterface}'s
4318
4321
  * `tasks`.
4319
4322
  *
@@ -4333,7 +4336,7 @@ var MCPServer = class {
4333
4336
  * client's id space, pending table, deadline policy, and `disconnect` drain rather than
4334
4337
  * opening a second path to the same peer.
4335
4338
  * - **The peer authorizes.** Nothing is checked locally. A server that never configured the
4336
- * extension answers all three `-32601`, and a task that never existed, one whose TTL purged
4339
+ * extension answers each of them `-32601`, and a task that never existed, one whose TTL purged
4337
4340
  * it, and one belonging to another principal are all the same `-32602` — a refusal this
4338
4341
  * client passes on rather than resolving into a distinction the peer refused to publish.
4339
4342
  *
@@ -4410,16 +4413,16 @@ var MCPTaskClient = class {
4410
4413
  * exit — the deadline, an abort, a rejecting `send`, the answer itself, and the
4411
4414
  * teardown's drain — without any of those paths knowing they exist.
4412
4415
  * - **Per-request deadline.** An ordinary `#request` carries `this.#timeout`. The initial
4413
- * discovery probe uses that same 30-second default, or the shorter probe deadline where
4414
- * `timeout` was configured, so a silent peer cannot hold negotiation indefinitely.
4416
+ * discovery probe uses that same configured deadline, so a silent peer cannot hold
4417
+ * negotiation indefinitely.
4415
4418
  * `AbortSignal.timeout` (never a raw `setTimeout`) rejects only that pending request, and the
4416
4419
  * same deadline bounds the WAIT on the transport's `close`, the one wait no drain and no signal
4417
4420
  * can reach. It bounds the wait rather than the close, which keeps running, so a retry joins it
4418
4421
  * instead of shutting one connection down twice.
4419
4422
  * - **Transport-agnostic.** Imports only core siblings (JSON-RPC + the tool vocabulary);
4420
- * the concrete transport is injected. Wire fields are narrowed via the contracts
4423
+ * the concrete transport is injected. Wire fields are narrowed with the contract
4421
4424
  * guards (no `as`).
4422
- * - **Observable (§13).** The owned `emitter` fires `connect` / `disconnect` /
4425
+ * - **Observable.** The owned `emitter` fires `connect` / `disconnect` /
4423
4426
  * `notification` / `error`; the emitter isolates a listener throw and routes it to its
4424
4427
  * `error` handler (the `error` option), so a listener throw can never escape.
4425
4428
  *
@@ -4440,7 +4443,6 @@ var MCPClient = class {
4440
4443
  #capabilities;
4441
4444
  #pin;
4442
4445
  #timeout;
4443
- #probe;
4444
4446
  #tasks;
4445
4447
  #pending = /* @__PURE__ */ new Map();
4446
4448
  #nextId = 0;
@@ -4455,6 +4457,11 @@ var MCPClient = class {
4455
4457
  #era = void 0;
4456
4458
  #offer;
4457
4459
  constructor(options) {
4460
+ const requested = options.version;
4461
+ if (requested !== void 0 && !isMCPVersion(requested)) throw new MCPError("Unsupported protocol version", MCP_UNSUPPORTED_VERSION, {
4462
+ supported: SUPPORTED_PROTOCOL_VERSIONS,
4463
+ requested
4464
+ });
4458
4465
  this.#emitter = new Emitter({
4459
4466
  ...options.on !== void 0 ? { on: options.on } : {},
4460
4467
  ...options.error !== void 0 ? { error: options.error } : {}
@@ -4465,10 +4472,9 @@ var MCPClient = class {
4465
4472
  version: "1.0.0"
4466
4473
  };
4467
4474
  this.#capabilities = options.capabilities ?? {};
4468
- this.#pin = options.version;
4469
- this.#offer = options.version ?? "2026-07-28";
4475
+ this.#pin = requested;
4476
+ this.#offer = requested ?? "2026-07-28";
4470
4477
  this.#timeout = options.timeout ?? 3e4;
4471
- this.#probe = options.timeout === void 0 ? DEFAULT_MCP_REQUEST_TIMEOUT : Math.min(options.timeout, 50);
4472
4478
  this.#tasks = new MCPTaskClient({
4473
4479
  request: this.#request.bind(this),
4474
4480
  timeout: this.#timeout
@@ -4490,9 +4496,6 @@ var MCPClient = class {
4490
4496
  get tasks() {
4491
4497
  return this.#tasks;
4492
4498
  }
4493
- on(event, handler) {
4494
- this.#emitter.on(event, handler);
4495
- }
4496
4499
  async connect() {
4497
4500
  for (;;) {
4498
4501
  const closing = this.#disconnecting;
@@ -4525,7 +4528,7 @@ var MCPClient = class {
4525
4528
  }
4526
4529
  }
4527
4530
  async discover() {
4528
- const received = await this.#request("server/discover", void 0, this.#probe, this.#version ?? this.#offer);
4531
+ const received = await this.#request("server/discover", void 0, this.#timeout, this.#version ?? this.#offer);
4529
4532
  const owned = attempt(() => cloneJSONRecord(received));
4530
4533
  if (!owned.success) throw new MCPError("MCP server returned a malformed discovery result", JSONRPC_INVALID_PARAMS);
4531
4534
  const result = owned.value;
@@ -4735,7 +4738,13 @@ var MCPClient = class {
4735
4738
  await this.#initialize(generation, MCP_PROTOCOL_VERSION);
4736
4739
  return;
4737
4740
  }
4738
- const version = inferVersion(discovery.supportedVersions);
4741
+ let version;
4742
+ if (this.#pin === void 0) version = inferVersion(discovery.supportedVersions);
4743
+ else if (discovery.supportedVersions.includes(this.#pin)) version = this.#pin;
4744
+ else throw new MCPError("MCP server does not support the pinned protocol version", MCP_UNSUPPORTED_VERSION, {
4745
+ supported: discovery.supportedVersions,
4746
+ requested: this.#pin
4747
+ });
4739
4748
  if (version === void 0) throw new MCPError("MCP server supports no compatible protocol version", MCP_UNSUPPORTED_VERSION, { supported: discovery.supportedVersions });
4740
4749
  if (generation !== this.#generation) throw new Error("MCP client disconnected");
4741
4750
  this.#version = version;
@@ -4811,6 +4820,10 @@ var MCPClient = class {
4811
4820
  if (protocol === void 0) throw new Error("MCP server returned no protocol version");
4812
4821
  if (!isString(protocol)) throw new Error("MCP server returned a malformed protocol version");
4813
4822
  if (!isMCPVersion(protocol) || inferEra(protocol) !== "legacy") throw new Error(`MCP server negotiated unsupported protocol version '${protocol}'`);
4823
+ if (this.#pin !== void 0 && protocol !== this.#pin) throw new MCPError("MCP server negotiated a different protocol version than the client pinned", MCP_UNSUPPORTED_VERSION, {
4824
+ requested: this.#pin,
4825
+ negotiated: protocol
4826
+ });
4814
4827
  if (generation !== this.#generation) throw new Error("MCP client disconnected");
4815
4828
  await Promise.race([this.#transport.send({
4816
4829
  jsonrpc: "2.0",
@@ -4844,7 +4857,7 @@ var MCPClient = class {
4844
4857
  //#endregion
4845
4858
  //#region src/core/factories.ts
4846
4859
  /**
4847
- * Create a transport-agnostic Model Context Protocol server — exposes a live
4860
+ * Creates a transport-agnostic Model Context Protocol server — exposes a live
4848
4861
  * {@link import('@orkestrel/tool').ToolManagerInterface} and an optional
4849
4862
  * {@link import('./types.js').MCPResourceManagerInterface},
4850
4863
  * {@link import('./types.js').MCPPromptManagerInterface}, and
@@ -4857,7 +4870,7 @@ var MCPClient = class {
4857
4870
  * and no model. The {@link import('@orkestrel/tool').ToolManagerInterface} already
4858
4871
  * isolates a thrown tool into a `success: false` result (surfaced as an MCP
4859
4872
  * `isError: true` tool result), so a misbehaving tool never crashes a dispatch. Subscribe to the
4860
- * `request` event via `server.emitter.on('request', …)` for tracing.
4873
+ * `request` event through `server.emitter.on('request', …)` for tracing.
4861
4874
  *
4862
4875
  * @param options - `identity` (the server identity), `tools` (the live tool
4863
4876
  * registry), optional `resources` (the consumer-owned resource registry), optional
@@ -4869,7 +4882,8 @@ var MCPClient = class {
4869
4882
  *
4870
4883
  * @example
4871
4884
  * ```ts
4872
- * import { createMCPServer, createTool, createToolManager } from '@src/core'
4885
+ * import { createMCPServer } from '@orkestrel/mcp'
4886
+ * import { createTool, createToolManager } from '@orkestrel/tool'
4873
4887
  *
4874
4888
  * const tools = createToolManager()
4875
4889
  * tools.add(createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }))
@@ -4886,7 +4900,7 @@ function createMCPServer(options) {
4886
4900
  return new MCPServer(options);
4887
4901
  }
4888
4902
  /**
4889
- * Decorate one MCP server with the fixed legacy method translation.
4903
+ * Decorates one MCP server with the fixed legacy method translation.
4890
4904
  *
4891
4905
  * @param server - The sole modern dispatcher and handshake identity source
4892
4906
  * @returns A dispatcher accepting both modern and legacy invocations
@@ -4898,7 +4912,7 @@ function createMCPLegacy(server) {
4898
4912
  });
4899
4913
  }
4900
4914
  /**
4901
- * Create a transport-agnostic Model Context Protocol CLIENT — connects to a REMOTE
4915
+ * Creates a transport-agnostic Model Context Protocol CLIENT — connects to a REMOTE
4902
4916
  * MCP server over an injected {@link import('./types.js').MCPClientTransportInterface},
4903
4917
  * runs the `initialize` handshake, and exposes the server's tools as local
4904
4918
  * {@link import('@orkestrel/tool').ToolInterface}s an agent can run.
@@ -4912,8 +4926,7 @@ function createMCPLegacy(server) {
4912
4926
  * locally, so an agent's {@link import('@orkestrel/tool').ToolManagerInterface}
4913
4927
  * isolates it). The transport is injected — a concrete one (the HTTP transport over
4914
4928
  * `fetch`) lives in the published server environment; the client itself is provider-agnostic. Subscribe
4915
- * to `connect` / `disconnect` / `notification` via `client.on(...)` (or
4916
- * `client.emitter.on(...)`).
4929
+ * to `connect` / `disconnect` / `notification` through `client.emitter.on(...)`.
4917
4930
  *
4918
4931
  * @param options - `transport` (the carrier; REQUIRED), an optional `identity`
4919
4932
  * (the client identity), `timeout` (the per-request deadline), and the reserved `on`
@@ -4922,7 +4935,7 @@ function createMCPLegacy(server) {
4922
4935
  *
4923
4936
  * @example
4924
4937
  * ```ts
4925
- * import { createMCPClient } from '@src/core'
4938
+ * import { createMCPClient } from '@orkestrel/mcp'
4926
4939
  * import { createHTTPClientTransport } from '@orkestrel/mcp/server'
4927
4940
  *
4928
4941
  * const client = createMCPClient({
@@ -4937,7 +4950,7 @@ function createMCPClient(options) {
4937
4950
  return new MCPClient(options);
4938
4951
  }
4939
4952
  /**
4940
- * Adapt an {@link MCPTransportInterface} (the environment-agnostic duplex message
4953
+ * Adapts an {@link MCPTransportInterface} (the environment-agnostic duplex message
4941
4954
  * channel) into a {@link MCPClientTransportInterface} — the additive bridge that lets
4942
4955
  * `createMCPClient` run over the new port without any change to `MCPClient`'s
4943
4956
  * existing shape.
@@ -4945,7 +4958,7 @@ function createMCPClient(options) {
4945
4958
  * @remarks
4946
4959
  * Hand the RESULT to `createMCPClient({ transport })`, then pass the SAME
4947
4960
  * `transport` to {@link import('./helpers.js').bindClient} to complete the inbound
4948
- * wiring: `send` serializes each outbound {@link JSONRPCMessage} and writes it via
4961
+ * wiring: `send` serializes each outbound {@link JSONRPCMessage} and writes it through
4949
4962
  * `transport.send`; `close` closes the underlying
4950
4963
  * `transport`; `start` is a no-op (the duplex channel is already open by the time
4951
4964
  * it is handed in — there is no separate connect step at this layer); `session` is
@@ -4985,6 +4998,6 @@ function createDuplexClientTransport(transport) {
4985
4998
  };
4986
4999
  }
4987
5000
  //#endregion
4988
- export { DEFAULT_MCP_CACHE_TTL, DEFAULT_MCP_CLIENT_NAME, DEFAULT_MCP_CLIENT_VERSION, DEFAULT_MCP_LIMITS, DEFAULT_MCP_PROBE_TIMEOUT, DEFAULT_MCP_REQUEST_TIMEOUT, EMPTY_MCP_ARGUMENTS, JSONRPC_INTERNAL_ERROR, JSONRPC_INVALID_PARAMS, JSONRPC_INVALID_REQUEST, JSONRPC_METHOD_NOT_FOUND, JSONRPC_PARSE_ERROR, JSONRPC_SERVER_ERROR, MCPClient, MCPError, MCPLegacy, MCPMethodManager, MCPProgressReporter, MCPServer, MCPStreamController, MCPTaskClient, MCPTextStreamController, MCP_EXTENSION_TASKS, MCP_HEADER_MISMATCH, MCP_LEGACY_VERSION, MCP_META_CAPABILITIES, MCP_META_CLIENT, MCP_META_SERVER, MCP_META_SUBSCRIPTION, MCP_META_VERSION, MCP_MISSING_CAPABILITY, MCP_MODERN_VERSION, MCP_PROTOCOL_VERSION, MCP_UNSUPPORTED_VERSION, SUPPORTED_PROTOCOL_VERSIONS, bindClient, bindServer, buildCallOutcome, buildCancelledNotification, buildDiscoverResult, buildInitializeResult, buildJSONRPCError, buildJSONRPCResult, buildMethodOptions, buildModernResult, buildProgressNotification, buildSubscriptionAcknowledgement, buildSubscriptionFilter, buildSubscriptionResult, buildToolCall, buildToolDescriptors, createDuplexClientTransport, createMCPClient, createMCPLegacy, createMCPServer, decodeBoundedMessage, digestJSON, extractContentText, inferEra, inferRequestVersion, inferVersion, isAbsoluteURI, isBoundedJSON, isBoundedString, isElicitContent, isFormElicitationSupported, isInitializeRequest, isJSONObject, isJSONRPCError, isJSONRPCErrorResponse, isJSONRPCId, isJSONRPCInvocation, isJSONRPCMessage, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse, isJSONRPCResultResponse, isMCPAnnotations, isMCPBlobResource, isMCPCallResult, isMCPClientCapabilities, isMCPCompletion, isMCPCompletionParams, isMCPCompletionReference, isMCPCompletionResult, isMCPContent, isMCPElicitFieldSchema, isMCPElicitForm, isMCPElicitRequest, isMCPElicitResult, isMCPElicitSchema, isMCPElicitURL, isMCPError, isMCPIcon, isMCPIdentity, isMCPInputRequest, isMCPInputRequestMap, isMCPInputResult, isMCPLegacyResult, isMCPLoggingLevel, isMCPMetaKey, isMCPMetaObject, isMCPPaginationParams, isMCPProgress, isMCPPrompt, isMCPPromptArgument, isMCPPromptGetResult, isMCPPromptMessage, isMCPPromptPage, isMCPResource, isMCPResourceContents, isMCPResourcePage, isMCPResourceTemplate, isMCPResourceTemplatePage, isMCPResult, isMCPResultMetaObject, isMCPServerCapabilities, isMCPStringArguments, isMCPSubscriptionFilter, isMCPTaskDetail, isMCPTaskResult, isMCPTaskStatus, isMCPTextResource, isMCPVersion, isModernRequest, isRFC3339Date, isRFC3339DateTime, isStandardBase64, isTaskSupported, matchesResultType, matchesSubscriptionNotification, parseJSONRPCMessage, parseMCPInputState, parseRequestContext, readCancelledId, sendStream, serializeJSON, snapshotJSON, snapshotToolResult, stampSubscriptionNotification };
5001
+ export { DEFAULT_MCP_CACHE_TTL, DEFAULT_MCP_CLIENT_NAME, DEFAULT_MCP_CLIENT_VERSION, DEFAULT_MCP_LIMITS, DEFAULT_MCP_REQUEST_TIMEOUT, EMPTY_MCP_ARGUMENTS, JSONRPC_INTERNAL_ERROR, JSONRPC_INVALID_PARAMS, JSONRPC_INVALID_REQUEST, JSONRPC_METHOD_NOT_FOUND, JSONRPC_PARSE_ERROR, JSONRPC_SERVER_ERROR, MCPClient, MCPError, MCPLegacy, MCPMethodManager, MCPProgressReporter, MCPServer, MCPStreamController, MCPTaskClient, MCPTextStreamController, MCP_EXTENSION_TASKS, MCP_HEADER_MISMATCH, MCP_LEGACY_VERSION, MCP_META_CAPABILITIES, MCP_META_CLIENT, MCP_META_SERVER, MCP_META_SUBSCRIPTION, MCP_META_VERSION, MCP_MISSING_CAPABILITY, MCP_MODERN_VERSION, MCP_PROTOCOL_VERSION, MCP_UNSUPPORTED_VERSION, SUPPORTED_PROTOCOL_VERSIONS, bindClient, bindServer, buildCallOutcome, buildCancelledNotification, buildDiscoverResult, buildInitializeResult, buildJSONRPCError, buildJSONRPCResult, buildMethodOptions, buildModernResult, buildProgressNotification, buildSubscriptionAcknowledgement, buildSubscriptionFilter, buildSubscriptionResult, buildToolCall, buildToolDescriptors, createDuplexClientTransport, createMCPClient, createMCPLegacy, createMCPServer, decodeBoundedMessage, digestJSON, extractContentText, inferEra, inferRequestVersion, inferVersion, isAbsoluteURI, isBoundedJSON, isBoundedString, isElicitContent, isFormElicitationSupported, isInitializeRequest, isJSONObject, isJSONRPCError, isJSONRPCErrorResponse, isJSONRPCId, isJSONRPCInvocation, isJSONRPCMessage, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse, isJSONRPCResultResponse, isMCPAnnotations, isMCPBlobResource, isMCPCallResult, isMCPClientCapabilities, isMCPCompletion, isMCPCompletionParams, isMCPCompletionReference, isMCPCompletionResult, isMCPContent, isMCPElicitFieldSchema, isMCPElicitForm, isMCPElicitRequest, isMCPElicitResult, isMCPElicitSchema, isMCPElicitURL, isMCPError, isMCPIcon, isMCPIdentity, isMCPInputRequest, isMCPInputRequestMap, isMCPInputResult, isMCPLegacyResult, isMCPLoggingLevel, isMCPMetaKey, isMCPMetaObject, isMCPPaginationParams, isMCPProgress, isMCPPrompt, isMCPPromptArgument, isMCPPromptGetResult, isMCPPromptMessage, isMCPPromptPage, isMCPResource, isMCPResourceContents, isMCPResourcePage, isMCPResourceTemplate, isMCPResourceTemplatePage, isMCPResult, isMCPResultMetaObject, isMCPServerCapabilities, isMCPStringArguments, isMCPSubscriptionFilter, isMCPTaskDetail, isMCPTaskResult, isMCPTaskStatus, isMCPTextResource, isMCPVersion, isModernRequest, isRFC3339Date, isRFC3339DateTime, isStandardBase64, isTaskSupported, matchesResultType, matchesSubscriptionNotification, parseJSONRPCMessage, parseMCPInputState, parseRequestContext, readCancelledId, sendStream, serializeJSON, snapshotJSON, snapshotToolResult, stampSubscriptionNotification };
4989
5002
 
4990
5003
  //# sourceMappingURL=index.js.map