@ai-sdk/mcp 1.0.41 → 1.0.43

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.
@@ -62,6 +62,10 @@ interface MCPTransport {
62
62
  * Event handler for received messages
63
63
  */
64
64
  onmessage?: (message: JSONRPCMessage) => void;
65
+ /**
66
+ * The protocol version negotiated during initialization.
67
+ */
68
+ protocolVersion?: string;
65
69
  }
66
70
 
67
71
  interface StdioConfig {
@@ -62,6 +62,10 @@ interface MCPTransport {
62
62
  * Event handler for received messages
63
63
  */
64
64
  onmessage?: (message: JSONRPCMessage) => void;
65
+ /**
66
+ * The protocol version negotiated during initialization.
67
+ */
68
+ protocolVersion?: string;
65
69
  }
66
70
 
67
71
  interface StdioConfig {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/mcp",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -42,8 +42,8 @@
42
42
  "typescript": "5.8.3",
43
43
  "vitest": "^4.1.0",
44
44
  "zod": "3.25.76",
45
- "@vercel/ai-tsconfig": "0.0.0",
46
- "@ai-sdk/test-server": "1.0.5"
45
+ "@ai-sdk/test-server": "1.0.5",
46
+ "@vercel/ai-tsconfig": "0.0.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "zod": "^3.25.76 || ^4.1.8"
@@ -132,6 +132,16 @@ export interface MCPClient {
132
132
  */
133
133
  readonly serverInfo: Configuration;
134
134
 
135
+ /**
136
+ * Optional instructions provided by the server during the initialize handshake.
137
+ *
138
+ * These describe how to use the server and its features, and can be used by clients
139
+ * to improve LLM interactions (e.g. by including them in the system prompt).
140
+ *
141
+ * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#initializeresult
142
+ */
143
+ readonly instructions?: string;
144
+
135
145
  tools<TOOL_SCHEMAS extends ToolSchemas = 'automatic'>(options?: {
136
146
  schemas?: TOOL_SCHEMAS;
137
147
  }): Promise<McpToolSet<TOOL_SCHEMAS>>;
@@ -215,6 +225,7 @@ class DefaultMCPClient implements MCPClient {
215
225
  > = new Map();
216
226
  private serverCapabilities: ServerCapabilities = {};
217
227
  private _serverInfo: Configuration = { name: '', version: '' };
228
+ private _serverInstructions?: string;
218
229
  private isClosed = true;
219
230
  private elicitationRequestHandler?: (
220
231
  request: ElicitationRequest,
@@ -266,6 +277,10 @@ class DefaultMCPClient implements MCPClient {
266
277
  return this._serverInfo;
267
278
  }
268
279
 
280
+ get instructions(): string | undefined {
281
+ return this._serverInstructions;
282
+ }
283
+
269
284
  async init(): Promise<this> {
270
285
  try {
271
286
  await this.transport.start();
@@ -297,6 +312,8 @@ class DefaultMCPClient implements MCPClient {
297
312
 
298
313
  this.serverCapabilities = result.capabilities;
299
314
  this._serverInfo = result.serverInfo;
315
+ this._serverInstructions = result.instructions;
316
+ this.transport.protocolVersion = result.protocolVersion;
300
317
 
301
318
  // Complete initialization handshake:
302
319
  await this.notification({
@@ -16,6 +16,7 @@ import {
16
16
  extractResourceMetadataUrl,
17
17
  UnauthorizedError,
18
18
  auth,
19
+ type AuthResult,
19
20
  type OAuthClientProvider,
20
21
  } from './oauth';
21
22
  import { LATEST_PROTOCOL_VERSION } from './types';
@@ -37,6 +38,7 @@ export class HttpMCPTransport implements MCPTransport {
37
38
  private inboundSseConnection?: { close: () => void };
38
39
  private redirectMode: RequestRedirect;
39
40
  private fetchFn: FetchFunction;
41
+ private authPromise?: Promise<AuthResult>;
40
42
 
41
43
  // Inbound SSE resumption and reconnection state
42
44
  private lastInboundEventId?: string;
@@ -51,6 +53,7 @@ export class HttpMCPTransport implements MCPTransport {
51
53
  onclose?: () => void;
52
54
  onerror?: (error: unknown) => void;
53
55
  onmessage?: (message: JSONRPCMessage) => void;
56
+ protocolVersion?: string;
54
57
 
55
58
  constructor({
56
59
  url,
@@ -78,7 +81,7 @@ export class HttpMCPTransport implements MCPTransport {
78
81
  const headers: Record<string, string> = {
79
82
  ...this.headers,
80
83
  ...base,
81
- 'mcp-protocol-version': LATEST_PROTOCOL_VERSION,
84
+ 'mcp-protocol-version': this.protocolVersion ?? LATEST_PROTOCOL_VERSION,
82
85
  };
83
86
 
84
87
  if (this.sessionId) {
@@ -99,6 +102,27 @@ export class HttpMCPTransport implements MCPTransport {
99
102
  );
100
103
  }
101
104
 
105
+ /**
106
+ * Runs a single OAuth recovery flow for concurrent 401 responses.
107
+ */
108
+ private authorizeOnce(resourceMetadataUrl?: URL): Promise<AuthResult> {
109
+ if (!this.authProvider) {
110
+ return Promise.resolve('REDIRECT');
111
+ }
112
+
113
+ if (!this.authPromise) {
114
+ this.authPromise = auth(this.authProvider, {
115
+ serverUrl: this.url,
116
+ resourceMetadataUrl,
117
+ fetchFn: this.fetchFn,
118
+ }).finally(() => {
119
+ this.authPromise = undefined;
120
+ });
121
+ }
122
+
123
+ return this.authPromise;
124
+ }
125
+
102
126
  async start(): Promise<void> {
103
127
  if (this.abortController) {
104
128
  throw new MCPClientError({
@@ -159,11 +183,7 @@ export class HttpMCPTransport implements MCPTransport {
159
183
  if (response.status === 401 && this.authProvider && !triedAuth) {
160
184
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
161
185
  try {
162
- const result = await auth(this.authProvider, {
163
- serverUrl: this.url,
164
- resourceMetadataUrl: this.resourceMetadataUrl,
165
- fetchFn: this.fetchFn,
166
- });
186
+ const result = await this.authorizeOnce(this.resourceMetadataUrl);
167
187
  if (result !== 'AUTHORIZED') {
168
188
  const error = new UnauthorizedError();
169
189
  throw error;
@@ -339,11 +359,7 @@ export class HttpMCPTransport implements MCPTransport {
339
359
  if (response.status === 401 && this.authProvider && !triedAuth) {
340
360
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
341
361
  try {
342
- const result = await auth(this.authProvider, {
343
- serverUrl: this.url,
344
- resourceMetadataUrl: this.resourceMetadataUrl,
345
- fetchFn: this.fetchFn,
346
- });
362
+ const result = await this.authorizeOnce(this.resourceMetadataUrl);
347
363
  if (result !== 'AUTHORIZED') {
348
364
  const error = new UnauthorizedError();
349
365
  this.onerror?.(error);
@@ -33,6 +33,7 @@ export class SseMCPTransport implements MCPTransport {
33
33
  onclose?: () => void;
34
34
  onerror?: (error: unknown) => void;
35
35
  onmessage?: (message: JSONRPCMessage) => void;
36
+ protocolVersion?: string;
36
37
 
37
38
  constructor({
38
39
  url,
@@ -60,7 +61,7 @@ export class SseMCPTransport implements MCPTransport {
60
61
  const headers: Record<string, string> = {
61
62
  ...this.headers,
62
63
  ...base,
63
- 'mcp-protocol-version': LATEST_PROTOCOL_VERSION,
64
+ 'mcp-protocol-version': this.protocolVersion ?? LATEST_PROTOCOL_VERSION,
64
65
  };
65
66
 
66
67
  if (this.authProvider) {
@@ -40,6 +40,11 @@ export interface MCPTransport {
40
40
  * Event handler for received messages
41
41
  */
42
42
  onmessage?: (message: JSONRPCMessage) => void;
43
+
44
+ /**
45
+ * The protocol version negotiated during initialization.
46
+ */
47
+ protocolVersion?: string;
43
48
  }
44
49
 
45
50
  export type MCPTransportConfig = {
@@ -45,7 +45,7 @@ export class MockMCPTransport implements MCPTransport {
45
45
  onmessage?: (message: JSONRPCMessage) => void;
46
46
  onclose?: () => void;
47
47
  onerror?: (error: Error) => void;
48
-
48
+ protocolVersion?: string;
49
49
  constructor({
50
50
  overrideTools = DEFAULT_TOOLS,
51
51
  resources = [