@ai-sdk/mcp 2.0.0 → 2.0.2
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/CHANGELOG.md +12 -0
- package/README.md +24 -1
- package/dist/index.d.ts +71 -1
- package/dist/index.js +101 -36
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/tool/mcp-client.ts +53 -15
- package/src/tool/mcp-http-transport.ts +81 -19
- package/src/tool/mcp-transport.ts +36 -0
- package/src/tool/oauth-types.ts +45 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ba6d510: chore: fix deprecated use of zod `.passthrough()`
|
|
8
|
+
|
|
9
|
+
## 2.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 241a8c5: Add Streamable HTTP session hooks, cached initialize metadata, and detach-on-close support for reattaching to MCP sessions.
|
|
14
|
+
|
|
3
15
|
## 2.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ const result = streamText({
|
|
|
76
76
|
model: 'openai/gpt-5.4',
|
|
77
77
|
tools: await mcpClient.tools(),
|
|
78
78
|
prompt: 'Use the available tools to answer the user question.',
|
|
79
|
-
|
|
79
|
+
onEnd: async () => {
|
|
80
80
|
await mcpClient.close();
|
|
81
81
|
},
|
|
82
82
|
});
|
|
@@ -93,12 +93,35 @@ HTTP is recommended for production deployments:
|
|
|
93
93
|
```ts
|
|
94
94
|
import { createMCPClient } from '@ai-sdk/mcp';
|
|
95
95
|
|
|
96
|
+
const savedSession = await loadMcpSession();
|
|
97
|
+
let currentSessionId = savedSession?.sessionId;
|
|
98
|
+
|
|
96
99
|
const mcpClient = await createMCPClient({
|
|
97
100
|
transport: {
|
|
98
101
|
type: 'http',
|
|
99
102
|
url: 'https://your-server.com/mcp',
|
|
103
|
+
initialSessionId: savedSession?.sessionId,
|
|
104
|
+
initialProtocolVersion: savedSession?.initializeResult.protocolVersion,
|
|
105
|
+
terminateSessionOnClose: false,
|
|
106
|
+
onSessionIdChange: sessionId => {
|
|
107
|
+
currentSessionId = sessionId;
|
|
108
|
+
},
|
|
109
|
+
onSessionExpired: sessionId => {
|
|
110
|
+
if (currentSessionId === sessionId) {
|
|
111
|
+
currentSessionId = undefined;
|
|
112
|
+
void clearMcpSession();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
100
115
|
},
|
|
116
|
+
initialInitializeResult: savedSession?.initializeResult,
|
|
101
117
|
});
|
|
118
|
+
|
|
119
|
+
if (currentSessionId) {
|
|
120
|
+
await saveMcpSession({
|
|
121
|
+
sessionId: currentSessionId,
|
|
122
|
+
initializeResult: mcpClient.initializeResult,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
102
125
|
```
|
|
103
126
|
|
|
104
127
|
SSE is also supported for MCP servers that use Server-Sent Events:
|
package/dist/index.d.ts
CHANGED
|
@@ -273,6 +273,37 @@ type MCPTransportConfig = {
|
|
|
273
273
|
* @default 'error'
|
|
274
274
|
*/
|
|
275
275
|
redirect?: 'follow' | 'error';
|
|
276
|
+
/**
|
|
277
|
+
* Initial MCP session id to send with resumed Streamable HTTP requests after
|
|
278
|
+
* initialization.
|
|
279
|
+
* Only used by the HTTP transport.
|
|
280
|
+
*/
|
|
281
|
+
initialSessionId?: string;
|
|
282
|
+
/**
|
|
283
|
+
* Initial MCP protocol version to send before initialize negotiates one.
|
|
284
|
+
* Only used by the HTTP transport.
|
|
285
|
+
*/
|
|
286
|
+
initialProtocolVersion?: string;
|
|
287
|
+
/**
|
|
288
|
+
* Called when the Streamable HTTP server creates, changes, or clears the MCP
|
|
289
|
+
* session id.
|
|
290
|
+
* Only used by the HTTP transport.
|
|
291
|
+
*/
|
|
292
|
+
onSessionIdChange?: (sessionId: string | undefined) => void;
|
|
293
|
+
/**
|
|
294
|
+
* Called when a Streamable HTTP request returns 404 for an existing MCP
|
|
295
|
+
* session id. The transport clears the session id before reporting the
|
|
296
|
+
* underlying HTTP error.
|
|
297
|
+
* Only used by the HTTP transport.
|
|
298
|
+
*/
|
|
299
|
+
onSessionExpired?: (sessionId: string) => void;
|
|
300
|
+
/**
|
|
301
|
+
* Whether close() should send DELETE for the current MCP session id.
|
|
302
|
+
* Set to false when the application intends to reattach to the session later.
|
|
303
|
+
* Only used by the HTTP transport.
|
|
304
|
+
* @default true
|
|
305
|
+
*/
|
|
306
|
+
terminateSessionOnClose?: boolean;
|
|
276
307
|
/**
|
|
277
308
|
* Optional custom fetch implementation to use for HTTP requests.
|
|
278
309
|
* Useful for runtimes that need a request-local fetch.
|
|
@@ -337,6 +368,34 @@ declare const ClientCapabilitiesSchema: z.ZodObject<{
|
|
|
337
368
|
}, z.core.$loose>>;
|
|
338
369
|
}, z.core.$loose>;
|
|
339
370
|
type ClientCapabilities = z.infer<typeof ClientCapabilitiesSchema>;
|
|
371
|
+
declare const InitializeResultSchema: z.ZodObject<{
|
|
372
|
+
_meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
373
|
+
protocolVersion: z.ZodString;
|
|
374
|
+
capabilities: z.ZodObject<{
|
|
375
|
+
experimental: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
376
|
+
logging: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
377
|
+
prompts: z.ZodOptional<z.ZodObject<{
|
|
378
|
+
listChanged: z.ZodOptional<z.ZodBoolean>;
|
|
379
|
+
}, z.core.$loose>>;
|
|
380
|
+
resources: z.ZodOptional<z.ZodObject<{
|
|
381
|
+
subscribe: z.ZodOptional<z.ZodBoolean>;
|
|
382
|
+
listChanged: z.ZodOptional<z.ZodBoolean>;
|
|
383
|
+
}, z.core.$loose>>;
|
|
384
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
385
|
+
listChanged: z.ZodOptional<z.ZodBoolean>;
|
|
386
|
+
}, z.core.$loose>>;
|
|
387
|
+
elicitation: z.ZodOptional<z.ZodObject<{
|
|
388
|
+
applyDefaults: z.ZodOptional<z.ZodBoolean>;
|
|
389
|
+
}, z.core.$loose>>;
|
|
390
|
+
}, z.core.$loose>;
|
|
391
|
+
serverInfo: z.ZodObject<{
|
|
392
|
+
name: z.ZodString;
|
|
393
|
+
version: z.ZodString;
|
|
394
|
+
title: z.ZodOptional<z.ZodString>;
|
|
395
|
+
}, z.core.$loose>;
|
|
396
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
397
|
+
}, z.core.$loose>;
|
|
398
|
+
type InitializeResult = z.infer<typeof InitializeResultSchema>;
|
|
340
399
|
type PaginatedRequest = Request & {
|
|
341
400
|
params?: BaseParams & {
|
|
342
401
|
cursor?: string;
|
|
@@ -513,6 +572,12 @@ interface MCPClientConfig {
|
|
|
513
572
|
transport: MCPTransportConfig | MCPTransport;
|
|
514
573
|
/** Optional callback for uncaught errors */
|
|
515
574
|
onUncaughtError?: (error: unknown) => void;
|
|
575
|
+
/**
|
|
576
|
+
* Initialize result from a previous MCP session. When provided, the client
|
|
577
|
+
* starts the transport and reuses this metadata without sending a new
|
|
578
|
+
* initialize request.
|
|
579
|
+
*/
|
|
580
|
+
initialInitializeResult?: InitializeResult;
|
|
516
581
|
/** Optional client name, defaults to 'ai-sdk-mcp-client' */
|
|
517
582
|
clientName?: string;
|
|
518
583
|
/**
|
|
@@ -537,6 +602,11 @@ interface MCPClient {
|
|
|
537
602
|
* @see https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation
|
|
538
603
|
*/
|
|
539
604
|
readonly serverInfo: Configuration;
|
|
605
|
+
/**
|
|
606
|
+
* The full initialize result used by this client, either from the server
|
|
607
|
+
* during initialization or from `initialInitializeResult`.
|
|
608
|
+
*/
|
|
609
|
+
readonly initializeResult: InitializeResult;
|
|
540
610
|
/**
|
|
541
611
|
* Optional instructions provided by the server during the initialize handshake.
|
|
542
612
|
*
|
|
@@ -651,4 +721,4 @@ declare function readMCPAppResource({ client, uri, options, }: {
|
|
|
651
721
|
options?: RequestOptions;
|
|
652
722
|
}): Promise<MCPAppResource>;
|
|
653
723
|
|
|
654
|
-
export { type CallToolResult, type Configuration, type ElicitResult, ElicitResultSchema, type ElicitationRequest, ElicitationRequestSchema, type JSONRPCError, type JSONRPCMessage, type JSONRPCNotification, type JSONRPCRequest, type JSONRPCResponse, type ListToolsResult, type MCPAppResource, type MCPAppResourceCSP, type MCPAppResourceMeta, type MCPClient, type ClientCapabilities as MCPClientCapabilities, type MCPClientConfig, type MCPTransport, MCP_APP_MIME_TYPE, type McpProviderMetadata, type OAuthAuthorizationServerInformation, type OAuthClientInformation, type OAuthClientMetadata, type OAuthClientProvider, type OAuthTokens, UnauthorizedError, auth, createMCPClient, type MCPClient as experimental_MCPClient, type ClientCapabilities as experimental_MCPClientCapabilities, type MCPClientConfig as experimental_MCPClientConfig, createMCPClient as experimental_createMCPClient, mcpAppClientCapabilities, readMCPAppResource, splitMCPAppTools };
|
|
724
|
+
export { type CallToolResult, type Configuration, type ElicitResult, ElicitResultSchema, type ElicitationRequest, ElicitationRequestSchema, type InitializeResult, type JSONRPCError, type JSONRPCMessage, type JSONRPCNotification, type JSONRPCRequest, type JSONRPCResponse, type ListToolsResult, type MCPAppResource, type MCPAppResourceCSP, type MCPAppResourceMeta, type MCPClient, type ClientCapabilities as MCPClientCapabilities, type MCPClientConfig, type MCPTransport, MCP_APP_MIME_TYPE, type McpProviderMetadata, type OAuthAuthorizationServerInformation, type OAuthClientInformation, type OAuthClientMetadata, type OAuthClientProvider, type OAuthTokens, UnauthorizedError, auth, createMCPClient, type MCPClient as experimental_MCPClient, type ClientCapabilities as experimental_MCPClientCapabilities, type MCPClientConfig as experimental_MCPClientConfig, createMCPClient as experimental_createMCPClient, mcpAppClientCapabilities, readMCPAppResource, splitMCPAppTools };
|
package/dist/index.js
CHANGED
|
@@ -339,7 +339,7 @@ var OAuthTokensSchema = z3.object({
|
|
|
339
339
|
authorization_server: SafeUrlSchema.optional(),
|
|
340
340
|
token_endpoint: SafeUrlSchema.optional()
|
|
341
341
|
}).strip();
|
|
342
|
-
var OAuthProtectedResourceMetadataSchema = z3.
|
|
342
|
+
var OAuthProtectedResourceMetadataSchema = z3.looseObject({
|
|
343
343
|
resource: z3.string().url(),
|
|
344
344
|
authorization_servers: z3.array(SafeUrlSchema).optional(),
|
|
345
345
|
jwks_uri: z3.string().url().optional(),
|
|
@@ -354,8 +354,8 @@ var OAuthProtectedResourceMetadataSchema = z3.object({
|
|
|
354
354
|
authorization_details_types_supported: z3.array(z3.string()).optional(),
|
|
355
355
|
dpop_signing_alg_values_supported: z3.array(z3.string()).optional(),
|
|
356
356
|
dpop_bound_access_tokens_required: z3.boolean().optional()
|
|
357
|
-
})
|
|
358
|
-
var OAuthMetadataSchema = z3.
|
|
357
|
+
});
|
|
358
|
+
var OAuthMetadataSchema = z3.looseObject({
|
|
359
359
|
issuer: z3.string(),
|
|
360
360
|
authorization_endpoint: SafeUrlSchema,
|
|
361
361
|
token_endpoint: SafeUrlSchema,
|
|
@@ -366,8 +366,8 @@ var OAuthMetadataSchema = z3.object({
|
|
|
366
366
|
code_challenge_methods_supported: z3.array(z3.string()),
|
|
367
367
|
token_endpoint_auth_methods_supported: z3.array(z3.string()).optional(),
|
|
368
368
|
token_endpoint_auth_signing_alg_values_supported: z3.array(z3.string()).optional()
|
|
369
|
-
})
|
|
370
|
-
var OpenIdProviderMetadataSchema = z3.
|
|
369
|
+
});
|
|
370
|
+
var OpenIdProviderMetadataSchema = z3.looseObject({
|
|
371
371
|
issuer: z3.string(),
|
|
372
372
|
authorization_endpoint: SafeUrlSchema,
|
|
373
373
|
token_endpoint: SafeUrlSchema,
|
|
@@ -381,7 +381,7 @@ var OpenIdProviderMetadataSchema = z3.object({
|
|
|
381
381
|
id_token_signing_alg_values_supported: z3.array(z3.string()),
|
|
382
382
|
claims_supported: z3.array(z3.string()).optional(),
|
|
383
383
|
token_endpoint_auth_methods_supported: z3.array(z3.string()).optional()
|
|
384
|
-
})
|
|
384
|
+
});
|
|
385
385
|
var OpenIdProviderDiscoveryMetadataSchema = OpenIdProviderMetadataSchema.merge(
|
|
386
386
|
OAuthMetadataSchema.pick({
|
|
387
387
|
code_challenge_methods_supported: true
|
|
@@ -1503,6 +1503,11 @@ var HttpMCPTransport = class {
|
|
|
1503
1503
|
headers,
|
|
1504
1504
|
authProvider,
|
|
1505
1505
|
redirect = "error",
|
|
1506
|
+
initialSessionId,
|
|
1507
|
+
initialProtocolVersion,
|
|
1508
|
+
onSessionIdChange,
|
|
1509
|
+
onSessionExpired,
|
|
1510
|
+
terminateSessionOnClose = true,
|
|
1506
1511
|
fetch: fetchFn
|
|
1507
1512
|
}) {
|
|
1508
1513
|
this.inboundReconnectAttempts = 0;
|
|
@@ -1516,19 +1521,27 @@ var HttpMCPTransport = class {
|
|
|
1516
1521
|
this.headers = headers;
|
|
1517
1522
|
this.authProvider = authProvider;
|
|
1518
1523
|
this.redirectMode = redirect;
|
|
1524
|
+
this.sessionId = initialSessionId;
|
|
1525
|
+
this.protocolVersion = initialProtocolVersion;
|
|
1526
|
+
this.onSessionIdChange = onSessionIdChange;
|
|
1527
|
+
this.onSessionExpired = onSessionExpired;
|
|
1528
|
+
this.terminateSessionOnClose = terminateSessionOnClose;
|
|
1519
1529
|
this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
|
|
1520
1530
|
}
|
|
1521
1531
|
setProtocolVersion(version) {
|
|
1522
1532
|
this.protocolVersion = version;
|
|
1523
1533
|
}
|
|
1524
|
-
async commonHeaders(
|
|
1534
|
+
async commonHeaders({
|
|
1535
|
+
base,
|
|
1536
|
+
includeSessionId = true
|
|
1537
|
+
}) {
|
|
1525
1538
|
var _a3;
|
|
1526
1539
|
const headers = {
|
|
1527
1540
|
...this.headers,
|
|
1528
1541
|
...base,
|
|
1529
1542
|
"mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
|
|
1530
1543
|
};
|
|
1531
|
-
if (this.sessionId) {
|
|
1544
|
+
if (includeSessionId && this.sessionId) {
|
|
1532
1545
|
headers["mcp-session-id"] = this.sessionId;
|
|
1533
1546
|
}
|
|
1534
1547
|
if (this.authProvider) {
|
|
@@ -1543,6 +1556,27 @@ var HttpMCPTransport = class {
|
|
|
1543
1556
|
getRuntimeEnvironmentUserAgent2()
|
|
1544
1557
|
);
|
|
1545
1558
|
}
|
|
1559
|
+
setSessionId(sessionId) {
|
|
1560
|
+
var _a3;
|
|
1561
|
+
if (this.sessionId === sessionId) {
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
this.sessionId = sessionId;
|
|
1565
|
+
(_a3 = this.onSessionIdChange) == null ? void 0 : _a3.call(this, sessionId);
|
|
1566
|
+
}
|
|
1567
|
+
applySessionIdFromResponse(response) {
|
|
1568
|
+
const sessionId = response.headers.get("mcp-session-id");
|
|
1569
|
+
if (sessionId) {
|
|
1570
|
+
this.setSessionId(sessionId);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
expireSessionId(sessionId) {
|
|
1574
|
+
var _a3;
|
|
1575
|
+
if (this.sessionId === sessionId) {
|
|
1576
|
+
this.setSessionId(void 0);
|
|
1577
|
+
}
|
|
1578
|
+
(_a3 = this.onSessionExpired) == null ? void 0 : _a3.call(this, sessionId);
|
|
1579
|
+
}
|
|
1546
1580
|
/**
|
|
1547
1581
|
* Runs a single OAuth recovery flow for concurrent 401 responses.
|
|
1548
1582
|
*/
|
|
@@ -1574,8 +1608,8 @@ var HttpMCPTransport = class {
|
|
|
1574
1608
|
var _a3, _b3, _c;
|
|
1575
1609
|
(_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
|
|
1576
1610
|
try {
|
|
1577
|
-
if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
|
|
1578
|
-
const headers = await this.commonHeaders({});
|
|
1611
|
+
if (this.sessionId && this.terminateSessionOnClose && this.abortController && !this.abortController.signal.aborted) {
|
|
1612
|
+
const headers = await this.commonHeaders({ base: {} });
|
|
1579
1613
|
await this.fetchFn(this.url.href, {
|
|
1580
1614
|
method: "DELETE",
|
|
1581
1615
|
headers,
|
|
@@ -1592,9 +1626,14 @@ var HttpMCPTransport = class {
|
|
|
1592
1626
|
const attempt = async (triedAuth = false) => {
|
|
1593
1627
|
var _a3, _b3, _c, _d, _e, _f, _g;
|
|
1594
1628
|
try {
|
|
1629
|
+
const isInitializeRequest = "method" in message && message.method === "initialize";
|
|
1630
|
+
const sessionIdForRequest = isInitializeRequest ? void 0 : this.sessionId;
|
|
1595
1631
|
const headers = await this.commonHeaders({
|
|
1596
|
-
|
|
1597
|
-
|
|
1632
|
+
base: {
|
|
1633
|
+
"Content-Type": "application/json",
|
|
1634
|
+
Accept: "application/json, text/event-stream"
|
|
1635
|
+
},
|
|
1636
|
+
includeSessionId: !isInitializeRequest
|
|
1598
1637
|
});
|
|
1599
1638
|
const init = {
|
|
1600
1639
|
method: "POST",
|
|
@@ -1604,10 +1643,7 @@ var HttpMCPTransport = class {
|
|
|
1604
1643
|
redirect: this.redirectMode
|
|
1605
1644
|
};
|
|
1606
1645
|
const response = await this.fetchFn(this.url.href, init);
|
|
1607
|
-
|
|
1608
|
-
if (sessionId) {
|
|
1609
|
-
this.sessionId = sessionId;
|
|
1610
|
-
}
|
|
1646
|
+
this.applySessionIdFromResponse(response);
|
|
1611
1647
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1612
1648
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1613
1649
|
try {
|
|
@@ -1632,7 +1668,12 @@ var HttpMCPTransport = class {
|
|
|
1632
1668
|
const text = await response.text().catch(() => null);
|
|
1633
1669
|
let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`;
|
|
1634
1670
|
if (response.status === 404) {
|
|
1635
|
-
|
|
1671
|
+
if (sessionIdForRequest) {
|
|
1672
|
+
this.expireSessionId(sessionIdForRequest);
|
|
1673
|
+
errorMessage += ". The MCP session expired. Create a new client without `initialSessionId` to start a fresh session";
|
|
1674
|
+
} else {
|
|
1675
|
+
errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
|
|
1676
|
+
}
|
|
1636
1677
|
}
|
|
1637
1678
|
const error2 = new MCPClientError({
|
|
1638
1679
|
message: errorMessage,
|
|
@@ -1749,8 +1790,11 @@ var HttpMCPTransport = class {
|
|
|
1749
1790
|
async openInboundSse(triedAuth = false, resumeToken) {
|
|
1750
1791
|
var _a3, _b3, _c, _d, _e, _f;
|
|
1751
1792
|
try {
|
|
1793
|
+
const sessionIdForRequest = this.sessionId;
|
|
1752
1794
|
const headers = await this.commonHeaders({
|
|
1753
|
-
|
|
1795
|
+
base: {
|
|
1796
|
+
Accept: "text/event-stream"
|
|
1797
|
+
}
|
|
1754
1798
|
});
|
|
1755
1799
|
if (resumeToken) {
|
|
1756
1800
|
headers["last-event-id"] = resumeToken;
|
|
@@ -1761,10 +1805,7 @@ var HttpMCPTransport = class {
|
|
|
1761
1805
|
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1762
1806
|
redirect: this.redirectMode
|
|
1763
1807
|
});
|
|
1764
|
-
|
|
1765
|
-
if (sessionId) {
|
|
1766
|
-
this.sessionId = sessionId;
|
|
1767
|
-
}
|
|
1808
|
+
this.applySessionIdFromResponse(response);
|
|
1768
1809
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1769
1810
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1770
1811
|
try {
|
|
@@ -1784,6 +1825,9 @@ var HttpMCPTransport = class {
|
|
|
1784
1825
|
return;
|
|
1785
1826
|
}
|
|
1786
1827
|
if (!response.ok || !response.body) {
|
|
1828
|
+
if (response.status === 404 && sessionIdForRequest) {
|
|
1829
|
+
this.expireSessionId(sessionIdForRequest);
|
|
1830
|
+
}
|
|
1787
1831
|
const error = new MCPClientError({
|
|
1788
1832
|
message: `MCP HTTP Transport Error: GET SSE failed: ${response.status} ${response.statusText}`,
|
|
1789
1833
|
statusCode: response.status,
|
|
@@ -2005,15 +2049,22 @@ var DefaultMCPClient = class {
|
|
|
2005
2049
|
clientName = name3 != null ? name3 : "ai-sdk-mcp-client",
|
|
2006
2050
|
version = CLIENT_VERSION,
|
|
2007
2051
|
onUncaughtError,
|
|
2008
|
-
capabilities
|
|
2052
|
+
capabilities,
|
|
2053
|
+
initialInitializeResult
|
|
2009
2054
|
}) {
|
|
2010
2055
|
this.requestMessageId = 0;
|
|
2011
2056
|
this.responseHandlers = /* @__PURE__ */ new Map();
|
|
2012
2057
|
this.serverCapabilities = {};
|
|
2013
2058
|
this._serverInfo = { name: "", version: "" };
|
|
2059
|
+
this._initializeResult = {
|
|
2060
|
+
protocolVersion: LATEST_PROTOCOL_VERSION,
|
|
2061
|
+
capabilities: {},
|
|
2062
|
+
serverInfo: this._serverInfo
|
|
2063
|
+
};
|
|
2014
2064
|
this.isClosed = true;
|
|
2015
2065
|
this.onUncaughtError = onUncaughtError;
|
|
2016
2066
|
this.clientCapabilities = capabilities != null ? capabilities : {};
|
|
2067
|
+
this.initialInitializeResult = initialInitializeResult;
|
|
2017
2068
|
if (isCustomMcpTransport(transportConfig)) {
|
|
2018
2069
|
this.transport = transportConfig;
|
|
2019
2070
|
} else {
|
|
@@ -2044,6 +2095,9 @@ var DefaultMCPClient = class {
|
|
|
2044
2095
|
get serverInfo() {
|
|
2045
2096
|
return this._serverInfo;
|
|
2046
2097
|
}
|
|
2098
|
+
get initializeResult() {
|
|
2099
|
+
return this._initializeResult;
|
|
2100
|
+
}
|
|
2047
2101
|
get instructions() {
|
|
2048
2102
|
return this._serverInstructions;
|
|
2049
2103
|
}
|
|
@@ -2051,6 +2105,13 @@ var DefaultMCPClient = class {
|
|
|
2051
2105
|
try {
|
|
2052
2106
|
await this.transport.start();
|
|
2053
2107
|
this.isClosed = false;
|
|
2108
|
+
if (this.initialInitializeResult) {
|
|
2109
|
+
const result2 = InitializeResultSchema.parse(
|
|
2110
|
+
this.initialInitializeResult
|
|
2111
|
+
);
|
|
2112
|
+
this.applyInitializeResult(result2);
|
|
2113
|
+
return this;
|
|
2114
|
+
}
|
|
2054
2115
|
const result = await this.request({
|
|
2055
2116
|
request: {
|
|
2056
2117
|
method: "initialize",
|
|
@@ -2067,19 +2128,7 @@ var DefaultMCPClient = class {
|
|
|
2067
2128
|
message: "Server sent invalid initialize result"
|
|
2068
2129
|
});
|
|
2069
2130
|
}
|
|
2070
|
-
|
|
2071
|
-
throw new MCPClientError({
|
|
2072
|
-
message: `Server's protocol version is not supported: ${result.protocolVersion}`
|
|
2073
|
-
});
|
|
2074
|
-
}
|
|
2075
|
-
this.serverCapabilities = result.capabilities;
|
|
2076
|
-
this._serverInfo = result.serverInfo;
|
|
2077
|
-
if (this.transport.setProtocolVersion) {
|
|
2078
|
-
this.transport.setProtocolVersion(result.protocolVersion);
|
|
2079
|
-
} else {
|
|
2080
|
-
this.transport.protocolVersion = result.protocolVersion;
|
|
2081
|
-
}
|
|
2082
|
-
this._serverInstructions = result.instructions;
|
|
2131
|
+
this.applyInitializeResult(result);
|
|
2083
2132
|
await this.notification({
|
|
2084
2133
|
method: "notifications/initialized"
|
|
2085
2134
|
});
|
|
@@ -2089,6 +2138,22 @@ var DefaultMCPClient = class {
|
|
|
2089
2138
|
throw error;
|
|
2090
2139
|
}
|
|
2091
2140
|
}
|
|
2141
|
+
applyInitializeResult(result) {
|
|
2142
|
+
if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
|
|
2143
|
+
throw new MCPClientError({
|
|
2144
|
+
message: `Server's protocol version is not supported: ${result.protocolVersion}`
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
this.serverCapabilities = result.capabilities;
|
|
2148
|
+
this._serverInfo = result.serverInfo;
|
|
2149
|
+
this._initializeResult = result;
|
|
2150
|
+
if (this.transport.setProtocolVersion) {
|
|
2151
|
+
this.transport.setProtocolVersion(result.protocolVersion);
|
|
2152
|
+
} else {
|
|
2153
|
+
this.transport.protocolVersion = result.protocolVersion;
|
|
2154
|
+
}
|
|
2155
|
+
this._serverInstructions = result.instructions;
|
|
2156
|
+
}
|
|
2092
2157
|
async close() {
|
|
2093
2158
|
var _a3;
|
|
2094
2159
|
if (this.isClosed) return;
|