@modelcontextprotocol/sdk 1.9.0 → 1.10.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 +284 -28
- package/dist/cjs/client/index.d.ts.map +1 -1
- package/dist/cjs/client/index.js +5 -0
- package/dist/cjs/client/index.js.map +1 -1
- package/dist/cjs/client/streamableHttp.d.ts +124 -0
- package/dist/cjs/client/streamableHttp.d.ts.map +1 -0
- package/dist/cjs/client/streamableHttp.js +353 -0
- package/dist/cjs/client/streamableHttp.js.map +1 -0
- package/dist/cjs/examples/client/simpleStreamableHttp.d.ts +2 -0
- package/dist/cjs/examples/client/simpleStreamableHttp.d.ts.map +1 -0
- package/dist/cjs/examples/client/simpleStreamableHttp.js +448 -0
- package/dist/cjs/examples/client/simpleStreamableHttp.js.map +1 -0
- package/dist/cjs/examples/client/streamableHttpWithSseFallbackClient.d.ts +2 -0
- package/dist/cjs/examples/client/streamableHttpWithSseFallbackClient.d.ts.map +1 -0
- package/dist/cjs/examples/client/streamableHttpWithSseFallbackClient.js +168 -0
- package/dist/cjs/examples/client/streamableHttpWithSseFallbackClient.js.map +1 -0
- package/dist/cjs/examples/server/jsonResponseStreamableHttp.d.ts +2 -0
- package/dist/cjs/examples/server/jsonResponseStreamableHttp.d.ts.map +1 -0
- package/dist/cjs/examples/server/jsonResponseStreamableHttp.js +139 -0
- package/dist/cjs/examples/server/jsonResponseStreamableHttp.js.map +1 -0
- package/dist/cjs/examples/server/simpleSseServer.d.ts +2 -0
- package/dist/cjs/examples/server/simpleSseServer.d.ts.map +1 -0
- package/dist/cjs/examples/server/simpleSseServer.js +148 -0
- package/dist/cjs/examples/server/simpleSseServer.js.map +1 -0
- package/dist/cjs/examples/server/simpleStreamableHttp.d.ts +2 -0
- package/dist/cjs/examples/server/simpleStreamableHttp.d.ts.map +1 -0
- package/dist/cjs/examples/server/simpleStreamableHttp.js +250 -0
- package/dist/cjs/examples/server/simpleStreamableHttp.js.map +1 -0
- package/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.d.ts +2 -0
- package/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.d.ts.map +1 -0
- package/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js +229 -0
- package/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -0
- package/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.d.ts +2 -0
- package/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.d.ts.map +1 -0
- package/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js +112 -0
- package/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -0
- package/dist/cjs/examples/shared/inMemoryEventStore.d.ts +31 -0
- package/dist/cjs/examples/shared/inMemoryEventStore.d.ts.map +1 -0
- package/dist/cjs/examples/shared/inMemoryEventStore.js +69 -0
- package/dist/cjs/examples/shared/inMemoryEventStore.js.map +1 -0
- package/dist/cjs/inMemory.d.ts +13 -3
- package/dist/cjs/inMemory.d.ts.map +1 -1
- package/dist/cjs/inMemory.js +9 -7
- package/dist/cjs/inMemory.js.map +1 -1
- package/dist/cjs/server/auth/types.d.ts +5 -0
- package/dist/cjs/server/auth/types.d.ts.map +1 -1
- package/dist/cjs/server/mcp.d.ts +100 -19
- package/dist/cjs/server/mcp.d.ts.map +1 -1
- package/dist/cjs/server/mcp.js +154 -12
- package/dist/cjs/server/mcp.js.map +1 -1
- package/dist/cjs/server/sse.d.ts +10 -3
- package/dist/cjs/server/sse.d.ts.map +1 -1
- package/dist/cjs/server/sse.js +13 -4
- package/dist/cjs/server/sse.js.map +1 -1
- package/dist/cjs/server/streamableHttp.d.ts +146 -0
- package/dist/cjs/server/streamableHttp.d.ts.map +1 -0
- package/dist/cjs/server/streamableHttp.js +538 -0
- package/dist/cjs/server/streamableHttp.js.map +1 -0
- package/dist/cjs/shared/protocol.d.ts +31 -5
- package/dist/cjs/shared/protocol.d.ts.map +1 -1
- package/dist/cjs/shared/protocol.js +23 -15
- package/dist/cjs/shared/protocol.js.map +1 -1
- package/dist/cjs/shared/transport.d.ts +32 -3
- package/dist/cjs/shared/transport.d.ts.map +1 -1
- package/dist/cjs/types.d.ts +6 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +14 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +5 -0
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/streamableHttp.d.ts +124 -0
- package/dist/esm/client/streamableHttp.d.ts.map +1 -0
- package/dist/esm/client/streamableHttp.js +348 -0
- package/dist/esm/client/streamableHttp.js.map +1 -0
- package/dist/esm/examples/client/simpleStreamableHttp.d.ts +2 -0
- package/dist/esm/examples/client/simpleStreamableHttp.d.ts.map +1 -0
- package/dist/esm/examples/client/simpleStreamableHttp.js +446 -0
- package/dist/esm/examples/client/simpleStreamableHttp.js.map +1 -0
- package/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts +2 -0
- package/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts.map +1 -0
- package/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js +166 -0
- package/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js.map +1 -0
- package/dist/esm/examples/server/jsonResponseStreamableHttp.d.ts +2 -0
- package/dist/esm/examples/server/jsonResponseStreamableHttp.d.ts.map +1 -0
- package/dist/esm/examples/server/jsonResponseStreamableHttp.js +134 -0
- package/dist/esm/examples/server/jsonResponseStreamableHttp.js.map +1 -0
- package/dist/esm/examples/server/simpleSseServer.d.ts +2 -0
- package/dist/esm/examples/server/simpleSseServer.d.ts.map +1 -0
- package/dist/esm/examples/server/simpleSseServer.js +143 -0
- package/dist/esm/examples/server/simpleSseServer.js.map +1 -0
- package/dist/esm/examples/server/simpleStreamableHttp.d.ts +2 -0
- package/dist/esm/examples/server/simpleStreamableHttp.d.ts.map +1 -0
- package/dist/esm/examples/server/simpleStreamableHttp.js +245 -0
- package/dist/esm/examples/server/simpleStreamableHttp.js.map +1 -0
- package/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.d.ts +2 -0
- package/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.d.ts.map +1 -0
- package/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js +224 -0
- package/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -0
- package/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.d.ts +2 -0
- package/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.d.ts.map +1 -0
- package/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js +107 -0
- package/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -0
- package/dist/esm/examples/shared/inMemoryEventStore.d.ts +31 -0
- package/dist/esm/examples/shared/inMemoryEventStore.d.ts.map +1 -0
- package/dist/esm/examples/shared/inMemoryEventStore.js +65 -0
- package/dist/esm/examples/shared/inMemoryEventStore.js.map +1 -0
- package/dist/esm/inMemory.d.ts +13 -3
- package/dist/esm/inMemory.d.ts.map +1 -1
- package/dist/esm/inMemory.js +9 -7
- package/dist/esm/inMemory.js.map +1 -1
- package/dist/esm/server/auth/types.d.ts +5 -0
- package/dist/esm/server/auth/types.d.ts.map +1 -1
- package/dist/esm/server/mcp.d.ts +100 -19
- package/dist/esm/server/mcp.d.ts.map +1 -1
- package/dist/esm/server/mcp.js +154 -12
- package/dist/esm/server/mcp.js.map +1 -1
- package/dist/esm/server/sse.d.ts +10 -3
- package/dist/esm/server/sse.d.ts.map +1 -1
- package/dist/esm/server/sse.js +13 -4
- package/dist/esm/server/sse.js.map +1 -1
- package/dist/esm/server/streamableHttp.d.ts +146 -0
- package/dist/esm/server/streamableHttp.d.ts.map +1 -0
- package/dist/esm/server/streamableHttp.js +531 -0
- package/dist/esm/server/streamableHttp.js.map +1 -0
- package/dist/esm/shared/protocol.d.ts +31 -5
- package/dist/esm/shared/protocol.d.ts.map +1 -1
- package/dist/esm/shared/protocol.js +24 -16
- package/dist/esm/shared/protocol.js.map +1 -1
- package/dist/esm/shared/transport.d.ts +32 -3
- package/dist/esm/shared/transport.d.ts.map +1 -1
- package/dist/esm/types.d.ts +6 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +6 -0
- package/dist/esm/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [Prompts](#prompts)
|
|
13
13
|
- [Running Your Server](#running-your-server)
|
|
14
14
|
- [stdio](#stdio)
|
|
15
|
-
- [HTTP
|
|
15
|
+
- [Streamable HTTP](#streamable-http)
|
|
16
16
|
- [Testing and Debugging](#testing-and-debugging)
|
|
17
17
|
- [Examples](#examples)
|
|
18
18
|
- [Echo Server](#echo-server)
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- [Writing MCP Clients](#writing-mcp-clients)
|
|
23
23
|
- [Server Capabilities](#server-capabilities)
|
|
24
24
|
- [Proxy OAuth Server](#proxy-authorization-requests-upstream)
|
|
25
|
+
- [Backwards Compatibility](#backwards-compatibility)
|
|
25
26
|
|
|
26
27
|
## Overview
|
|
27
28
|
|
|
@@ -29,7 +30,7 @@ The Model Context Protocol allows applications to provide context for LLMs in a
|
|
|
29
30
|
|
|
30
31
|
- Build MCP clients that can connect to any MCP server
|
|
31
32
|
- Create MCP servers that expose resources, prompts and tools
|
|
32
|
-
- Use standard transports like stdio and
|
|
33
|
+
- Use standard transports like stdio and Streamable HTTP
|
|
33
34
|
- Handle all MCP protocol messages and lifecycle events
|
|
34
35
|
|
|
35
36
|
## Installation
|
|
@@ -207,50 +208,143 @@ const transport = new StdioServerTransport();
|
|
|
207
208
|
await server.connect(transport);
|
|
208
209
|
```
|
|
209
210
|
|
|
210
|
-
### HTTP
|
|
211
|
+
### Streamable HTTP
|
|
211
212
|
|
|
212
|
-
For remote servers,
|
|
213
|
+
For remote servers, set up a Streamable HTTP transport that handles both client requests and server-to-client notifications.
|
|
214
|
+
|
|
215
|
+
#### With Session Management
|
|
216
|
+
|
|
217
|
+
In some cases, servers need to be stateful. This is achieved by [session management](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#session-management).
|
|
213
218
|
|
|
214
219
|
```typescript
|
|
215
|
-
import express
|
|
220
|
+
import express from "express";
|
|
221
|
+
import { randomUUID } from "node:crypto";
|
|
216
222
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
217
|
-
import {
|
|
223
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
224
|
+
import { InMemoryEventStore } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
const app = express();
|
|
228
|
+
app.use(express.json());
|
|
229
|
+
|
|
230
|
+
// Map to store transports by session ID
|
|
231
|
+
const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
|
|
232
|
+
|
|
233
|
+
// Handle POST requests for client-to-server communication
|
|
234
|
+
app.post('/mcp', async (req, res) => {
|
|
235
|
+
// Check for existing session ID
|
|
236
|
+
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
|
237
|
+
let transport: StreamableHTTPServerTransport;
|
|
238
|
+
|
|
239
|
+
if (sessionId && transports[sessionId]) {
|
|
240
|
+
// Reuse existing transport
|
|
241
|
+
transport = transports[sessionId];
|
|
242
|
+
} else if (!sessionId && isInitializeRequest(req.body)) {
|
|
243
|
+
// New initialization request
|
|
244
|
+
const eventStore = new InMemoryEventStore();
|
|
245
|
+
transport = new StreamableHTTPServerTransport({
|
|
246
|
+
sessionIdGenerator: () => randomUUID(),
|
|
247
|
+
eventStore, // Enable resumability
|
|
248
|
+
onsessioninitialized: (sessionId) => {
|
|
249
|
+
// Store the transport by session ID
|
|
250
|
+
transports[sessionId] = transport;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Clean up transport when closed
|
|
255
|
+
transport.onclose = () => {
|
|
256
|
+
if (transport.sessionId) {
|
|
257
|
+
delete transports[transport.sessionId];
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
const server = new McpServer({
|
|
261
|
+
name: "example-server",
|
|
262
|
+
version: "1.0.0"
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// ... set up server resources, tools, and prompts ...
|
|
266
|
+
|
|
267
|
+
// Connect to the MCP server
|
|
268
|
+
await server.connect(transport);
|
|
269
|
+
} else {
|
|
270
|
+
// Invalid request
|
|
271
|
+
res.status(400).json({
|
|
272
|
+
jsonrpc: '2.0',
|
|
273
|
+
error: {
|
|
274
|
+
code: -32000,
|
|
275
|
+
message: 'Bad Request: No valid session ID provided',
|
|
276
|
+
},
|
|
277
|
+
id: null,
|
|
278
|
+
});
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Handle the request
|
|
283
|
+
await transport.handleRequest(req, res, req.body);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Reusable handler for GET and DELETE requests
|
|
287
|
+
const handleSessionRequest = async (req: express.Request, res: express.Response) => {
|
|
288
|
+
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
|
289
|
+
if (!sessionId || !transports[sessionId]) {
|
|
290
|
+
res.status(400).send('Invalid or missing session ID');
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const transport = transports[sessionId];
|
|
295
|
+
await transport.handleRequest(req, res);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// Handle GET requests for server-to-client notifications via SSE
|
|
299
|
+
app.get('/mcp', handleSessionRequest);
|
|
300
|
+
|
|
301
|
+
// Handle DELETE requests for session termination
|
|
302
|
+
app.delete('/mcp', handleSessionRequest);
|
|
303
|
+
|
|
304
|
+
app.listen(3000);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### Without Session Management (Stateless)
|
|
308
|
+
|
|
309
|
+
For simpler use cases where session management isn't needed:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import express from "express";
|
|
313
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
314
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
218
315
|
|
|
219
316
|
const server = new McpServer({
|
|
220
|
-
name: "
|
|
317
|
+
name: "stateless-server",
|
|
221
318
|
version: "1.0.0"
|
|
222
319
|
});
|
|
223
320
|
|
|
224
321
|
// ... set up server resources, tools, and prompts ...
|
|
225
322
|
|
|
226
323
|
const app = express();
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
delete transports[transport.sessionId];
|
|
324
|
+
app.use(express.json());
|
|
325
|
+
|
|
326
|
+
// Handle all MCP requests (GET, POST, DELETE) at a single endpoint
|
|
327
|
+
app.all('/mcp', async (req, res) => {
|
|
328
|
+
// Disable session tracking by setting sessionIdGenerator to undefined
|
|
329
|
+
const transport = new StreamableHTTPServerTransport({
|
|
330
|
+
sessionIdGenerator: undefined,
|
|
331
|
+
req,
|
|
332
|
+
res
|
|
237
333
|
});
|
|
334
|
+
|
|
335
|
+
// Connect to server and handle the request
|
|
238
336
|
await server.connect(transport);
|
|
337
|
+
await transport.handleRequest(req, res);
|
|
239
338
|
});
|
|
240
339
|
|
|
241
|
-
app.
|
|
242
|
-
const sessionId = req.query.sessionId as string;
|
|
243
|
-
const transport = transports[sessionId];
|
|
244
|
-
if (transport) {
|
|
245
|
-
await transport.handlePostMessage(req, res);
|
|
246
|
-
} else {
|
|
247
|
-
res.status(400).send('No transport found for sessionId');
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
app.listen(3001);
|
|
340
|
+
app.listen(3000);
|
|
252
341
|
```
|
|
253
342
|
|
|
343
|
+
This stateless approach is useful for:
|
|
344
|
+
- Simple API wrappers
|
|
345
|
+
- RESTful scenarios where each request is independent
|
|
346
|
+
- Horizontally scaled deployments without shared session state
|
|
347
|
+
|
|
254
348
|
### Testing and Debugging
|
|
255
349
|
|
|
256
350
|
To test your server, you can use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector). See its README for more information.
|
|
@@ -380,6 +474,68 @@ server.tool(
|
|
|
380
474
|
|
|
381
475
|
## Advanced Usage
|
|
382
476
|
|
|
477
|
+
### Dynamic Servers
|
|
478
|
+
|
|
479
|
+
If you want to offer an initial set of tools/prompts/resources, but later add additional ones based on user action or external state change, you can add/update/remove them _after_ the Server is connected. This will automatically emit the corresponding `listChanged` notificaions:
|
|
480
|
+
|
|
481
|
+
```ts
|
|
482
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
483
|
+
import { z } from "zod";
|
|
484
|
+
|
|
485
|
+
const server = new McpServer({
|
|
486
|
+
name: "Dynamic Example",
|
|
487
|
+
version: "1.0.0"
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const listMessageTool = server.tool(
|
|
491
|
+
"listMessages",
|
|
492
|
+
{ channel: z.string() },
|
|
493
|
+
async ({ channel }) => ({
|
|
494
|
+
content: [{ type: "text", text: await listMessages(channel) }]
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
const putMessageTool = server.tool(
|
|
499
|
+
"putMessage",
|
|
500
|
+
{ channel: z.string(), message: z.string() },
|
|
501
|
+
async ({ channel, message }) => ({
|
|
502
|
+
content: [{ type: "text", text: await putMessage(channel, string) }]
|
|
503
|
+
})
|
|
504
|
+
);
|
|
505
|
+
// Until we upgrade auth, `putMessage` is disabled (won't show up in listTools)
|
|
506
|
+
putMessageTool.disable()
|
|
507
|
+
|
|
508
|
+
const upgradeAuthTool = server.tool(
|
|
509
|
+
"upgradeAuth",
|
|
510
|
+
{ permission: z.enum(["write', vadmin"])},
|
|
511
|
+
// Any mutations here will automatically emit `listChanged` notifications
|
|
512
|
+
async ({ permission }) => {
|
|
513
|
+
const { ok, err, previous } = await upgradeAuthAndStoreToken(permission)
|
|
514
|
+
if (!ok) return {content: [{ type: "text", text: `Error: ${err}` }]}
|
|
515
|
+
|
|
516
|
+
// If we previously had read-only access, 'putMessage' is now available
|
|
517
|
+
if (previous === "read") {
|
|
518
|
+
putMessageTool.enable()
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
if (permission === 'write') {
|
|
522
|
+
// If we've just upgraded to 'write' permissions, we can still call 'upgradeAuth'
|
|
523
|
+
// but can only upgrade to 'admin'.
|
|
524
|
+
upgradeAuthTool.update({
|
|
525
|
+
paramSchema: { permission: z.enum(["admin"]) }, // change validation rules
|
|
526
|
+
})
|
|
527
|
+
} else {
|
|
528
|
+
// If we're now an admin, we no longer have anywhere to upgrade to, so fully remove that tool
|
|
529
|
+
upgradeAuthTool.remove()
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
// Connect as normal
|
|
535
|
+
const transport = new StdioServerTransport();
|
|
536
|
+
await server.connect(transport);
|
|
537
|
+
```
|
|
538
|
+
|
|
383
539
|
### Low-Level Server
|
|
384
540
|
|
|
385
541
|
For more control, you can use the low-level Server class directly:
|
|
@@ -534,6 +690,106 @@ This setup allows you to:
|
|
|
534
690
|
- Provide custom documentation URLs
|
|
535
691
|
- Maintain control over the OAuth flow while delegating to an external provider
|
|
536
692
|
|
|
693
|
+
### Backwards Compatibility
|
|
694
|
+
|
|
695
|
+
Clients and servers with StreamableHttp tranport can maintain [backwards compatibility](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#backwards-compatibility) with the deprecated HTTP+SSE transport (from protocol version 2024-11-05) as follows
|
|
696
|
+
|
|
697
|
+
#### Client-Side Compatibility
|
|
698
|
+
|
|
699
|
+
For clients that need to work with both Streamable HTTP and older SSE servers:
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
703
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
704
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
705
|
+
let client: Client|undefined = undefined
|
|
706
|
+
const baseUrl = new URL(url);
|
|
707
|
+
try {
|
|
708
|
+
client = new Client({
|
|
709
|
+
name: 'streamable-http-client',
|
|
710
|
+
version: '1.0.0'
|
|
711
|
+
});
|
|
712
|
+
const transport = new StreamableHTTPClientTransport(
|
|
713
|
+
new URL(baseUrl)
|
|
714
|
+
);
|
|
715
|
+
await client.connect(transport);
|
|
716
|
+
console.log("Connected using Streamable HTTP transport");
|
|
717
|
+
} catch (error) {
|
|
718
|
+
// If that fails with a 4xx error, try the older SSE transport
|
|
719
|
+
console.log("Streamable HTTP connection failed, falling back to SSE transport");
|
|
720
|
+
client = new Client({
|
|
721
|
+
name: 'sse-client',
|
|
722
|
+
version: '1.0.0'
|
|
723
|
+
});
|
|
724
|
+
const sseTransport = new SSEClientTransport(baseUrl);
|
|
725
|
+
await client.connect(sseTransport);
|
|
726
|
+
console.log("Connected using SSE transport");
|
|
727
|
+
}
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
#### Server-Side Compatibility
|
|
731
|
+
|
|
732
|
+
For servers that need to support both Streamable HTTP and older clients:
|
|
733
|
+
|
|
734
|
+
```typescript
|
|
735
|
+
import express from "express";
|
|
736
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
737
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
738
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
739
|
+
import { InMemoryEventStore } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
740
|
+
|
|
741
|
+
const server = new McpServer({
|
|
742
|
+
name: "backwards-compatible-server",
|
|
743
|
+
version: "1.0.0"
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// ... set up server resources, tools, and prompts ...
|
|
747
|
+
|
|
748
|
+
const app = express();
|
|
749
|
+
app.use(express.json());
|
|
750
|
+
|
|
751
|
+
// Store transports for each session type
|
|
752
|
+
const transports = {
|
|
753
|
+
streamable: {} as Record<string, StreamableHTTPServerTransport>,
|
|
754
|
+
sse: {} as Record<string, SSEServerTransport>
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
// Modern Streamable HTTP endpoint
|
|
758
|
+
app.all('/mcp', async (req, res) => {
|
|
759
|
+
// Handle Streamable HTTP transport for modern clients
|
|
760
|
+
// Implementation as shown in the "With Session Management" example
|
|
761
|
+
// ...
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
// Legacy SSE endpoint for older clients
|
|
765
|
+
app.get('/sse', async (req, res) => {
|
|
766
|
+
// Create SSE transport for legacy clients
|
|
767
|
+
const transport = new SSEServerTransport('/messages', res);
|
|
768
|
+
transports.sse[transport.sessionId] = transport;
|
|
769
|
+
|
|
770
|
+
res.on("close", () => {
|
|
771
|
+
delete transports.sse[transport.sessionId];
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
await server.connect(transport);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
// Legacy message endpoint for older clients
|
|
778
|
+
app.post('/messages', async (req, res) => {
|
|
779
|
+
const sessionId = req.query.sessionId as string;
|
|
780
|
+
const transport = transports.sse[sessionId];
|
|
781
|
+
if (transport) {
|
|
782
|
+
await transport.handlePostMessage(req, res);
|
|
783
|
+
} else {
|
|
784
|
+
res.status(400).send('No transport found for sessionId');
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
app.listen(3000);
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
**Note**: The SSE transport is now deprecated in favor of Streamable HTTP. New implementations should use Streamable HTTP, and existing SSE implementations should plan to migrate.
|
|
792
|
+
|
|
537
793
|
## Documentation
|
|
538
794
|
|
|
539
795
|
- [Model Context Protocol documentation](https://modelcontextprotocol.io)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,iCAAiC,EACjC,eAAe,EAGf,gBAAgB,EAEhB,cAAc,EAGd,kBAAkB,EAElB,oBAAoB,EAEpB,4BAA4B,EAE5B,gBAAgB,EAEhB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EAEnB,OAAO,EACP,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG;IAC5C;;OAEG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,MAAM,CACjB,QAAQ,SAAS,OAAO,GAAG,OAAO,EAClC,aAAa,SAAS,YAAY,GAAG,YAAY,EACjD,OAAO,SAAS,MAAM,GAAG,MAAM,CAC/B,SAAQ,QAAQ,CAChB,aAAa,GAAG,QAAQ,EACxB,kBAAkB,GAAG,aAAa,EAClC,YAAY,GAAG,OAAO,CACvB;IAUG,OAAO,CAAC,WAAW;IATrB,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;IAE/B;;OAEG;gBAEO,WAAW,EAAE,cAAc,EACnC,OAAO,CAAC,EAAE,aAAa;IAMzB;;;;OAIG;IACI,oBAAoB,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI;IAUnE,SAAS,CAAC,gBAAgB,CACxB,UAAU,EAAE,MAAM,kBAAkB,EACpC,MAAM,EAAE,MAAM,GACb,IAAI;IAQQ,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,iCAAiC,EACjC,eAAe,EAGf,gBAAgB,EAEhB,cAAc,EAGd,kBAAkB,EAElB,oBAAoB,EAEpB,4BAA4B,EAE5B,gBAAgB,EAEhB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EAEnB,OAAO,EACP,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG;IAC5C;;OAEG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,MAAM,CACjB,QAAQ,SAAS,OAAO,GAAG,OAAO,EAClC,aAAa,SAAS,YAAY,GAAG,YAAY,EACjD,OAAO,SAAS,MAAM,GAAG,MAAM,CAC/B,SAAQ,QAAQ,CAChB,aAAa,GAAG,QAAQ,EACxB,kBAAkB,GAAG,aAAa,EAClC,YAAY,GAAG,OAAO,CACvB;IAUG,OAAO,CAAC,WAAW;IATrB,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;IAE/B;;OAEG;gBAEO,WAAW,EAAE,cAAc,EACnC,OAAO,CAAC,EAAE,aAAa;IAMzB;;;;OAIG;IACI,oBAAoB,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI;IAUnE,SAAS,CAAC,gBAAgB,CACxB,UAAU,EAAE,MAAM,kBAAkB,EACpC,MAAM,EAAE,MAAM,GACb,IAAI;IAQQ,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CrF;;OAEG;IACH,qBAAqB,IAAI,kBAAkB,GAAG,SAAS;IAIvD;;OAEG;IACH,gBAAgB,IAAI,cAAc,GAAG,SAAS;IAI9C;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC,SAAS,CAAC,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI;IAoErE,SAAS,CAAC,4BAA4B,CACpC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC9B,IAAI;IAwBP,SAAS,CAAC,8BAA8B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAwBxD,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc;;;IAI7B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;IAQpE,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc;;;IAQ7D,SAAS,CACb,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,WAAW,CACf,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EACrC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,aAAa,CACjB,MAAM,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EACvC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;IASpB,qBAAqB,CACzB,MAAM,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,EAC/C,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;IASpB,YAAY,CAChB,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,EACrC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,iBAAiB,CACrB,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc;;;IASpB,mBAAmB,CACvB,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EACpC,OAAO,CAAC,EAAE,cAAc;;;IASpB,QAAQ,CACZ,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EACjC,YAAY,GACR,OAAO,oBAAoB,GAC3B,OAAO,iCAAwD,EACnE,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,SAAS,CACb,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EACnC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,oBAAoB;CAG3B"}
|
package/dist/cjs/client/index.js
CHANGED
|
@@ -57,6 +57,11 @@ class Client extends protocol_js_1.Protocol {
|
|
|
57
57
|
}
|
|
58
58
|
async connect(transport, options) {
|
|
59
59
|
await super.connect(transport);
|
|
60
|
+
// When transport sessionId is already set this means we are trying to reconnect.
|
|
61
|
+
// In this case we don't need to initialize again.
|
|
62
|
+
if (transport.sessionId !== undefined) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
60
65
|
try {
|
|
61
66
|
const result = await this.request({
|
|
62
67
|
method: "initialize",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":";;;AAAA,uDAK+B;AAE/B,0CAkCqB;AASrB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAa,MAIX,SAAQ,sBAIT;IAMC;;OAEG;IACH,YACU,WAA2B,EACnC,OAAuB;;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHP,gBAAW,GAAX,WAAW,CAAgB;QAInC,IAAI,CAAC,aAAa,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,mCAAI,EAAE,CAAC;IACnD,CAAC;IAED;;;;OAIG;IACI,oBAAoB,CAAC,YAAgC;QAC1D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAA,+BAAiB,EAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC3E,CAAC;IAES,gBAAgB,CACxB,UAAoC,EACpC,MAAc;;QAEd,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,mBAAmB,0CAAG,UAAU,CAAC,CAAA,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb,2BAA2B,UAAU,kBAAkB,MAAM,GAAG,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAEQ,KAAK,CAAC,OAAO,CAAC,SAAoB,EAAE,OAAwB;QACnE,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Transport } from "../shared/transport.js";
|
|
2
|
+
import { JSONRPCMessage } from "../types.js";
|
|
3
|
+
import { OAuthClientProvider } from "./auth.js";
|
|
4
|
+
export declare class StreamableHTTPError extends Error {
|
|
5
|
+
readonly code: number | undefined;
|
|
6
|
+
constructor(code: number | undefined, message: string | undefined);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for reconnection behavior of the StreamableHTTPClientTransport.
|
|
10
|
+
*/
|
|
11
|
+
export interface StreamableHTTPReconnectionOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Maximum backoff time between reconnection attempts in milliseconds.
|
|
14
|
+
* Default is 30000 (30 seconds).
|
|
15
|
+
*/
|
|
16
|
+
maxReconnectionDelay: number;
|
|
17
|
+
/**
|
|
18
|
+
* Initial backoff time between reconnection attempts in milliseconds.
|
|
19
|
+
* Default is 1000 (1 second).
|
|
20
|
+
*/
|
|
21
|
+
initialReconnectionDelay: number;
|
|
22
|
+
/**
|
|
23
|
+
* The factor by which the reconnection delay increases after each attempt.
|
|
24
|
+
* Default is 1.5.
|
|
25
|
+
*/
|
|
26
|
+
reconnectionDelayGrowFactor: number;
|
|
27
|
+
/**
|
|
28
|
+
* Maximum number of reconnection attempts before giving up.
|
|
29
|
+
* Default is 2.
|
|
30
|
+
*/
|
|
31
|
+
maxRetries: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration options for the `StreamableHTTPClientTransport`.
|
|
35
|
+
*/
|
|
36
|
+
export type StreamableHTTPClientTransportOptions = {
|
|
37
|
+
/**
|
|
38
|
+
* An OAuth client provider to use for authentication.
|
|
39
|
+
*
|
|
40
|
+
* When an `authProvider` is specified and the connection is started:
|
|
41
|
+
* 1. The connection is attempted with any existing access token from the `authProvider`.
|
|
42
|
+
* 2. If the access token has expired, the `authProvider` is used to refresh the token.
|
|
43
|
+
* 3. If token refresh fails or no access token exists, and auth is required, `OAuthClientProvider.redirectToAuthorization` is called, and an `UnauthorizedError` will be thrown from `connect`/`start`.
|
|
44
|
+
*
|
|
45
|
+
* After the user has finished authorizing via their user agent, and is redirected back to the MCP client application, call `StreamableHTTPClientTransport.finishAuth` with the authorization code before retrying the connection.
|
|
46
|
+
*
|
|
47
|
+
* If an `authProvider` is not provided, and auth is required, an `UnauthorizedError` will be thrown.
|
|
48
|
+
*
|
|
49
|
+
* `UnauthorizedError` might also be thrown when sending any message over the transport, indicating that the session has expired, and needs to be re-authed and reconnected.
|
|
50
|
+
*/
|
|
51
|
+
authProvider?: OAuthClientProvider;
|
|
52
|
+
/**
|
|
53
|
+
* Customizes HTTP requests to the server.
|
|
54
|
+
*/
|
|
55
|
+
requestInit?: RequestInit;
|
|
56
|
+
/**
|
|
57
|
+
* Options to configure the reconnection behavior.
|
|
58
|
+
*/
|
|
59
|
+
reconnectionOptions?: StreamableHTTPReconnectionOptions;
|
|
60
|
+
/**
|
|
61
|
+
* Session ID for the connection. This is used to identify the session on the server.
|
|
62
|
+
* When not provided and connecting to a server that supports session IDs, the server will generate a new session ID.
|
|
63
|
+
*/
|
|
64
|
+
sessionId?: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Client transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification.
|
|
68
|
+
* It will connect to a server using HTTP POST for sending messages and HTTP GET with Server-Sent Events
|
|
69
|
+
* for receiving messages.
|
|
70
|
+
*/
|
|
71
|
+
export declare class StreamableHTTPClientTransport implements Transport {
|
|
72
|
+
private _abortController?;
|
|
73
|
+
private _url;
|
|
74
|
+
private _requestInit?;
|
|
75
|
+
private _authProvider?;
|
|
76
|
+
private _sessionId?;
|
|
77
|
+
private _reconnectionOptions;
|
|
78
|
+
onclose?: () => void;
|
|
79
|
+
onerror?: (error: Error) => void;
|
|
80
|
+
onmessage?: (message: JSONRPCMessage) => void;
|
|
81
|
+
constructor(url: URL, opts?: StreamableHTTPClientTransportOptions);
|
|
82
|
+
private _authThenStart;
|
|
83
|
+
private _commonHeaders;
|
|
84
|
+
private _startOrAuthSse;
|
|
85
|
+
/**
|
|
86
|
+
* Calculates the next reconnection delay using backoff algorithm
|
|
87
|
+
*
|
|
88
|
+
* @param attempt Current reconnection attempt count for the specific stream
|
|
89
|
+
* @returns Time to wait in milliseconds before next reconnection attempt
|
|
90
|
+
*/
|
|
91
|
+
private _getNextReconnectionDelay;
|
|
92
|
+
/**
|
|
93
|
+
* Schedule a reconnection attempt with exponential backoff
|
|
94
|
+
*
|
|
95
|
+
* @param lastEventId The ID of the last received event for resumability
|
|
96
|
+
* @param attemptCount Current reconnection attempt count for this specific stream
|
|
97
|
+
*/
|
|
98
|
+
private _scheduleReconnection;
|
|
99
|
+
private _handleSseStream;
|
|
100
|
+
start(): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
|
|
103
|
+
*/
|
|
104
|
+
finishAuth(authorizationCode: string): Promise<void>;
|
|
105
|
+
close(): Promise<void>;
|
|
106
|
+
send(message: JSONRPCMessage | JSONRPCMessage[], options?: {
|
|
107
|
+
resumptionToken?: string;
|
|
108
|
+
onresumptiontoken?: (token: string) => void;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
get sessionId(): string | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Terminates the current session by sending a DELETE request to the server.
|
|
113
|
+
*
|
|
114
|
+
* Clients that no longer need a particular session
|
|
115
|
+
* (e.g., because the user is leaving the client application) SHOULD send an
|
|
116
|
+
* HTTP DELETE to the MCP endpoint with the Mcp-Session-Id header to explicitly
|
|
117
|
+
* terminate the session.
|
|
118
|
+
*
|
|
119
|
+
* The server MAY respond with HTTP 405 Method Not Allowed, indicating that
|
|
120
|
+
* the server does not allow clients to terminate sessions.
|
|
121
|
+
*/
|
|
122
|
+
terminateSession(): Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=streamableHttp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamableHttp.d.ts","sourceRoot":"","sources":["../../../src/client/streamableHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAkE,cAAc,EAAwB,MAAM,aAAa,CAAC;AACnI,OAAO,EAAoB,mBAAmB,EAAqB,MAAM,WAAW,CAAC;AAWrF,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,MAAM,GAAG,SAAS;gBAAxB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxC,OAAO,EAAE,MAAM,GAAG,SAAS;CAI9B;AA2BD;;GAEG;AACH,MAAM,WAAW,iCAAiC;IAChD;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,wBAAwB,EAAE,MAAM,CAAC;IAEjC;;;OAGG;IACH,2BAA2B,EAAE,MAAM,CAAC;IAEpC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,mBAAmB,CAAC,EAAE,iCAAiC,CAAC;IAExD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,qBAAa,6BAA8B,YAAW,SAAS;IAC7D,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAC3C,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,aAAa,CAAC,CAAsB;IAC5C,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,oBAAoB,CAAoC;IAEhE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;gBAG5C,GAAG,EAAE,GAAG,EACR,IAAI,CAAC,EAAE,oCAAoC;YAS/B,cAAc;YAoBd,cAAc;YAmBd,eAAe;IA6C7B;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;IAWjC;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,gBAAgB;IAoElB,KAAK;IAUX;;OAEG;IACG,UAAU,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA+F1J,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED;;;;;;;;;;OAUG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CAgCxC"}
|