@tambo-ai/react 0.54.0 → 0.55.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.
- package/README.md +49 -14
- package/dist/hooks/__tests__/use-tambo-threads.test.js +1 -9
- package/dist/hooks/__tests__/use-tambo-threads.test.js.map +1 -1
- package/dist/mcp/__tests__/mcp-client.test.js +21 -21
- package/dist/mcp/__tests__/mcp-client.test.js.map +1 -1
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js +115 -0
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +61 -210
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js +43 -17
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +22 -4
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/providers/__tests__/tambo-interactable-provider-partial-updates.test.js +15 -0
- package/dist/providers/__tests__/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/__tests__/tambo-registry-provider.test.js +44 -9
- package/dist/providers/__tests__/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/hooks/use-tambo-session-token.d.ts +2 -2
- package/dist/providers/hooks/use-tambo-session-token.js +2 -2
- package/dist/providers/hooks/use-tambo-session-token.js.map +1 -1
- package/dist/providers/tambo-context-helpers-provider.d.ts +7 -2
- package/dist/providers/tambo-context-helpers-provider.d.ts.map +1 -1
- package/dist/providers/tambo-context-helpers-provider.js +12 -7
- package/dist/providers/tambo-context-helpers-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +3 -0
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-prop-stream-provider/index.d.ts +1 -1
- package/dist/providers/tambo-prop-stream-provider/index.js +1 -1
- package/dist/providers/tambo-prop-stream-provider/index.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +1 -1
- package/dist/providers/tambo-provider.js +1 -1
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js +12 -1
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/util/validate-component-name.d.ts +7 -0
- package/dist/util/validate-component-name.d.ts.map +1 -0
- package/dist/util/validate-component-name.js +14 -0
- package/dist/util/validate-component-name.js.map +1 -0
- package/esm/hooks/__tests__/use-tambo-threads.test.js +1 -9
- package/esm/hooks/__tests__/use-tambo-threads.test.js.map +1 -1
- package/esm/mcp/__tests__/mcp-client.test.js +21 -21
- package/esm/mcp/__tests__/mcp-client.test.js.map +1 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js +83 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +61 -210
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.js +43 -17
- package/esm/mcp/mcp-client.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +22 -4
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/providers/__tests__/tambo-interactable-provider-partial-updates.test.js +15 -0
- package/esm/providers/__tests__/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/__tests__/tambo-registry-provider.test.js +44 -9
- package/esm/providers/__tests__/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/hooks/use-tambo-session-token.d.ts +2 -2
- package/esm/providers/hooks/use-tambo-session-token.js +2 -2
- package/esm/providers/hooks/use-tambo-session-token.js.map +1 -1
- package/esm/providers/tambo-context-helpers-provider.d.ts +7 -2
- package/esm/providers/tambo-context-helpers-provider.d.ts.map +1 -1
- package/esm/providers/tambo-context-helpers-provider.js +12 -7
- package/esm/providers/tambo-context-helpers-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +3 -0
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/index.js +1 -1
- package/esm/providers/tambo-prop-stream-provider/index.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +1 -1
- package/esm/providers/tambo-provider.js +1 -1
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js +12 -1
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/util/validate-component-name.d.ts +7 -0
- package/esm/util/validate-component-name.d.ts.map +1 -0
- package/esm/util/validate-component-name.js +11 -0
- package/esm/util/validate-component-name.js.map +1 -0
- package/package.json +12 -11
package/esm/mcp/mcp-client.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
2
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
1
3
|
import { JSONSchema7 } from "json-schema";
|
|
2
4
|
export declare enum MCPTransport {
|
|
3
5
|
SSE = "sse",
|
|
@@ -17,8 +19,10 @@ export declare class MCPClient {
|
|
|
17
19
|
private client;
|
|
18
20
|
private transport;
|
|
19
21
|
private transportType;
|
|
22
|
+
sessionId?: string;
|
|
20
23
|
private endpoint;
|
|
21
24
|
private headers;
|
|
25
|
+
private authProvider?;
|
|
22
26
|
/**
|
|
23
27
|
* Tracks an in-flight reconnect so concurrent triggers coalesce
|
|
24
28
|
* (single-flight). When set, additional calls to `reconnect()` or
|
|
@@ -62,16 +66,19 @@ export declare class MCPClient {
|
|
|
62
66
|
*/
|
|
63
67
|
private constructor();
|
|
64
68
|
/**
|
|
65
|
-
* Creates and initializes a new MCPClient instance.
|
|
66
|
-
*
|
|
67
|
-
*
|
|
69
|
+
* Creates and initializes a new MCPClient instance. This is the recommended
|
|
70
|
+
* way to create an MCPClient as it handles both instantiation and connection
|
|
71
|
+
* setup.
|
|
68
72
|
* @param endpoint - The URL of the MCP server to connect to
|
|
69
73
|
* @param transportType - The transport type to use for the MCP client. Defaults to HTTP.
|
|
70
74
|
* @param headers - Optional custom headers to include in requests
|
|
75
|
+
* @param authProvider - Optional auth provider to use for authentication
|
|
76
|
+
* @param sessionId - Optional session id to use for the MCP client - if not
|
|
77
|
+
* provided, a new session will be created
|
|
71
78
|
* @returns A connected MCPClient instance ready for use
|
|
72
|
-
* @throws Will throw an error if connection fails
|
|
79
|
+
* @throws {Error} Will throw an error if connection fails
|
|
73
80
|
*/
|
|
74
|
-
static create(endpoint: string, transportType
|
|
81
|
+
static create(endpoint: string, transportType: MCPTransport | undefined, headers: Record<string, string> | undefined, authProvider: OAuthClientProvider | undefined, sessionId: string | undefined): Promise<MCPClient>;
|
|
75
82
|
/**
|
|
76
83
|
* Reconnects to the MCP server, optionally retaining the same session ID.
|
|
77
84
|
*
|
|
@@ -89,6 +96,7 @@ export declare class MCPClient {
|
|
|
89
96
|
* @param newSession - Whether to create a new session (true) or reuse existing session ID (false)
|
|
90
97
|
* @param reportErrorOnClose - Whether to report errors when closing the client
|
|
91
98
|
* Note that only StreamableHTTPClientTransport supports session IDs.
|
|
99
|
+
* @returns A promise that resolves when the reconnect is complete
|
|
92
100
|
*/
|
|
93
101
|
reconnect(newSession?: boolean, reportErrorOnClose?: boolean): Promise<void>;
|
|
94
102
|
/**
|
|
@@ -99,6 +107,7 @@ export declare class MCPClient {
|
|
|
99
107
|
private onclose;
|
|
100
108
|
/**
|
|
101
109
|
* Compute the next backoff delay with symmetric jitter.
|
|
110
|
+
* @returns The next backoff delay in milliseconds
|
|
102
111
|
*/
|
|
103
112
|
private computeBackoffDelayMs;
|
|
104
113
|
/**
|
|
@@ -112,220 +121,62 @@ export declare class MCPClient {
|
|
|
112
121
|
* Retrieves a complete list of all available tools from the MCP server.
|
|
113
122
|
* Handles pagination automatically by following cursors until all tools are fetched.
|
|
114
123
|
* @returns A complete list of all available tools and their descriptions
|
|
115
|
-
* @throws Will throw an error if any server request fails during pagination
|
|
124
|
+
* @throws {Error} Will throw an error if any server request fails during pagination
|
|
116
125
|
*/
|
|
117
126
|
listTools(): Promise<MCPToolSpec[]>;
|
|
127
|
+
getServerCapabilities(): {
|
|
128
|
+
[x: string]: unknown;
|
|
129
|
+
tools?: {
|
|
130
|
+
[x: string]: unknown;
|
|
131
|
+
listChanged?: boolean | undefined;
|
|
132
|
+
} | undefined;
|
|
133
|
+
experimental?: {
|
|
134
|
+
[x: string]: unknown;
|
|
135
|
+
} | undefined;
|
|
136
|
+
logging?: {
|
|
137
|
+
[x: string]: unknown;
|
|
138
|
+
} | undefined;
|
|
139
|
+
completions?: {
|
|
140
|
+
[x: string]: unknown;
|
|
141
|
+
} | undefined;
|
|
142
|
+
prompts?: {
|
|
143
|
+
[x: string]: unknown;
|
|
144
|
+
listChanged?: boolean | undefined;
|
|
145
|
+
} | undefined;
|
|
146
|
+
resources?: {
|
|
147
|
+
[x: string]: unknown;
|
|
148
|
+
listChanged?: boolean | undefined;
|
|
149
|
+
subscribe?: boolean | undefined;
|
|
150
|
+
} | undefined;
|
|
151
|
+
} | undefined;
|
|
152
|
+
getServerVersion(): {
|
|
153
|
+
[x: string]: unknown;
|
|
154
|
+
name: string;
|
|
155
|
+
version: string;
|
|
156
|
+
title?: string | undefined;
|
|
157
|
+
websiteUrl?: string | undefined;
|
|
158
|
+
icons?: {
|
|
159
|
+
[x: string]: unknown;
|
|
160
|
+
src: string;
|
|
161
|
+
mimeType?: string | undefined;
|
|
162
|
+
sizes?: string | undefined;
|
|
163
|
+
}[] | undefined;
|
|
164
|
+
} | undefined;
|
|
165
|
+
getInstructions(): string | undefined;
|
|
118
166
|
/**
|
|
119
167
|
* Calls a specific tool on the MCP server with the provided arguments.
|
|
120
168
|
* @param name - The name of the tool to call
|
|
121
169
|
* @param args - Arguments to pass to the tool, must match the tool's expected schema
|
|
122
170
|
* @returns The result from the tool execution
|
|
123
|
-
* @throws Will throw an error if the tool call fails or if arguments are invalid
|
|
171
|
+
* @throws {Error} Will throw an error if the tool call fails or if arguments are invalid
|
|
124
172
|
*/
|
|
125
|
-
callTool(name: string, args: Record<string, unknown>): Promise<
|
|
126
|
-
_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">>>;
|
|
127
|
-
} & {
|
|
128
|
-
content: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodUnion<[import("zod").ZodObject<{
|
|
129
|
-
type: import("zod").ZodLiteral<"text">;
|
|
130
|
-
text: import("zod").ZodString;
|
|
131
|
-
_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">>>;
|
|
132
|
-
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
133
|
-
type: import("zod").ZodLiteral<"text">;
|
|
134
|
-
text: import("zod").ZodString;
|
|
135
|
-
_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">>>;
|
|
136
|
-
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
137
|
-
type: import("zod").ZodLiteral<"text">;
|
|
138
|
-
text: import("zod").ZodString;
|
|
139
|
-
_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">>>;
|
|
140
|
-
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
|
|
141
|
-
type: import("zod").ZodLiteral<"image">;
|
|
142
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
143
|
-
mimeType: import("zod").ZodString;
|
|
144
|
-
_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">>>;
|
|
145
|
-
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
146
|
-
type: import("zod").ZodLiteral<"image">;
|
|
147
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
148
|
-
mimeType: import("zod").ZodString;
|
|
149
|
-
_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">>>;
|
|
150
|
-
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
151
|
-
type: import("zod").ZodLiteral<"image">;
|
|
152
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
153
|
-
mimeType: import("zod").ZodString;
|
|
154
|
-
_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">>>;
|
|
155
|
-
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
|
|
156
|
-
type: import("zod").ZodLiteral<"audio">;
|
|
157
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
158
|
-
mimeType: import("zod").ZodString;
|
|
159
|
-
_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">>>;
|
|
160
|
-
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
161
|
-
type: import("zod").ZodLiteral<"audio">;
|
|
162
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
163
|
-
mimeType: import("zod").ZodString;
|
|
164
|
-
_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">>>;
|
|
165
|
-
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
166
|
-
type: import("zod").ZodLiteral<"audio">;
|
|
167
|
-
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
168
|
-
mimeType: import("zod").ZodString;
|
|
169
|
-
_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">>>;
|
|
170
|
-
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<import("zod").objectUtil.extendShape<{
|
|
171
|
-
name: import("zod").ZodString;
|
|
172
|
-
title: import("zod").ZodOptional<import("zod").ZodString>;
|
|
173
|
-
}, {
|
|
174
|
-
uri: import("zod").ZodString;
|
|
175
|
-
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
176
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
177
|
-
_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">>>;
|
|
178
|
-
}>, {
|
|
179
|
-
type: import("zod").ZodLiteral<"resource_link">;
|
|
180
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<import("zod").objectUtil.extendShape<{
|
|
181
|
-
name: import("zod").ZodString;
|
|
182
|
-
title: import("zod").ZodOptional<import("zod").ZodString>;
|
|
183
|
-
}, {
|
|
184
|
-
uri: import("zod").ZodString;
|
|
185
|
-
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
186
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
187
|
-
_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">>>;
|
|
188
|
-
}>, {
|
|
189
|
-
type: import("zod").ZodLiteral<"resource_link">;
|
|
190
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<import("zod").objectUtil.extendShape<{
|
|
191
|
-
name: import("zod").ZodString;
|
|
192
|
-
title: import("zod").ZodOptional<import("zod").ZodString>;
|
|
193
|
-
}, {
|
|
194
|
-
uri: import("zod").ZodString;
|
|
195
|
-
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
196
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
197
|
-
_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">>>;
|
|
198
|
-
}>, {
|
|
199
|
-
type: import("zod").ZodLiteral<"resource_link">;
|
|
200
|
-
}>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
|
|
201
|
-
type: import("zod").ZodLiteral<"resource">;
|
|
202
|
-
resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
203
|
-
uri: import("zod").ZodString;
|
|
204
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
205
|
-
_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">>>;
|
|
206
|
-
}, {
|
|
207
|
-
text: import("zod").ZodString;
|
|
208
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
209
|
-
uri: import("zod").ZodString;
|
|
210
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
211
|
-
_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">>>;
|
|
212
|
-
}, {
|
|
213
|
-
text: import("zod").ZodString;
|
|
214
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
215
|
-
uri: import("zod").ZodString;
|
|
216
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
217
|
-
_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">>>;
|
|
218
|
-
}, {
|
|
219
|
-
text: import("zod").ZodString;
|
|
220
|
-
}>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
221
|
-
uri: import("zod").ZodString;
|
|
222
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
223
|
-
_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">>>;
|
|
224
|
-
}, {
|
|
225
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
226
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
227
|
-
uri: import("zod").ZodString;
|
|
228
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
229
|
-
_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">>>;
|
|
230
|
-
}, {
|
|
231
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
232
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
233
|
-
uri: import("zod").ZodString;
|
|
234
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
235
|
-
_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">>>;
|
|
236
|
-
}, {
|
|
237
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
238
|
-
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
239
|
-
_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">>>;
|
|
240
|
-
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
241
|
-
type: import("zod").ZodLiteral<"resource">;
|
|
242
|
-
resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
243
|
-
uri: import("zod").ZodString;
|
|
244
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
245
|
-
_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">>>;
|
|
246
|
-
}, {
|
|
247
|
-
text: import("zod").ZodString;
|
|
248
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
249
|
-
uri: import("zod").ZodString;
|
|
250
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
251
|
-
_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">>>;
|
|
252
|
-
}, {
|
|
253
|
-
text: import("zod").ZodString;
|
|
254
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
255
|
-
uri: import("zod").ZodString;
|
|
256
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
257
|
-
_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">>>;
|
|
258
|
-
}, {
|
|
259
|
-
text: import("zod").ZodString;
|
|
260
|
-
}>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
261
|
-
uri: import("zod").ZodString;
|
|
262
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
263
|
-
_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">>>;
|
|
264
|
-
}, {
|
|
265
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
266
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
267
|
-
uri: import("zod").ZodString;
|
|
268
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
269
|
-
_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">>>;
|
|
270
|
-
}, {
|
|
271
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
272
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
273
|
-
uri: import("zod").ZodString;
|
|
274
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
275
|
-
_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">>>;
|
|
276
|
-
}, {
|
|
277
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
278
|
-
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
279
|
-
_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">>>;
|
|
280
|
-
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
281
|
-
type: import("zod").ZodLiteral<"resource">;
|
|
282
|
-
resource: import("zod").ZodUnion<[import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
283
|
-
uri: import("zod").ZodString;
|
|
284
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
285
|
-
_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">>>;
|
|
286
|
-
}, {
|
|
287
|
-
text: import("zod").ZodString;
|
|
288
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
289
|
-
uri: import("zod").ZodString;
|
|
290
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
291
|
-
_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">>>;
|
|
292
|
-
}, {
|
|
293
|
-
text: import("zod").ZodString;
|
|
294
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
295
|
-
uri: import("zod").ZodString;
|
|
296
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
297
|
-
_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">>>;
|
|
298
|
-
}, {
|
|
299
|
-
text: import("zod").ZodString;
|
|
300
|
-
}>, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<{
|
|
301
|
-
uri: import("zod").ZodString;
|
|
302
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
303
|
-
_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">>>;
|
|
304
|
-
}, {
|
|
305
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
306
|
-
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
307
|
-
uri: import("zod").ZodString;
|
|
308
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
309
|
-
_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">>>;
|
|
310
|
-
}, {
|
|
311
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
312
|
-
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
313
|
-
uri: import("zod").ZodString;
|
|
314
|
-
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
315
|
-
_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">>>;
|
|
316
|
-
}, {
|
|
317
|
-
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
318
|
-
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
319
|
-
_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">>>;
|
|
320
|
-
}, import("zod").ZodTypeAny, "passthrough">>]>, "many">>;
|
|
321
|
-
structuredContent: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
322
|
-
isError: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
323
|
-
}, import("zod").ZodTypeAny, "passthrough"> | import("zod").objectOutputType<{
|
|
324
|
-
_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">>>;
|
|
325
|
-
} & {
|
|
326
|
-
toolResult: import("zod").ZodUnknown;
|
|
327
|
-
}, import("zod").ZodTypeAny, "passthrough">>;
|
|
173
|
+
callTool(name: string, args: Record<string, unknown>): Promise<MCPToolCallResult>;
|
|
328
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* The result of a tool call.
|
|
177
|
+
* This is the same as the result of a tool call in the OpenAI SDK, but is reified here
|
|
178
|
+
*/
|
|
179
|
+
export type MCPToolCallResult = Awaited<ReturnType<typeof Client.prototype.callTool>>;
|
|
329
180
|
export interface MCPToolSpec {
|
|
330
181
|
name: string;
|
|
331
182
|
description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,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;IACtE,OAAO,CAAC,aAAa,CAAe;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,YAAY,CAAC,CAAsB;IAC3C;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAK;IAE5B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,OAAO;IACzC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,KAAK;IACvC,MAAM,CAAC,QAAQ,CAAC,cAAc,SAAU;IACxC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,OAAO;IAE3C;;;;;OAKG;IACH,OAAO;IAeP;;;;;;;;;;;;OAYG;WACU,MAAM,CACjB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,YAAY,YAAoB,EAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,YAAY,EAAE,mBAAmB,GAAG,SAAS,EAC7C,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,SAAS,CAAC;IAcrB;;;;;;;;;;;;;;;;;;OAkBG;IACG,SAAS,CAAC,UAAU,UAAQ,EAAE,kBAAkB,UAAO;IAuD7D;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAoC7B,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,gBAAgB;IASxB;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAiCzC,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;IAIrB,gBAAgB;;;;;;;;;;;;;IAIhB,eAAe;IAIf;;;;;;OAMG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,iBAAiB,CAAC;CAO9B;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,CACrC,UAAU,CAAC,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAC7C,CAAC;AASF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B"}
|
package/esm/mcp/mcp-client.js
CHANGED
|
@@ -20,8 +20,10 @@ export class MCPClient {
|
|
|
20
20
|
client;
|
|
21
21
|
transport;
|
|
22
22
|
transportType;
|
|
23
|
+
sessionId;
|
|
23
24
|
endpoint;
|
|
24
25
|
headers;
|
|
26
|
+
authProvider;
|
|
25
27
|
/**
|
|
26
28
|
* Tracks an in-flight reconnect so concurrent triggers coalesce
|
|
27
29
|
* (single-flight). When set, additional calls to `reconnect()` or
|
|
@@ -63,26 +65,33 @@ export class MCPClient {
|
|
|
63
65
|
* @param transportType - The transport to use for the MCP client
|
|
64
66
|
* @param headers - Optional custom headers to include in requests
|
|
65
67
|
*/
|
|
66
|
-
constructor(endpoint, transportType, headers
|
|
68
|
+
constructor(endpoint, transportType, headers, authProvider, sessionId) {
|
|
67
69
|
this.endpoint = endpoint;
|
|
68
|
-
this.headers = headers;
|
|
70
|
+
this.headers = headers ?? {};
|
|
71
|
+
this.authProvider = authProvider;
|
|
69
72
|
this.transportType = transportType;
|
|
70
|
-
this.transport = this.initializeTransport(
|
|
73
|
+
this.transport = this.initializeTransport(sessionId);
|
|
71
74
|
this.client = this.initializeClient();
|
|
72
75
|
}
|
|
73
76
|
/**
|
|
74
|
-
* Creates and initializes a new MCPClient instance.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
+
* Creates and initializes a new MCPClient instance. This is the recommended
|
|
78
|
+
* way to create an MCPClient as it handles both instantiation and connection
|
|
79
|
+
* setup.
|
|
77
80
|
* @param endpoint - The URL of the MCP server to connect to
|
|
78
81
|
* @param transportType - The transport type to use for the MCP client. Defaults to HTTP.
|
|
79
82
|
* @param headers - Optional custom headers to include in requests
|
|
83
|
+
* @param authProvider - Optional auth provider to use for authentication
|
|
84
|
+
* @param sessionId - Optional session id to use for the MCP client - if not
|
|
85
|
+
* provided, a new session will be created
|
|
80
86
|
* @returns A connected MCPClient instance ready for use
|
|
81
|
-
* @throws Will throw an error if connection fails
|
|
87
|
+
* @throws {Error} Will throw an error if connection fails
|
|
82
88
|
*/
|
|
83
|
-
static async create(endpoint, transportType = MCPTransport.HTTP, headers) {
|
|
84
|
-
const mcpClient = new MCPClient(endpoint, transportType, headers);
|
|
89
|
+
static async create(endpoint, transportType = MCPTransport.HTTP, headers, authProvider, sessionId) {
|
|
90
|
+
const mcpClient = new MCPClient(endpoint, transportType, headers, authProvider, sessionId);
|
|
85
91
|
await mcpClient.client.connect(mcpClient.transport);
|
|
92
|
+
if ("sessionId" in mcpClient.transport) {
|
|
93
|
+
mcpClient.sessionId = mcpClient.transport.sessionId;
|
|
94
|
+
}
|
|
86
95
|
return mcpClient;
|
|
87
96
|
}
|
|
88
97
|
/**
|
|
@@ -102,6 +111,7 @@ export class MCPClient {
|
|
|
102
111
|
* @param newSession - Whether to create a new session (true) or reuse existing session ID (false)
|
|
103
112
|
* @param reportErrorOnClose - Whether to report errors when closing the client
|
|
104
113
|
* Note that only StreamableHTTPClientTransport supports session IDs.
|
|
114
|
+
* @returns A promise that resolves when the reconnect is complete
|
|
105
115
|
*/
|
|
106
116
|
async reconnect(newSession = false, reportErrorOnClose = true) {
|
|
107
117
|
// If a reconnect is already running, coalesce into it.
|
|
@@ -114,11 +124,7 @@ export class MCPClient {
|
|
|
114
124
|
this.reconnectTimer = undefined;
|
|
115
125
|
}
|
|
116
126
|
const doReconnect = async () => {
|
|
117
|
-
const sessionId = newSession
|
|
118
|
-
? undefined
|
|
119
|
-
: "sessionId" in this.transport
|
|
120
|
-
? this.transport.sessionId
|
|
121
|
-
: undefined;
|
|
127
|
+
const sessionId = newSession ? undefined : this.sessionId;
|
|
122
128
|
// Prevent re-entrant onclose during deliberate close by detaching
|
|
123
129
|
// the handler from the previous client instance.
|
|
124
130
|
const prevClient = this.client;
|
|
@@ -135,6 +141,14 @@ export class MCPClient {
|
|
|
135
141
|
this.transport = this.initializeTransport(sessionId);
|
|
136
142
|
this.client = this.initializeClient();
|
|
137
143
|
await this.client.connect(this.transport);
|
|
144
|
+
// We may have gotten a session id from the server, so we need to set it
|
|
145
|
+
if ("sessionId" in this.transport) {
|
|
146
|
+
this.sessionId = this.transport.sessionId;
|
|
147
|
+
if (sessionId !== this.sessionId) {
|
|
148
|
+
// This is a pretty unusual thing to happen, but it might be possible?
|
|
149
|
+
console.warn("Session id mismatch", sessionId, this.sessionId);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
138
152
|
};
|
|
139
153
|
this.reconnecting = (async () => {
|
|
140
154
|
try {
|
|
@@ -158,6 +172,7 @@ export class MCPClient {
|
|
|
158
172
|
}
|
|
159
173
|
/**
|
|
160
174
|
* Compute the next backoff delay with symmetric jitter.
|
|
175
|
+
* @returns The next backoff delay in milliseconds
|
|
161
176
|
*/
|
|
162
177
|
computeBackoffDelayMs() {
|
|
163
178
|
const base = Math.min(MCPClient.BACKOFF_MAX_MS, MCPClient.BACKOFF_INITIAL_MS *
|
|
@@ -203,13 +218,15 @@ export class MCPClient {
|
|
|
203
218
|
initializeTransport(sessionId) {
|
|
204
219
|
if (this.transportType === MCPTransport.SSE) {
|
|
205
220
|
return new SSEClientTransport(new URL(this.endpoint), {
|
|
221
|
+
authProvider: this.authProvider,
|
|
206
222
|
requestInit: { headers: this.headers },
|
|
207
223
|
});
|
|
208
224
|
}
|
|
209
225
|
else {
|
|
210
226
|
return new StreamableHTTPClientTransport(new URL(this.endpoint), {
|
|
211
|
-
|
|
227
|
+
authProvider: this.authProvider,
|
|
212
228
|
requestInit: { headers: this.headers },
|
|
229
|
+
sessionId,
|
|
213
230
|
});
|
|
214
231
|
}
|
|
215
232
|
}
|
|
@@ -225,7 +242,7 @@ export class MCPClient {
|
|
|
225
242
|
* Retrieves a complete list of all available tools from the MCP server.
|
|
226
243
|
* Handles pagination automatically by following cursors until all tools are fetched.
|
|
227
244
|
* @returns A complete list of all available tools and their descriptions
|
|
228
|
-
* @throws Will throw an error if any server request fails during pagination
|
|
245
|
+
* @throws {Error} Will throw an error if any server request fails during pagination
|
|
229
246
|
*/
|
|
230
247
|
async listTools() {
|
|
231
248
|
const allTools = [];
|
|
@@ -252,12 +269,21 @@ export class MCPClient {
|
|
|
252
269
|
}
|
|
253
270
|
return allTools;
|
|
254
271
|
}
|
|
272
|
+
getServerCapabilities() {
|
|
273
|
+
return this.client.getServerCapabilities();
|
|
274
|
+
}
|
|
275
|
+
getServerVersion() {
|
|
276
|
+
return this.client.getServerVersion();
|
|
277
|
+
}
|
|
278
|
+
getInstructions() {
|
|
279
|
+
return this.client.getInstructions();
|
|
280
|
+
}
|
|
255
281
|
/**
|
|
256
282
|
* Calls a specific tool on the MCP server with the provided arguments.
|
|
257
283
|
* @param name - The name of the tool to call
|
|
258
284
|
* @param args - Arguments to pass to the tool, must match the tool's expected schema
|
|
259
285
|
* @returns The result from the tool execution
|
|
260
|
-
* @throws Will throw an error if the tool call fails or if arguments are invalid
|
|
286
|
+
* @throws {Error} Will throw an error if the tool call fails or if arguments are invalid
|
|
261
287
|
*/
|
|
262
288
|
async callTool(name, args) {
|
|
263
289
|
const result = await this.client.callTool({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/mcp/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 private transportType: MCPTransport;\n private endpoint: string;\n private headers: Record<string, string>;\n /**\n * Tracks an in-flight reconnect so concurrent triggers coalesce\n * (single-flight). When set, additional calls to `reconnect()` or\n * the automatic `onclose` handler will await the same Promise instead of\n * starting another reconnect sequence.\n */\n private reconnecting?: Promise<void>;\n /**\n * Timer id for a scheduled automatic reconnect (used by `onclose`).\n * Present only while waiting for the backoff delay to elapse.\n */\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n /**\n * Count of consecutive automatic reconnect failures used to compute\n * exponential backoff. Reset to 0 after a successful connection.\n */\n private backoffAttempts = 0;\n\n /**\n * Backoff policy (discoverable constants)\n * - BACKOFF_INITIAL_MS: initial delay for the first automatic retry\n * - BACKOFF_MULTIPLIER: exponential growth factor for each failed attempt\n * - BACKOFF_MAX_MS: upper bound for the delay\n * - BACKOFF_JITTER_RATIO: jitter range as a fraction of the base delay\n *\n * Jitter is applied symmetrically in [-ratio, +ratio]. For example, with a\n * 500ms base delay and 0.2 ratio, the actual delay is in [400ms, 600ms].\n *\n * The backoff applies only to automatic reconnects started from the\n * `onclose` handler. Explicit/manual calls to `reconnect()` run immediately\n * (no backoff), and will preempt any scheduled automatic attempt.\n */\n static readonly BACKOFF_INITIAL_MS = 500;\n static readonly BACKOFF_MULTIPLIER = 2;\n static readonly BACKOFF_MAX_MS = 30_000;\n static readonly BACKOFF_JITTER_RATIO = 0.2;\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 transportType - 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 transportType: MCPTransport,\n headers: Record<string, string> = {},\n ) {\n this.endpoint = endpoint;\n this.headers = headers;\n this.transportType = transportType;\n this.transport = this.initializeTransport(undefined);\n this.client = this.initializeClient();\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 transportType - The transport type to use for the MCP client. Defaults to HTTP.\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 transportType: MCPTransport = MCPTransport.HTTP,\n headers?: Record<string, string>,\n ): Promise<MCPClient> {\n const mcpClient = new MCPClient(endpoint, transportType, headers);\n await mcpClient.client.connect(mcpClient.transport);\n return mcpClient;\n }\n /**\n * Reconnects to the MCP server, optionally retaining the same session ID.\n *\n * Single‑flight semantics:\n * - If a reconnect is already in progress (triggered either manually or by\n * the automatic `onclose` handler), additional calls will await the\n * in-flight reconnect rather than start another one.\n * - If an automatic reconnect has been scheduled but not yet started (i.e.,\n * we are waiting in a backoff delay), calling `reconnect()` manually will\n * cancel the scheduled attempt and perform an immediate reconnect.\n *\n * Backoff policy:\n * - Backoff delays with jitter are applied only for automatic reconnects\n * (via `onclose`). Manual calls to `reconnect()` do not use backoff.\n * @param newSession - Whether to create a new session (true) or reuse existing session ID (false)\n * @param reportErrorOnClose - Whether to report errors when closing the client\n * Note that only StreamableHTTPClientTransport supports session IDs.\n */\n async reconnect(newSession = false, reportErrorOnClose = true) {\n // If a reconnect is already running, coalesce into it.\n if (this.reconnecting) {\n return await this.reconnecting;\n }\n\n // Manual reconnect preempts any scheduled automatic attempt.\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n const doReconnect = async () => {\n const sessionId = newSession\n ? undefined\n : \"sessionId\" in this.transport\n ? this.transport.sessionId\n : undefined;\n\n // Prevent re-entrant onclose during deliberate close by detaching\n // the handler from the previous client instance.\n const prevClient = this.client;\n // Prevent re-entrant onclose callbacks from the previous client\n prevClient.onclose = undefined;\n\n try {\n await prevClient.close();\n } catch (error) {\n if (reportErrorOnClose) {\n console.error(\"Error closing Tambo MCP Client:\", error);\n }\n }\n\n this.transport = this.initializeTransport(sessionId);\n this.client = this.initializeClient();\n await this.client.connect(this.transport);\n };\n\n this.reconnecting = (async () => {\n try {\n await doReconnect();\n // Successful manual reconnect: reset backoff.\n this.backoffAttempts = 0;\n } finally {\n this.reconnecting = undefined;\n }\n })();\n\n return await this.reconnecting;\n }\n\n /**\n * Called by the underlying MCP SDK when the connection closes.\n * Schedules an automatic reconnect with bounded exponential backoff and\n * jitter. If a reconnect is already scheduled or running, this is a no-op.\n */\n private onclose() {\n this.scheduleAutoReconnect();\n }\n\n /**\n * Compute the next backoff delay with symmetric jitter.\n */\n private computeBackoffDelayMs(): number {\n const base = Math.min(\n MCPClient.BACKOFF_MAX_MS,\n MCPClient.BACKOFF_INITIAL_MS *\n Math.pow(MCPClient.BACKOFF_MULTIPLIER, this.backoffAttempts),\n );\n const jitterRange = MCPClient.BACKOFF_JITTER_RATIO * base;\n const jitter = (Math.random() * 2 - 1) * jitterRange; // [-range, +range]\n const ms = Math.max(0, Math.round(base + jitter));\n return ms;\n }\n\n /**\n * Schedule an automatic reconnect attempt if one is not already scheduled\n * or running. Uses the backoff policy and self-reschedules on failure.\n */\n private scheduleAutoReconnect() {\n if (this.reconnecting || this.reconnectTimer) {\n return;\n }\n\n const delayMs = this.computeBackoffDelayMs();\n console.warn(\n \"Tambo MCP Client closed; attempting automatic reconnect in\",\n `${delayMs}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = undefined;\n // Start the actual reconnect (single-flight)\n const inFlight = (this.reconnecting = this.reconnect(false, false));\n try {\n await inFlight;\n // Success: reset attempts\n this.backoffAttempts = 0;\n } catch (err) {\n // Failure: increase attempts; scheduling occurs in finally below so the\n // new timer isn't blocked by `this.reconnecting` being truthy.\n this.backoffAttempts += 1;\n console.warn(\n \"Automatic reconnect failed; will retry with backoff.\",\n err,\n );\n } finally {\n this.reconnecting = undefined;\n if (this.backoffAttempts > 0) {\n this.scheduleAutoReconnect();\n }\n }\n }, delayMs);\n }\n\n private initializeTransport(sessionId: string | undefined) {\n if (this.transportType === MCPTransport.SSE) {\n return new SSEClientTransport(new URL(this.endpoint), {\n requestInit: { headers: this.headers },\n });\n } else {\n return new StreamableHTTPClientTransport(new URL(this.endpoint), {\n sessionId,\n requestInit: { headers: this.headers },\n });\n }\n }\n\n private initializeClient() {\n const client = new Client({\n name: \"tambo-mcp-client\",\n version: \"1.0.0\",\n });\n client.onclose = this.onclose.bind(this);\n return client;\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"]}
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/mcp/mcp-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,2BAAW,CAAA;IACX,6BAAa,CAAA;AACf,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AACD;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,SAAS,CAAqD;IAC9D,aAAa,CAAe;IAC7B,SAAS,CAAU;IAClB,QAAQ,CAAS;IACjB,OAAO,CAAyB;IAChC,YAAY,CAAuB;IAC3C;;;;;OAKG;IACK,YAAY,CAAiB;IACrC;;;OAGG;IACK,cAAc,CAAiC;IACvD;;;OAGG;IACK,eAAe,GAAG,CAAC,CAAC;IAE5B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAU,kBAAkB,GAAG,GAAG,CAAC;IACzC,MAAM,CAAU,kBAAkB,GAAG,CAAC,CAAC;IACvC,MAAM,CAAU,cAAc,GAAG,MAAM,CAAC;IACxC,MAAM,CAAU,oBAAoB,GAAG,GAAG,CAAC;IAE3C;;;;;OAKG;IACH,YACE,QAAgB,EAChB,aAA2B,EAC3B,OAAgC,EAChC,YAAkC,EAClC,SAAkB;QAElB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,QAAgB,EAChB,gBAA8B,YAAY,CAAC,IAAI,EAC/C,OAA2C,EAC3C,YAA6C,EAC7C,SAA6B;QAE7B,MAAM,SAAS,GAAG,IAAI,SAAS,CAC7B,QAAQ,EACR,aAAa,EACb,OAAO,EACP,YAAY,EACZ,SAAS,CACV,CAAC;QACF,MAAM,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,WAAW,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YACvC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC;QACtD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,SAAS,CAAC,UAAU,GAAG,KAAK,EAAE,kBAAkB,GAAG,IAAI;QAC3D,uDAAuD;QACvD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC;QACjC,CAAC;QAED,6DAA6D;QAC7D,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAClC,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;YAC7B,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YAE1D,kEAAkE;YAClE,iDAAiD;YACjD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;YAC/B,gEAAgE;YAChE,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;YAE/B,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,kBAAkB,EAAE,CAAC;oBACvB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;gBAC1D,CAAC;YACH,CAAC;YAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,wEAAwE;YACxE,IAAI,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;gBAC1C,IAAI,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,sEAAsE;oBACtE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,IAAI,CAAC;gBACH,MAAM,WAAW,EAAE,CAAC;gBACpB,8CAA8C;gBAC9C,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;YAC3B,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACK,OAAO;QACb,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACK,qBAAqB;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB,SAAS,CAAC,cAAc,EACxB,SAAS,CAAC,kBAAkB;YAC1B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,eAAe,CAAC,CAC/D,CAAC;QACF,MAAM,WAAW,GAAG,SAAS,CAAC,oBAAoB,GAAG,IAAI,CAAC;QAC1D,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,mBAAmB;QACzE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACK,qBAAqB;QAC3B,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7C,OAAO,CAAC,IAAI,CACV,4DAA4D,EAC5D,GAAG,OAAO,IAAI,CACf,CAAC;QAEF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC1C,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAChC,6CAA6C;YAC7C,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC;gBACf,0BAA0B;gBAC1B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,wEAAwE;gBACxE,+DAA+D;gBAC/D,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC;gBAC1B,OAAO,CAAC,IAAI,CACV,sDAAsD,EACtD,GAAG,CACJ,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC,EAAE,OAAO,CAAC,CAAC;IACd,CAAC;IAEO,mBAAmB,CAAC,SAA6B;QACvD,IAAI,IAAI,CAAC,aAAa,KAAK,YAAY,CAAC,GAAG,EAAE,CAAC;YAC5C,OAAO,IAAI,kBAAkB,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gBACpD,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;aACvC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,6BAA6B,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAC/D,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;gBACtC,SAAS;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;YACxB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,MAAM,GAAuB,SAAS,CAAC;QAE3C,OAAO,OAAO,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAC7D,QAAQ,CAAC,IAAI,CACX,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAe,EAAE;gBAC1C,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACvC,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,CAAC,IAAI,mBAAmB,CACtD,CAAC;gBACJ,CAAC;gBAED,OAAO;oBACL,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,WAAW,EAAE,IAAI,CAAC,WAA0B;iBAC7C,CAAC;YACJ,CAAC,CAAC,CACH,CAAC;YAEF,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBACxB,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAC7C,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;IACvC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,CACZ,IAAY,EACZ,IAA6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YACxC,IAAI;YACJ,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC","sourcesContent":["import { type OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport { 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 private transportType: MCPTransport;\n public sessionId?: string;\n private endpoint: string;\n private headers: Record<string, string>;\n private authProvider?: OAuthClientProvider;\n /**\n * Tracks an in-flight reconnect so concurrent triggers coalesce\n * (single-flight). When set, additional calls to `reconnect()` or\n * the automatic `onclose` handler will await the same Promise instead of\n * starting another reconnect sequence.\n */\n private reconnecting?: Promise<void>;\n /**\n * Timer id for a scheduled automatic reconnect (used by `onclose`).\n * Present only while waiting for the backoff delay to elapse.\n */\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n /**\n * Count of consecutive automatic reconnect failures used to compute\n * exponential backoff. Reset to 0 after a successful connection.\n */\n private backoffAttempts = 0;\n\n /**\n * Backoff policy (discoverable constants)\n * - BACKOFF_INITIAL_MS: initial delay for the first automatic retry\n * - BACKOFF_MULTIPLIER: exponential growth factor for each failed attempt\n * - BACKOFF_MAX_MS: upper bound for the delay\n * - BACKOFF_JITTER_RATIO: jitter range as a fraction of the base delay\n *\n * Jitter is applied symmetrically in [-ratio, +ratio]. For example, with a\n * 500ms base delay and 0.2 ratio, the actual delay is in [400ms, 600ms].\n *\n * The backoff applies only to automatic reconnects started from the\n * `onclose` handler. Explicit/manual calls to `reconnect()` run immediately\n * (no backoff), and will preempt any scheduled automatic attempt.\n */\n static readonly BACKOFF_INITIAL_MS = 500;\n static readonly BACKOFF_MULTIPLIER = 2;\n static readonly BACKOFF_MAX_MS = 30_000;\n static readonly BACKOFF_JITTER_RATIO = 0.2;\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 transportType - 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 transportType: MCPTransport,\n headers?: Record<string, string>,\n authProvider?: OAuthClientProvider,\n sessionId?: string,\n ) {\n this.endpoint = endpoint;\n this.headers = headers ?? {};\n this.authProvider = authProvider;\n this.transportType = transportType;\n this.transport = this.initializeTransport(sessionId);\n this.client = this.initializeClient();\n }\n\n /**\n * Creates and initializes a new MCPClient instance. This is the recommended\n * way to create an MCPClient as it handles both instantiation and connection\n * setup.\n * @param endpoint - The URL of the MCP server to connect to\n * @param transportType - The transport type to use for the MCP client. Defaults to HTTP.\n * @param headers - Optional custom headers to include in requests\n * @param authProvider - Optional auth provider to use for authentication\n * @param sessionId - Optional session id to use for the MCP client - if not\n * provided, a new session will be created\n * @returns A connected MCPClient instance ready for use\n * @throws {Error} Will throw an error if connection fails\n */\n static async create(\n endpoint: string,\n transportType: MCPTransport = MCPTransport.HTTP,\n headers: Record<string, string> | undefined,\n authProvider: OAuthClientProvider | undefined,\n sessionId: string | undefined,\n ): Promise<MCPClient> {\n const mcpClient = new MCPClient(\n endpoint,\n transportType,\n headers,\n authProvider,\n sessionId,\n );\n await mcpClient.client.connect(mcpClient.transport);\n if (\"sessionId\" in mcpClient.transport) {\n mcpClient.sessionId = mcpClient.transport.sessionId;\n }\n return mcpClient;\n }\n /**\n * Reconnects to the MCP server, optionally retaining the same session ID.\n *\n * Single‑flight semantics:\n * - If a reconnect is already in progress (triggered either manually or by\n * the automatic `onclose` handler), additional calls will await the\n * in-flight reconnect rather than start another one.\n * - If an automatic reconnect has been scheduled but not yet started (i.e.,\n * we are waiting in a backoff delay), calling `reconnect()` manually will\n * cancel the scheduled attempt and perform an immediate reconnect.\n *\n * Backoff policy:\n * - Backoff delays with jitter are applied only for automatic reconnects\n * (via `onclose`). Manual calls to `reconnect()` do not use backoff.\n * @param newSession - Whether to create a new session (true) or reuse existing session ID (false)\n * @param reportErrorOnClose - Whether to report errors when closing the client\n * Note that only StreamableHTTPClientTransport supports session IDs.\n * @returns A promise that resolves when the reconnect is complete\n */\n async reconnect(newSession = false, reportErrorOnClose = true) {\n // If a reconnect is already running, coalesce into it.\n if (this.reconnecting) {\n return await this.reconnecting;\n }\n\n // Manual reconnect preempts any scheduled automatic attempt.\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n const doReconnect = async () => {\n const sessionId = newSession ? undefined : this.sessionId;\n\n // Prevent re-entrant onclose during deliberate close by detaching\n // the handler from the previous client instance.\n const prevClient = this.client;\n // Prevent re-entrant onclose callbacks from the previous client\n prevClient.onclose = undefined;\n\n try {\n await prevClient.close();\n } catch (error) {\n if (reportErrorOnClose) {\n console.error(\"Error closing Tambo MCP Client:\", error);\n }\n }\n\n this.transport = this.initializeTransport(sessionId);\n this.client = this.initializeClient();\n await this.client.connect(this.transport);\n // We may have gotten a session id from the server, so we need to set it\n if (\"sessionId\" in this.transport) {\n this.sessionId = this.transport.sessionId;\n if (sessionId !== this.sessionId) {\n // This is a pretty unusual thing to happen, but it might be possible?\n console.warn(\"Session id mismatch\", sessionId, this.sessionId);\n }\n }\n };\n\n this.reconnecting = (async () => {\n try {\n await doReconnect();\n // Successful manual reconnect: reset backoff.\n this.backoffAttempts = 0;\n } finally {\n this.reconnecting = undefined;\n }\n })();\n\n return await this.reconnecting;\n }\n\n /**\n * Called by the underlying MCP SDK when the connection closes.\n * Schedules an automatic reconnect with bounded exponential backoff and\n * jitter. If a reconnect is already scheduled or running, this is a no-op.\n */\n private onclose() {\n this.scheduleAutoReconnect();\n }\n\n /**\n * Compute the next backoff delay with symmetric jitter.\n * @returns The next backoff delay in milliseconds\n */\n private computeBackoffDelayMs(): number {\n const base = Math.min(\n MCPClient.BACKOFF_MAX_MS,\n MCPClient.BACKOFF_INITIAL_MS *\n Math.pow(MCPClient.BACKOFF_MULTIPLIER, this.backoffAttempts),\n );\n const jitterRange = MCPClient.BACKOFF_JITTER_RATIO * base;\n const jitter = (Math.random() * 2 - 1) * jitterRange; // [-range, +range]\n const ms = Math.max(0, Math.round(base + jitter));\n return ms;\n }\n\n /**\n * Schedule an automatic reconnect attempt if one is not already scheduled\n * or running. Uses the backoff policy and self-reschedules on failure.\n */\n private scheduleAutoReconnect() {\n if (this.reconnecting || this.reconnectTimer) {\n return;\n }\n\n const delayMs = this.computeBackoffDelayMs();\n console.warn(\n \"Tambo MCP Client closed; attempting automatic reconnect in\",\n `${delayMs}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = undefined;\n // Start the actual reconnect (single-flight)\n const inFlight = (this.reconnecting = this.reconnect(false, false));\n try {\n await inFlight;\n // Success: reset attempts\n this.backoffAttempts = 0;\n } catch (err) {\n // Failure: increase attempts; scheduling occurs in finally below so the\n // new timer isn't blocked by `this.reconnecting` being truthy.\n this.backoffAttempts += 1;\n console.warn(\n \"Automatic reconnect failed; will retry with backoff.\",\n err,\n );\n } finally {\n this.reconnecting = undefined;\n if (this.backoffAttempts > 0) {\n this.scheduleAutoReconnect();\n }\n }\n }, delayMs);\n }\n\n private initializeTransport(sessionId: string | undefined) {\n if (this.transportType === MCPTransport.SSE) {\n return new SSEClientTransport(new URL(this.endpoint), {\n authProvider: this.authProvider,\n requestInit: { headers: this.headers },\n });\n } else {\n return new StreamableHTTPClientTransport(new URL(this.endpoint), {\n authProvider: this.authProvider,\n requestInit: { headers: this.headers },\n sessionId,\n });\n }\n }\n\n private initializeClient() {\n const client = new Client({\n name: \"tambo-mcp-client\",\n version: \"1.0.0\",\n });\n client.onclose = this.onclose.bind(this);\n return client;\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 {Error} 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 getServerCapabilities() {\n return this.client.getServerCapabilities();\n }\n\n getServerVersion() {\n return this.client.getServerVersion();\n }\n\n getInstructions() {\n return this.client.getInstructions();\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 {Error} Will throw an error if the tool call fails or if arguments are invalid\n */\n async callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<MCPToolCallResult> {\n const result = await this.client.callTool({\n name,\n arguments: args,\n });\n return result;\n }\n}\n\n/**\n * The result of a tool call.\n * This is the same as the result of a tool call in the OpenAI SDK, but is reified here\n */\nexport type MCPToolCallResult = Awaited<\n ReturnType<typeof Client.prototype.callTool>\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"]}
|
|
@@ -43,7 +43,7 @@ export declare const TamboMcpProvider: FC<{
|
|
|
43
43
|
* For example, to forcibly disconnect and reconnect all MCP servers:
|
|
44
44
|
*
|
|
45
45
|
* ```tsx
|
|
46
|
-
* const mcpServers =
|
|
46
|
+
* const mcpServers = useTamboMcpServers();
|
|
47
47
|
* mcpServers.forEach((mcpServer) => {
|
|
48
48
|
* mcpServer.client?.reconnect();
|
|
49
49
|
* });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,EAAE,EAIH,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAsB5D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,eAAe,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAG7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC;IAChC,UAAU,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAwIA,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,mBAE9B,CAAC"}
|