@orkestrel/mcp 0.0.32 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,8 +76,9 @@ and the browser face (`./browser`), which is ESM only.
76
76
 
77
77
  `npm run test:conformance` starts the real Streamable HTTP server from this
78
78
  package's source and runs
79
- `@modelcontextprotocol/conformance@0.2.0-alpha.10` against MCP revision
80
- `2026-07-28`. The recorded result is **23 passed / 0 failed**. That is a
79
+ `@modelcontextprotocol/conformance@0.2.0-alpha.11` against MCP revision
80
+ `2026-07-28`. The recorded result is **147 passed / 0 failed**, from the run on
81
+ 2026-09-29 against the built `dist/`. That is a
81
82
  genuine foreign MCP client driving this server end to end, and it is
82
83
  evidence about the wire. It resolves the runner from `node_modules` and
83
84
  drives a loopback socket, so the run is offline and `npm test` gates it.
@@ -433,6 +433,23 @@ export declare function isWebMCPDocument(value: unknown): value is WebMCPDocumen
433
433
  */
434
434
  export declare function isWebMCPRegistry(value: unknown): value is WebMCPRegistryInterface;
435
435
 
436
+ /**
437
+ * Determines whether an unknown value is a WebMCP execution event.
438
+ *
439
+ * @remarks
440
+ * Reads the IDL's `toolName` attribute and nothing else, so it admits a `ToolActivatedEvent`
441
+ * and a `ToolCancelEvent` and refuses a plain `Event`.
442
+ *
443
+ * @param value - The unknown value to inspect
444
+ * @returns True if the value carries a string `toolName`; false otherwise
445
+ *
446
+ * @example
447
+ * ```ts
448
+ * isWebMCPToolEvent(new Event('toolactivated')) // false
449
+ * ```
450
+ */
451
+ export declare function isWebMCPToolEvent(value: unknown): value is WebMCPToolEvent;
452
+
436
453
  /**
437
454
  * Determines whether two WebMCP descriptors advertise the same tool to the registry.
438
455
  *
@@ -618,7 +635,7 @@ export declare interface MessagePortTransportOptions {
618
635
  export declare class ModelContext implements ModelContextInterface {
619
636
  #private;
620
637
  /**
621
- * Binds a narrowed document's registry and arms the `toolchange` subscription.
638
+ * Binds a narrowed document's registry and arms its change and execution subscriptions.
622
639
  *
623
640
  * @param document - The document whose `modelContext` this handle bridges
624
641
  * @param options - The emitter's initial hooks and listener-error handler; see
@@ -632,28 +649,37 @@ export declare class ModelContext implements ModelContextInterface {
632
649
  }
633
650
 
634
651
  /**
635
- * Options for {@link ModelContextInterface.adopt} — the origins whose tools are read.
652
+ * Options for {@link ModelContextInterface.adopt} — the origins and debugging tools to include.
636
653
  *
637
654
  * @remarks
638
655
  * `origins` is this package's one-word name for WebMCP's `fromOrigins`, forwarded unchanged.
639
656
  * Omitting it reads this document's own registrations.
657
+ * If `debugging` is `true`, tools carrying `annotations.debugging: true` are included;
658
+ * if `false` or omitted, they are excluded. Default: `false`.
640
659
  */
641
660
  export declare interface ModelContextAdoptOptions {
642
661
  readonly origins?: readonly string[];
662
+ readonly debugging?: boolean;
643
663
  }
644
664
 
645
665
  /**
646
- * Reports the moments a WebMCP registry's contents changed.
666
+ * Reports changes and execution events from a WebMCP registry.
647
667
  *
648
668
  * @remarks
649
669
  * Declared as a `type` alias rather than an interface, so the type-literal satisfies
650
- * `EventMap` structurally. One event, because the registry publishes one: WebMCP's
670
+ * `EventMap` structurally. The 2026-09-29 WebMCP draft's
651
671
  * `toolchange` names no tool and carries no payload, so the bridge republishes it as a bare
652
672
  * signal and a listener re-reads {@link ModelContextInterface.adopt} to learn what changed.
673
+ * `toolactivated` and `toolcancel` carry the tool name; cancellation uses the bridge's
674
+ * lifecycle verb `abort`.
653
675
  */
654
676
  export declare type ModelContextEventMap = {
655
677
  /** Reports that the document's registry changed — re-read it to learn how. */
656
678
  readonly change: readonly [];
679
+ /** Reports the tool whose execution begins. */
680
+ readonly activate: readonly [name: string];
681
+ /** Reports the tool whose pending execution is aborted. */
682
+ readonly abort: readonly [name: string];
657
683
  };
658
684
 
