@tanstack/ai-solid 0.20.0 → 0.21.1

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.
@@ -1,9 +1,9 @@
1
1
  import { UseChatOptions, UseChatReturn } from "./types.js";
2
2
  import { InferredClientContext } from "@tanstack/ai-client";
3
- import { AnyClientTool, InterruptDefinition, SchemaInput } from "@tanstack/ai";
3
+ import { AnyClientTool as AnyClientTool$1, InterruptDefinition, SchemaInput } from "@tanstack/ai";
4
4
 
5
5
  //#region src/create-chat-hook.d.ts
6
- type ChatHookOverrides<TTools extends ReadonlyArray<AnyClientTool>, TSchema extends SchemaInput | undefined, TContext, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>> = {
6
+ type ChatHookOverrides<TTools extends ReadonlyArray<AnyClientTool$1>, TSchema extends SchemaInput | undefined, TContext, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>> = {
7
7
  threadId?: string;
8
8
  live?: boolean;
9
9
  forwardedProps?: Record<string, any>;
@@ -31,7 +31,7 @@ type ChatHookOverrides<TTools extends ReadonlyArray<AnyClientTool>, TSchema exte
31
31
  * }
32
32
  * ```
33
33
  */
34
- declare function createChatHook<const TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []>(options: UseChatOptions<TTools, TSchema, TContext, TInterrupts>): {
34
+ declare function createChatHook<const TTools extends ReadonlyArray<AnyClientTool$1> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []>(options: UseChatOptions<TTools, TSchema, TContext, TInterrupts>): {
35
35
  useChat: (overrides?: ChatHookOverrides<TTools, TSchema, TContext, TInterrupts>) => UseChatReturn<TTools, TSchema, TInterrupts>;
36
36
  };
37
37
  //#endregion
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { ChatRequestBody, DeepPartial, QueueConfig, QueueOption, QueueStrategy,
2
2
  import { useChat } from "./use-chat.js";
3
3
  import { createChatHook } from "./create-chat-hook.js";
4
4
  import { useByok } from "./use-byok.js";
5
+ import { UseWebMCPToolsOptions, useWebMCPTools } from "./use-web-mcp-tools.js";
5
6
  import { UseGenerationOptions, UseGenerationReturn, useGeneration } from "./use-generation.js";
6
7
  import { UseGenerateImageOptions, UseGenerateImageReturn, useGenerateImage } from "./use-generate-image.js";
7
8
  import { UseGenerateAudioOptions, UseGenerateAudioReturn, useGenerateAudio } from "./use-generate-audio.js";
@@ -11,4 +12,4 @@ import { UseSummarizeOptions, UseSummarizeReturn, useSummarize } from "./use-sum
11
12
  import { UseGenerateVideoOptions, UseGenerateVideoReturn, useGenerateVideo } from "./use-generate-video.js";
12
13
  import { UseAudioRecorderOptions, UseAudioRecorderReturn, useAudioRecorder } from "./use-audio-recorder.js";
13
14
  import { AudioGenerateInput, ChatClientPersistence, ChatPersistedState, ChatPersistenceOption, ChatStorageAdapter, ConnectConnectionAdapter, ConnectionAdapter, FetchConnectionOptions, GenerationClientState, ImageGenerateInput, IndexedDBPersistenceOptions, InferChatMessages, RunAgentInputContext, SpeechGenerateInput, StorageUnavailableError, SubscribeConnectionAdapter, SummarizeGenerateInput, TranscriptionGenerateInput, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo, WebSocketConnectionOptions, WebStoragePersistenceOptions, XhrConnectionOptions, createChatClientOptions, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, webSocket, xhrHttpStream, xhrServerSentEvents } from "@tanstack/ai-client";
14
- export { type AudioGenerateInput, type ChatClientPersistence, type ChatPersistedState, type ChatPersistenceOption, type ChatRequestBody, type ChatStorageAdapter, type ConnectConnectionAdapter, type ConnectionAdapter, type DeepPartial, type FetchConnectionOptions, type GenerationClientState, type ImageGenerateInput, type IndexedDBPersistenceOptions, type InferChatMessages, type QueueConfig, type QueueOption, type QueueStrategy, type QueuedMessage, type RunAgentInputContext, type SendMessageOptions, type SpeechGenerateInput, StorageUnavailableError, type SubscribeConnectionAdapter, type SummarizeGenerateInput, type TranscriptionGenerateInput, type UIMessage, type UseAudioRecorderOptions, type UseAudioRecorderReturn, type UseChatOptions, type UseChatReturn, type UseGenerateAudioOptions, type UseGenerateAudioReturn, type UseGenerateImageOptions, type UseGenerateImageReturn, type UseGenerateSpeechOptions, type UseGenerateSpeechReturn, type UseGenerateVideoOptions, type UseGenerateVideoReturn, type UseGenerationOptions, type UseGenerationReturn, type UseSummarizeOptions, type UseSummarizeReturn, type UseTranscriptionOptions, type UseTranscriptionReturn, type VideoGenerateInput, type VideoGenerateResult, type VideoStatusInfo, type WebSocketConnectionOptions, type WebStoragePersistenceOptions, type WhenBusy, type XhrConnectionOptions, createChatClientOptions, createChatHook, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, useAudioRecorder, useByok, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, webSocket, xhrHttpStream, xhrServerSentEvents };
15
+ export { type AudioGenerateInput, type ChatClientPersistence, type ChatPersistedState, type ChatPersistenceOption, type ChatRequestBody, type ChatStorageAdapter, type ConnectConnectionAdapter, type ConnectionAdapter, type DeepPartial, type FetchConnectionOptions, type GenerationClientState, type ImageGenerateInput, type IndexedDBPersistenceOptions, type InferChatMessages, type QueueConfig, type QueueOption, type QueueStrategy, type QueuedMessage, type RunAgentInputContext, type SendMessageOptions, type SpeechGenerateInput, StorageUnavailableError, type SubscribeConnectionAdapter, type SummarizeGenerateInput, type TranscriptionGenerateInput, type UIMessage, type UseAudioRecorderOptions, type UseAudioRecorderReturn, type UseChatOptions, type UseChatReturn, type UseGenerateAudioOptions, type UseGenerateAudioReturn, type UseGenerateImageOptions, type UseGenerateImageReturn, type UseGenerateSpeechOptions, type UseGenerateSpeechReturn, type UseGenerateVideoOptions, type UseGenerateVideoReturn, type UseGenerationOptions, type UseGenerationReturn, type UseSummarizeOptions, type UseSummarizeReturn, type UseTranscriptionOptions, type UseTranscriptionReturn, type UseWebMCPToolsOptions, type VideoGenerateInput, type VideoGenerateResult, type VideoStatusInfo, type WebSocketConnectionOptions, type WebStoragePersistenceOptions, type WhenBusy, type XhrConnectionOptions, createChatClientOptions, createChatHook, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, useAudioRecorder, useByok, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, useWebMCPTools, webSocket, xhrHttpStream, xhrServerSentEvents };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { useChat } from "./use-chat.js";
2
2
  import { createChatHook } from "./create-chat-hook.js";
3
3
  import { useByok } from "./use-byok.js";
4
+ import { useWebMCPTools } from "./use-web-mcp-tools.js";
4
5
  import { useGeneration } from "./use-generation.js";
5
6
  import { useGenerateImage } from "./use-generate-image.js";
6
7
  import { useGenerateAudio } from "./use-generate-audio.js";
@@ -11,4 +12,4 @@ import { useGenerateVideo } from "./use-generate-video.js";
11
12
  import { useAudioRecorder } from "./use-audio-recorder.js";
12
13
  import { StorageUnavailableError, createChatClientOptions, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, webSocket, xhrHttpStream, xhrServerSentEvents } from "@tanstack/ai-client";
13
14
 
14
- export { StorageUnavailableError, createChatClientOptions, createChatHook, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, useAudioRecorder, useByok, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, webSocket, xhrHttpStream, xhrServerSentEvents };
15
+ export { StorageUnavailableError, createChatClientOptions, createChatHook, fetchHttpStream, fetchServerSentEvents, indexedDBPersistence, localStoragePersistence, rpcStream, sessionStoragePersistence, stream, useAudioRecorder, useByok, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, useWebMCPTools, webSocket, xhrHttpStream, xhrServerSentEvents };
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Accessor } from "solid-js";
2
2
  import { AIDevtoolsDisplayOptions, BoundInterrupts, ChatClientOptions, ChatClientState, ChatInterruptState, ChatRequestBody, ChatResumeState, ClientContextOptionFromTools, ConnectionStatus, DistributedOmit, InferredClientContext, MultimodalContent, QueueConfig, QueueOption, QueueStrategy, QueuedMessage, ResolvableChatInterrupt, SendMessageOptions, UIMessage, WhenBusy } from "@tanstack/ai-client";
3
- import { AnyClientTool, InferSchemaType, InterruptDefinition, ModelMessage, RunAgentResumeItem, SchemaInput } from "@tanstack/ai";
3
+ import { AnyClientTool as AnyClientTool$1, InferSchemaType, InterruptDefinition, ModelMessage, RunAgentResumeItem, SchemaInput } from "@tanstack/ai";
4
4
 
5
5
  //#region src/types.d.ts
6
6
 
@@ -31,7 +31,7 @@ type DeepPartial<T> = T extends ReadonlyArray<infer U> ? Array<DeepPartial<U>> :
31
31
  * Note: Connection and body changes will recreate the ChatClient instance.
32
32
  * To update these options, remount the component or use a key prop.
33
33
  */
34
- type UseChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> = DistributedOmit<ChatClientOptions<TTools, TContext, TInterrupts>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'onQueueChange' | 'onResumeStateChange' | 'onRunIdChange' | 'context' | 'devtools'> & {
34
+ type UseChatOptions<TTools extends ReadonlyArray<AnyClientTool$1> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> = DistributedOmit<ChatClientOptions<TTools, TContext, TInterrupts>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'onQueueChange' | 'onResumeStateChange' | 'onRunIdChange' | 'context' | 'devtools'> & {
35
35
  /** Display options for TanStack AI Devtools. */
36
36
  devtools?: AIDevtoolsDisplayOptions;
37
37
  live?: boolean;
@@ -45,7 +45,7 @@ type UseChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema e
45
45
  * Discriminated return shape: when `outputSchema` is supplied, the hook adds
46
46
  * typed `partial` / `final` accessors; otherwise the return is unchanged.
47
47
  */
48
- type UseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> = BaseUseChatReturn<TTools, TSchema extends SchemaInput ? InferSchemaType<TSchema> : unknown, TInterrupts> & (TSchema extends SchemaInput ? {
48
+ type UseChatReturn<TTools extends ReadonlyArray<AnyClientTool$1> = any, TSchema extends SchemaInput | undefined = undefined, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> = BaseUseChatReturn<TTools, TSchema extends SchemaInput ? InferSchemaType<TSchema> : unknown, TInterrupts> & (TSchema extends SchemaInput ? {
49
49
  /**
50
50
  * Live progressively-parsed structured output. Derived from the
51
51
  * latest assistant message's structured-output part.
@@ -57,7 +57,7 @@ type UseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema ex
57
57
  */
58
58
  final: Accessor<InferSchemaType<TSchema> | null>;
59
59
  } : Record<never, never>);
60
- interface BaseUseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any, TData = unknown, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> {
60
+ interface BaseUseChatReturn<TTools extends ReadonlyArray<AnyClientTool$1> = any, TData = unknown, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []> {
61
61
  /**
62
62
  * Current messages in the conversation. When `outputSchema` is supplied,
63
63
  * `messages()[i].parts.find(p => p.type === 'structured-output')` is typed
@@ -1,9 +1,9 @@
1
1
  import { UseChatOptions, UseChatReturn } from "./types.js";
2
2
  import { InferredClientContext } from "@tanstack/ai-client";
3
- import { AnyClientTool, InterruptDefinition, SchemaInput } from "@tanstack/ai";
3
+ import { AnyClientTool as AnyClientTool$1, InterruptDefinition, SchemaInput } from "@tanstack/ai";
4
4
 
5
5
  //#region src/use-chat.d.ts
6
- declare function useChat<const TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []>(options?: UseChatOptions<TTools, TSchema, TContext, TInterrupts>): UseChatReturn<TTools, TSchema, TInterrupts>;
6
+ declare function useChat<const TTools extends ReadonlyArray<AnyClientTool$1> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []>(options?: UseChatOptions<TTools, TSchema, TContext, TInterrupts>): UseChatReturn<TTools, TSchema, TInterrupts>;
7
7
  //#endregion
8
8
  export { useChat };
9
9
  //# sourceMappingURL=use-chat.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { AnyClientTool, InferredClientContext, RegisterWebMCPToolsOptions } from "@tanstack/ai-client";
2
+
3
+ //#region src/use-web-mcp-tools.d.ts
4
+ /** Options for {@link useWebMCPTools}. */
5
+ type UseWebMCPToolsOptions<TTools extends ReadonlyArray<AnyClientTool>, TContext = InferredClientContext<TTools>> = Omit<RegisterWebMCPToolsOptions<TTools, TContext>, 'signal'> & {
6
+ /** Receives an asynchronous registration error. */
7
+ onError?: (error: unknown) => void;
8
+ };
9
+ type UseWebMCPToolsArguments<TTools extends ReadonlyArray<AnyClientTool>, TContext> = {} extends UseWebMCPToolsOptions<TTools, TContext> ? [options?: UseWebMCPToolsOptions<TTools, TContext>] : [options: UseWebMCPToolsOptions<TTools, TContext>];
10
+ /**
11
+ * Registers executable client tools with WebMCP for the current Solid owner.
12
+ *
13
+ * The owner cleanup removes every tool registered by this call.
14
+ *
15
+ * @param tools - The executable client tools to expose through WebMCP.
16
+ * @param options - Runtime context, per-tool options, and error handling.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * useWebMCPTools([searchProducts])
21
+ * ```
22
+ */
23
+ declare function useWebMCPTools<const TTools extends ReadonlyArray<AnyClientTool>, TContext = InferredClientContext<TTools>>(tools: TTools, ...[options]: UseWebMCPToolsArguments<TTools, TContext>): void;
24
+ //#endregion
25
+ export { UseWebMCPToolsOptions, useWebMCPTools };
26
+ //# sourceMappingURL=use-web-mcp-tools.d.ts.map
@@ -0,0 +1,31 @@
1
+ import { onCleanup } from "solid-js";
2
+ import { registerWebMCPTools } from "@tanstack/ai-client";
3
+
4
+ //#region src/use-web-mcp-tools.ts
5
+ /**
6
+ * Registers executable client tools with WebMCP for the current Solid owner.
7
+ *
8
+ * The owner cleanup removes every tool registered by this call.
9
+ *
10
+ * @param tools - The executable client tools to expose through WebMCP.
11
+ * @param options - Runtime context, per-tool options, and error handling.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * useWebMCPTools([searchProducts])
16
+ * ```
17
+ */
18
+ function useWebMCPTools(tools, ...[options]) {
19
+ const controller = new AbortController();
20
+ registerWebMCPTools(tools, {
21
+ ...options,
22
+ signal: controller.signal
23
+ }).catch((error) => {
24
+ if (!controller.signal.aborted) options?.onError?.(error);
25
+ });
26
+ onCleanup(() => controller.abort());
27
+ }
28
+
29
+ //#endregion
30
+ export { useWebMCPTools };
31
+ //# sourceMappingURL=use-web-mcp-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-web-mcp-tools.js","names":[],"sources":["../src/use-web-mcp-tools.ts"],"sourcesContent":["import { onCleanup } from 'solid-js'\nimport { registerWebMCPTools } from '@tanstack/ai-client'\nimport type {\n AnyClientTool,\n InferredClientContext,\n RegisterWebMCPToolsOptions,\n} from '@tanstack/ai-client'\n\n/** Options for {@link useWebMCPTools}. */\nexport type UseWebMCPToolsOptions<\n TTools extends ReadonlyArray<AnyClientTool>,\n TContext = InferredClientContext<TTools>,\n> = Omit<RegisterWebMCPToolsOptions<TTools, TContext>, 'signal'> & {\n /** Receives an asynchronous registration error. */\n onError?: (error: unknown) => void\n}\n\ntype UseWebMCPToolsArguments<\n TTools extends ReadonlyArray<AnyClientTool>,\n TContext,\n> =\n {} extends UseWebMCPToolsOptions<TTools, TContext>\n ? [options?: UseWebMCPToolsOptions<TTools, TContext>]\n : [options: UseWebMCPToolsOptions<TTools, TContext>]\n\n/**\n * Registers executable client tools with WebMCP for the current Solid owner.\n *\n * The owner cleanup removes every tool registered by this call.\n *\n * @param tools - The executable client tools to expose through WebMCP.\n * @param options - Runtime context, per-tool options, and error handling.\n *\n * @example\n * ```ts\n * useWebMCPTools([searchProducts])\n * ```\n */\nexport function useWebMCPTools<\n const TTools extends ReadonlyArray<AnyClientTool>,\n TContext = InferredClientContext<TTools>,\n>(tools: TTools, ...[options]: UseWebMCPToolsArguments<TTools, TContext>) {\n const controller = new AbortController()\n\n void registerWebMCPTools(tools, {\n ...options,\n signal: controller.signal,\n }).catch((error) => {\n if (!controller.signal.aborted) {\n options?.onError?.(error)\n }\n })\n\n onCleanup(() => controller.abort())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsCA,SAAgB,eAGd,OAAe,GAAG,CAAC,UAAqD;CACxE,MAAM,aAAa,IAAI,iBAAiB;AAExC,CAAK,oBAAoB,OAAO;EAC9B,GAAG;EACH,QAAQ,WAAW;EACpB,CAAC,CAAC,OAAO,UAAU;AAClB,MAAI,CAAC,WAAW,OAAO,QACrB,UAAS,UAAU,MAAM;GAE3B;AAEF,iBAAgB,WAAW,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-solid",
3
- "version": "0.20.0",
3
+ "version": "0.21.1",
4
4
  "description": "Solid hooks for TanStack AI streaming chat, structured outputs, and media generation.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -55,11 +55,11 @@
55
55
  "rehype-sanitize": "^6.0.0",
56
56
  "remark-gfm": "^4.0.1",
57
57
  "solid-markdown": "^2.1.0",
58
- "@tanstack/ai-client": "^0.30.0"
58
+ "@tanstack/ai-client": "^0.31.1"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "solid-js": ">=1.9.10",
62
- "@tanstack/ai": "^0.52.1"
62
+ "@tanstack/ai": "^0.54.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@solidjs/testing-library": "^0.8.10",
@@ -73,7 +73,7 @@
73
73
  "vite": "^8.2.1",
74
74
  "vite-plugin-solid": "^2.11.14",
75
75
  "vitest": "^4.1.10",
76
- "@tanstack/ai": "0.52.1"
76
+ "@tanstack/ai": "0.54.0"
77
77
  },
