@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 +13 -0
- package/README.md +134 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +29 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -12
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-stdio/index.d.mts +4 -0
- package/dist/mcp-stdio/index.d.ts +4 -0
- package/package.json +3 -3
- package/src/tool/mcp-client.ts +17 -0
- package/src/tool/mcp-http-transport.ts +27 -11
- package/src/tool/mcp-sse-transport.ts +2 -1
- package/src/tool/mcp-transport.ts +5 -0
- package/src/tool/mock-mcp-transport.ts +1 -1
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
|
|
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
|
|
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
|
});
|