659
685
  /**
@@ -672,7 +698,7 @@ export declare type ModelContextEventMap = {
672
698
  * never registered are untouched.
673
699
  */
674
700
  export declare interface ModelContextInterface {
675
- /** Holds the emitter republishing the registry's `toolchange` as `change`. */
701
+ /** Holds the emitter republishing registry changes, activation, and aborts. */
676
702
  readonly emitter: EmitterInterface<ModelContextEventMap>;
677
703
  /**
678
704
  * Registers every tool the manager holds at this moment, then follows it.
@@ -734,9 +760,12 @@ export declare interface ModelContextInterface {
734
760
  */
735
761
  publish(tools: ToolManagerInterface, options?: ModelContextPublishOptions): Promise<void>;
736
762
  /**
737
- * Reads the document's registered tools as locally executable tools.
763
+ * Reads the document's registered tools as locally executable tools, excluding debugging tools unless requested.
738
764
  *
739
765
  * @remarks
766
+ * Tools carrying `annotations.debugging: true` are excluded unless `options.debugging`
767
+ * is `true`. Tools with a false or omitted hint are included either way.
768
+ *
740
769
  * Each returned tool's `execute` runs the registry's `executeTool` and forwards its
741
770
  * `ToolContext.signal` as WebMCP's `signal`, so an agent-side abort reaches the foreign
742
771
  * tool. The value resolves unchanged: WebMCP's own sources disagree about whether a tool
@@ -747,8 +776,8 @@ export declare interface ModelContextInterface {
747
776
  * unreadable or hostile schema refuse the whole `adopt` call, and the arguments reach a
748
777
  * handler in another document that has to validate them anyway.
749
778
  *
750
- * @param options - The optional origin filter; see {@link ModelContextAdoptOptions}
751
- * @returns The registry's tools, in registry order
779
+ * @param options - The origin and debugging filters; see {@link ModelContextAdoptOptions}
780
+ * @returns The included registry tools, in registry order
752
781
  */
753
782
  adopt(options?: ModelContextAdoptOptions): Promise<readonly ToolInterface[]>;
754
783
  /**
@@ -964,6 +993,12 @@ export declare function toolAnnotationsToWebMCP(annotations: ToolAnnotations): W
964
993
  */
965
994
  export declare function toolToWebMCP(definition: ToolDefinition): WebMCPDescriptor | undefined;
966
995
 
996
+ /** Names the WebMCP IDL `toolcancel` event the bridge republishes as `abort`. */
997
+ export declare const WEBMCP_ABORT_EVENT = "toolcancel";
998
+
999
+ /** Names the WebMCP IDL `toolactivated` event the bridge republishes as `activate`. */
1000
+ export declare const WEBMCP_ACTIVATED_EVENT = "toolactivated";
1001
+
967
1002
  /** Names the WebMCP registry event the bridge republishes as its own `change`. */
968
1003
  export declare const WEBMCP_CHANGE_EVENT = "toolchange";
969
1004
 
@@ -971,17 +1006,20 @@ export declare const WEBMCP_CHANGE_EVENT = "toolchange";
971
1006
  * Describes a tool's observable effects as the WebMCP registry declares them.
972
1007
  *
973
1008
  * @remarks
974
- * Transliterates the WebMCP `ToolAnnotations` dictionary. The IDL defaults each member to
1009
+ * Transliterates the 2026-09-29 WebMCP draft's `ToolAnnotations` dictionary. The IDL defaults each member to
975
1010
  * `false`; this declaration keeps every member optional instead, because the bridge projects
976
1011
  * from `@orkestrel/tool`'s `ToolAnnotations` and never invents a hint the author omitted. The
977
1012
  * mapping is `pure` to `readOnlyHint`, `untrusted` to `untrustedContentHint`, and
978
1013
  * `consequential` to `consequentialHint` — a fuller correspondence than the MCP wire's, which
979
1014
  * has no counterpart for `untrusted` and spells the consequence `destructiveHint`.
1015
+ * The `debugging` hint has no domain counterpart: publication omits it and adoption filters it before
1016
+ * projecting the remaining hints.
980
1017
  */
981
1018
  export declare interface WebMCPAnnotations {
982
1019
  readonly readOnlyHint?: boolean;
983
1020
  readonly untrustedContentHint?: boolean;
984
1021
  readonly consequentialHint?: boolean;
1022
+ readonly debugging?: boolean;
985
1023
  }
986
1024
 
987
1025
  /**
@@ -1109,9 +1147,10 @@ export declare interface WebMCPRegisterOptions {
1109
1147
  * Represents the WebMCP tool registry a document exposes as `document.modelContext`.
1110
1148
  *
1111
1149
  * @remarks
1112
- * Transliterates the WebMCP `ModelContext` interface, which extends `EventTarget`: the
1113
- * operations plus the `toolchange` subscription the bridge republishes as
1114
- * {@link ModelContextEventMap}'s `change`. Only the members the bridge touches are declared,
1150
+ * Transliterates the 2026-09-29 WebMCP draft's `ModelContext` interface, which extends
1151
+ * `EventTarget`: the operations plus the `toolchange`, `toolactivated`, and `toolcancel`
1152
+ * subscriptions the bridge republishes as {@link ModelContextEventMap}'s `change`,
1153
+ * `activate`, and `abort`. Only the members the bridge touches are declared,
1115
1154
  * exactly as {@link ScopeInterface} declares only what `createScopeServer` touches, so a real
1116
1155
  * `ModelContext` satisfies this structurally and an IDL-faithful double satisfies it without
1117
1156
  * implementing the whole of `EventTarget`.
@@ -1131,8 +1170,10 @@ export declare interface WebMCPRegistryInterface {
1131
1170
  executeTool(tool: WebMCPRegisteredTool, input?: Readonly<Record<string, unknown>>, options?: WebMCPExecuteOptions): Promise<unknown>;
1132
1171
  /** Subscribes to the registry's `toolchange` event. */
1133
1172
  addEventListener(type: 'toolchange', listener: () => void): void;
1173
+ addEventListener(type: 'toolactivated' | 'toolcancel', listener: (event: Event) => void): void;
1134
1174
  /** Drops a `toolchange` subscription. */
1135
1175
  removeEventListener(type: 'toolchange', listener: () => void): void;
1176
+ removeEventListener(type: 'toolactivated' | 'toolcancel', listener: (event: Event) => void): void;
1136
1177
  }