78
78
  "scripts": {
79
79
  "clean": "premove ./build ./dist",
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { useChat } from './use-chat'
2
2
  export { createChatHook } from './create-chat-hook'
3
3
  export { useByok } from './use-byok'
4
+ export { useWebMCPTools } from './use-web-mcp-tools'
5
+ export type { UseWebMCPToolsOptions } from './use-web-mcp-tools'
4
6
  export type {
5
7
  DeepPartial,
6
8
  UseChatOptions,
@@ -0,0 +1,55 @@
1
+ import { onCleanup } from 'solid-js'
2
+ import { registerWebMCPTools } from '@tanstack/ai-client'
3
+ import type {
4
+ AnyClientTool,
5
+ InferredClientContext,
6
+ RegisterWebMCPToolsOptions,
7
+ } from '@tanstack/ai-client'
8
+
9
+ /** Options for {@link useWebMCPTools}. */
10
+ export type UseWebMCPToolsOptions<
11
+ TTools extends ReadonlyArray<AnyClientTool>,
12
+ TContext = InferredClientContext<TTools>,
13
+ > = Omit<RegisterWebMCPToolsOptions<TTools, TContext>, 'signal'> & {
14
+ /** Receives an asynchronous registration error. */
15
+ onError?: (error: unknown) => void
16
+ }
17
+
18
+ type UseWebMCPToolsArguments<
19
+ TTools extends ReadonlyArray<AnyClientTool>,
20
+ TContext,
21
+ > =
22
+ {} extends UseWebMCPToolsOptions<TTools, TContext>
23
+ ? [options?: UseWebMCPToolsOptions<TTools, TContext>]
24
+ : [options: UseWebMCPToolsOptions<TTools, TContext>]
25
+
26
+ /**
27
+ * Registers executable client tools with WebMCP for the current Solid owner.
28
+ *
29
+ * The owner cleanup removes every tool registered by this call.
30
+ *
31
+ * @param tools - The executable client tools to expose through WebMCP.
32
+ * @param options - Runtime context, per-tool options, and error handling.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * useWebMCPTools([searchProducts])
37
+ * ```
38
+ */
39
+ export function useWebMCPTools<
40
+ const TTools extends ReadonlyArray<AnyClientTool>,
41
+ TContext = InferredClientContext<TTools>,
42
+ >(tools: TTools, ...[options]: UseWebMCPToolsArguments<TTools, TContext>) {
43
+ const controller = new AbortController()
44
+
45
+ void registerWebMCPTools(tools, {
46
+ ...options,
47
+ signal: controller.signal,
48
+ }).catch((error) => {
49
+ if (!controller.signal.aborted) {
50
+ options?.onError?.(error)
51
+ }
52
+ })
53
+
54
+ onCleanup(() => controller.abort())
55
+ }