agents 0.0.0-ac0e999 → 0.0.0-ac74811
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/dist/ai-chat-agent.d.ts +13 -12
- package/dist/ai-chat-agent.js +94 -57
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +9 -8
- package/dist/ai-react.js +27 -29
- package/dist/ai-react.js.map +1 -1
- package/dist/{chunk-D6UOOELW.js → chunk-767EASBA.js} +15 -15
- package/dist/chunk-767EASBA.js.map +1 -0
- package/dist/{chunk-25YDMV4H.js → chunk-E3LCYPCB.js} +34 -29
- package/dist/chunk-E3LCYPCB.js.map +1 -0
- package/dist/{chunk-DMJ7L3FI.js → chunk-JFRK72K3.js} +305 -168
- package/dist/chunk-JFRK72K3.js.map +1 -0
- package/dist/{chunk-ZKIVUOTQ.js → chunk-NKZZ66QY.js} +14 -21
- package/dist/chunk-NKZZ66QY.js.map +1 -0
- package/dist/client.d.ts +7 -1
- package/dist/client.js +1 -2
- package/dist/index-CITGJflw.d.ts +486 -0
- package/dist/index.d.ts +25 -369
- package/dist/index.js +4 -5
- package/dist/mcp/client.d.ts +287 -15
- package/dist/mcp/client.js +1 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +3 -3
- package/dist/mcp/do-oauth-client-provider.js +1 -2
- package/dist/mcp/index.d.ts +12 -12
- package/dist/mcp/index.js +124 -121
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +12 -0
- package/dist/observability/index.js +10 -0
- package/dist/react.d.ts +76 -10
- package/dist/react.js +16 -8
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +6 -6
- package/dist/schedule.js +4 -6
- package/dist/schedule.js.map +1 -1
- package/dist/serializable.d.ts +32 -0
- package/dist/serializable.js +1 -0
- package/dist/serializable.js.map +1 -0
- package/package.json +75 -71
- package/src/index.ts +253 -131
- package/dist/chunk-25YDMV4H.js.map +0 -1
- package/dist/chunk-D6UOOELW.js.map +0 -1
- package/dist/chunk-DMJ7L3FI.js.map +0 -1
- package/dist/chunk-NOUFNU2O.js +0 -12
- package/dist/chunk-ZKIVUOTQ.js.map +0 -1
- /package/dist/{chunk-NOUFNU2O.js.map → observability/index.js.map} +0 -0
package/dist/mcp/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-NOUFNU2O.js";
|
|
3
|
+
} from "../chunk-JFRK72K3.js";
|
|
4
|
+
import "../chunk-E3LCYPCB.js";
|
|
5
|
+
import "../chunk-767EASBA.js";
|
|
6
|
+
import "../chunk-NKZZ66QY.js";
|
|
8
7
|
|
|
9
8
|
// src/mcp/index.ts
|
|
10
9
|
import { DurableObject } from "cloudflare:workers";
|
|
@@ -17,16 +16,19 @@ import {
|
|
|
17
16
|
JSONRPCMessageSchema
|
|
18
17
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
19
18
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
20
|
-
function corsHeaders(
|
|
19
|
+
function corsHeaders(_request, corsOptions = {}) {
|
|
21
20
|
const origin = "*";
|
|
22
21
|
return {
|
|
23
|
-
"Access-Control-Allow-
|
|
22
|
+
"Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
|
|
24
23
|
"Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
|
|
25
|
-
"Access-Control-Allow-
|
|
26
|
-
"Access-Control-
|
|
27
|
-
"Access-Control-
|
|
24
|
+
"Access-Control-Allow-Origin": corsOptions.origin || origin,
|
|
25
|
+
"Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id",
|
|
26
|
+
"Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString()
|
|
28
27
|
};
|
|
29
28
|
}
|
|
29
|
+
function isDurableObjectNamespace(namespace) {
|
|
30
|
+
return typeof namespace === "object" && namespace !== null && "newUniqueId" in namespace && typeof namespace.newUniqueId === "function" && "idFromName" in namespace && typeof namespace.idFromName === "function";
|
|
31
|
+
}
|
|
30
32
|
function handleCORS(request, corsOptions) {
|
|
31
33
|
if (request.method === "OPTIONS") {
|
|
32
34
|
return new Response(null, { headers: corsHeaders(request, corsOptions) });
|
|
@@ -35,20 +37,20 @@ function handleCORS(request, corsOptions) {
|
|
|
35
37
|
}
|
|
36
38
|
var McpSSETransport = class {
|
|
37
39
|
constructor(getWebSocket) {
|
|
38
|
-
this.
|
|
39
|
-
this.
|
|
40
|
+
this._started = false;
|
|
41
|
+
this._getWebSocket = getWebSocket;
|
|
40
42
|
}
|
|
41
43
|
async start() {
|
|
42
|
-
if (this.
|
|
44
|
+
if (this._started) {
|
|
43
45
|
throw new Error("Transport already started");
|
|
44
46
|
}
|
|
45
|
-
this.
|
|
47
|
+
this._started = true;
|
|
46
48
|
}
|
|
47
49
|
async send(message) {
|
|
48
|
-
if (!this.
|
|
50
|
+
if (!this._started) {
|
|
49
51
|
throw new Error("Transport not started");
|
|
50
52
|
}
|
|
51
|
-
const websocket = this.
|
|
53
|
+
const websocket = this._getWebSocket();
|
|
52
54
|
if (!websocket) {
|
|
53
55
|
throw new Error("WebSocket not connected");
|
|
54
56
|
}
|
|
@@ -65,38 +67,38 @@ var McpSSETransport = class {
|
|
|
65
67
|
};
|
|
66
68
|
var McpStreamableHttpTransport = class {
|
|
67
69
|
constructor(getWebSocketForMessageID, notifyResponseIdSent) {
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
70
|
+
this._started = false;
|
|
71
|
+
this._getWebSocketForMessageID = getWebSocketForMessageID;
|
|
72
|
+
this._notifyResponseIdSent = notifyResponseIdSent;
|
|
73
|
+
this._getWebSocketForGetRequest = () => null;
|
|
72
74
|
}
|
|
73
75
|
async start() {
|
|
74
|
-
if (this.
|
|
76
|
+
if (this._started) {
|
|
75
77
|
throw new Error("Transport already started");
|
|
76
78
|
}
|
|
77
|
-
this.
|
|
79
|
+
this._started = true;
|
|
78
80
|
}
|
|
79
81
|
async send(message) {
|
|
80
|
-
if (!this.
|
|
82
|
+
if (!this._started) {
|
|
81
83
|
throw new Error("Transport not started");
|
|
82
84
|
}
|
|
83
85
|
let websocket = null;
|
|
84
86
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
|
|
85
|
-
websocket = this.
|
|
87
|
+
websocket = this._getWebSocketForMessageID(message.id.toString());
|
|
86
88
|
if (!websocket) {
|
|
87
89
|
throw new Error(
|
|
88
90
|
`Could not find WebSocket for message id: ${message.id}`
|
|
89
91
|
);
|
|
90
92
|
}
|
|
91
93
|
} else if (isJSONRPCRequest(message)) {
|
|
92
|
-
websocket = this.
|
|
94
|
+
websocket = this._getWebSocketForGetRequest();
|
|
93
95
|
} else if (isJSONRPCNotification(message)) {
|
|
94
96
|
websocket = null;
|
|
95
97
|
}
|
|
96
98
|
try {
|
|
97
99
|
websocket?.send(JSON.stringify(message));
|
|
98
100
|
if (isJSONRPCResponse(message)) {
|
|
99
|
-
this.
|
|
101
|
+
this._notifyResponseIdSent(message.id.toString());
|
|
100
102
|
}
|
|
101
103
|
} catch (error) {
|
|
102
104
|
this.onerror?.(error);
|
|
@@ -111,12 +113,12 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
111
113
|
constructor(ctx, env) {
|
|
112
114
|
var _a;
|
|
113
115
|
super(ctx, env);
|
|
114
|
-
this.
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
116
|
+
this._status = "zero";
|
|
117
|
+
this._transportType = "unset";
|
|
118
|
+
this._requestIdToConnectionId = /* @__PURE__ */ new Map();
|
|
117
119
|
this.initRun = false;
|
|
118
120
|
const self = this;
|
|
119
|
-
this.
|
|
121
|
+
this._agent = new (_a = class extends Agent {
|
|
120
122
|
onStateUpdate(state, source) {
|
|
121
123
|
return self.onStateUpdate(state, source);
|
|
122
124
|
}
|
|
@@ -128,23 +130,24 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
128
130
|
}, _a)(ctx, env);
|
|
129
131
|
}
|
|
130
132
|
get mcp() {
|
|
131
|
-
return this.
|
|
133
|
+
return this._agent.mcp;
|
|
132
134
|
}
|
|
133
135
|
get state() {
|
|
134
|
-
return this.
|
|
136
|
+
return this._agent.state;
|
|
135
137
|
}
|
|
136
138
|
sql(strings, ...values) {
|
|
137
|
-
return this.
|
|
139
|
+
return this._agent.sql(strings, ...values);
|
|
138
140
|
}
|
|
139
141
|
setState(state) {
|
|
140
|
-
return this.
|
|
142
|
+
return this._agent.setState(state);
|
|
141
143
|
}
|
|
144
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later
|
|
142
145
|
onStateUpdate(state, source) {
|
|
143
146
|
}
|
|
144
147
|
async onStart() {
|
|
145
148
|
var _a;
|
|
146
149
|
const self = this;
|
|
147
|
-
this.
|
|
150
|
+
this._agent = new (_a = class extends Agent {
|
|
148
151
|
constructor() {
|
|
149
152
|
super(...arguments);
|
|
150
153
|
this.initialState = self.initialState;
|
|
@@ -159,20 +162,20 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
159
162
|
hibernate: true
|
|
160
163
|
}, _a)(this.ctx, this.env);
|
|
161
164
|
this.props = await this.ctx.storage.get("props");
|
|
162
|
-
this.
|
|
165
|
+
this._transportType = await this.ctx.storage.get(
|
|
163
166
|
"transportType"
|
|
164
167
|
);
|
|
165
168
|
await this._init(this.props);
|
|
166
169
|
const server = await this.server;
|
|
167
|
-
if (this.
|
|
168
|
-
this.
|
|
169
|
-
await server.connect(this.
|
|
170
|
-
} else if (this.
|
|
171
|
-
this.
|
|
170
|
+
if (this._transportType === "sse") {
|
|
171
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
172
|
+
await server.connect(this._transport);
|
|
173
|
+
} else if (this._transportType === "streamable-http") {
|
|
174
|
+
this._transport = new McpStreamableHttpTransport(
|
|
172
175
|
(id) => this.getWebSocketForResponseID(id),
|
|
173
|
-
(id) => this.
|
|
176
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
174
177
|
);
|
|
175
|
-
await server.connect(this.
|
|
178
|
+
await server.connect(this._transport);
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
181
|
async _init(props) {
|
|
@@ -192,17 +195,17 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
192
195
|
async isInitialized() {
|
|
193
196
|
return await this.ctx.storage.get("initialized") === true;
|
|
194
197
|
}
|
|
195
|
-
async
|
|
198
|
+
async _initialize() {
|
|
196
199
|
await this.ctx.blockConcurrencyWhile(async () => {
|
|
197
|
-
this.
|
|
200
|
+
this._status = "starting";
|
|
198
201
|
await this.onStart();
|
|
199
|
-
this.
|
|
202
|
+
this._status = "started";
|
|
200
203
|
});
|
|
201
204
|
}
|
|
202
205
|
// Allow the worker to fetch a websocket connection to the agent
|
|
203
206
|
async fetch(request) {
|
|
204
|
-
if (this.
|
|
205
|
-
await this.
|
|
207
|
+
if (this._status !== "started") {
|
|
208
|
+
await this._initialize();
|
|
206
209
|
}
|
|
207
210
|
if (request.headers.get("Upgrade") !== "websocket") {
|
|
208
211
|
return new Response("Expected WebSocket Upgrade request", {
|
|
@@ -219,24 +222,24 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
219
222
|
return new Response("Websocket already connected", { status: 400 });
|
|
220
223
|
}
|
|
221
224
|
await this.ctx.storage.put("transportType", "sse");
|
|
222
|
-
this.
|
|
223
|
-
if (!this.
|
|
224
|
-
this.
|
|
225
|
-
await server.connect(this.
|
|
225
|
+
this._transportType = "sse";
|
|
226
|
+
if (!this._transport) {
|
|
227
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
228
|
+
await server.connect(this._transport);
|
|
226
229
|
}
|
|
227
|
-
return this.
|
|
230
|
+
return this._agent.fetch(request);
|
|
228
231
|
}
|
|
229
232
|
case "/streamable-http": {
|
|
230
|
-
if (!this.
|
|
231
|
-
this.
|
|
233
|
+
if (!this._transport) {
|
|
234
|
+
this._transport = new McpStreamableHttpTransport(
|
|
232
235
|
(id) => this.getWebSocketForResponseID(id),
|
|
233
|
-
(id) => this.
|
|
236
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
234
237
|
);
|
|
235
|
-
await server.connect(this.
|
|
238
|
+
await server.connect(this._transport);
|
|
236
239
|
}
|
|
237
240
|
await this.ctx.storage.put("transportType", "streamable-http");
|
|
238
|
-
this.
|
|
239
|
-
return this.
|
|
241
|
+
this._transportType = "streamable-http";
|
|
242
|
+
return this._agent.fetch(request);
|
|
240
243
|
}
|
|
241
244
|
default:
|
|
242
245
|
return new Response(
|
|
@@ -255,19 +258,19 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
255
258
|
return websockets[0];
|
|
256
259
|
}
|
|
257
260
|
getWebSocketForResponseID(id) {
|
|
258
|
-
const connectionId = this.
|
|
261
|
+
const connectionId = this._requestIdToConnectionId.get(id);
|
|
259
262
|
if (connectionId === void 0) {
|
|
260
263
|
return null;
|
|
261
264
|
}
|
|
262
|
-
return this.
|
|
265
|
+
return this._agent.getConnection(connectionId) ?? null;
|
|
263
266
|
}
|
|
264
267
|
// All messages received here. This is currently never called
|
|
265
268
|
async onMessage(connection, event) {
|
|
266
|
-
if (this.
|
|
269
|
+
if (this._transportType !== "streamable-http") {
|
|
267
270
|
const err = new Error(
|
|
268
271
|
"Internal Server Error: Expected streamable-http protocol"
|
|
269
272
|
);
|
|
270
|
-
this.
|
|
273
|
+
this._transport?.onerror?.(err);
|
|
271
274
|
return;
|
|
272
275
|
}
|
|
273
276
|
let message;
|
|
@@ -275,21 +278,21 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
275
278
|
const data = typeof event === "string" ? event : new TextDecoder().decode(event);
|
|
276
279
|
message = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
277
280
|
} catch (error) {
|
|
278
|
-
this.
|
|
281
|
+
this._transport?.onerror?.(error);
|
|
279
282
|
return;
|
|
280
283
|
}
|
|
281
284
|
if (isJSONRPCRequest(message)) {
|
|
282
|
-
this.
|
|
285
|
+
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
283
286
|
}
|
|
284
|
-
this.
|
|
287
|
+
this._transport?.onmessage?.(message);
|
|
285
288
|
}
|
|
286
289
|
// All messages received over SSE after the initial connection has been established
|
|
287
290
|
// will be passed here
|
|
288
|
-
async onSSEMcpMessage(
|
|
289
|
-
if (this.
|
|
290
|
-
await this.
|
|
291
|
+
async onSSEMcpMessage(_sessionId, request) {
|
|
292
|
+
if (this._status !== "started") {
|
|
293
|
+
await this._initialize();
|
|
291
294
|
}
|
|
292
|
-
if (this.
|
|
295
|
+
if (this._transportType !== "sse") {
|
|
293
296
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
294
297
|
}
|
|
295
298
|
try {
|
|
@@ -298,36 +301,36 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
298
301
|
try {
|
|
299
302
|
parsedMessage = JSONRPCMessageSchema.parse(message);
|
|
300
303
|
} catch (error) {
|
|
301
|
-
this.
|
|
304
|
+
this._transport?.onerror?.(error);
|
|
302
305
|
throw error;
|
|
303
306
|
}
|
|
304
|
-
this.
|
|
307
|
+
this._transport?.onmessage?.(parsedMessage);
|
|
305
308
|
return null;
|
|
306
309
|
} catch (error) {
|
|
307
310
|
console.error("Error forwarding message to SSE:", error);
|
|
308
|
-
this.
|
|
311
|
+
this._transport?.onerror?.(error);
|
|
309
312
|
return error;
|
|
310
313
|
}
|
|
311
314
|
}
|
|
312
315
|
// Delegate all websocket events to the underlying agent
|
|
313
316
|
async webSocketMessage(ws, event) {
|
|
314
|
-
if (this.
|
|
315
|
-
await this.
|
|
317
|
+
if (this._status !== "started") {
|
|
318
|
+
await this._initialize();
|
|
316
319
|
}
|
|
317
|
-
return await this.
|
|
320
|
+
return await this._agent.webSocketMessage(ws, event);
|
|
318
321
|
}
|
|
319
322
|
// WebSocket event handlers for hibernation support
|
|
320
323
|
async webSocketError(ws, error) {
|
|
321
|
-
if (this.
|
|
322
|
-
await this.
|
|
324
|
+
if (this._status !== "started") {
|
|
325
|
+
await this._initialize();
|
|
323
326
|
}
|
|
324
|
-
return await this.
|
|
327
|
+
return await this._agent.webSocketError(ws, error);
|
|
325
328
|
}
|
|
326
329
|
async webSocketClose(ws, code, reason, wasClean) {
|
|
327
|
-
if (this.
|
|
328
|
-
await this.
|
|
330
|
+
if (this._status !== "started") {
|
|
331
|
+
await this._initialize();
|
|
329
332
|
}
|
|
330
|
-
return await this.
|
|
333
|
+
return await this._agent.webSocketClose(ws, code, reason, wasClean);
|
|
331
334
|
}
|
|
332
335
|
static mount(path, {
|
|
333
336
|
binding = "MCP_OBJECT",
|
|
@@ -357,7 +360,7 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
357
360
|
);
|
|
358
361
|
return new Response("Invalid binding", { status: 500 });
|
|
359
362
|
}
|
|
360
|
-
if (bindingValue
|
|
363
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
361
364
|
return new Response("Invalid binding", { status: 500 });
|
|
362
365
|
}
|
|
363
366
|
const namespace = bindingValue;
|
|
@@ -418,10 +421,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
418
421
|
onMessage(event).catch(console.error);
|
|
419
422
|
});
|
|
420
423
|
ws.addEventListener("error", (error) => {
|
|
421
|
-
async function onError(
|
|
424
|
+
async function onError(_error) {
|
|
422
425
|
try {
|
|
423
426
|
await writer.close();
|
|
424
|
-
} catch (
|
|
427
|
+
} catch (_e) {
|
|
425
428
|
}
|
|
426
429
|
}
|
|
427
430
|
onError(error).catch(console.error);
|
|
@@ -438,9 +441,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
438
441
|
});
|
|
439
442
|
return new Response(readable, {
|
|
440
443
|
headers: {
|
|
441
|
-
"Content-Type": "text/event-stream",
|
|
442
444
|
"Cache-Control": "no-cache",
|
|
443
445
|
Connection: "keep-alive",
|
|
446
|
+
"Content-Type": "text/event-stream",
|
|
444
447
|
...corsHeaders(request, corsOptions)
|
|
445
448
|
}
|
|
446
449
|
});
|
|
@@ -476,23 +479,23 @@ data: ${JSON.stringify(result.data)}
|
|
|
476
479
|
const error = await doStub.onSSEMcpMessage(sessionId, request);
|
|
477
480
|
if (error) {
|
|
478
481
|
return new Response(error.message, {
|
|
479
|
-
status: 400,
|
|
480
482
|
headers: {
|
|
481
|
-
"Content-Type": "text/event-stream",
|
|
482
483
|
"Cache-Control": "no-cache",
|
|
483
484
|
Connection: "keep-alive",
|
|
485
|
+
"Content-Type": "text/event-stream",
|
|
484
486
|
...corsHeaders(request, corsOptions)
|
|
485
|
-
}
|
|
487
|
+
},
|
|
488
|
+
status: 400
|
|
486
489
|
});
|
|
487
490
|
}
|
|
488
491
|
return new Response("Accepted", {
|
|
489
|
-
status: 202,
|
|
490
492
|
headers: {
|
|
491
|
-
"Content-Type": "text/event-stream",
|
|
492
493
|
"Cache-Control": "no-cache",
|
|
493
494
|
Connection: "keep-alive",
|
|
495
|
+
"Content-Type": "text/event-stream",
|
|
494
496
|
...corsHeaders(request, corsOptions)
|
|
495
|
-
}
|
|
497
|
+
},
|
|
498
|
+
status: 202
|
|
496
499
|
});
|
|
497
500
|
}
|
|
498
501
|
return new Response("Not Found", { status: 404 });
|
|
@@ -522,7 +525,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
522
525
|
);
|
|
523
526
|
return new Response("Invalid binding", { status: 500 });
|
|
524
527
|
}
|
|
525
|
-
if (bindingValue
|
|
528
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
526
529
|
return new Response("Invalid binding", { status: 500 });
|
|
527
530
|
}
|
|
528
531
|
const namespace = bindingValue;
|
|
@@ -530,24 +533,24 @@ data: ${JSON.stringify(result.data)}
|
|
|
530
533
|
const acceptHeader = request.headers.get("accept");
|
|
531
534
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
532
535
|
const body2 = JSON.stringify({
|
|
533
|
-
jsonrpc: "2.0",
|
|
534
536
|
error: {
|
|
535
537
|
code: -32e3,
|
|
536
538
|
message: "Not Acceptable: Client must accept both application/json and text/event-stream"
|
|
537
539
|
},
|
|
538
|
-
id: null
|
|
540
|
+
id: null,
|
|
541
|
+
jsonrpc: "2.0"
|
|
539
542
|
});
|
|
540
543
|
return new Response(body2, { status: 406 });
|
|
541
544
|
}
|
|
542
545
|
const ct = request.headers.get("content-type");
|
|
543
546
|
if (!ct || !ct.includes("application/json")) {
|
|
544
547
|
const body2 = JSON.stringify({
|
|
545
|
-
jsonrpc: "2.0",
|
|
546
548
|
error: {
|
|
547
549
|
code: -32e3,
|
|
548
550
|
message: "Unsupported Media Type: Content-Type must be application/json"
|
|
549
551
|
},
|
|
550
|
-
id: null
|
|
552
|
+
id: null,
|
|
553
|
+
jsonrpc: "2.0"
|
|
551
554
|
});
|
|
552
555
|
return new Response(body2, { status: 415 });
|
|
553
556
|
}
|
|
@@ -557,12 +560,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
557
560
|
);
|
|
558
561
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
|
|
559
562
|
const body2 = JSON.stringify({
|
|
560
|
-
jsonrpc: "2.0",
|
|
561
563
|
error: {
|
|
562
564
|
code: -32e3,
|
|
563
565
|
message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
|
|
564
566
|
},
|
|
565
|
-
id: null
|
|
567
|
+
id: null,
|
|
568
|
+
jsonrpc: "2.0"
|
|
566
569
|
});
|
|
567
570
|
return new Response(body2, { status: 413 });
|
|
568
571
|
}
|
|
@@ -570,14 +573,14 @@ data: ${JSON.stringify(result.data)}
|
|
|
570
573
|
let rawMessage;
|
|
571
574
|
try {
|
|
572
575
|
rawMessage = await request.json();
|
|
573
|
-
} catch (
|
|
576
|
+
} catch (_error) {
|
|
574
577
|
const body2 = JSON.stringify({
|
|
575
|
-
jsonrpc: "2.0",
|
|
576
578
|
error: {
|
|
577
579
|
code: -32700,
|
|
578
580
|
message: "Parse error: Invalid JSON"
|
|
579
581
|
},
|
|
580
|
-
id: null
|
|
582
|
+
id: null,
|
|
583
|
+
jsonrpc: "2.0"
|
|
581
584
|
});
|
|
582
585
|
return new Response(body2, { status: 400 });
|
|
583
586
|
}
|
|
@@ -591,12 +594,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
591
594
|
for (const msg of arrayMessage) {
|
|
592
595
|
if (!JSONRPCMessageSchema.safeParse(msg).success) {
|
|
593
596
|
const body2 = JSON.stringify({
|
|
594
|
-
jsonrpc: "2.0",
|
|
595
597
|
error: {
|
|
596
598
|
code: -32700,
|
|
597
599
|
message: "Parse error: Invalid JSON-RPC message"
|
|
598
600
|
},
|
|
599
|
-
id: null
|
|
601
|
+
id: null,
|
|
602
|
+
jsonrpc: "2.0"
|
|
600
603
|
});
|
|
601
604
|
return new Response(body2, { status: 400 });
|
|
602
605
|
}
|
|
@@ -607,34 +610,34 @@ data: ${JSON.stringify(result.data)}
|
|
|
607
610
|
);
|
|
608
611
|
if (isInitializationRequest && sessionId) {
|
|
609
612
|
const body2 = JSON.stringify({
|
|
610
|
-
jsonrpc: "2.0",
|
|
611
613
|
error: {
|
|
612
614
|
code: -32600,
|
|
613
615
|
message: "Invalid Request: Initialization requests must not include a sessionId"
|
|
614
616
|
},
|
|
615
|
-
id: null
|
|
617
|
+
id: null,
|
|
618
|
+
jsonrpc: "2.0"
|
|
616
619
|
});
|
|
617
620
|
return new Response(body2, { status: 400 });
|
|
618
621
|
}
|
|
619
622
|
if (isInitializationRequest && messages.length > 1) {
|
|
620
623
|
const body2 = JSON.stringify({
|
|
621
|
-
jsonrpc: "2.0",
|
|
622
624
|
error: {
|
|
623
625
|
code: -32600,
|
|
624
626
|
message: "Invalid Request: Only one initialization request is allowed"
|
|
625
627
|
},
|
|
626
|
-
id: null
|
|
628
|
+
id: null,
|
|
629
|
+
jsonrpc: "2.0"
|
|
627
630
|
});
|
|
628
631
|
return new Response(body2, { status: 400 });
|
|
629
632
|
}
|
|
630
633
|
if (!isInitializationRequest && !sessionId) {
|
|
631
634
|
const body2 = JSON.stringify({
|
|
632
|
-
jsonrpc: "2.0",
|
|
633
635
|
error: {
|
|
634
636
|
code: -32e3,
|
|
635
637
|
message: "Bad Request: Mcp-Session-Id header is required"
|
|
636
638
|
},
|
|
637
|
-
id: null
|
|
639
|
+
id: null,
|
|
640
|
+
jsonrpc: "2.0"
|
|
638
641
|
});
|
|
639
642
|
return new Response(body2, { status: 400 });
|
|
640
643
|
}
|
|
@@ -647,12 +650,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
647
650
|
await doStub.setInitialized();
|
|
648
651
|
} else if (!isInitialized) {
|
|
649
652
|
const body2 = JSON.stringify({
|
|
650
|
-
jsonrpc: "2.0",
|
|
651
653
|
error: {
|
|
652
654
|
code: -32001,
|
|
653
655
|
message: "Session not found"
|
|
654
656
|
},
|
|
655
|
-
id: null
|
|
657
|
+
id: null,
|
|
658
|
+
jsonrpc: "2.0"
|
|
656
659
|
});
|
|
657
660
|
return new Response(body2, { status: 404 });
|
|
658
661
|
}
|
|
@@ -675,12 +678,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
675
678
|
console.error("Failed to establish WebSocket connection");
|
|
676
679
|
await writer.close();
|
|
677
680
|
const body2 = JSON.stringify({
|
|
678
|
-
jsonrpc: "2.0",
|
|
679
681
|
error: {
|
|
680
682
|
code: -32001,
|
|
681
683
|
message: "Failed to establish WebSocket connection"
|
|
682
684
|
},
|
|
683
|
-
id: null
|
|
685
|
+
id: null,
|
|
686
|
+
jsonrpc: "2.0"
|
|
684
687
|
});
|
|
685
688
|
return new Response(body2, { status: 500 });
|
|
686
689
|
}
|
|
@@ -713,10 +716,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
713
716
|
onMessage(event).catch(console.error);
|
|
714
717
|
});
|
|
715
718
|
ws.addEventListener("error", (error) => {
|
|
716
|
-
async function onError(
|
|
719
|
+
async function onError(_error) {
|
|
717
720
|
try {
|
|
718
721
|
await writer.close();
|
|
719
|
-
} catch (
|
|
722
|
+
} catch (_e) {
|
|
720
723
|
}
|
|
721
724
|
}
|
|
722
725
|
onError(error).catch(console.error);
|
|
@@ -740,8 +743,8 @@ data: ${JSON.stringify(result.data)}
|
|
|
740
743
|
}
|
|
741
744
|
ws.close();
|
|
742
745
|
return new Response(null, {
|
|
743
|
-
|
|
744
|
-
|
|
746
|
+
headers: corsHeaders(request, corsOptions),
|
|
747
|
+
status: 202
|
|
745
748
|
});
|
|
746
749
|
}
|
|
747
750
|
for (const message of messages) {
|
|
@@ -752,9 +755,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
752
755
|
}
|
|
753
756
|
return new Response(readable, {
|
|
754
757
|
headers: {
|
|
755
|
-
"Content-Type": "text/event-stream",
|
|
756
758
|
"Cache-Control": "no-cache",
|
|
757
759
|
Connection: "keep-alive",
|
|
760
|
+
"Content-Type": "text/event-stream",
|
|
758
761
|
"mcp-session-id": sessionId,
|
|
759
762
|
...corsHeaders(request, corsOptions)
|
|
760
763
|
},
|
|
@@ -762,12 +765,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
762
765
|
});
|
|
763
766
|
}
|
|
764
767
|
const body = JSON.stringify({
|
|
765
|
-
jsonrpc: "2.0",
|
|
766
768
|
error: {
|
|
767
769
|
code: -32e3,
|
|
768
770
|
message: "Method not allowed"
|
|
769
771
|
},
|
|
770
|
-
id: null
|
|
772
|
+
id: null,
|
|
773
|
+
jsonrpc: "2.0"
|
|
771
774
|
});
|
|
772
775
|
return new Response(body, { status: 405 });
|
|
773
776
|
}
|