1137
1178
 
1138
1179
  /**
@@ -1146,6 +1187,18 @@ export declare interface WebMCPTool extends WebMCPDescriptor {
1146
1187
  readonly execute: WebMCPExecuteHandler;
1147
1188
  }
1148
1189
 
1190
+ /**
1191
+ * Carries the tool name a WebMCP execution event reports.
1192
+ *
1193
+ * @remarks
1194
+ * Transliterates the `toolName` attribute of `ToolActivatedEvent` and `ToolCancelEvent` in
1195
+ * the 2026-09-29 WebMCP draft, the only event member the bridge reads. The `isWebMCPToolEvent`
1196
+ * guard narrows a dispatched `Event` onto this shape.
1197
+ */
1198
+ export declare interface WebMCPToolEvent {
1199
+ readonly toolName: string;
1200
+ }
1201
+
1149
1202
  /**
1150
1203
  * Options for the WebMCP registry's `getTools` — the origins whose tools are read.
1151
1204
  *
@@ -9,6 +9,10 @@ var DEFAULT_MCP_SERVER_NAME = "@orkestrel/mcp";
9
9
  var DEFAULT_MCP_SERVER_VERSION = "1.0.0";
10
10
  /** Names the WebMCP registry event the bridge republishes as its own `change`. */
11
11
  var WEBMCP_CHANGE_EVENT = "toolchange";
12
+ /** Names the WebMCP IDL `toolactivated` event the bridge republishes as `activate`. */
13
+ var WEBMCP_ACTIVATED_EVENT = "toolactivated";
14
+ /** Names the WebMCP IDL `toolcancel` event the bridge republishes as `abort`. */
15
+ var WEBMCP_ABORT_EVENT = "toolcancel";
12
16
  //#endregion
13
17
  //#region src/browser/validators.ts
14
18
  /**
@@ -57,6 +61,24 @@ function isWebMCPRegistry(value) {
57
61
  function isWebMCPDocument(value) {
58
62
  return objectOf({ modelContext: isWebMCPRegistry })(value);
59
63
  }
64
+ /**
65
+ * Determines whether an unknown value is a WebMCP execution event.
66
+ *
67
+ * @remarks
68
+ * Reads the IDL's `toolName` attribute and nothing else, so it admits a `ToolActivatedEvent`
69
+ * and a `ToolCancelEvent` and refuses a plain `Event`.
70
+ *
71
+ * @param value - The unknown value to inspect
72
+ * @returns True if the value carries a string `toolName`; false otherwise
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * isWebMCPToolEvent(new Event('toolactivated')) // false
77
+ * ```
78
+ */
79
+ function isWebMCPToolEvent(value) {
80
+ return objectOf({ toolName: isString })(value);
81
+ }
60
82
  //#endregion
61
83
  //#region src/browser/helpers.ts
62
84
  /**
@@ -358,12 +380,14 @@ var ModelContext = class {
358
380
  #emitter;
359
381
  #registrations = /* @__PURE__ */ new Map();
