@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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 1.0.43
4
+
5
+ ### Patch Changes
6
+
7
+ - e2b923f: fix(mcp): deduplicate auth refresh on http transport
8
+
9
+ ## 1.0.42
10
+
11
+ ### Patch Changes
12
+
13
+ - 725f2ed: feat(mcp): expose server instructions to be accessible through client
14
+ - 7281592: fix(mcp): use negotiated protocol version in transport request headers
15
+
3
16
  ## 1.0.41
4
17
 
5
18
  ### Patch Changes
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # AI SDK - Model Context Protocol Client
2
+
3
+ The **Model Context Protocol (MCP) client** for the
4
+ [AI SDK](https://ai-sdk.dev/docs) lets you connect to MCP servers and use their
5
+ tools with AI SDK functions like `generateText` and `streamText`.
6
+
7
+ ## Setup
8
+
9
+ The MCP client is available in the `@ai-sdk/mcp` module. You can install it with
10
+
11
+ ```bash
12
+ npm i @ai-sdk/mcp ai zod
13
+ ```
14
+
15
+ ## Skill for Coding Agents
16
+
17
+ If you use coding agents such as Claude Code or Cursor, we highly recommend
18
+ adding the AI SDK skill to your repository:
19
+
20
+ ```shell
21
+ npx skills add vercel/ai
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ Create an MCP client with `createMCPClient()`, fetch the server tools with
27
+ `mcpClient.tools()`, and pass them to an AI SDK call:
28
+
29
+ ```ts
30
+ import { createMCPClient } from '@ai-sdk/mcp';
31
+ import { generateText, isStepCount } from 'ai';
32
+
33
+ const mcpClient = await createMCPClient({
34
+ transport: {
35
+ type: 'http',
36
+ url: 'https://your-server.com/mcp',
37
+ headers: {
38
+ Authorization: `Bearer ${process.env.MCP_API_KEY}`,
39
+ },
40
+ },
41
+ });
42
+
43
+ try {
44
+ const tools = await mcpClient.tools();
45
+
46
+ const { text } = await generateText({
47
+ model: 'openai/gpt-5.4',
48
+ tools,
49
+ stopWhen: isStepCount(10),
50
+ prompt: 'Use the available tools to answer the user question.',
51
+ });
52
+
53
+ console.log(text);
54
+ } finally {
55
+ await mcpClient.close();
56
+ }
57
+ ```
58
+
59
+ The client converts MCP tool definitions into AI SDK tools, so model calls can
60
+ use them through the standard `tools` option.
61
+
62
+ For streaming responses, close the MCP client when the stream finishes:
63
+
64
+ ```ts
65
+ import { createMCPClient } from '@ai-sdk/mcp';
66
+ import { streamText } from 'ai';
67
+
68
+ const mcpClient = await createMCPClient({
69
+ transport: {
70
+ type: 'http',
71
+ url: 'https://your-server.com/mcp',
72
+ },
73
+ });
74
+
75
+ const result = streamText({
76
+ model: 'openai/gpt-5.4',
77
+ tools: await mcpClient.tools(),
78
+ prompt: 'Use the available tools to answer the user question.',
79
+ onFinish: async () => {
80
+ await mcpClient.close();
81
+ },
82
+ });
83
+
84
+ for await (const textPart of result.textStream) {
85
+ process.stdout.write(textPart);
86
+ }
87
+ ```
88
+
89
+ ## Transports
90
+
91
+ HTTP is recommended for production deployments:
92
+
93
+ ```ts
94
+ import { createMCPClient } from '@ai-sdk/mcp';
95
+
96
+ const mcpClient = await createMCPClient({
97
+ transport: {
98
+ type: 'http',
99
+ url: 'https://your-server.com/mcp',
100
+ },
101
+ });
102
+ ```
103
+
104
+ SSE is also supported for MCP servers that use Server-Sent Events:
105
+
106
+ ```ts
107
+ const mcpClient = await createMCPClient({
108
+ transport: {
109
+ type: 'sse',
110
+ url: 'https://your-server.com/sse',
111
+ },
112
+ });
113
+ ```
114
+
115
+ For local MCP servers, you can use stdio transport from the `@ai-sdk/mcp/mcp-stdio`
116
+ subpath:
117
+
118
+ ```ts
119
+ import { createMCPClient } from '@ai-sdk/mcp';
120
+ import { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';
121
+
122
+ const mcpClient = await createMCPClient({
123
+ transport: new Experimental_StdioMCPTransport({
124
+ command: 'node',
125
+ args: ['server.js'],
126
+ }),
127
+ });
128
+ ```
129
+
130
+ ## Documentation
131
+
132
+ Please check out the
133
+ [AI SDK MCP documentation](https://ai-sdk.dev/docs/ai-sdk-core/mcp-tools) for
134
+ more information.
package/dist/index.d.mts CHANGED
@@ -228,6 +228,10 @@ interface MCPTransport {
228
228
  * Event handler for received messages
229
229
  */
230
230
  onmessage?: (message: JSONRPCMessage) => void;
231
+ /**
232
+ * The protocol version negotiated during initialization.
233
+ */
234
+ protocolVersion?: string;
231
235
  }
232
236
  type MCPTransportConfig = {
233
237
  type: 'sse' | 'http';
@@ -508,6 +512,15 @@ interface MCPClient {
508
512
  * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation
509
513
  */
510
514
  readonly serverInfo: Configuration;
515
+ /**
516
+ * Optional instructions provided by the server during the initialize handshake.
517
+ *
518
+ * These describe how to use the server and its features, and can be used by clients
519
+ * to improve LLM interactions (e.g. by including them in the system prompt).
520
+ *
521
+ * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#initializeresult
522
+ */
523
+ readonly instructions?: string;
511
524
  tools<TOOL_SCHEMAS extends ToolSchemas = 'automatic'>(options?: {
512
525
  schemas?: TOOL_SCHEMAS;
513
526
  }): Promise<McpToolSet<TOOL_SCHEMAS>>;
package/dist/index.d.ts CHANGED
@@ -228,6 +228,10 @@ interface MCPTransport {
228
228
  * Event handler for received messages
229
229
  */
230
230
  onmessage?: (message: JSONRPCMessage) => void;
231
+ /**
232
+ * The protocol version negotiated during initialization.
233
+ */
234
+ protocolVersion?: string;
231
235
  }
232
236
  type MCPTransportConfig = {
233
237
  type: 'sse' | 'http';
@@ -508,6 +512,15 @@ interface MCPClient {
508
512
  * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation
509
513
  */
510
514
  readonly serverInfo: Configuration;
515
+ /**
516
+ * Optional instructions provided by the server during the initialize handshake.
517
+ *
518
+ * These describe how to use the server and its features, and can be used by clients
519
+ * to improve LLM interactions (e.g. by including them in the system prompt).
520
+ *
521
+ * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#initializeresult
522
+ */
523
+ readonly instructions?: string;
511
524
  tools<TOOL_SCHEMAS extends ToolSchemas = 'automatic'>(options?: {
512
525
  schemas?: TOOL_SCHEMAS;
513
526
  }): Promise<McpToolSet<TOOL_SCHEMAS>>;
package/dist/index.js CHANGED
@@ -1115,10 +1115,11 @@ var SseMCPTransport = class {
1115
1115
  this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1116
1116
  }
1117
1117
  async commonHeaders(base) {
1118
+ var _a3;
1118
1119
  const headers = {
1119
1120
  ...this.headers,
1120
1121
  ...base,
1121
- "mcp-protocol-version": LATEST_PROTOCOL_VERSION
1122
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1122
1123
  };
1123
1124
  if (this.authProvider) {
1124
1125
  const tokens = await this.authProvider.tokens();
@@ -1329,10 +1330,11 @@ var HttpMCPTransport = class {
1329
1330
  this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1330
1331
  }
1331
1332
  async commonHeaders(base) {
1333
+ var _a3;
1332
1334
  const headers = {
1333
1335
  ...this.headers,
1334
1336
  ...base,
1335
- "mcp-protocol-version": LATEST_PROTOCOL_VERSION
1337
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1336
1338
  };
1337
1339
  if (this.sessionId) {
1338
1340
  headers["mcp-session-id"] = this.sessionId;
@@ -1349,6 +1351,24 @@ var HttpMCPTransport = class {
1349
1351
  (0, import_provider_utils4.getRuntimeEnvironmentUserAgent)()
1350
1352
  );
1351
1353
  }
1354
+ /**
1355
+ * Runs a single OAuth recovery flow for concurrent 401 responses.
1356
+ */
1357
+ authorizeOnce(resourceMetadataUrl) {
1358
+ if (!this.authProvider) {
1359
+ return Promise.resolve("REDIRECT");
1360
+ }
1361
+ if (!this.authPromise) {
1362
+ this.authPromise = auth(this.authProvider, {
1363
+ serverUrl: this.url,
1364
+ resourceMetadataUrl,
1365
+ fetchFn: this.fetchFn
1366
+ }).finally(() => {
1367
+ this.authPromise = void 0;
1368
+ });
1369
+ }
1370
+ return this.authPromise;
1371
+ }
1352
1372
  async start() {
1353
1373
  if (this.abortController) {
1354
1374
  throw new MCPClientError({
@@ -1399,11 +1419,7 @@ var HttpMCPTransport = class {
1399
1419
  if (response.status === 401 && this.authProvider && !triedAuth) {
1400
1420
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1401
1421
  try {
1402
- const result = await auth(this.authProvider, {
1403
- serverUrl: this.url,
1404
- resourceMetadataUrl: this.resourceMetadataUrl,
1405
- fetchFn: this.fetchFn
1406
- });
1422
+ const result = await this.authorizeOnce(this.resourceMetadataUrl);
1407
1423
  if (result !== "AUTHORIZED") {
1408
1424
  const error2 = new UnauthorizedError();
1409
1425
  throw error2;
@@ -1549,11 +1565,7 @@ var HttpMCPTransport = class {
1549
1565
  if (response.status === 401 && this.authProvider && !triedAuth) {
1550
1566
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1551
1567
  try {
1552
- const result = await auth(this.authProvider, {
1553
- serverUrl: this.url,
1554
- resourceMetadataUrl: this.resourceMetadataUrl,
1555
- fetchFn: this.fetchFn
1556
- });
1568
+ const result = await this.authorizeOnce(this.resourceMetadataUrl);
1557
1569
  if (result !== "AUTHORIZED") {
1558
1570
  const error = new UnauthorizedError();
1559
1571
  (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
@@ -1721,6 +1733,9 @@ var DefaultMCPClient = class {
1721
1733
  get serverInfo() {
1722
1734
  return this._serverInfo;
1723
1735
  }
1736
+ get instructions() {
1737
+ return this._serverInstructions;
1738
+ }
1724
1739
  async init() {
1725
1740
  try {
1726
1741
  await this.transport.start();
@@ -1748,6 +1763,8 @@ var DefaultMCPClient = class {
1748
1763
  }
1749
1764
  this.serverCapabilities = result.capabilities;
1750
1765
  this._serverInfo = result.serverInfo;
1766
+ this._serverInstructions = result.instructions;
1767
+ this.transport.protocolVersion = result.protocolVersion;
1751
1768
  await this.notification({
1752
1769
  method: "notifications/initialized"
1753
1770
  });