@tambo-ai/react 0.22.0 → 0.23.0

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.
Files changed (47) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/model/component-metadata.d.ts +10 -1
  6. package/dist/model/component-metadata.d.ts.map +1 -1
  7. package/dist/model/component-metadata.js.map +1 -1
  8. package/dist/providers/tambo-mcp-provider.d.ts +10 -0
  9. package/dist/providers/tambo-mcp-provider.d.ts.map +1 -0
  10. package/dist/providers/tambo-mcp-provider.js +65 -0
  11. package/dist/providers/tambo-mcp-provider.js.map +1 -0
  12. package/dist/testing/tools.js.map +1 -1
  13. package/dist/util/mcp-client.d.ts +198 -0
  14. package/dist/util/mcp-client.d.ts.map +1 -0
  15. package/dist/util/mcp-client.js +108 -0
  16. package/dist/util/mcp-client.js.map +1 -0
  17. package/dist/util/mcp-tools-client.d.ts +96 -0
  18. package/dist/util/mcp-tools-client.d.ts.map +1 -0
  19. package/dist/util/mcp-tools-client.js +178 -0
  20. package/dist/util/mcp-tools-client.js.map +1 -0
  21. package/dist/util/registry.d.ts.map +1 -1
  22. package/dist/util/registry.js +18 -0
  23. package/dist/util/registry.js.map +1 -1
  24. package/esm/index.d.ts +1 -0
  25. package/esm/index.d.ts.map +1 -1
  26. package/esm/index.js +1 -0
  27. package/esm/index.js.map +1 -1
  28. package/esm/model/component-metadata.d.ts +10 -1
  29. package/esm/model/component-metadata.d.ts.map +1 -1
  30. package/esm/model/component-metadata.js.map +1 -1
  31. package/esm/providers/tambo-mcp-provider.d.ts +10 -0
  32. package/esm/providers/tambo-mcp-provider.d.ts.map +1 -0
  33. package/esm/providers/tambo-mcp-provider.js +61 -0
  34. package/esm/providers/tambo-mcp-provider.js.map +1 -0
  35. package/esm/testing/tools.js.map +1 -1
  36. package/esm/util/mcp-client.d.ts +198 -0
  37. package/esm/util/mcp-client.d.ts.map +1 -0
  38. package/esm/util/mcp-client.js +104 -0
  39. package/esm/util/mcp-client.js.map +1 -0
  40. package/esm/util/mcp-tools-client.d.ts +96 -0
  41. package/esm/util/mcp-tools-client.d.ts.map +1 -0
  42. package/esm/util/mcp-tools-client.js +174 -0
  43. package/esm/util/mcp-tools-client.js.map +1 -0
  44. package/esm/util/registry.d.ts.map +1 -1
  45. package/esm/util/registry.js +18 -0
  46. package/esm/util/registry.js.map +1 -1
  47. package/package.json +2 -1
