agents 0.0.0-671bdf7 → 0.0.0-696d33e
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 +166 -53
- 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-LL2AFX7V.js +109 -0
- package/dist/chunk-LL2AFX7V.js.map +1 -0
- package/dist/chunk-PNF6ZMUA.js +1296 -0
- package/dist/chunk-PNF6ZMUA.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 +4 -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 +61 -11
- package/dist/mcp/index.js +362 -184
- 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 -67
- package/src/index.ts +1178 -152
- 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-PNF6ZMUA.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
SSEEdgeClientTransport,
|
|
6
|
+
StreamableHTTPEdgeClientTransport
|
|
7
|
+
} from "../chunk-VYENMKFS.js";
|
|
8
|
+
import "../chunk-LL2AFX7V.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);
|
|
163
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);
|
|
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,32 +206,50 @@ 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
|
-
)
|
|
213
|
+
);
|
|
187
214
|
await this._init(this.props);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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.
|
|
241
|
+
await this.updateProps(props);
|
|
201
242
|
if (!this.ctx.storage.get("transportType")) {
|
|
202
243
|
await this.ctx.storage.put("transportType", "unset");
|
|
203
244
|
}
|
|
204
|
-
this.props = props;
|
|
205
245
|
if (!this.initRun) {
|
|
206
246
|
this.initRun = true;
|
|
207
|
-
|
|
247
|
+
try {
|
|
248
|
+
await this.init();
|
|
249
|
+
} catch (error) {
|
|
250
|
+
const errorResponse = this.onError(error);
|
|
251
|
+
throw new Error(`Initialization failed: ${errorResponse.message}`);
|
|
252
|
+
}
|
|
208
253
|
}
|
|
209
254
|
}
|
|
210
255
|
async setInitialized() {
|
|
@@ -213,10 +258,21 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
213
258
|
async isInitialized() {
|
|
214
259
|
return await this.ctx.storage.get("initialized") === true;
|
|
215
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
|
+
});
|
|
271
|
+
}
|
|
216
272
|
// Allow the worker to fetch a websocket connection to the agent
|
|
217
273
|
async fetch(request) {
|
|
218
|
-
if (
|
|
219
|
-
await
|
|
274
|
+
if (this._status !== "started") {
|
|
275
|
+
await this._initialize();
|
|
220
276
|
}
|
|
221
277
|
if (request.headers.get("Upgrade") !== "websocket") {
|
|
222
278
|
return new Response("Expected WebSocket Upgrade request", {
|
|
@@ -225,6 +281,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
225
281
|
}
|
|
226
282
|
const url = new URL(request.url);
|
|
227
283
|
const path = url.pathname;
|
|
284
|
+
const server = await this.server;
|
|
228
285
|
switch (path) {
|
|
229
286
|
case "/sse": {
|
|
230
287
|
const websockets = this.ctx.getWebSockets();
|
|
@@ -232,24 +289,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
232
289
|
return new Response("Websocket already connected", { status: 400 });
|
|
233
290
|
}
|
|
234
291
|
await this.ctx.storage.put("transportType", "sse");
|
|
235
|
-
|
|
236
|
-
if (!
|
|
237
|
-
|
|
238
|
-
await
|
|
292
|
+
this._transportType = "sse";
|
|
293
|
+
if (!this._transport) {
|
|
294
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
295
|
+
await server.connect(this._transport);
|
|
239
296
|
}
|
|
240
|
-
return
|
|
297
|
+
return this._agent.fetch(request);
|
|
241
298
|
}
|
|
242
299
|
case "/streamable-http": {
|
|
243
|
-
if (!
|
|
244
|
-
|
|
300
|
+
if (!this._transport) {
|
|
301
|
+
this._transport = new McpStreamableHttpTransport(
|
|
245
302
|
(id) => this.getWebSocketForResponseID(id),
|
|
246
|
-
(id) =>
|
|
247
|
-
)
|
|
248
|
-
await
|
|
303
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
304
|
+
);
|
|
305
|
+
await server.connect(this._transport);
|
|
249
306
|
}
|
|
250
307
|
await this.ctx.storage.put("transportType", "streamable-http");
|
|
251
|
-
|
|
252
|
-
return
|
|
308
|
+
this._transportType = "streamable-http";
|
|
309
|
+
return this._agent.fetch(request);
|
|
253
310
|
}
|
|
254
311
|
default:
|
|
255
312
|
return new Response(
|
|
@@ -268,19 +325,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
268
325
|
return websockets[0];
|
|
269
326
|
}
|
|
270
327
|
getWebSocketForResponseID(id) {
|
|
271
|
-
const connectionId =
|
|
328
|
+
const connectionId = this._requestIdToConnectionId.get(id);
|
|
272
329
|
if (connectionId === void 0) {
|
|
273
330
|
return null;
|
|
274
331
|
}
|
|
275
|
-
return
|
|
332
|
+
return this._agent.getConnection(connectionId) ?? null;
|
|
276
333
|
}
|
|
277
334
|
// All messages received here. This is currently never called
|
|
278
335
|
async onMessage(connection, event) {
|
|
279
|
-
if (
|
|
336
|
+
if (this._transportType !== "streamable-http") {
|
|
280
337
|
const err = new Error(
|
|
281
338
|
"Internal Server Error: Expected streamable-http protocol"
|
|
282
339
|
);
|
|
283
|
-
|
|
340
|
+
this._transport?.onerror?.(err);
|
|
284
341
|
return;
|
|
285
342
|
}
|
|
286
343
|
let message;
|
|
@@ -288,58 +345,125 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
288
345
|
const data = typeof event === "string" ? event : new TextDecoder().decode(event);
|
|
289
346
|
message = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
290
347
|
} catch (error) {
|
|
291
|
-
|
|
348
|
+
this._transport?.onerror?.(error);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (await this._handleElicitationResponse(message)) {
|
|
292
352
|
return;
|
|
293
353
|
}
|
|
294
354
|
if (isJSONRPCRequest(message)) {
|
|
295
|
-
|
|
355
|
+
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
356
|
+
}
|
|
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}`);
|
|
296
381
|
}
|
|
297
|
-
|
|
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;
|
|
298
419
|
}
|
|
299
420
|
// All messages received over SSE after the initial connection has been established
|
|
300
421
|
// will be passed here
|
|
301
|
-
async onSSEMcpMessage(
|
|
302
|
-
if (
|
|
303
|
-
await
|
|
422
|
+
async onSSEMcpMessage(_sessionId, messageBody) {
|
|
423
|
+
if (this._status !== "started") {
|
|
424
|
+
await this._initialize();
|
|
304
425
|
}
|
|
305
|
-
if (
|
|
426
|
+
if (this._transportType !== "sse") {
|
|
306
427
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
307
428
|
}
|
|
308
429
|
try {
|
|
309
|
-
const message = await request.json();
|
|
310
430
|
let parsedMessage;
|
|
311
431
|
try {
|
|
312
|
-
parsedMessage = JSONRPCMessageSchema.parse(
|
|
432
|
+
parsedMessage = JSONRPCMessageSchema.parse(messageBody);
|
|
313
433
|
} catch (error) {
|
|
314
|
-
|
|
434
|
+
this._transport?.onerror?.(error);
|
|
315
435
|
throw error;
|
|
316
436
|
}
|
|
317
|
-
|
|
437
|
+
if (await this._handleElicitationResponse(parsedMessage)) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
this._transport?.onmessage?.(parsedMessage);
|
|
318
441
|
return null;
|
|
319
442
|
} catch (error) {
|
|
320
|
-
|
|
443
|
+
console.error("Error forwarding message to SSE:", error);
|
|
444
|
+
this._transport?.onerror?.(error);
|
|
321
445
|
return error;
|
|
322
446
|
}
|
|
323
447
|
}
|
|
324
448
|
// Delegate all websocket events to the underlying agent
|
|
325
449
|
async webSocketMessage(ws, event) {
|
|
326
|
-
if (
|
|
327
|
-
await
|
|
450
|
+
if (this._status !== "started") {
|
|
451
|
+
await this._initialize();
|
|
328
452
|
}
|
|
329
|
-
return await
|
|
453
|
+
return await this._agent.webSocketMessage(ws, event);
|
|
330
454
|
}
|
|
331
455
|
// WebSocket event handlers for hibernation support
|
|
332
456
|
async webSocketError(ws, error) {
|
|
333
|
-
if (
|
|
334
|
-
await
|
|
457
|
+
if (this._status !== "started") {
|
|
458
|
+
await this._initialize();
|
|
335
459
|
}
|
|
336
|
-
return await
|
|
460
|
+
return await this._agent.webSocketError(ws, error);
|
|
337
461
|
}
|
|
338
462
|
async webSocketClose(ws, code, reason, wasClean) {
|
|
339
|
-
if (
|
|
340
|
-
await
|
|
463
|
+
if (this._status !== "started") {
|
|
464
|
+
await this._initialize();
|
|
341
465
|
}
|
|
342
|
-
return await
|
|
466
|
+
return await this._agent.webSocketClose(ws, code, reason, wasClean);
|
|
343
467
|
}
|
|
344
468
|
static mount(path, {
|
|
345
469
|
binding = "MCP_OBJECT",
|
|
@@ -358,29 +482,57 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
358
482
|
const basePattern = new URLPattern({ pathname });
|
|
359
483
|
const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
|
|
360
484
|
return {
|
|
361
|
-
|
|
485
|
+
async fetch(request, env, ctx) {
|
|
362
486
|
const corsResponse = handleCORS(request, corsOptions);
|
|
363
487
|
if (corsResponse) return corsResponse;
|
|
364
488
|
const url = new URL(request.url);
|
|
365
|
-
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;
|
|
366
500
|
if (request.method === "GET" && basePattern.test(url)) {
|
|
367
501
|
const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
|
|
368
502
|
const { readable, writable } = new TransformStream();
|
|
369
503
|
const writer = writable.getWriter();
|
|
370
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;
|
|
371
509
|
const endpointMessage = `event: endpoint
|
|
372
|
-
data: ${
|
|
510
|
+
data: ${relativeUrlWithSession}
|
|
373
511
|
|
|
374
512
|
`;
|
|
375
513
|
writer.write(encoder.encode(endpointMessage));
|
|
376
514
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
377
515
|
const doStub = namespace.get(id);
|
|
378
|
-
|
|
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
|
+
}
|
|
379
526
|
const upgradeUrl = new URL(request.url);
|
|
380
527
|
upgradeUrl.pathname = "/sse";
|
|
528
|
+
const existingHeaders = {};
|
|
529
|
+
request.headers.forEach((value, key) => {
|
|
530
|
+
existingHeaders[key] = value;
|
|
531
|
+
});
|
|
381
532
|
const response = await doStub.fetch(
|
|
382
533
|
new Request(upgradeUrl, {
|
|
383
534
|
headers: {
|
|
535
|
+
...existingHeaders,
|
|
384
536
|
Upgrade: "websocket",
|
|
385
537
|
// Required by PartyServer
|
|
386
538
|
"x-partykit-room": sessionId
|
|
@@ -416,10 +568,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
416
568
|
onMessage(event).catch(console.error);
|
|
417
569
|
});
|
|
418
570
|
ws.addEventListener("error", (error) => {
|
|
419
|
-
async function onError(
|
|
571
|
+
async function onError(_error) {
|
|
420
572
|
try {
|
|
421
573
|
await writer.close();
|
|
422
|
-
} catch (
|
|
574
|
+
} catch (_e) {
|
|
423
575
|
}
|
|
424
576
|
}
|
|
425
577
|
onError(error).catch(console.error);
|
|
@@ -436,10 +588,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
436
588
|
});
|
|
437
589
|
return new Response(readable, {
|
|
438
590
|
headers: {
|
|
439
|
-
"Content-Type": "text/event-stream",
|
|
440
591
|
"Cache-Control": "no-cache",
|
|
441
592
|
Connection: "keep-alive",
|
|
442
|
-
"
|
|
593
|
+
"Content-Type": "text/event-stream",
|
|
594
|
+
...corsHeaders(request, corsOptions)
|
|
443
595
|
}
|
|
444
596
|
});
|
|
445
597
|
}
|
|
@@ -471,26 +623,28 @@ data: ${JSON.stringify(result.data)}
|
|
|
471
623
|
}
|
|
472
624
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
473
625
|
const doStub = namespace.get(id);
|
|
474
|
-
const
|
|
626
|
+
const messageBody = await request.json();
|
|
627
|
+
await doStub.updateProps(ctx.props);
|
|
628
|
+
const error = await doStub.onSSEMcpMessage(sessionId, messageBody);
|
|
475
629
|
if (error) {
|
|
476
630
|
return new Response(error.message, {
|
|
477
|
-
status: 400,
|
|
478
631
|
headers: {
|
|
479
|
-
"Content-Type": "text/event-stream",
|
|
480
632
|
"Cache-Control": "no-cache",
|
|
481
633
|
Connection: "keep-alive",
|
|
482
|
-
"
|
|
483
|
-
|
|
634
|
+
"Content-Type": "text/event-stream",
|
|
635
|
+
...corsHeaders(request, corsOptions)
|
|
636
|
+
},
|
|
637
|
+
status: 400
|
|
484
638
|
});
|
|
485
639
|
}
|
|
486
640
|
return new Response("Accepted", {
|
|
487
|
-
status: 202,
|
|
488
641
|
headers: {
|
|
489
|
-
"Content-Type": "text/event-stream",
|
|
490
642
|
"Cache-Control": "no-cache",
|
|
491
643
|
Connection: "keep-alive",
|
|
492
|
-
"
|
|
493
|
-
|
|
644
|
+
"Content-Type": "text/event-stream",
|
|
645
|
+
...corsHeaders(request, corsOptions)
|
|
646
|
+
},
|
|
647
|
+
status: 202
|
|
494
648
|
});
|
|
495
649
|
}
|
|
496
650
|
return new Response("Not Found", { status: 404 });
|
|
@@ -507,35 +661,45 @@ data: ${JSON.stringify(result.data)}
|
|
|
507
661
|
}
|
|
508
662
|
const basePattern = new URLPattern({ pathname });
|
|
509
663
|
return {
|
|
510
|
-
|
|
664
|
+
async fetch(request, env, ctx) {
|
|
511
665
|
const corsResponse = handleCORS(request, corsOptions);
|
|
512
666
|
if (corsResponse) {
|
|
513
667
|
return corsResponse;
|
|
514
668
|
}
|
|
515
669
|
const url = new URL(request.url);
|
|
516
|
-
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;
|
|
517
681
|
if (request.method === "POST" && basePattern.test(url)) {
|
|
518
682
|
const acceptHeader = request.headers.get("accept");
|
|
519
683
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
520
684
|
const body2 = JSON.stringify({
|
|
521
|
-
jsonrpc: "2.0",
|
|
522
685
|
error: {
|
|
523
686
|
code: -32e3,
|
|
524
687
|
message: "Not Acceptable: Client must accept both application/json and text/event-stream"
|
|
525
688
|
},
|
|
526
|
-
id: null
|
|
689
|
+
id: null,
|
|
690
|
+
jsonrpc: "2.0"
|
|
527
691
|
});
|
|
528
692
|
return new Response(body2, { status: 406 });
|
|
529
693
|
}
|
|
530
694
|
const ct = request.headers.get("content-type");
|
|
531
695
|
if (!ct || !ct.includes("application/json")) {
|
|
532
696
|
const body2 = JSON.stringify({
|
|
533
|
-
jsonrpc: "2.0",
|
|
534
697
|
error: {
|
|
535
698
|
code: -32e3,
|
|
536
699
|
message: "Unsupported Media Type: Content-Type must be application/json"
|
|
537
700
|
},
|
|
538
|
-
id: null
|
|
701
|
+
id: null,
|
|
702
|
+
jsonrpc: "2.0"
|
|
539
703
|
});
|
|
540
704
|
return new Response(body2, { status: 415 });
|
|
541
705
|
}
|
|
@@ -545,12 +709,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
545
709
|
);
|
|
546
710
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
|
|
547
711
|
const body2 = JSON.stringify({
|
|
548
|
-
jsonrpc: "2.0",
|
|
549
712
|
error: {
|
|
550
713
|
code: -32e3,
|
|
551
714
|
message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
|
|
552
715
|
},
|
|
553
|
-
id: null
|
|
716
|
+
id: null,
|
|
717
|
+
jsonrpc: "2.0"
|
|
554
718
|
});
|
|
555
719
|
return new Response(body2, { status: 413 });
|
|
556
720
|
}
|
|
@@ -558,14 +722,14 @@ data: ${JSON.stringify(result.data)}
|
|
|
558
722
|
let rawMessage;
|
|
559
723
|
try {
|
|
560
724
|
rawMessage = await request.json();
|
|
561
|
-
} catch (
|
|
725
|
+
} catch (_error) {
|
|
562
726
|
const body2 = JSON.stringify({
|
|
563
|
-
jsonrpc: "2.0",
|
|
564
727
|
error: {
|
|
565
728
|
code: -32700,
|
|
566
729
|
message: "Parse error: Invalid JSON"
|
|
567
730
|
},
|
|
568
|
-
id: null
|
|
731
|
+
id: null,
|
|
732
|
+
jsonrpc: "2.0"
|
|
569
733
|
});
|
|
570
734
|
return new Response(body2, { status: 400 });
|
|
571
735
|
}
|
|
@@ -579,12 +743,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
579
743
|
for (const msg of arrayMessage) {
|
|
580
744
|
if (!JSONRPCMessageSchema.safeParse(msg).success) {
|
|
581
745
|
const body2 = JSON.stringify({
|
|
582
|
-
jsonrpc: "2.0",
|
|
583
746
|
error: {
|
|
584
747
|
code: -32700,
|
|
585
748
|
message: "Parse error: Invalid JSON-RPC message"
|
|
586
749
|
},
|
|
587
|
-
id: null
|
|
750
|
+
id: null,
|
|
751
|
+
jsonrpc: "2.0"
|
|
588
752
|
});
|
|
589
753
|
return new Response(body2, { status: 400 });
|
|
590
754
|
}
|
|
@@ -595,34 +759,34 @@ data: ${JSON.stringify(result.data)}
|
|
|
595
759
|
);
|
|
596
760
|
if (isInitializationRequest && sessionId) {
|
|
597
761
|
const body2 = JSON.stringify({
|
|
598
|
-
jsonrpc: "2.0",
|
|
599
762
|
error: {
|
|
600
763
|
code: -32600,
|
|
601
764
|
message: "Invalid Request: Initialization requests must not include a sessionId"
|
|
602
765
|
},
|
|
603
|
-
id: null
|
|
766
|
+
id: null,
|
|
767
|
+
jsonrpc: "2.0"
|
|
604
768
|
});
|
|
605
769
|
return new Response(body2, { status: 400 });
|
|
606
770
|
}
|
|
607
771
|
if (isInitializationRequest && messages.length > 1) {
|
|
608
772
|
const body2 = JSON.stringify({
|
|
609
|
-
jsonrpc: "2.0",
|
|
610
773
|
error: {
|
|
611
774
|
code: -32600,
|
|
612
775
|
message: "Invalid Request: Only one initialization request is allowed"
|
|
613
776
|
},
|
|
614
|
-
id: null
|
|
777
|
+
id: null,
|
|
778
|
+
jsonrpc: "2.0"
|
|
615
779
|
});
|
|
616
780
|
return new Response(body2, { status: 400 });
|
|
617
781
|
}
|
|
618
782
|
if (!isInitializationRequest && !sessionId) {
|
|
619
783
|
const body2 = JSON.stringify({
|
|
620
|
-
jsonrpc: "2.0",
|
|
621
784
|
error: {
|
|
622
785
|
code: -32e3,
|
|
623
786
|
message: "Bad Request: Mcp-Session-Id header is required"
|
|
624
787
|
},
|
|
625
|
-
id: null
|
|
788
|
+
id: null,
|
|
789
|
+
jsonrpc: "2.0"
|
|
626
790
|
});
|
|
627
791
|
return new Response(body2, { status: 400 });
|
|
628
792
|
}
|
|
@@ -631,26 +795,48 @@ data: ${JSON.stringify(result.data)}
|
|
|
631
795
|
const doStub = namespace.get(id);
|
|
632
796
|
const isInitialized = await doStub.isInitialized();
|
|
633
797
|
if (isInitializationRequest) {
|
|
634
|
-
|
|
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
|
+
}
|
|
635
814
|
} else if (!isInitialized) {
|
|
636
815
|
const body2 = JSON.stringify({
|
|
637
|
-
jsonrpc: "2.0",
|
|
638
816
|
error: {
|
|
639
817
|
code: -32001,
|
|
640
818
|
message: "Session not found"
|
|
641
819
|
},
|
|
642
|
-
id: null
|
|
820
|
+
id: null,
|
|
821
|
+
jsonrpc: "2.0"
|
|
643
822
|
});
|
|
644
823
|
return new Response(body2, { status: 404 });
|
|
824
|
+
} else {
|
|
825
|
+
await doStub.updateProps(ctx.props);
|
|
645
826
|
}
|
|
646
827
|
const { readable, writable } = new TransformStream();
|
|
647
828
|
const writer = writable.getWriter();
|
|
648
829
|
const encoder = new TextEncoder();
|
|
649
830
|
const upgradeUrl = new URL(request.url);
|
|
650
831
|
upgradeUrl.pathname = "/streamable-http";
|
|
832
|
+
const existingHeaders = {};
|
|
833
|
+
request.headers.forEach((value, key) => {
|
|
834
|
+
existingHeaders[key] = value;
|
|
835
|
+
});
|
|
651
836
|
const response = await doStub.fetch(
|
|
652
837
|
new Request(upgradeUrl, {
|
|
653
838
|
headers: {
|
|
839
|
+
...existingHeaders,
|
|
654
840
|
Upgrade: "websocket",
|
|
655
841
|
// Required by PartyServer
|
|
656
842
|
"x-partykit-room": sessionId
|
|
@@ -662,12 +848,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
662
848
|
console.error("Failed to establish WebSocket connection");
|
|
663
849
|
await writer.close();
|
|
664
850
|
const body2 = JSON.stringify({
|
|
665
|
-
jsonrpc: "2.0",
|
|
666
851
|
error: {
|
|
667
852
|
code: -32001,
|
|
668
853
|
message: "Failed to establish WebSocket connection"
|
|
669
854
|
},
|
|
670
|
-
id: null
|
|
855
|
+
id: null,
|
|
856
|
+
jsonrpc: "2.0"
|
|
671
857
|
});
|
|
672
858
|
return new Response(body2, { status: 500 });
|
|
673
859
|
}
|
|
@@ -700,10 +886,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
700
886
|
onMessage(event).catch(console.error);
|
|
701
887
|
});
|
|
702
888
|
ws.addEventListener("error", (error) => {
|
|
703
|
-
async function onError(
|
|
889
|
+
async function onError(_error) {
|
|
704
890
|
try {
|
|
705
891
|
await writer.close();
|
|
706
|
-
} catch (
|
|
892
|
+
} catch (_e) {
|
|
707
893
|
}
|
|
708
894
|
}
|
|
709
895
|
onError(error).catch(console.error);
|
|
@@ -726,7 +912,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
726
912
|
ws.send(JSON.stringify(message));
|
|
727
913
|
}
|
|
728
914
|
ws.close();
|
|
729
|
-
return new Response(null, {
|
|
915
|
+
return new Response(null, {
|
|
916
|
+
headers: corsHeaders(request, corsOptions),
|
|
917
|
+
status: 202
|
|
918
|
+
});
|
|
730
919
|
}
|
|
731
920
|
for (const message of messages) {
|
|
732
921
|
if (isJSONRPCRequest(message)) {
|
|
@@ -736,43 +925,32 @@ data: ${JSON.stringify(result.data)}
|
|
|
736
925
|
}
|
|
737
926
|
return new Response(readable, {
|
|
738
927
|
headers: {
|
|
739
|
-
"Content-Type": "text/event-stream",
|
|
740
928
|
"Cache-Control": "no-cache",
|
|
741
929
|
Connection: "keep-alive",
|
|
930
|
+
"Content-Type": "text/event-stream",
|
|
742
931
|
"mcp-session-id": sessionId,
|
|
743
|
-
|
|
932
|
+
...corsHeaders(request, corsOptions)
|
|
744
933
|
},
|
|
745
934
|
status: 200
|
|
746
935
|
});
|
|
747
936
|
}
|
|
748
937
|
const body = JSON.stringify({
|
|
749
|
-
jsonrpc: "2.0",
|
|
750
938
|
error: {
|
|
751
939
|
code: -32e3,
|
|
752
940
|
message: "Method not allowed"
|
|
753
941
|
},
|
|
754
|
-
id: null
|
|
942
|
+
id: null,
|
|
943
|
+
jsonrpc: "2.0"
|
|
755
944
|
});
|
|
756
945
|
return new Response(body, { status: 405 });
|
|
757
946
|
}
|
|
758
947
|
};
|
|
759
948
|
}
|
|
760
949
|
};
|
|
761
|
-
_status = new WeakMap();
|
|
762
|
-
_transport = new WeakMap();
|
|
763
|
-
_transportType = new WeakMap();
|
|
764
|
-
_requestIdToConnectionId = new WeakMap();
|
|
765
|
-
_agent = new WeakMap();
|
|
766
|
-
_McpAgent_instances = new WeakSet();
|
|
767
|
-
initialize_fn = async function() {
|
|
768
|
-
await this.ctx.blockConcurrencyWhile(async () => {
|
|
769
|
-
__privateSet(this, _status, "starting");
|
|
770
|
-
await this.onStart();
|
|
771
|
-
__privateSet(this, _status, "started");
|
|
772
|
-
});
|
|
773
|
-
};
|
|
774
|
-
var McpAgent = _McpAgent;
|
|
775
950
|
export {
|
|
776
|
-
|
|
951
|
+
ElicitRequestSchema,
|
|
952
|
+
McpAgent,
|
|
953
|
+
SSEEdgeClientTransport,
|
|
954
|
+
StreamableHTTPEdgeClientTransport
|
|
777
955
|
};
|
|
778
956
|
//# sourceMappingURL=index.js.map
|