360
382
  #listener;
383
+ #activated;
384
+ #aborted;
361
385
  #followed = void 0;
362
386
  #pendingManager = void 0;
363
387
  #queue = Promise.resolve();
364
388
  #destroyed = false;
365
389
  /**
366
- * Binds a narrowed document's registry and arms the `toolchange` subscription.
390
+ * Binds a narrowed document's registry and arms its change and execution subscriptions.
367
391
  *
368
392
  * @param document - The document whose `modelContext` this handle bridges
369
393
  * @param options - The emitter's initial hooks and listener-error handler; see
@@ -377,6 +401,10 @@ var ModelContext = class {
377
401
  });
378
402
  this.#listener = this.#republish.bind(this);
379
403
  this.#registry.addEventListener(WEBMCP_CHANGE_EVENT, this.#listener);
404
+ this.#activated = this.#republishTool.bind(this, "activate");
405
+ this.#aborted = this.#republishTool.bind(this, "abort");
406
+ this.#registry.addEventListener(WEBMCP_ACTIVATED_EVENT, this.#activated);
407
+ this.#registry.addEventListener(WEBMCP_ABORT_EVENT, this.#aborted);
380
408
  }
381
409
  get emitter() {
382
410
  return this.#emitter;
@@ -391,7 +419,7 @@ var ModelContext = class {
391
419
  return settled;
392
420
  }
393
421
  async adopt(options) {
394
- return (await this.#registry.getTools(options?.origins === void 0 ? {} : { fromOrigins: options.origins })).map((tool) => createTool({
422
+ return (await this.#registry.getTools(options?.origins === void 0 ? {} : { fromOrigins: options.origins })).filter((tool) => options?.debugging === true || tool.annotations?.debugging !== true).map((tool) => createTool({
395
423
  ...webMCPToTool(tool),
396
424
  execute: this.#execute.bind(this, tool)
397
425
  }));
@@ -402,6 +430,8 @@ var ModelContext = class {
402
430
  this.#unfollow();
403
431
  this.#pendingManager = void 0;
404
432
  this.#registry.removeEventListener(WEBMCP_CHANGE_EVENT, this.#listener);
433
+ this.#registry.removeEventListener(WEBMCP_ACTIVATED_EVENT, this.#activated);
434
+ this.#registry.removeEventListener(WEBMCP_ABORT_EVENT, this.#aborted);
405
435
  for (const held of this.#registrations.values()) held.controller.abort();
406
436
  this.#registrations.clear();
407
437
  this.#emitter.destroy();
@@ -409,6 +439,9 @@ var ModelContext = class {
409
439
  #republish() {
410
440
  this.#emitter.emit("change");
411
441
  }
442
+ #republishTool(name, event) {
443
+ if (isWebMCPToolEvent(event)) this.#emitter.emit(name, event.toolName);
444
+ }
412
445
  #follow(tools, options) {
413
446
  this.#unfollow();
414
447
  const changed = this.#changed.bind(this, tools, options);
@@ -1182,6 +1215,6 @@ function createModelContext(options) {
1182
1215
  return new ModelContext(host, options);
1183
1216
  }
1184
1217
  //#endregion
1185
- export { DEFAULT_MCP_SERVER_NAME, DEFAULT_MCP_SERVER_VERSION, MessagePortTransport, ModelContext, WEBMCP_CHANGE_EVENT, WebSocketClientTransport, buildWebMCPProjections, collectWebMCPProjections, createHTTPClientTransport, createMessagePortTransport, createModelContext, createPageServer, createScopeMessageListener, createScopeServer, createScopeTransport, createWebSocketClientTransport, describeWebMCPTool, isWebMCPDocument, isWebMCPRegistry, matchesDescriptor, toolAnnotationsToWebMCP, toolToWebMCP, webMCPAnnotationsToTool, webMCPToTool };
1218
+ export { DEFAULT_MCP_SERVER_NAME, DEFAULT_MCP_SERVER_VERSION, MessagePortTransport, ModelContext, WEBMCP_ABORT_EVENT, WEBMCP_ACTIVATED_EVENT, WEBMCP_CHANGE_EVENT, WebSocketClientTransport, buildWebMCPProjections, collectWebMCPProjections, createHTTPClientTransport, createMessagePortTransport, createModelContext, createPageServer, createScopeMessageListener, createScopeServer, createScopeTransport, createWebSocketClientTransport, describeWebMCPTool, isWebMCPDocument, isWebMCPRegistry, isWebMCPToolEvent, matchesDescriptor, toolAnnotationsToWebMCP, toolToWebMCP, webMCPAnnotationsToTool, webMCPToTool };
1186
1219
 
1187
1220
  //# sourceMappingURL=index.js.map