@@ -38,3 +38,94 @@ await client.callTool('add', { a: 1, b: 1 })
3838await client .callTool (' echo' , { message: ' Hello, World!' })
3939await client .callTool (' getTinyImage' , {})
4040```
41+
42+ ## integration with [ xsAI] ( https://xsai.js.org ) (experimental)
43+
44+ > This feature is yet to be tested and feedback is welcome.
45+
46+ ### Library
47+
48+ ``` ts
49+ import type { AudioPart , ImagePart , TextPart , Tool as XSAITool } from ' @xsai/shared-chat'
50+ import type { Client } from ' @xsmcp/client-shared'
51+ import type { CallToolResult } from ' @xsmcp/shared'
52+
53+ import { rawTool } from ' @xsai/tool'
54+
55+ const toXSAIContent = (contents : CallToolResult [' content' ]): (AudioPart | ImagePart | TextPart )[] =>
56+ // eslint-disable-next-line array-callback-return
57+ contents .map ((content ) => {
58+ switch (content .type ) {
59+ case ' audio' :
60+ return {
61+ input_audio: {
62+ data: content .data ,
63+ format: content .mimeType === ' audio/wav'
64+ ? ' wav'
65+ // TODO: fallback
66+ : ' mp3' ,
67+ },
68+ type: ' input_audio' ,
69+ } satisfies AudioPart
70+ case ' image' :
71+ return {
72+ image_url: { url: content .data },
73+ type: ' image_url' ,
74+ } satisfies ImagePart
75+ case ' resource' :
76+ return {
77+ text: (' text' in content .resource
78+ ? content .resource .text
79+ // TODO: fallback
80+ : content .resource .blob
81+ ),
82+ type: ' text' ,
83+ } satisfies TextPart
84+ case ' text' :
85+ return {
86+ text: content .text ,
87+ type: ' text' ,
88+ } satisfies TextPart
89+ }
90+ })
91+
92+ export const getTools = async (client : Client ): Promise <XSAITool []> =>
93+ client
94+ .listTools ()
95+ .then (({ tools }) => tools .map (tool => rawTool ({
96+ description: tool .description ,
97+ execute : async params => client .callTool (tool .name , params as Record <string , unknown >)
98+ // eslint-disable-next-line sonarjs/no-nested-functions
99+ .then (result => toXSAIContent (result .content )),
100+ name: tool .name ,
101+ parameters: tool .inputSchema ,
102+ })))
103+ ```
104+
105+ ### Usage
106+
107+ ``` ts
108+ import { createHttpTransport } from ' @xsmcp/client-http'
109+ import { createClient } from ' @xsmcp/server-shared'
110+
111+ import { getTools } from ' ./get-tools'
112+
113+ const client = createClient ({
114+ name: ' example-client' ,
115+ transport: createHttpTransport ({ url: ' http://localhost:3000/mcp' }),
116+ version: ' 1.0.0' ,
117+ })
118+
119+ const mcpTools = await client .listTools ()
120+
121+ const result = await streamText ({
122+ baseURL: ' http://localhost:11434/v1/' ,
123+ messages: [{
124+ content: ' What is the weather in Brooklyn, New York?' ,
125+ role: ' user' ,
126+ }],
127+ model: ' gemma3' ,
128+ onFinish : async () => await client .close (),
129+ tools: await getTools (client ),
130+ })
131+ ```
0 commit comments