@@ -0,0 +1,198 @@
1
+ import { JSONSchema7 } from "json-schema";
2
+ export declare enum MCPTransport {
3
+ SSE = "sse",
4
+ HTTP = "http"
5
+ }
6
+ /**
7
+ * A client for interacting with MCP (Model Context Protocol) servers.
8
+ * Provides a simple interface for listing and calling tools exposed by the server.
9
+ * @example
10
+ * ```typescript
11
+ * const mcp = await MCPClient.create('https://api.example.com/mcp');
12
+ * const tools = await mcp.listTools();
13
+ * const result = await mcp.callTool('toolName', { arg1: 'value1' });
14
+ * ```
15
+ */
16
+ export declare class MCPClient {
17
+ private client;
18
+ private transport;
19
+ /**
20
+ * Private constructor to enforce using the static create method.
21
+ * @param endpoint - The URL of the MCP server to connect to
22
+ * @param transport - The transport to use for the MCP client
23
+ * @param headers - Optional custom headers to include in requests
24
+ */
25
+ private constructor();
26
+ /**
27
+ * Creates and initializes a new MCPClient instance.
28
+ * This is the recommended way to create an MCPClient as it handles both
29
+ * instantiation and connection setup.
30
+ * @param endpoint - The URL of the MCP server to connect to
31
+ * @param headers - Optional custom headers to include in requests
32
+ * @returns A connected MCPClient instance ready for use
33
+ * @throws Will throw an error if connection fails
34
+ */
35
+ static create(endpoint: string, transport?: MCPTransport, headers?: Record<string, string>): Promise<MCPClient>;
36
+ /**
37
+ * Retrieves a complete list of all available tools from the MCP server.
38
+ * Handles pagination automatically by following cursors until all tools are fetched.
39
+ * @returns A complete list of all available tools and their descriptions
40
+ * @throws Will throw an error if any server request fails during pagination
41
+ */
42
+ listTools(): Promise<MCPToolSpec[]>;
43
+ /**
44
+ * Calls a specific tool on the MCP server with the provided arguments.
45
+ * @param name - The name of the tool to call
46
+ * @param args - Arguments to pass to the tool, must match the tool's expected schema
47
+ * @returns The result from the tool execution
48
+ * @throws Will throw an error if the tool call fails or if arguments are invalid
49
+ */
50
+ callTool(name: string, args: Record<string, unknown>): Promise<import("zod").objectOutputType<{
51
+ _meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
52
+ } & {
53
+ content: import("zod").ZodArray<import("zod").ZodUnion<[import("zod").ZodObject<{
54
+ type: import("zod").ZodLiteral<"text">;
55
+ text: import("zod").ZodString;
56
+ }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
57
+ type: import("zod").ZodLiteral<"text">;
58
+ text: import("zod").ZodString;
59
+ }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
60
+ type: import("zod").ZodLiteral<"text">;
61
+ text: import("zod").ZodString;
62
+ }, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
63
+ type: import("zod").ZodLiteral<"image">;
64
+ data: import("zod").ZodString;
65
+ mimeType: import("zod").ZodString;
66
+ }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
67
+ type: import("zod").ZodLiteral<"image">;
68
+ data: import("zod").ZodString;
69
+ mimeType: import("zod").ZodString;
70
+ }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
71
+ type: import("zod").ZodLiteral<"image">;
72
+ data: import("zod").ZodString;
73
+ mimeType: import("zod").ZodString;
74
+ }, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
75
+ type: import("zod").ZodLiteral<"audio">;
76
+ data: import("zod").ZodString;
77
+ mimeType: import("zod").ZodString;
78
+ }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
79
+ type: import("zod").ZodLiteral<"audio">;
80
+ data: import("zod").ZodString;
81
+ mimeType: import("zod").ZodString;
82
+ }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
83
+ type: import("zod").ZodLiteral<"audio">;
84
+ data: import("zod").ZodString;
85
+ mimeType: import("zod").ZodString;
86
+ }, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
87
+ type: import("zod").ZodLiteral<"resource">;
88
+ resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
89
+ uri: import("zod").ZodString;
90
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
91
+ }, {
92
+ text: import("zod").ZodString;
93
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
94
+ uri: import("zod").ZodString;
95
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
96
+ }, {
97
+ text: import("zod").ZodString;
98
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
99
+ uri: import("zod").ZodString;
100
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
101
+ }, {
102
+ text: import("zod").ZodString;
103
+ }>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
104
+ uri: import("zod").ZodString;
105
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
106
+ }, {
107
+ blob: import("zod").ZodString;
108
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
109
+ uri: import("zod").ZodString;
110
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
111
+ }, {
112
+ blob: import("zod").ZodString;
113
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
114
+ uri: import("zod").ZodString;
115
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
116
+ }, {
117
+ blob: import("zod").ZodString;
118
+ }>, import("zod").ZodTypeAny, "passthrough">>]>;
119
+ }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
120
+ type: import("zod").ZodLiteral<"resource">;
121
+ resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
122
+ uri: import("zod").ZodString;
123
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
124
+ }, {
125
+ text: import("zod").ZodString;
126
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
127
+ uri: import("zod").ZodString;
128
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
129
+ }, {
130
+ text: import("zod").ZodString;
131
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
132
+ uri: import("zod").ZodString;
133
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
134
+ }, {
135
+ text: import("zod").ZodString;
136
+ }>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
137
+ uri: import("zod").ZodString;
138
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
139
+ }, {
140
+ blob: import("zod").ZodString;
141
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
142
+ uri: import("zod").ZodString;
143
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
144
+ }, {
145
+ blob: import("zod").ZodString;
146
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
147
+ uri: import("zod").ZodString;
148
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
149
+ }, {
150
+ blob: import("zod").ZodString;
151
+ }>, import("zod").ZodTypeAny, "passthrough">>]>;
152
+ }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
153
+ type: import("zod").ZodLiteral<"resource">;
154
+ resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
155
+ uri: import("zod").ZodString;
156
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
157
+ }, {
158
+ text: import("zod").ZodString;
159
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
160
+ uri: import("zod").ZodString;
161
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
162
+ }, {
163
+ text: import("zod").ZodString;
164
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
165
+ uri: import("zod").ZodString;
166
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
167
+ }, {
168
+ text: import("zod").ZodString;
169
+ }>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
170
+ uri: import("zod").ZodString;
171
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
172
+ }, {
173
+ blob: import("zod").ZodString;
174
+ }>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
175
+ uri: import("zod").ZodString;
176
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
177
+ }, {
178
+ blob: import("zod").ZodString;
179
+ }>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
180
+ uri: import("zod").ZodString;
181
+ mimeType: import("zod").ZodOptional<import("zod").ZodString>;
182
+ }, {
183
+ blob: import("zod").ZodString;
184
+ }>, import("zod").ZodTypeAny, "passthrough">>]>;
185
+ }, import("zod").ZodTypeAny, "passthrough">>]>, "many">;
186
+ isError: import("zod").ZodOptional<import("zod").ZodDefault<import("zod").ZodBoolean>>;
187
+ }, import("zod").ZodTypeAny, "passthrough"> | import("zod").objectOutputType<{
188
+ _meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
189
+ } & {
190
+ toolResult: import("zod").ZodUnknown;
191
+ }, import("zod").ZodTypeAny, "passthrough">>;
192
+ }
193
+ export interface MCPToolSpec {
194
+ name: string;
195
+ description?: string;
196
+ inputSchema?: JSONSchema7;
197
+ }
198
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/util/mcp-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,oBAAY,YAAY;IACtB,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AACD;;;;;;;;;GASG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqD;IAEtE;;;;;OAKG;IACH,OAAO;IAoBP;;;;;;;;OAQG;WACU,MAAM,CACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,YAAgC,EAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,SAAS,CAAC;IAMrB;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAiCzC;;;;;;OAMG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO3D;AASD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B"}
@@ -0,0 +1,104 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
3
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
+ export var MCPTransport;
5
+ (function (MCPTransport) {
6
+ MCPTransport["SSE"] = "sse";
7
+ MCPTransport["HTTP"] = "http";
8
+ })(MCPTransport || (MCPTransport = {}));
9
+ /**
10
+ * A client for interacting with MCP (Model Context Protocol) servers.
11
+ * Provides a simple interface for listing and calling tools exposed by the server.
12
+ * @example
13
+ * ```typescript
14
+ * const mcp = await MCPClient.create('https://api.example.com/mcp');
15
+ * const tools = await mcp.listTools();
16
+ * const result = await mcp.callTool('toolName', { arg1: 'value1' });
17
+ * ```
18
+ */
19
+ export class MCPClient {
20
+ client;
21
+ transport;
22
+ /**
23
+ * Private constructor to enforce using the static create method.
24
+ * @param endpoint - The URL of the MCP server to connect to
25
+ * @param transport - The transport to use for the MCP client
26
+ * @param headers - Optional custom headers to include in requests
27
+ */
28
+ constructor(endpoint, transport, headers) {
29
+ if (transport === MCPTransport.SSE) {
30
+ this.transport = new SSEClientTransport(new URL(endpoint), {
31
+ requestInit: { headers },
32
+ });
33
+ }
34
+ else {
35
+ this.transport = new StreamableHTTPClientTransport(new URL(endpoint), {
36
+ requestInit: { headers },
37
+ });
38
+ }
39
+ this.client = new Client({
40
+ name: "tambo-mcp-client",
41
+ version: "1.0.0",
42
+ });
43
+ }
44
+ /**
45
+ * Creates and initializes a new MCPClient instance.
46
+ * This is the recommended way to create an MCPClient as it handles both
47
+ * instantiation and connection setup.
48
+ * @param endpoint - The URL of the MCP server to connect to
49
+ * @param headers - Optional custom headers to include in requests
50
+ * @returns A connected MCPClient instance ready for use
51
+ * @throws Will throw an error if connection fails
52
+ */
53
+ static async create(endpoint, transport = MCPTransport.HTTP, headers) {
54
+ const mcpClient = new MCPClient(endpoint, transport, headers);
55
+ await mcpClient.client.connect(mcpClient.transport);
56
+ return mcpClient;
57
+ }
58
+ /**
59
+ * Retrieves a complete list of all available tools from the MCP server.
60
+ * Handles pagination automatically by following cursors until all tools are fetched.
61
+ * @returns A complete list of all available tools and their descriptions
62
+ * @throws Will throw an error if any server request fails during pagination
63
+ */
64
+ async listTools() {
65
+ const allTools = [];
66
+ let hasMore = true;
67
+ let cursor = undefined;
68
+ while (hasMore) {
69
+ const response = await this.client.listTools({ cursor }, {});
70
+ allTools.push(...response.tools.map((tool) => {
71
+ if (tool.inputSchema.type !== "object") {
72
+ throw new Error(`Input schema for tool ${tool.name} is not an object`);
73
+ }
74
+ return {
75
+ name: tool.name,
76
+ description: tool.description,
77
+ inputSchema: tool.inputSchema,
78
+ };
79
+ }));
80
+ if (response.nextCursor) {
81
+ cursor = response.nextCursor;
82
+ }
83
+ else {
84
+ hasMore = false;
85
+ }
86
+ }
87
+ return allTools;
88
+ }
89
+ /**
90
+ * Calls a specific tool on the MCP server with the provided arguments.
91
+ * @param name - The name of the tool to call
92
+ * @param args - Arguments to pass to the tool, must match the tool's expected schema
93
+ * @returns The result from the tool execution
94
+ * @throws Will throw an error if the tool call fails or if arguments are invalid
95
+ */
96
+ async callTool(name, args) {
97
+ const result = await this.client.callTool({
98
+ name,
99
+ arguments: args,
100
+ });
101
+ return result;
102
+ }
103
+ }
104
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/util/mcp-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { JSONSchema7 } from \"json-schema\";\n\nexport enum MCPTransport {\n SSE = \"sse\",\n HTTP = \"http\",\n}\n/**\n * A client for interacting with MCP (Model Context Protocol) servers.\n * Provides a simple interface for listing and calling tools exposed by the server.\n * @example\n * ```typescript\n * const mcp = await MCPClient.create('https://api.example.com/mcp');\n * const tools = await mcp.listTools();\n * const result = await mcp.callTool('toolName', { arg1: 'value1' });\n * ```\n */\nexport class MCPClient {\n private client: Client;\n private transport: SSEClientTransport | StreamableHTTPClientTransport;\n\n /**\n * Private constructor to enforce using the static create method.\n * @param endpoint - The URL of the MCP server to connect to\n * @param transport - The transport to use for the MCP client\n * @param headers - Optional custom headers to include in requests\n */\n private constructor(\n endpoint: string,\n transport: MCPTransport,\n headers?: Record<string, string>,\n ) {\n if (transport === MCPTransport.SSE) {\n this.transport = new SSEClientTransport(new URL(endpoint), {\n requestInit: { headers },\n });\n } else {\n this.transport = new StreamableHTTPClientTransport(new URL(endpoint), {\n requestInit: { headers },\n });\n }\n this.client = new Client({\n name: \"tambo-mcp-client\",\n version: \"1.0.0\",\n });\n }\n\n /**\n * Creates and initializes a new MCPClient instance.\n * This is the recommended way to create an MCPClient as it handles both\n * instantiation and connection setup.\n * @param endpoint - The URL of the MCP server to connect to\n * @param headers - Optional custom headers to include in requests\n * @returns A connected MCPClient instance ready for use\n * @throws Will throw an error if connection fails\n */\n static async create(\n endpoint: string,\n transport: MCPTransport = MCPTransport.HTTP,\n headers?: Record<string, string>,\n ): Promise<MCPClient> {\n const mcpClient = new MCPClient(endpoint, transport, headers);\n await mcpClient.client.connect(mcpClient.transport);\n return mcpClient;\n }\n\n /**\n * Retrieves a complete list of all available tools from the MCP server.\n * Handles pagination automatically by following cursors until all tools are fetched.\n * @returns A complete list of all available tools and their descriptions\n * @throws Will throw an error if any server request fails during pagination\n */\n async listTools(): Promise<MCPToolSpec[]> {\n const allTools: MCPToolSpec[] = [];\n let hasMore = true;\n let cursor: string | undefined = undefined;\n\n while (hasMore) {\n const response = await this.client.listTools({ cursor }, {});\n allTools.push(\n ...response.tools.map((tool): MCPToolSpec => {\n if (tool.inputSchema.type !== \"object\") {\n throw new Error(\n `Input schema for tool ${tool.name} is not an object`,\n );\n }\n\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema as JSONSchema7,\n };\n }),\n );\n\n if (response.nextCursor) {\n cursor = response.nextCursor;\n } else {\n hasMore = false;\n }\n }\n\n return allTools;\n }\n\n /**\n * Calls a specific tool on the MCP server with the provided arguments.\n * @param name - The name of the tool to call\n * @param args - Arguments to pass to the tool, must match the tool's expected schema\n * @returns The result from the tool execution\n * @throws Will throw an error if the tool call fails or if arguments are invalid\n */\n async callTool(name: string, args: Record<string, unknown>) {\n const result = await this.client.callTool({\n name,\n arguments: args,\n });\n return result;\n }\n}\n\n// Example usage:\n/*\nconst mcp = await MCPClient.create('https://api.example.com/mcp', MCPTransport.HTTP);\nconst tools = await mcp.listTools();\nconst result = await mcp.callTool('toolName', { arg1: 'value1' });\n*/\n\nexport interface MCPToolSpec {\n name: string;\n description?: string;\n inputSchema?: JSONSchema7;\n}\n"]}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Minimal Model Context Protocol (MCP) client using JSON-RPC 2.0
3
+ * Supports only listTools() and callTool() operations
4
+ */
5
+ /**
6
+ * Interface representing a Tool in the MCP
7
+ */
8
+ export interface Tool {
9
+ name: string;
10
+ description?: string;
11
+ inputSchema: {
12
+ type: "object";
13
+ properties: Record<string, any>;
14
+ required?: string[];
15
+ };
16
+ annotations?: Record<string, any>;
17
+ }
18
+ /**
19
+ * Response from tools/list endpoint
20
+ */
21
+ export interface ListToolsResult {
22
+ tools: Tool[];
23
+ }
24
+ /**
25
+ * Content type for tool responses
26
+ */
27
+ export interface ToolContent {
28
+ type: string;
29
+ text?: string;
30
+ annotations?: Record<string, any>;
31
+ }
32
+ /**
33
+ * Response from tools/call endpoint
34
+ */
35
+ export interface CallToolResult {
36
+ content: ToolContent[];
37
+ isError?: boolean;
38
+ }
39
+ /**
40
+ * A minimal TypeScript client for the Model Context Protocol (MCP)
41
+ *
42
+ * This client provides a streamlined interface to communicate with MCP servers
43
+ * using JSON-RPC 2.0 over HTTP. It supports listing available tools and calling tools
44
+ * with arguments, including support for Server-Sent Events (SSE) streaming responses.
45
+ * @example
46
+ * ```typescript
47
+ * // Basic usage
48
+ * const mcpClient = new MCPClient('https://example.com/mcp');
49
+ * const tools = await mcpClient.listTools();
50
+ * const toolResponse = await mcpClient.callTool('my-tool', { arg1: 'value1' });
51
+ *
52
+ * // For streaming responses:
53
+ * const stream = await mcpClient.callToolStream('streaming-tool', { arg1: 'value1' });
54
+ * for await (const chunk of mcpClient.parseStreamingResponses(stream)) {
55
+ * console.log('Received chunk:', chunk);
56
+ * }
57
+ * ```
58
+ */
59
+ export declare class MCPClient {
60
+ private baseUrl;
61
+ private headers;
62
+ private requestId;
63
+ /**
64
+ * Creates a new MCP client
65
+ * @param url - The base URL of the MCP server
66
+ * @param extraHeaders - Optional additional headers to include in requests
67
+ */
68
+ constructor(url: string, extraHeaders?: Record<string, string>);
69
+ /**
70
+ * Lists available tools on the MCP server
71
+ * @returns Promise resolving to the list of available tools
72
+ */
73
+ listTools(): Promise<ListToolsResult>;
74
+ /**
75
+ * Calls a tool with the provided arguments
76
+ * @param toolName - The name of the tool to call
77
+ * @param args - The arguments to pass to the tool
78
+ * @returns Promise resolving to the tool's response
79
+ */
80
+ callTool(toolName: string, args: any): Promise<CallToolResult>;
81
+ /**
82
+ * Calls a tool with the provided arguments and returns a stream of results
83
+ * @param toolName - The name of the tool to call
84
+ * @param args - The arguments to pass to the tool
85
+ * @returns ReadableStream of the tool's response
86
+ */
87
+ callToolStream(toolName: string, args: any): Promise<ReadableStream<Uint8Array>>;
88
+ /**
89
+ * Parse SSE messages from a stream into JSON-RPC responses
90
+ * @param stream - ReadableStream to parse
91
+ * @returns AsyncGenerator yielding parsed JSON-RPC responses
92
+ * @yields {CallToolResult} The parsed JSON-RPC response
93
+ */
94
+ parseStreamingResponses(stream: ReadableStream<Uint8Array>): AsyncGenerator<CallToolResult, void, unknown>;
95
+ }
96
+ //# sourceMappingURL=mcp-tools-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools-client.d.ts","sourceRoot":"","sources":["../../src/util/mcp-tools-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,SAAS,CAAK;IAEtB;;;;OAIG;gBACS,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAS9D;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAgC3C;;;;;OAKG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;IAmCpE;;;;;OAKG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAkCtC;;;;;OAKG;IACI,uBAAuB,CAC5B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,cAAc,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC;CAwCjD"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Minimal Model Context Protocol (MCP) client using JSON-RPC 2.0
3
+ * Supports only listTools() and callTool() operations
4
+ */
5
+ /**
6
+ * A minimal TypeScript client for the Model Context Protocol (MCP)
7
+ *
8
+ * This client provides a streamlined interface to communicate with MCP servers
9
+ * using JSON-RPC 2.0 over HTTP. It supports listing available tools and calling tools
10
+ * with arguments, including support for Server-Sent Events (SSE) streaming responses.
11
+ * @example
12
+ * ```typescript
13
+ * // Basic usage
14
+ * const mcpClient = new MCPClient('https://example.com/mcp');
15
+ * const tools = await mcpClient.listTools();
16
+ * const toolResponse = await mcpClient.callTool('my-tool', { arg1: 'value1' });
17
+ *
18
+ * // For streaming responses:
19
+ * const stream = await mcpClient.callToolStream('streaming-tool', { arg1: 'value1' });
20
+ * for await (const chunk of mcpClient.parseStreamingResponses(stream)) {
21
+ * console.log('Received chunk:', chunk);
22
+ * }
23
+ * ```
24
+ */
25
+ export class MCPClient {
26
+ baseUrl;
27
+ headers;
28
+ requestId = 1;
29
+ /**
30
+ * Creates a new MCP client
31
+ * @param url - The base URL of the MCP server
32
+ * @param extraHeaders - Optional additional headers to include in requests
33
+ */
34
+ constructor(url, extraHeaders) {
35
+ this.baseUrl = url.endsWith("/") ? url : `${url}/`;
36
+ this.headers = {
37
+ "Content-Type": "application/json",
38
+ Accept: "application/json",
39
+ ...(extraHeaders ?? {}),
40
+ };
41
+ }
42
+ /**
43
+ * Lists available tools on the MCP server
44
+ * @returns Promise resolving to the list of available tools
45
+ */
46
+ async listTools() {
47
+ const jsonRpcRequest = {
48
+ jsonrpc: "2.0",
49
+ method: "tools/list",
50
+ params: {},
51
+ id: this.requestId++,
52
+ };
53
+ const response = await fetch(this.baseUrl, {
54
+ method: "POST",
55
+ headers: this.headers,
56
+ body: JSON.stringify(jsonRpcRequest),
57
+ });
58
+ if (!response.ok) {
59
+ throw new Error(`Failed to list tools: ${response.status} ${response.statusText}`);
60
+ }
61
+ const jsonRpcResponse = await response.json();
62
+ // Handle JSON-RPC error
63
+ if (jsonRpcResponse.error) {
64
+ throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
65
+ }
66
+ return jsonRpcResponse.result;
67
+ }
68
+ /**
69
+ * Calls a tool with the provided arguments
70
+ * @param toolName - The name of the tool to call
71
+ * @param args - The arguments to pass to the tool
72
+ * @returns Promise resolving to the tool's response
73
+ */
74
+ async callTool(toolName, args) {
75
+ const jsonRpcRequest = {
76
+ jsonrpc: "2.0",
77
+ method: "tools/call",
78
+ params: {
79
+ name: toolName,
80
+ arguments: args,
81
+ },
82
+ id: this.requestId++,
83
+ };
84
+ const response = await fetch(this.baseUrl, {
85
+ method: "POST",
86
+ headers: this.headers,
87
+ body: JSON.stringify(jsonRpcRequest),
88
+ });
89
+ if (!response.ok) {
90
+ throw new Error(`Failed to call tool ${toolName}: ${response.status} ${response.statusText}`);
91
+ }
92
+ const jsonRpcResponse = await response.json();
93
+ // Handle JSON-RPC error
94
+ if (jsonRpcResponse.error) {
95
+ throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
96
+ }
97
+ return jsonRpcResponse.result;
98
+ }
99
+ /**
100
+ * Calls a tool with the provided arguments and returns a stream of results
101
+ * @param toolName - The name of the tool to call
102
+ * @param args - The arguments to pass to the tool
103
+ * @returns ReadableStream of the tool's response
104
+ */
105
+ async callToolStream(toolName, args) {
106
+ const jsonRpcRequest = {
107
+ jsonrpc: "2.0",
108
+ method: "tools/call",
109
+ params: {
110
+ name: toolName,
111
+ arguments: args,
112
+ },
113
+ id: this.requestId++,
114
+ };
115
+ const response = await fetch(this.baseUrl, {
116
+ method: "POST",
117
+ headers: {
118
+ ...this.headers,
119
+ Accept: "text/event-stream",
120
+ },
121
+ body: JSON.stringify(jsonRpcRequest),
122
+ });
123
+ if (!response.ok) {
124
+ throw new Error(`Failed to call tool ${toolName}: ${response.status} ${response.statusText}`);
125
+ }
126
+ if (!response.body) {
127
+ throw new Error("Response body is null");
128
+ }
129
+ // Return the response body as a stream
130
+ return response.body;
131
+ }
132
+ /**
133
+ * Parse SSE messages from a stream into JSON-RPC responses
134
+ * @param stream - ReadableStream to parse
135
+ * @returns AsyncGenerator yielding parsed JSON-RPC responses
136
+ * @yields {CallToolResult} The parsed JSON-RPC response
137
+ */
138
+ async *parseStreamingResponses(stream) {
139
+ const reader = stream.getReader();
140
+ const decoder = new TextDecoder();
141
+ let buffer = "";
142
+ try {
143
+ while (true) {
144
+ const { done, value } = await reader.read();
145
+ if (done)
146
+ break;
147
+ buffer += decoder.decode(value, { stream: true });
148
+ // Process complete SSE messages
149
+ const lines = buffer.split("\n\n");
150
+ buffer = lines.pop() ?? "";
151
+ for (const line of lines) {
152
+ if (line.startsWith("data: ")) {
153
+ const jsonData = line.slice(6).trim();
154
+ try {
155
+ const jsonRpcResponse = JSON.parse(jsonData);
156
+ // Handle JSON-RPC error
157
+ if (jsonRpcResponse.error) {
158
+ throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
159
+ }
160
+ yield jsonRpcResponse.result;
161
+ }
162
+ catch (e) {
163
+ console.error("Failed to parse JSON:", e);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ finally {
170
+ reader.releaseLock();
171
+ }
172
+ }
173
+ }
174
+ //# sourceMappingURL=mcp-tools-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools-client.js","sourceRoot":"","sources":["../../src/util/mcp-tools-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Minimal Model Context Protocol (MCP) client using JSON-RPC 2.0\n * Supports only listTools() and callTool() operations\n */\n\n/**\n * Interface representing a Tool in the MCP\n */\nexport interface Tool {\n name: string;\n description?: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n annotations?: Record<string, any>;\n}\n\n/**\n * Response from tools/list endpoint\n */\nexport interface ListToolsResult {\n tools: Tool[];\n}\n\n/**\n * Content type for tool responses\n */\nexport interface ToolContent {\n type: string;\n text?: string;\n annotations?: Record<string, any>;\n}\n\n/**\n * Response from tools/call endpoint\n */\nexport interface CallToolResult {\n content: ToolContent[];\n isError?: boolean;\n}\n\n/**\n * A minimal TypeScript client for the Model Context Protocol (MCP)\n *\n * This client provides a streamlined interface to communicate with MCP servers\n * using JSON-RPC 2.0 over HTTP. It supports listing available tools and calling tools\n * with arguments, including support for Server-Sent Events (SSE) streaming responses.\n * @example\n * ```typescript\n * // Basic usage\n * const mcpClient = new MCPClient('https://example.com/mcp');\n * const tools = await mcpClient.listTools();\n * const toolResponse = await mcpClient.callTool('my-tool', { arg1: 'value1' });\n *\n * // For streaming responses:\n * const stream = await mcpClient.callToolStream('streaming-tool', { arg1: 'value1' });\n * for await (const chunk of mcpClient.parseStreamingResponses(stream)) {\n * console.log('Received chunk:', chunk);\n * }\n * ```\n */\nexport class MCPClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n private requestId = 1;\n\n /**\n * Creates a new MCP client\n * @param url - The base URL of the MCP server\n * @param extraHeaders - Optional additional headers to include in requests\n */\n constructor(url: string, extraHeaders?: Record<string, string>) {\n this.baseUrl = url.endsWith(\"/\") ? url : `${url}/`;\n this.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(extraHeaders ?? {}),\n };\n }\n\n /**\n * Lists available tools on the MCP server\n * @returns Promise resolving to the list of available tools\n */\n async listTools(): Promise<ListToolsResult> {\n const jsonRpcRequest = {\n jsonrpc: \"2.0\",\n method: \"tools/list\",\n params: {},\n id: this.requestId++,\n };\n\n const response = await fetch(this.baseUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(jsonRpcRequest),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to list tools: ${response.status} ${response.statusText}`,\n );\n }\n\n const jsonRpcResponse = await response.json();\n\n // Handle JSON-RPC error\n if (jsonRpcResponse.error) {\n throw new Error(\n `JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`,\n );\n }\n\n return jsonRpcResponse.result;\n }\n\n /**\n * Calls a tool with the provided arguments\n * @param toolName - The name of the tool to call\n * @param args - The arguments to pass to the tool\n * @returns Promise resolving to the tool's response\n */\n async callTool(toolName: string, args: any): Promise<CallToolResult> {\n const jsonRpcRequest = {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: toolName,\n arguments: args,\n },\n id: this.requestId++,\n };\n\n const response = await fetch(this.baseUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(jsonRpcRequest),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to call tool ${toolName}: ${response.status} ${response.statusText}`,\n );\n }\n\n const jsonRpcResponse = await response.json();\n\n // Handle JSON-RPC error\n if (jsonRpcResponse.error) {\n throw new Error(\n `JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`,\n );\n }\n\n return jsonRpcResponse.result;\n }\n\n /**\n * Calls a tool with the provided arguments and returns a stream of results\n * @param toolName - The name of the tool to call\n * @param args - The arguments to pass to the tool\n * @returns ReadableStream of the tool's response\n */\n async callToolStream(\n toolName: string,\n args: any,\n ): Promise<ReadableStream<Uint8Array>> {\n const jsonRpcRequest = {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: toolName,\n arguments: args,\n },\n id: this.requestId++,\n };\n\n const response = await fetch(this.baseUrl, {\n method: \"POST\",\n headers: {\n ...this.headers,\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(jsonRpcRequest),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to call tool ${toolName}: ${response.status} ${response.statusText}`,\n );\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n // Return the response body as a stream\n return response.body;\n }\n\n /**\n * Parse SSE messages from a stream into JSON-RPC responses\n * @param stream - ReadableStream to parse\n * @returns AsyncGenerator yielding parsed JSON-RPC responses\n * @yields {CallToolResult} The parsed JSON-RPC response\n */\n async *parseStreamingResponses(\n stream: ReadableStream<Uint8Array>,\n ): AsyncGenerator<CallToolResult, void, unknown> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE messages\n const lines = buffer.split(\"\\n\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const jsonData = line.slice(6).trim();\n try {\n const jsonRpcResponse = JSON.parse(jsonData);\n\n // Handle JSON-RPC error\n if (jsonRpcResponse.error) {\n throw new Error(\n `JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`,\n );\n }\n\n yield jsonRpcResponse.result;\n } catch (e) {\n console.error(\"Failed to parse JSON:\", e);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/util/registry.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,0BAA0B,CAAC;AAG/C,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EAEjB,mBAAmB,EACnB,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,mBAAmB,iBAAiB,EACpC,cAAc,iBAAiB,EAC/B,kBAAkB,qBAAqB,KACtC,OAAO,CAAC,kBAAkB,EAuB5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,cAAc,iBAAiB,EAC/B,kBAAkB,qBAAqB,KACtC,SAAS,EAKX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,mBAAmB,KAC7B,GAYF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,eAAe,MAAM,EACrB,mBAAmB,iBAAiB,KACnC,mBAUF,CAAC;AAUF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAGnC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,MAAM,SAAS,KACd,4BAQF,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/util/registry.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,0BAA0B,CAAC;AAG/C,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EAGjB,mBAAmB,EACnB,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,mBAAmB,iBAAiB,EACpC,cAAc,iBAAiB,EAC/B,kBAAkB,qBAAqB,KACtC,OAAO,CAAC,kBAAkB,EAuB5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,cAAc,iBAAiB,EAC/B,kBAAkB,qBAAqB,KACtC,SAAS,EAKX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,mBAAmB,KAC7B,GAYF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,eAAe,MAAM,EACrB,mBAAmB,iBAAiB,KACnC,mBAUF,CAAC;AAUF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAGnC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,MAAM,SAAS,KACd,4BAQF,CAAC"}
@@ -96,7 +96,25 @@ export const mapTamboToolToContextTool = (tool) => {
96
96
  parameters,
97
97
  };
98
98
  };
99
+ function isJsonSchema(schema) {
100
+ return (typeof schema === "object" &&
101
+ schema !== null &&
102
+ "type" in schema &&
103
+ typeof schema.type === "string" &&
104
+ schema.type === "object");
105
+ }
99
106
  const getParametersFromZodFunction = (schema) => {
107
+ if (isJsonSchema(schema)) {
108
+ return [
109
+ {
110
+ name: "args",
111
+ type: "object",
112
+ description: schema.description ?? "",
113
+ isRequired: true,
114
+ schema: schema,
115
+ },
116
+ ];
117
+ }
100
118
  const parameters = schema.parameters();
101
119
  return parameters.items.map((param, index) => {
102
120
  const name = `param${index + 1}`;