MCPcopy Create free account
hub / github.com/angular/angular / declareExperimentalWebMcpTool

Function declareExperimentalWebMcpTool

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

Source from the content-addressed store, hash-verified

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

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