MCPcopy
hub / github.com/angular/angular / declareExperimentalWebMcpTool

Function declareExperimentalWebMcpTool

packages/core/src/webmcp/declare_tool.ts:31–75  ·  view source on GitHub ↗
(
  tool: ToolDescriptor<InputSchema>,
  injector?: Injector,
)

Source from the content-addressed store, hash-verified

29 * @experimental
30 */
31export function declareExperimentalWebMcpTool<const InputSchema extends JsonSchemaForInference>(
32 tool: ToolDescriptor<InputSchema>,
33 injector?: Injector,
34): void {
35 // SSR may not have a document yet, so we abort before checking it.
36 if (typeof ngServerMode !== 'undefined' && ngServerMode) return;
37
38 // modelContext was moved from `navigator` to `document` in the spec, but we check both for compatibility with different environments.
39 const modelContext =
40 (globalThis.document as {modelContext?: ModelContext}).modelContext ??
41 (globalThis.navigator as unknown as {modelContext?: ModelContext}).modelContext;
42
43 // Verify WebMCP is supported in this client. The typeof check guards against
44 // DOM clobbering (e.g. <form id="modelContext">), which would produce a truthy
45 // Element instead of a ModelContext object.
46 if (!modelContext || typeof modelContext.registerTool !== 'function') return;
47
48 if (typeof ngDevMode !== 'undefined' && ngDevMode) {
49 if (!injector) assertInInjectionContext(declareExperimentalWebMcpTool);
50 }
51
52 // Inject the `DestroyRef` and `Injector` immediately, so if it fails we abort
53 // before causing any side effects.
54 const currentInjector = injector ?? inject(Injector);
55 const destroyRef = currentInjector.get(DestroyRef);
56
57 // Wrap the input tool with an `AbortSignal` which aborts when the
58 // injection context is destroyed.
59 const abortCtrl = new AbortController();
60 const wrappedTool: ToolDescriptor<InputSchema> = {
61 ...tool,
62 execute: (args, client) =>
63 runInInjectionContext(currentInjector, () =>
64 tool.execute(args, {
65 ...client,
66 signal: abortCtrl.signal,
67 }),
68 ),
69 };
70
71 modelContext.registerTool(wrappedTool, {signal: abortCtrl.signal});
72
73 // Unregister when the associated `Injector` is destroyed.
74 destroyRef.onDestroy(() => void abortCtrl.abort());
75}

Callers 3

initWebMcpFormFunction · 0.90

Calls 8

assertInInjectionContextFunction · 0.90
injectFunction · 0.90
runInInjectionContextFunction · 0.90
registerToolMethod · 0.80
getMethod · 0.65
executeMethod · 0.65
onDestroyMethod · 0.65
abortMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…