agents 0.0.0-1e060d3 → 0.0.0-1e4188c
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 +131 -25
- package/dist/ai-chat-agent.d.ts +54 -8
- package/dist/ai-chat-agent.js +259 -90
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.d.ts +152 -0
- package/dist/ai-chat-v5-migration.js +19 -0
- package/dist/ai-react.d.ts +71 -67
- package/dist/ai-react.js +179 -61
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +40 -18
- package/dist/ai-types.js +6 -0
- package/dist/chunk-AVYJQSLW.js +17 -0
- package/dist/chunk-AVYJQSLW.js.map +1 -0
- package/dist/chunk-HKY5L652.js +1301 -0
- package/dist/chunk-HKY5L652.js.map +1 -0
- package/dist/chunk-PVQZBKN7.js +106 -0
- package/dist/chunk-PVQZBKN7.js.map +1 -0
- package/dist/chunk-QEVM4BVL.js +116 -0
- package/dist/chunk-QEVM4BVL.js.map +1 -0
- package/dist/chunk-UJVEAURM.js +150 -0
- package/dist/chunk-UJVEAURM.js.map +1 -0
- package/dist/chunk-VYENMKFS.js +612 -0
- package/dist/chunk-VYENMKFS.js.map +1 -0
- package/dist/client-B9tFv5gX.d.ts +4607 -0
- package/dist/client.d.ts +16 -2
- package/dist/client.js +7 -126
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +274 -21
- package/dist/index.js +17 -6
- package/dist/mcp/client.d.ts +9 -761
- package/dist/mcp/client.js +3 -402
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +3 -3
- package/dist/mcp/do-oauth-client-provider.js +3 -103
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +63 -11
- package/dist/mcp/index.js +371 -188
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +46 -0
- package/dist/observability/index.js +11 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/react.d.ts +89 -5
- package/dist/react.js +23 -9
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +81 -7
- package/dist/schedule.js +19 -8
- 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 +83 -56
- package/src/index.ts +1170 -144
- package/dist/chunk-HMLY7DHA.js +0 -16
- package/dist/chunk-XG52S6YY.js +0 -591
- package/dist/chunk-XG52S6YY.js.map +0 -1
- /package/dist/{chunk-HMLY7DHA.js.map → ai-chat-v5-migration.js.map} +0 -0
package/dist/mcp/index.js
CHANGED
|
@@ -1,55 +1,63 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-HKY5L652.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
SSEEdgeClientTransport,
|
|
6
|
+
StreamableHTTPEdgeClientTransport
|
|
7
|
+
} from "../chunk-VYENMKFS.js";
|
|
8
|
+
import "../chunk-PVQZBKN7.js";
|
|
9
|
+
import "../chunk-QEVM4BVL.js";
|
|
10
|
+
import "../chunk-AVYJQSLW.js";
|
|
10
11
|
|
|
11
12
|
// src/mcp/index.ts
|
|
12
13
|
import { DurableObject } from "cloudflare:workers";
|
|
13
14
|
import {
|
|
14
15
|
InitializeRequestSchema,
|
|
16
|
+
JSONRPCMessageSchema,
|
|
15
17
|
isJSONRPCError,
|
|
16
18
|
isJSONRPCNotification,
|
|
17
19
|
isJSONRPCRequest,
|
|
18
|
-
isJSONRPCResponse
|
|
19
|
-
|
|
20
|
+
isJSONRPCResponse
|
|
21
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
22
|
+
import {
|
|
23
|
+
ElicitRequestSchema
|
|
20
24
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
21
25
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
22
|
-
function
|
|
23
|
-
const origin =
|
|
24
|
-
|
|
25
|
-
"Access-Control-Allow-
|
|
26
|
-
"Access-Control-Allow-Methods": corsOptions
|
|
27
|
-
"Access-Control-Allow-
|
|
28
|
-
"Access-Control-
|
|
26
|
+
function corsHeaders(_request, corsOptions = {}) {
|
|
27
|
+
const origin = "*";
|
|
28
|
+
return {
|
|
29
|
+
"Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
|
|
30
|
+
"Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
|
|
31
|
+
"Access-Control-Allow-Origin": corsOptions.origin || origin,
|
|
32
|
+
"Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id",
|
|
33
|
+
"Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString()
|
|
29
34
|
};
|
|
35
|
+
}
|
|
36
|
+
function isDurableObjectNamespace(namespace) {
|
|
37
|
+
return typeof namespace === "object" && namespace !== null && "newUniqueId" in namespace && typeof namespace.newUniqueId === "function" && "idFromName" in namespace && typeof namespace.idFromName === "function";
|
|
38
|
+
}
|
|
39
|
+
function handleCORS(request, corsOptions) {
|
|
30
40
|
if (request.method === "OPTIONS") {
|
|
31
|
-
return new Response(null, { headers: corsHeaders });
|
|
41
|
+
return new Response(null, { headers: corsHeaders(request, corsOptions) });
|
|
32
42
|
}
|
|
33
43
|
return null;
|
|
34
44
|
}
|
|
35
|
-
var _getWebSocket, _started;
|
|
36
45
|
var McpSSETransport = class {
|
|
37
46
|
constructor(getWebSocket) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
__privateSet(this, _getWebSocket, getWebSocket);
|
|
47
|
+
this._started = false;
|
|
48
|
+
this._getWebSocket = getWebSocket;
|
|
41
49
|
}
|
|
42
50
|
async start() {
|
|
43
|
-
if (
|
|
51
|
+
if (this._started) {
|
|
44
52
|
throw new Error("Transport already started");
|
|
45
53
|
}
|
|
46
|
-
|
|
54
|
+
this._started = true;
|
|
47
55
|
}
|
|
48
56
|
async send(message) {
|
|
49
|
-
if (!
|
|
57
|
+
if (!this._started) {
|
|
50
58
|
throw new Error("Transport not started");
|
|
51
59
|
}
|
|
52
|
-
const websocket =
|
|
60
|
+
const websocket = this._getWebSocket();
|
|
53
61
|
if (!websocket) {
|
|
54
62
|
throw new Error("WebSocket not connected");
|
|
55
63
|
}
|
|
@@ -64,52 +72,40 @@ var McpSSETransport = class {
|
|
|
64
72
|
this.onclose?.();
|
|
65
73
|
}
|
|
66
74
|
};
|
|
67
|
-
_getWebSocket = new WeakMap();
|
|
68
|
-
_started = new WeakMap();
|
|
69
|
-
var _getWebSocketForGetRequest, _getWebSocketForMessageID, _notifyResponseIdSent, _started2;
|
|
70
75
|
var McpStreamableHttpTransport = class {
|
|
71
76
|
constructor(getWebSocketForMessageID, notifyResponseIdSent) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
__privateAdd(this, _getWebSocketForMessageID);
|
|
77
|
-
// Notify the server that a response has been sent for a given message id
|
|
78
|
-
// so that it may clean up it's mapping of message ids to connections
|
|
79
|
-
// once they are no longer needed
|
|
80
|
-
__privateAdd(this, _notifyResponseIdSent);
|
|
81
|
-
__privateAdd(this, _started2, false);
|
|
82
|
-
__privateSet(this, _getWebSocketForMessageID, getWebSocketForMessageID);
|
|
83
|
-
__privateSet(this, _notifyResponseIdSent, notifyResponseIdSent);
|
|
84
|
-
__privateSet(this, _getWebSocketForGetRequest, () => null);
|
|
77
|
+
this._started = false;
|
|
78
|
+
this._getWebSocketForMessageID = getWebSocketForMessageID;
|
|
79
|
+
this._notifyResponseIdSent = notifyResponseIdSent;
|
|
80
|
+
this._getWebSocketForGetRequest = () => null;
|
|
85
81
|
}
|
|
86
82
|
async start() {
|
|
87
|
-
if (
|
|
83
|
+
if (this._started) {
|
|
88
84
|
throw new Error("Transport already started");
|
|
89
85
|
}
|
|
90
|
-
|
|
86
|
+
this._started = true;
|
|
91
87
|
}
|
|
92
88
|
async send(message) {
|
|
93
|
-
if (!
|
|
89
|
+
if (!this._started) {
|
|
94
90
|
throw new Error("Transport not started");
|
|
95
91
|
}
|
|
96
92
|
let websocket = null;
|
|
97
93
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
|
|
98
|
-
websocket =
|
|
94
|
+
websocket = this._getWebSocketForMessageID(message.id.toString());
|
|
99
95
|
if (!websocket) {
|
|
100
96
|
throw new Error(
|
|
101
97
|
`Could not find WebSocket for message id: ${message.id}`
|
|
102
98
|
);
|
|
103
99
|
}
|
|
104
100
|
} else if (isJSONRPCRequest(message)) {
|
|
105
|
-
websocket =
|
|
101
|
+
websocket = this._getWebSocketForGetRequest();
|
|
106
102
|
} else if (isJSONRPCNotification(message)) {
|
|
107
103
|
websocket = null;
|
|
108
104
|
}
|
|
109
105
|
try {
|
|
110
106
|
websocket?.send(JSON.stringify(message));
|
|
111
107
|
if (isJSONRPCResponse(message)) {
|
|
112
|
-
|
|
108
|
+
this._notifyResponseIdSent(message.id.toString());
|
|
113
109
|
}
|
|
114
110
|
} catch (error) {
|
|
115
111
|
this.onerror?.(error);
|
|
@@ -120,28 +116,16 @@ var McpStreamableHttpTransport = class {
|
|
|
120
116
|
this.onclose?.();
|
|
121
117
|
}
|
|
122
118
|
};
|
|
123
|
-
|
|
124
|
-
_getWebSocketForMessageID = new WeakMap();
|
|
125
|
-
_notifyResponseIdSent = new WeakMap();
|
|
126
|
-
_started2 = new WeakMap();
|
|
127
|
-
var _status, _transport, _transportType, _requestIdToConnectionId, _agent, _McpAgent_instances, initialize_fn;
|
|
128
|
-
var _McpAgent = class _McpAgent extends DurableObject {
|
|
119
|
+
var McpAgent = class _McpAgent extends DurableObject {
|
|
129
120
|
constructor(ctx, env) {
|
|
130
121
|
var _a;
|
|
131
122
|
super(ctx, env);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
__privateAdd(this, _transportType, "unset");
|
|
136
|
-
__privateAdd(this, _requestIdToConnectionId, /* @__PURE__ */ new Map());
|
|
137
|
-
/**
|
|
138
|
-
* Since McpAgent's _aren't_ yet real "Agents", let's only expose a couple of the methods
|
|
139
|
-
* to the outer class: initialState/state/setState/onStateUpdate/sql
|
|
140
|
-
*/
|
|
141
|
-
__privateAdd(this, _agent);
|
|
123
|
+
this._status = "zero";
|
|
124
|
+
this._transportType = "unset";
|
|
125
|
+
this._requestIdToConnectionId = /* @__PURE__ */ new Map();
|
|
142
126
|
this.initRun = false;
|
|
143
127
|
const self = this;
|
|
144
|
-
|
|
128
|
+
this._agent = new (_a = class extends Agent {
|
|
145
129
|
onStateUpdate(state, source) {
|
|
146
130
|
return self.onStateUpdate(state, source);
|
|
147
131
|
}
|
|
@@ -150,23 +134,66 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
150
134
|
}
|
|
151
135
|
}, _a.options = {
|
|
152
136
|
hibernate: true
|
|
153
|
-
}, _a)(ctx, env)
|
|
137
|
+
}, _a)(ctx, env);
|
|
138
|
+
}
|
|
139
|
+
get mcp() {
|
|
140
|
+
return this._agent.mcp;
|
|
154
141
|
}
|
|
155
142
|
get state() {
|
|
156
|
-
return
|
|
143
|
+
return this._agent.state;
|
|
157
144
|
}
|
|
158
145
|
sql(strings, ...values) {
|
|
159
|
-
return
|
|
146
|
+
return this._agent.sql(strings, ...values);
|
|
160
147
|
}
|
|
161
148
|
setState(state) {
|
|
162
|
-
return
|
|
149
|
+
return this._agent.setState(state);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Elicit user input with a message and schema
|
|
153
|
+
*/
|
|
154
|
+
async elicitInput(params) {
|
|
155
|
+
const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;
|
|
156
|
+
await this.ctx.storage.put(`elicitation:${requestId}`, {
|
|
157
|
+
message: params.message,
|
|
158
|
+
requestedSchema: params.requestedSchema,
|
|
159
|
+
timestamp: Date.now()
|
|
160
|
+
});
|
|
161
|
+
const elicitRequest = {
|
|
162
|
+
jsonrpc: "2.0",
|
|
163
|
+
id: requestId,
|
|
164
|
+
method: "elicitation/create",
|
|
165
|
+
params: {
|
|
166
|
+
message: params.message,
|
|
167
|
+
requestedSchema: params.requestedSchema
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
if (this._transport) {
|
|
171
|
+
await this._transport.send(elicitRequest);
|
|
172
|
+
} else {
|
|
173
|
+
const connections = this._agent?.getConnections();
|
|
174
|
+
if (!connections || Array.from(connections).length === 0) {
|
|
175
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
176
|
+
throw new Error("No active connections available for elicitation");
|
|
177
|
+
}
|
|
178
|
+
const connectionList = Array.from(connections);
|
|
179
|
+
for (const connection of connectionList) {
|
|
180
|
+
try {
|
|
181
|
+
connection.send(JSON.stringify(elicitRequest));
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error("Failed to send elicitation request:", error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return this._waitForElicitationResponse(requestId);
|
|
163
188
|
}
|
|
189
|
+
// we leave the variables as unused for autocomplete purposes
|
|
190
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later
|
|
164
191
|
onStateUpdate(state, source) {
|
|
165
192
|
}
|
|
166
193
|
async onStart() {
|
|
167
194
|
var _a;
|
|
168
195
|
const self = this;
|
|
169
|
-
|
|
196
|
+
this._agent = new (_a = class extends Agent {
|
|
170
197
|
constructor() {
|
|
171
198
|
super(...arguments);
|
|
172
199
|
this.initialState = self.initialState;
|
|
@@ -179,39 +206,73 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
179
206
|
}
|
|
180
207
|
}, _a.options = {
|
|
181
208
|
hibernate: true
|
|
182
|
-
}, _a)(this.ctx, this.env)
|
|
209
|
+
}, _a)(this.ctx, this.env);
|
|
183
210
|
this.props = await this.ctx.storage.get("props");
|
|
184
|
-
|
|
211
|
+
this._transportType = await this.ctx.storage.get(
|
|
185
212
|
"transportType"
|
|
186
|
-
)
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
213
|
+
);
|
|
214
|
+
await this._init(this.props);
|
|
215
|
+
const server = await this.server;
|
|
216
|
+
if (this._transportType === "sse") {
|
|
217
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
218
|
+
await server.connect(this._transport);
|
|
219
|
+
} else if (this._transportType === "streamable-http") {
|
|
220
|
+
this._transport = new McpStreamableHttpTransport(
|
|
193
221
|
(id) => this.getWebSocketForResponseID(id),
|
|
194
|
-
(id) =>
|
|
195
|
-
)
|
|
196
|
-
await
|
|
222
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
223
|
+
);
|
|
224
|
+
await server.connect(this._transport);
|
|
197
225
|
}
|
|
198
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Handle errors that occur during initialization or operation.
|
|
229
|
+
* Override this method to provide custom error handling.
|
|
230
|
+
* @param error - The error that occurred
|
|
231
|
+
* @returns An error response object with status code and message
|
|
232
|
+
*/
|
|
233
|
+
onError(error) {
|
|
234
|
+
console.error("McpAgent error:", error);
|
|
235
|
+
return {
|
|
236
|
+
status: 500,
|
|
237
|
+
message: error.message || "An unexpected error occurred during initialization"
|
|
238
|
+
};
|
|
239
|
+
}
|
|
199
240
|
async _init(props) {
|
|
200
|
-
await this.
|
|
201
|
-
|
|
202
|
-
|
|
241
|
+
await this.updateProps(props);
|
|
242
|
+
if (!this.ctx.storage.get("transportType")) {
|
|
243
|
+
await this.ctx.storage.put("transportType", "unset");
|
|
244
|
+
}
|
|
203
245
|
if (!this.initRun) {
|
|
204
246
|
this.initRun = true;
|
|
205
|
-
|
|
247
|
+
try {
|
|
248
|
+
await this.init();
|
|
249
|
+
} catch (error) {
|
|
250
|
+
const errorResponse = this.onError(error);
|
|
251
|
+
throw new Error(`Initialization failed: ${errorResponse.message}`);
|
|
252
|
+
}
|
|
206
253
|
}
|
|
207
254
|
}
|
|
208
|
-
|
|
209
|
-
|
|
255
|
+
async setInitialized() {
|
|
256
|
+
await this.ctx.storage.put("initialized", true);
|
|
257
|
+
}
|
|
258
|
+
async isInitialized() {
|
|
259
|
+
return await this.ctx.storage.get("initialized") === true;
|
|
260
|
+
}
|
|
261
|
+
async updateProps(props) {
|
|
262
|
+
await this.ctx.storage.put("props", props ?? {});
|
|
263
|
+
this.props = props;
|
|
264
|
+
}
|
|
265
|
+
async _initialize() {
|
|
266
|
+
await this.ctx.blockConcurrencyWhile(async () => {
|
|
267
|
+
this._status = "starting";
|
|
268
|
+
await this.onStart();
|
|
269
|
+
this._status = "started";
|
|
270
|
+
});
|
|
210
271
|
}
|
|
211
272
|
// Allow the worker to fetch a websocket connection to the agent
|
|
212
273
|
async fetch(request) {
|
|
213
|
-
if (
|
|
214
|
-
await
|
|
274
|
+
if (this._status !== "started") {
|
|
275
|
+
await this._initialize();
|
|
215
276
|
}
|
|
216
277
|
if (request.headers.get("Upgrade") !== "websocket") {
|
|
217
278
|
return new Response("Expected WebSocket Upgrade request", {
|
|
@@ -220,6 +281,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
220
281
|
}
|
|
221
282
|
const url = new URL(request.url);
|
|
222
283
|
const path = url.pathname;
|
|
284
|
+
const server = await this.server;
|
|
223
285
|
switch (path) {
|
|
224
286
|
case "/sse": {
|
|
225
287
|
const websockets = this.ctx.getWebSockets();
|
|
@@ -227,24 +289,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
227
289
|
return new Response("Websocket already connected", { status: 400 });
|
|
228
290
|
}
|
|
229
291
|
await this.ctx.storage.put("transportType", "sse");
|
|
230
|
-
|
|
231
|
-
if (!
|
|
232
|
-
|
|
233
|
-
await
|
|
292
|
+
this._transportType = "sse";
|
|
293
|
+
if (!this._transport) {
|
|
294
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
295
|
+
await server.connect(this._transport);
|
|
234
296
|
}
|
|
235
|
-
return
|
|
297
|
+
return this._agent.fetch(request);
|
|
236
298
|
}
|
|
237
299
|
case "/streamable-http": {
|
|
238
|
-
if (!
|
|
239
|
-
|
|
300
|
+
if (!this._transport) {
|
|
301
|
+
this._transport = new McpStreamableHttpTransport(
|
|
240
302
|
(id) => this.getWebSocketForResponseID(id),
|
|
241
|
-
(id) =>
|
|
242
|
-
)
|
|
243
|
-
await
|
|
303
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
304
|
+
);
|
|
305
|
+
await server.connect(this._transport);
|
|
244
306
|
}
|
|
245
307
|
await this.ctx.storage.put("transportType", "streamable-http");
|
|
246
|
-
|
|
247
|
-
return
|
|
308
|
+
this._transportType = "streamable-http";
|
|
309
|
+
return this._agent.fetch(request);
|
|
248
310
|
}
|
|
249
311
|
default:
|
|
250
312
|
return new Response(
|
|
@@ -263,19 +325,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
263
325
|
return websockets[0];
|
|
264
326
|
}
|
|
265
327
|
getWebSocketForResponseID(id) {
|
|
266
|
-
const connectionId =
|
|
328
|
+
const connectionId = this._requestIdToConnectionId.get(id);
|
|
267
329
|
if (connectionId === void 0) {
|
|
268
330
|
return null;
|
|
269
331
|
}
|
|
270
|
-
return
|
|
332
|
+
return this._agent.getConnection(connectionId) ?? null;
|
|
271
333
|
}
|
|
272
334
|
// All messages received here. This is currently never called
|
|
273
335
|
async onMessage(connection, event) {
|
|
274
|
-
if (
|
|
336
|
+
if (this._transportType !== "streamable-http") {
|
|
275
337
|
const err = new Error(
|
|
276
338
|
"Internal Server Error: Expected streamable-http protocol"
|
|
277
339
|
);
|
|
278
|
-
|
|
340
|
+
this._transport?.onerror?.(err);
|
|
279
341
|
return;
|
|
280
342
|
}
|
|
281
343
|
let message;
|
|
@@ -283,58 +345,125 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
283
345
|
const data = typeof event === "string" ? event : new TextDecoder().decode(event);
|
|
284
346
|
message = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
285
347
|
} catch (error) {
|
|
286
|
-
|
|
348
|
+
this._transport?.onerror?.(error);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (await this._handleElicitationResponse(message)) {
|
|
287
352
|
return;
|
|
288
353
|
}
|
|
289
354
|
if (isJSONRPCRequest(message)) {
|
|
290
|
-
|
|
355
|
+
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
291
356
|
}
|
|
292
|
-
|
|
357
|
+
this._transport?.onmessage?.(message);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Wait for elicitation response through storage polling
|
|
361
|
+
*/
|
|
362
|
+
async _waitForElicitationResponse(requestId) {
|
|
363
|
+
const startTime = Date.now();
|
|
364
|
+
const timeout = 6e4;
|
|
365
|
+
try {
|
|
366
|
+
while (Date.now() - startTime < timeout) {
|
|
367
|
+
const response = await this.ctx.storage.get(
|
|
368
|
+
`elicitation:response:${requestId}`
|
|
369
|
+
);
|
|
370
|
+
if (response) {
|
|
371
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
372
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
373
|
+
return response;
|
|
374
|
+
}
|
|
375
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
376
|
+
}
|
|
377
|
+
throw new Error("Elicitation request timed out");
|
|
378
|
+
} finally {
|
|
379
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
380
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Handle elicitation responses */
|
|
385
|
+
async _handleElicitationResponse(message) {
|
|
386
|
+
if (isJSONRPCResponse(message) && message.result) {
|
|
387
|
+
const requestId = message.id?.toString();
|
|
388
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
389
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
390
|
+
`elicitation:${requestId}`
|
|
391
|
+
);
|
|
392
|
+
if (!pendingRequest) return false;
|
|
393
|
+
await this.ctx.storage.put(
|
|
394
|
+
`elicitation:response:${requestId}`,
|
|
395
|
+
message.result
|
|
396
|
+
);
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
if (isJSONRPCError(message)) {
|
|
400
|
+
const requestId = message.id?.toString();
|
|
401
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
402
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
403
|
+
`elicitation:${requestId}`
|
|
404
|
+
);
|
|
405
|
+
if (!pendingRequest) return false;
|
|
406
|
+
const errorResult = {
|
|
407
|
+
action: "cancel",
|
|
408
|
+
content: {
|
|
409
|
+
error: message.error.message || "Elicitation request failed"
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
await this.ctx.storage.put(
|
|
413
|
+
`elicitation:response:${requestId}`,
|
|
414
|
+
errorResult
|
|
415
|
+
);
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
293
419
|
}
|
|
294
420
|
// All messages received over SSE after the initial connection has been established
|
|
295
421
|
// will be passed here
|
|
296
|
-
async onSSEMcpMessage(
|
|
297
|
-
if (
|
|
298
|
-
await
|
|
422
|
+
async onSSEMcpMessage(_sessionId, messageBody) {
|
|
423
|
+
if (this._status !== "started") {
|
|
424
|
+
await this._initialize();
|
|
299
425
|
}
|
|
300
|
-
if (
|
|
426
|
+
if (this._transportType !== "sse") {
|
|
301
427
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
302
428
|
}
|
|
303
429
|
try {
|
|
304
|
-
const message = await request.json();
|
|
305
430
|
let parsedMessage;
|
|
306
431
|
try {
|
|
307
|
-
parsedMessage = JSONRPCMessageSchema.parse(
|
|
432
|
+
parsedMessage = JSONRPCMessageSchema.parse(messageBody);
|
|
308
433
|
} catch (error) {
|
|
309
|
-
|
|
434
|
+
this._transport?.onerror?.(error);
|
|
310
435
|
throw error;
|
|
311
436
|
}
|
|
312
|
-
|
|
437
|
+
if (await this._handleElicitationResponse(parsedMessage)) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
this._transport?.onmessage?.(parsedMessage);
|
|
313
441
|
return null;
|
|
314
442
|
} catch (error) {
|
|
315
|
-
|
|
443
|
+
console.error("Error forwarding message to SSE:", error);
|
|
444
|
+
this._transport?.onerror?.(error);
|
|
316
445
|
return error;
|
|
317
446
|
}
|
|
318
447
|
}
|
|
319
448
|
// Delegate all websocket events to the underlying agent
|
|
320
449
|
async webSocketMessage(ws, event) {
|
|
321
|
-
if (
|
|
322
|
-
await
|
|
450
|
+
if (this._status !== "started") {
|
|
451
|
+
await this._initialize();
|
|
323
452
|
}
|
|
324
|
-
return await
|
|
453
|
+
return await this._agent.webSocketMessage(ws, event);
|
|
325
454
|
}
|
|
326
455
|
// WebSocket event handlers for hibernation support
|
|
327
456
|
async webSocketError(ws, error) {
|
|
328
|
-
if (
|
|
329
|
-
await
|
|
457
|
+
if (this._status !== "started") {
|
|
458
|
+
await this._initialize();
|
|
330
459
|
}
|
|
331
|
-
return await
|
|
460
|
+
return await this._agent.webSocketError(ws, error);
|
|
332
461
|
}
|
|
333
462
|
async webSocketClose(ws, code, reason, wasClean) {
|
|
334
|
-
if (
|
|
335
|
-
await
|
|
463
|
+
if (this._status !== "started") {
|
|
464
|
+
await this._initialize();
|
|
336
465
|
}
|
|
337
|
-
return await
|
|
466
|
+
return await this._agent.webSocketClose(ws, code, reason, wasClean);
|
|
338
467
|
}
|
|
339
468
|
static mount(path, {
|
|
340
469
|
binding = "MCP_OBJECT",
|
|
@@ -353,29 +482,57 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
353
482
|
const basePattern = new URLPattern({ pathname });
|
|
354
483
|
const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
|
|
355
484
|
return {
|
|
356
|
-
|
|
485
|
+
async fetch(request, env, ctx) {
|
|
357
486
|
const corsResponse = handleCORS(request, corsOptions);
|
|
358
487
|
if (corsResponse) return corsResponse;
|
|
359
488
|
const url = new URL(request.url);
|
|
360
|
-
const
|
|
489
|
+
const bindingValue = env[binding];
|
|
490
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
491
|
+
console.error(
|
|
492
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
493
|
+
);
|
|
494
|
+
return new Response("Invalid binding", { status: 500 });
|
|
495
|
+
}
|
|
496
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
497
|
+
return new Response("Invalid binding", { status: 500 });
|
|
498
|
+
}
|
|
499
|
+
const namespace = bindingValue;
|
|
361
500
|
if (request.method === "GET" && basePattern.test(url)) {
|
|
362
501
|
const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
|
|
363
502
|
const { readable, writable } = new TransformStream();
|
|
364
503
|
const writer = writable.getWriter();
|
|
365
504
|
const encoder = new TextEncoder();
|
|
505
|
+
const endpointUrl = new URL(request.url);
|
|
506
|
+
endpointUrl.pathname = encodeURI(`${pathname}/message`);
|
|
507
|
+
endpointUrl.searchParams.set("sessionId", sessionId);
|
|
508
|
+
const relativeUrlWithSession = endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;
|
|
366
509
|
const endpointMessage = `event: endpoint
|
|
367
|
-
data: ${
|
|
510
|
+
data: ${relativeUrlWithSession}
|
|
368
511
|
|
|
369
512
|
`;
|
|
370
513
|
writer.write(encoder.encode(endpointMessage));
|
|
371
514
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
372
515
|
const doStub = namespace.get(id);
|
|
373
|
-
|
|
516
|
+
try {
|
|
517
|
+
await doStub._init(ctx.props);
|
|
518
|
+
} catch (error) {
|
|
519
|
+
console.error("Failed to initialize McpAgent:", error);
|
|
520
|
+
await writer.close();
|
|
521
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
522
|
+
return new Response(`Initialization failed: ${errorMessage}`, {
|
|
523
|
+
status: 500
|
|
524
|
+
});
|
|
525
|
+
}
|
|
374
526
|
const upgradeUrl = new URL(request.url);
|
|
375
527
|
upgradeUrl.pathname = "/sse";
|
|
528
|
+
const existingHeaders = {};
|
|
529
|
+
request.headers.forEach((value, key) => {
|
|
530
|
+
existingHeaders[key] = value;
|
|
531
|
+
});
|
|
376
532
|
const response = await doStub.fetch(
|
|
377
533
|
new Request(upgradeUrl, {
|
|
378
534
|
headers: {
|
|
535
|
+
...existingHeaders,
|
|
379
536
|
Upgrade: "websocket",
|
|
380
537
|
// Required by PartyServer
|
|
381
538
|
"x-partykit-room": sessionId
|
|
@@ -411,10 +568,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
411
568
|
onMessage(event).catch(console.error);
|
|
412
569
|
});
|
|
413
570
|
ws.addEventListener("error", (error) => {
|
|
414
|
-
async function onError(
|
|
571
|
+
async function onError(_error) {
|
|
415
572
|
try {
|
|
416
573
|
await writer.close();
|
|
417
|
-
} catch (
|
|
574
|
+
} catch (_e) {
|
|
418
575
|
}
|
|
419
576
|
}
|
|
420
577
|
onError(error).catch(console.error);
|
|
@@ -431,10 +588,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
431
588
|
});
|
|
432
589
|
return new Response(readable, {
|
|
433
590
|
headers: {
|
|
434
|
-
"Content-Type": "text/event-stream",
|
|
435
591
|
"Cache-Control": "no-cache",
|
|
436
592
|
Connection: "keep-alive",
|
|
437
|
-
"
|
|
593
|
+
"Content-Type": "text/event-stream",
|
|
594
|
+
...corsHeaders(request, corsOptions)
|
|
438
595
|
}
|
|
439
596
|
});
|
|
440
597
|
}
|
|
@@ -466,26 +623,28 @@ data: ${JSON.stringify(result.data)}
|
|
|
466
623
|
}
|
|
467
624
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
468
625
|
const doStub = namespace.get(id);
|
|
469
|
-
const
|
|
626
|
+
const messageBody = await request.json();
|
|
627
|
+
await doStub.updateProps(ctx.props);
|
|
628
|
+
const error = await doStub.onSSEMcpMessage(sessionId, messageBody);
|
|
470
629
|
if (error) {
|
|
471
630
|
return new Response(error.message, {
|
|
472
|
-
status: 400,
|
|
473
631
|
headers: {
|
|
474
|
-
"Content-Type": "text/event-stream",
|
|
475
632
|
"Cache-Control": "no-cache",
|
|
476
633
|
Connection: "keep-alive",
|
|
477
|
-
"
|
|
478
|
-
|
|
634
|
+
"Content-Type": "text/event-stream",
|
|
635
|
+
...corsHeaders(request, corsOptions)
|
|
636
|
+
},
|
|
637
|
+
status: 400
|
|
479
638
|
});
|
|
480
639
|
}
|
|
481
640
|
return new Response("Accepted", {
|
|
482
|
-
status: 202,
|
|
483
641
|
headers: {
|
|
484
|
-
"Content-Type": "text/event-stream",
|
|
485
642
|
"Cache-Control": "no-cache",
|
|
486
643
|
Connection: "keep-alive",
|
|
487
|
-
"
|
|
488
|
-
|
|
644
|
+
"Content-Type": "text/event-stream",
|
|
645
|
+
...corsHeaders(request, corsOptions)
|
|
646
|
+
},
|
|
647
|
+
status: 202
|
|
489
648
|
});
|
|
490
649
|
}
|
|
491
650
|
return new Response("Not Found", { status: 404 });
|
|
@@ -502,35 +661,45 @@ data: ${JSON.stringify(result.data)}
|
|
|
502
661
|
}
|
|
503
662
|
const basePattern = new URLPattern({ pathname });
|
|
504
663
|
return {
|
|
505
|
-
|
|
664
|
+
async fetch(request, env, ctx) {
|
|
506
665
|
const corsResponse = handleCORS(request, corsOptions);
|
|
507
666
|
if (corsResponse) {
|
|
508
667
|
return corsResponse;
|
|
509
668
|
}
|
|
510
669
|
const url = new URL(request.url);
|
|
511
|
-
const
|
|
670
|
+
const bindingValue = env[binding];
|
|
671
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
672
|
+
console.error(
|
|
673
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
674
|
+
);
|
|
675
|
+
return new Response("Invalid binding", { status: 500 });
|
|
676
|
+
}
|
|
677
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
678
|
+
return new Response("Invalid binding", { status: 500 });
|
|
679
|
+
}
|
|
680
|
+
const namespace = bindingValue;
|
|
512
681
|
if (request.method === "POST" && basePattern.test(url)) {
|
|
513
682
|
const acceptHeader = request.headers.get("accept");
|
|
514
683
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
515
684
|
const body2 = JSON.stringify({
|
|
516
|
-
jsonrpc: "2.0",
|
|
517
685
|
error: {
|
|
518
686
|
code: -32e3,
|
|
519
687
|
message: "Not Acceptable: Client must accept both application/json and text/event-stream"
|
|
520
688
|
},
|
|
521
|
-
id: null
|
|
689
|
+
id: null,
|
|
690
|
+
jsonrpc: "2.0"
|
|
522
691
|
});
|
|
523
692
|
return new Response(body2, { status: 406 });
|
|
524
693
|
}
|
|
525
694
|
const ct = request.headers.get("content-type");
|
|
526
695
|
if (!ct || !ct.includes("application/json")) {
|
|
527
696
|
const body2 = JSON.stringify({
|
|
528
|
-
jsonrpc: "2.0",
|
|
529
697
|
error: {
|
|
530
698
|
code: -32e3,
|
|
531
699
|
message: "Unsupported Media Type: Content-Type must be application/json"
|
|
532
700
|
},
|
|
533
|
-
id: null
|
|
701
|
+
id: null,
|
|
702
|
+
jsonrpc: "2.0"
|
|
534
703
|
});
|
|
535
704
|
return new Response(body2, { status: 415 });
|
|
536
705
|
}
|
|
@@ -540,12 +709,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
540
709
|
);
|
|
541
710
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
|
|
542
711
|
const body2 = JSON.stringify({
|
|
543
|
-
jsonrpc: "2.0",
|
|
544
712
|
error: {
|
|
545
713
|
code: -32e3,
|
|
546
714
|
message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
|
|
547
715
|
},
|
|
548
|
-
id: null
|
|
716
|
+
id: null,
|
|
717
|
+
jsonrpc: "2.0"
|
|
549
718
|
});
|
|
550
719
|
return new Response(body2, { status: 413 });
|
|
551
720
|
}
|
|
@@ -553,14 +722,14 @@ data: ${JSON.stringify(result.data)}
|
|
|
553
722
|
let rawMessage;
|
|
554
723
|
try {
|
|
555
724
|
rawMessage = await request.json();
|
|
556
|
-
} catch (
|
|
725
|
+
} catch (_error) {
|
|
557
726
|
const body2 = JSON.stringify({
|
|
558
|
-
jsonrpc: "2.0",
|
|
559
727
|
error: {
|
|
560
728
|
code: -32700,
|
|
561
729
|
message: "Parse error: Invalid JSON"
|
|
562
730
|
},
|
|
563
|
-
id: null
|
|
731
|
+
id: null,
|
|
732
|
+
jsonrpc: "2.0"
|
|
564
733
|
});
|
|
565
734
|
return new Response(body2, { status: 400 });
|
|
566
735
|
}
|
|
@@ -574,12 +743,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
574
743
|
for (const msg of arrayMessage) {
|
|
575
744
|
if (!JSONRPCMessageSchema.safeParse(msg).success) {
|
|
576
745
|
const body2 = JSON.stringify({
|
|
577
|
-
jsonrpc: "2.0",
|
|
578
746
|
error: {
|
|
579
747
|
code: -32700,
|
|
580
748
|
message: "Parse error: Invalid JSON-RPC message"
|
|
581
749
|
},
|
|
582
|
-
id: null
|
|
750
|
+
id: null,
|
|
751
|
+
jsonrpc: "2.0"
|
|
583
752
|
});
|
|
584
753
|
return new Response(body2, { status: 400 });
|
|
585
754
|
}
|
|
@@ -590,34 +759,34 @@ data: ${JSON.stringify(result.data)}
|
|
|
590
759
|
);
|
|
591
760
|
if (isInitializationRequest && sessionId) {
|
|
592
761
|
const body2 = JSON.stringify({
|
|
593
|
-
jsonrpc: "2.0",
|
|
594
762
|
error: {
|
|
595
763
|
code: -32600,
|
|
596
764
|
message: "Invalid Request: Initialization requests must not include a sessionId"
|
|
597
765
|
},
|
|
598
|
-
id: null
|
|
766
|
+
id: null,
|
|
767
|
+
jsonrpc: "2.0"
|
|
599
768
|
});
|
|
600
769
|
return new Response(body2, { status: 400 });
|
|
601
770
|
}
|
|
602
771
|
if (isInitializationRequest && messages.length > 1) {
|
|
603
772
|
const body2 = JSON.stringify({
|
|
604
|
-
jsonrpc: "2.0",
|
|
605
773
|
error: {
|
|
606
774
|
code: -32600,
|
|
607
775
|
message: "Invalid Request: Only one initialization request is allowed"
|
|
608
776
|
},
|
|
609
|
-
id: null
|
|
777
|
+
id: null,
|
|
778
|
+
jsonrpc: "2.0"
|
|
610
779
|
});
|
|
611
780
|
return new Response(body2, { status: 400 });
|
|
612
781
|
}
|
|
613
782
|
if (!isInitializationRequest && !sessionId) {
|
|
614
783
|
const body2 = JSON.stringify({
|
|
615
|
-
jsonrpc: "2.0",
|
|
616
784
|
error: {
|
|
617
785
|
code: -32e3,
|
|
618
786
|
message: "Bad Request: Mcp-Session-Id header is required"
|
|
619
787
|
},
|
|
620
|
-
id: null
|
|
788
|
+
id: null,
|
|
789
|
+
jsonrpc: "2.0"
|
|
621
790
|
});
|
|
622
791
|
return new Response(body2, { status: 400 });
|
|
623
792
|
}
|
|
@@ -626,26 +795,48 @@ data: ${JSON.stringify(result.data)}
|
|
|
626
795
|
const doStub = namespace.get(id);
|
|
627
796
|
const isInitialized = await doStub.isInitialized();
|
|
628
797
|
if (isInitializationRequest) {
|
|
629
|
-
|
|
798
|
+
try {
|
|
799
|
+
await doStub._init(ctx.props);
|
|
800
|
+
await doStub.setInitialized();
|
|
801
|
+
} catch (error) {
|
|
802
|
+
console.error("Failed to initialize McpAgent:", error);
|
|
803
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
804
|
+
const body2 = JSON.stringify({
|
|
805
|
+
error: {
|
|
806
|
+
code: -32001,
|
|
807
|
+
message: `Initialization failed: ${errorMessage}`
|
|
808
|
+
},
|
|
809
|
+
id: null,
|
|
810
|
+
jsonrpc: "2.0"
|
|
811
|
+
});
|
|
812
|
+
return new Response(body2, { status: 500 });
|
|
813
|
+
}
|
|
630
814
|
} else if (!isInitialized) {
|
|
631
815
|
const body2 = JSON.stringify({
|
|
632
|
-
jsonrpc: "2.0",
|
|
633
816
|
error: {
|
|
634
817
|
code: -32001,
|
|
635
818
|
message: "Session not found"
|
|
636
819
|
},
|
|
637
|
-
id: null
|
|
820
|
+
id: null,
|
|
821
|
+
jsonrpc: "2.0"
|
|
638
822
|
});
|
|
639
823
|
return new Response(body2, { status: 404 });
|
|
824
|
+
} else {
|
|
825
|
+
await doStub.updateProps(ctx.props);
|
|
640
826
|
}
|
|
641
827
|
const { readable, writable } = new TransformStream();
|
|
642
828
|
const writer = writable.getWriter();
|
|
643
829
|
const encoder = new TextEncoder();
|
|
644
830
|
const upgradeUrl = new URL(request.url);
|
|
645
831
|
upgradeUrl.pathname = "/streamable-http";
|
|
832
|
+
const existingHeaders = {};
|
|
833
|
+
request.headers.forEach((value, key) => {
|
|
834
|
+
existingHeaders[key] = value;
|
|
835
|
+
});
|
|
646
836
|
const response = await doStub.fetch(
|
|
647
837
|
new Request(upgradeUrl, {
|
|
648
838
|
headers: {
|
|
839
|
+
...existingHeaders,
|
|
649
840
|
Upgrade: "websocket",
|
|
650
841
|
// Required by PartyServer
|
|
651
842
|
"x-partykit-room": sessionId
|
|
@@ -657,12 +848,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
657
848
|
console.error("Failed to establish WebSocket connection");
|
|
658
849
|
await writer.close();
|
|
659
850
|
const body2 = JSON.stringify({
|
|
660
|
-
jsonrpc: "2.0",
|
|
661
851
|
error: {
|
|
662
852
|
code: -32001,
|
|
663
853
|
message: "Failed to establish WebSocket connection"
|
|
664
854
|
},
|
|
665
|
-
id: null
|
|
855
|
+
id: null,
|
|
856
|
+
jsonrpc: "2.0"
|
|
666
857
|
});
|
|
667
858
|
return new Response(body2, { status: 500 });
|
|
668
859
|
}
|
|
@@ -695,10 +886,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
695
886
|
onMessage(event).catch(console.error);
|
|
696
887
|
});
|
|
697
888
|
ws.addEventListener("error", (error) => {
|
|
698
|
-
async function onError(
|
|
889
|
+
async function onError(_error) {
|
|
699
890
|
try {
|
|
700
891
|
await writer.close();
|
|
701
|
-
} catch (
|
|
892
|
+
} catch (_e) {
|
|
702
893
|
}
|
|
703
894
|
}
|
|
704
895
|
onError(error).catch(console.error);
|
|
@@ -721,7 +912,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
721
912
|
ws.send(JSON.stringify(message));
|
|
722
913
|
}
|
|
723
914
|
ws.close();
|
|
724
|
-
return new Response(null, {
|
|
915
|
+
return new Response(null, {
|
|
916
|
+
headers: corsHeaders(request, corsOptions),
|
|
917
|
+
status: 202
|
|
918
|
+
});
|
|
725
919
|
}
|
|
726
920
|
for (const message of messages) {
|
|
727
921
|
if (isJSONRPCRequest(message)) {
|
|
@@ -731,43 +925,32 @@ data: ${JSON.stringify(result.data)}
|
|
|
731
925
|
}
|
|
732
926
|
return new Response(readable, {
|
|
733
927
|
headers: {
|
|
734
|
-
"Content-Type": "text/event-stream",
|
|
735
928
|
"Cache-Control": "no-cache",
|
|
736
929
|
Connection: "keep-alive",
|
|
930
|
+
"Content-Type": "text/event-stream",
|
|
737
931
|
"mcp-session-id": sessionId,
|
|
738
|
-
|
|
932
|
+
...corsHeaders(request, corsOptions)
|
|
739
933
|
},
|
|
740
934
|
status: 200
|
|
741
935
|
});
|
|
742
936
|
}
|
|
743
937
|
const body = JSON.stringify({
|
|
744
|
-
jsonrpc: "2.0",
|
|
745
938
|
error: {
|
|
746
939
|
code: -32e3,
|
|
747
940
|
message: "Method not allowed"
|
|
748
941
|
},
|
|
749
|
-
id: null
|
|
942
|
+
id: null,
|
|
943
|
+
jsonrpc: "2.0"
|
|
750
944
|
});
|
|
751
945
|
return new Response(body, { status: 405 });
|
|
752
946
|
}
|
|
753
947
|
};
|
|
754
948
|
}
|
|
755
949
|
};
|
|
756
|
-
_status = new WeakMap();
|
|
757
|
-
_transport = new WeakMap();
|
|
758
|
-
_transportType = new WeakMap();
|
|
759
|
-
_requestIdToConnectionId = new WeakMap();
|
|
760
|
-
_agent = new WeakMap();
|
|
761
|
-
_McpAgent_instances = new WeakSet();
|
|
762
|
-
initialize_fn = async function() {
|
|
763
|
-
await this.ctx.blockConcurrencyWhile(async () => {
|
|
764
|
-
__privateSet(this, _status, "starting");
|
|
765
|
-
await this.onStart();
|
|
766
|
-
__privateSet(this, _status, "started");
|
|
767
|
-
});
|
|
768
|
-
};
|
|
769
|
-
var McpAgent = _McpAgent;
|
|
770
950
|
export {
|
|
771
|
-
|
|
951
|
+
ElicitRequestSchema,
|
|
952
|
+
McpAgent,
|
|
953
|
+
SSEEdgeClientTransport,
|
|
954
|
+
StreamableHTTPEdgeClientTransport
|
|
772
955
|
};
|
|
773
956
|
//# sourceMappingURL=index.js.map
|