agents 0.0.0-90db5ba → 0.0.0-93ccdbd
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 +45 -3
- package/dist/ai-chat-agent.js +117 -55
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +12 -0
- package/dist/ai-react.js +24 -13
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +5 -0
- package/dist/chunk-BZXOAZUX.js +106 -0
- package/dist/chunk-BZXOAZUX.js.map +1 -0
- package/dist/{chunk-XG52S6YY.js → chunk-J6T74FUS.js} +325 -133
- package/dist/chunk-J6T74FUS.js.map +1 -0
- package/dist/chunk-QSGN3REV.js +123 -0
- package/dist/chunk-QSGN3REV.js.map +1 -0
- package/dist/chunk-Y67CHZBI.js +464 -0
- package/dist/chunk-Y67CHZBI.js.map +1 -0
- package/dist/client.d.ts +9 -1
- package/dist/client.js +6 -126
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +120 -11
- package/dist/index.js +8 -6
- package/dist/mcp/client.d.ts +33 -13
- 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 +30 -6
- package/dist/mcp/index.js +206 -182
- package/dist/mcp/index.js.map +1 -1
- package/dist/react.d.ts +71 -0
- package/dist/react.js +14 -2
- package/dist/react.js.map +1 -1
- package/dist/schedule.js +0 -2
- package/dist/schedule.js.map +1 -1
- package/package.json +21 -6
- package/src/index.ts +389 -51
- package/dist/chunk-HMLY7DHA.js +0 -16
- package/dist/chunk-HMLY7DHA.js.map +0 -1
- package/dist/chunk-XG52S6YY.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
__privateMethod,
|
|
8
|
-
__privateSet
|
|
9
|
-
} from "../chunk-HMLY7DHA.js";
|
|
3
|
+
} from "../chunk-J6T74FUS.js";
|
|
4
|
+
import "../chunk-BZXOAZUX.js";
|
|
5
|
+
import "../chunk-QSGN3REV.js";
|
|
6
|
+
import "../chunk-Y67CHZBI.js";
|
|
10
7
|
|
|
11
8
|
// src/mcp/index.ts
|
|
12
9
|
import { DurableObject } from "cloudflare:workers";
|
|
@@ -19,37 +16,38 @@ import {
|
|
|
19
16
|
JSONRPCMessageSchema
|
|
20
17
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
21
18
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
22
|
-
function
|
|
23
|
-
const origin =
|
|
24
|
-
|
|
25
|
-
"Access-Control-Allow-Origin": corsOptions
|
|
26
|
-
"Access-Control-Allow-Methods": corsOptions
|
|
27
|
-
"Access-Control-Allow-Headers": corsOptions
|
|
28
|
-
"Access-Control-Max-Age": (corsOptions
|
|
19
|
+
function corsHeaders(request, corsOptions = {}) {
|
|
20
|
+
const origin = "*";
|
|
21
|
+
return {
|
|
22
|
+
"Access-Control-Allow-Origin": corsOptions.origin || origin,
|
|
23
|
+
"Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
|
|
24
|
+
"Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id",
|
|
25
|
+
"Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString(),
|
|
26
|
+
"Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id"
|
|
29
27
|
};
|
|
28
|
+
}
|
|
29
|
+
function handleCORS(request, corsOptions) {
|
|
30
30
|
if (request.method === "OPTIONS") {
|
|
31
|
-
return new Response(null, { headers: corsHeaders });
|
|
31
|
+
return new Response(null, { headers: corsHeaders(request, corsOptions) });
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
-
var _getWebSocket, _started;
|
|
36
35
|
var McpSSETransport = class {
|
|
37
36
|
constructor(getWebSocket) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
__privateSet(this, _getWebSocket, getWebSocket);
|
|
37
|
+
this._started = false;
|
|
38
|
+
this._getWebSocket = getWebSocket;
|
|
41
39
|
}
|
|
42
40
|
async start() {
|
|
43
|
-
if (
|
|
41
|
+
if (this._started) {
|
|
44
42
|
throw new Error("Transport already started");
|
|
45
43
|
}
|
|
46
|
-
|
|
44
|
+
this._started = true;
|
|
47
45
|
}
|
|
48
46
|
async send(message) {
|
|
49
|
-
if (!
|
|
47
|
+
if (!this._started) {
|
|
50
48
|
throw new Error("Transport not started");
|
|
51
49
|
}
|
|
52
|
-
const websocket =
|
|
50
|
+
const websocket = this._getWebSocket();
|
|
53
51
|
if (!websocket) {
|
|
54
52
|
throw new Error("WebSocket not connected");
|
|
55
53
|
}
|
|
@@ -64,52 +62,40 @@ var McpSSETransport = class {
|
|
|
64
62
|
this.onclose?.();
|
|
65
63
|
}
|
|
66
64
|
};
|
|
67
|
-
_getWebSocket = new WeakMap();
|
|
68
|
-
_started = new WeakMap();
|
|
69
|
-
var _getWebSocketForGetRequest, _getWebSocketForMessageID, _notifyResponseIdSent, _started2;
|
|
70
65
|
var McpStreamableHttpTransport = class {
|
|
71
66
|
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);
|
|
67
|
+
this._started = false;
|
|
68
|
+
this._getWebSocketForMessageID = getWebSocketForMessageID;
|
|
69
|
+
this._notifyResponseIdSent = notifyResponseIdSent;
|
|
70
|
+
this._getWebSocketForGetRequest = () => null;
|
|
85
71
|
}
|
|
86
72
|
async start() {
|
|
87
|
-
if (
|
|
73
|
+
if (this._started) {
|
|
88
74
|
throw new Error("Transport already started");
|
|
89
75
|
}
|
|
90
|
-
|
|
76
|
+
this._started = true;
|
|
91
77
|
}
|
|
92
78
|
async send(message) {
|
|
93
|
-
if (!
|
|
79
|
+
if (!this._started) {
|
|
94
80
|
throw new Error("Transport not started");
|
|
95
81
|
}
|
|
96
82
|
let websocket = null;
|
|
97
83
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
|
|
98
|
-
websocket =
|
|
84
|
+
websocket = this._getWebSocketForMessageID(message.id.toString());
|
|
99
85
|
if (!websocket) {
|
|
100
86
|
throw new Error(
|
|
101
87
|
`Could not find WebSocket for message id: ${message.id}`
|
|
102
88
|
);
|
|
103
89
|
}
|
|
104
90
|
} else if (isJSONRPCRequest(message)) {
|
|
105
|
-
websocket =
|
|
91
|
+
websocket = this._getWebSocketForGetRequest();
|
|
106
92
|
} else if (isJSONRPCNotification(message)) {
|
|
107
93
|
websocket = null;
|
|
108
94
|
}
|
|
109
95
|
try {
|
|
110
96
|
websocket?.send(JSON.stringify(message));
|
|
111
97
|
if (isJSONRPCResponse(message)) {
|
|
112
|
-
|
|
98
|
+
this._notifyResponseIdSent(message.id.toString());
|
|
113
99
|
}
|
|
114
100
|
} catch (error) {
|
|
115
101
|
this.onerror?.(error);
|
|
@@ -120,28 +106,16 @@ var McpStreamableHttpTransport = class {
|
|
|
120
106
|
this.onclose?.();
|
|
121
107
|
}
|
|
122
108
|
};
|
|
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 {
|
|
109
|
+
var McpAgent = class _McpAgent extends DurableObject {
|
|
129
110
|
constructor(ctx, env) {
|
|
130
111
|
var _a;
|
|
131
112
|
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);
|
|
113
|
+
this._status = "zero";
|
|
114
|
+
this._transportType = "unset";
|
|
115
|
+
this._requestIdToConnectionId = /* @__PURE__ */ new Map();
|
|
142
116
|
this.initRun = false;
|
|
143
117
|
const self = this;
|
|
144
|
-
|
|
118
|
+
this._agent = new (_a = class extends Agent {
|
|
145
119
|
onStateUpdate(state, source) {
|
|
146
120
|
return self.onStateUpdate(state, source);
|
|
147
121
|
}
|
|
@@ -150,23 +124,26 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
150
124
|
}
|
|
151
125
|
}, _a.options = {
|
|
152
126
|
hibernate: true
|
|
153
|
-
}, _a)(ctx, env)
|
|
127
|
+
}, _a)(ctx, env);
|
|
128
|
+
}
|
|
129
|
+
get mcp() {
|
|
130
|
+
return this._agent.mcp;
|
|
154
131
|
}
|
|
155
132
|
get state() {
|
|
156
|
-
return
|
|
133
|
+
return this._agent.state;
|
|
157
134
|
}
|
|
158
135
|
sql(strings, ...values) {
|
|
159
|
-
return
|
|
136
|
+
return this._agent.sql(strings, ...values);
|
|
160
137
|
}
|
|
161
138
|
setState(state) {
|
|
162
|
-
return
|
|
139
|
+
return this._agent.setState(state);
|
|
163
140
|
}
|
|
164
141
|
onStateUpdate(state, source) {
|
|
165
142
|
}
|
|
166
143
|
async onStart() {
|
|
167
144
|
var _a;
|
|
168
145
|
const self = this;
|
|
169
|
-
|
|
146
|
+
this._agent = new (_a = class extends Agent {
|
|
170
147
|
constructor() {
|
|
171
148
|
super(...arguments);
|
|
172
149
|
this.initialState = self.initialState;
|
|
@@ -179,39 +156,52 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
179
156
|
}
|
|
180
157
|
}, _a.options = {
|
|
181
158
|
hibernate: true
|
|
182
|
-
}, _a)(this.ctx, this.env)
|
|
159
|
+
}, _a)(this.ctx, this.env);
|
|
183
160
|
this.props = await this.ctx.storage.get("props");
|
|
184
|
-
|
|
161
|
+
this._transportType = await this.ctx.storage.get(
|
|
185
162
|
"transportType"
|
|
186
|
-
)
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
163
|
+
);
|
|
164
|
+
await this._init(this.props);
|
|
165
|
+
const server = await this.server;
|
|
166
|
+
if (this._transportType === "sse") {
|
|
167
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
168
|
+
await server.connect(this._transport);
|
|
169
|
+
} else if (this._transportType === "streamable-http") {
|
|
170
|
+
this._transport = new McpStreamableHttpTransport(
|
|
193
171
|
(id) => this.getWebSocketForResponseID(id),
|
|
194
|
-
(id) =>
|
|
195
|
-
)
|
|
196
|
-
await
|
|
172
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
173
|
+
);
|
|
174
|
+
await server.connect(this._transport);
|
|
197
175
|
}
|
|
198
176
|
}
|
|
199
177
|
async _init(props) {
|
|
200
178
|
await this.ctx.storage.put("props", props ?? {});
|
|
201
|
-
|
|
179
|
+
if (!this.ctx.storage.get("transportType")) {
|
|
180
|
+
await this.ctx.storage.put("transportType", "unset");
|
|
181
|
+
}
|
|
202
182
|
this.props = props;
|
|
203
183
|
if (!this.initRun) {
|
|
204
184
|
this.initRun = true;
|
|
205
185
|
await this.init();
|
|
206
186
|
}
|
|
207
187
|
}
|
|
208
|
-
|
|
209
|
-
|
|
188
|
+
async setInitialized() {
|
|
189
|
+
await this.ctx.storage.put("initialized", true);
|
|
190
|
+
}
|
|
191
|
+
async isInitialized() {
|
|
192
|
+
return await this.ctx.storage.get("initialized") === true;
|
|
193
|
+
}
|
|
194
|
+
async _initialize() {
|
|
195
|
+
await this.ctx.blockConcurrencyWhile(async () => {
|
|
196
|
+
this._status = "starting";
|
|
197
|
+
await this.onStart();
|
|
198
|
+
this._status = "started";
|
|
199
|
+
});
|
|
210
200
|
}
|
|
211
201
|
// Allow the worker to fetch a websocket connection to the agent
|
|
212
202
|
async fetch(request) {
|
|
213
|
-
if (
|
|
214
|
-
await
|
|
203
|
+
if (this._status !== "started") {
|
|
204
|
+
await this._initialize();
|
|
215
205
|
}
|
|
216
206
|
if (request.headers.get("Upgrade") !== "websocket") {
|
|
217
207
|
return new Response("Expected WebSocket Upgrade request", {
|
|
@@ -220,6 +210,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
220
210
|
}
|
|
221
211
|
const url = new URL(request.url);
|
|
222
212
|
const path = url.pathname;
|
|
213
|
+
const server = await this.server;
|
|
223
214
|
switch (path) {
|
|
224
215
|
case "/sse": {
|
|
225
216
|
const websockets = this.ctx.getWebSockets();
|
|
@@ -227,24 +218,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
227
218
|
return new Response("Websocket already connected", { status: 400 });
|
|
228
219
|
}
|
|
229
220
|
await this.ctx.storage.put("transportType", "sse");
|
|
230
|
-
|
|
231
|
-
if (!
|
|
232
|
-
|
|
233
|
-
await
|
|
221
|
+
this._transportType = "sse";
|
|
222
|
+
if (!this._transport) {
|
|
223
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
224
|
+
await server.connect(this._transport);
|
|
234
225
|
}
|
|
235
|
-
return
|
|
226
|
+
return this._agent.fetch(request);
|
|
236
227
|
}
|
|
237
228
|
case "/streamable-http": {
|
|
238
|
-
if (!
|
|
239
|
-
|
|
229
|
+
if (!this._transport) {
|
|
230
|
+
this._transport = new McpStreamableHttpTransport(
|
|
240
231
|
(id) => this.getWebSocketForResponseID(id),
|
|
241
|
-
(id) =>
|
|
242
|
-
)
|
|
243
|
-
await
|
|
232
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
233
|
+
);
|
|
234
|
+
await server.connect(this._transport);
|
|
244
235
|
}
|
|
245
236
|
await this.ctx.storage.put("transportType", "streamable-http");
|
|
246
|
-
|
|
247
|
-
return
|
|
237
|
+
this._transportType = "streamable-http";
|
|
238
|
+
return this._agent.fetch(request);
|
|
248
239
|
}
|
|
249
240
|
default:
|
|
250
241
|
return new Response(
|
|
@@ -263,19 +254,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
263
254
|
return websockets[0];
|
|
264
255
|
}
|
|
265
256
|
getWebSocketForResponseID(id) {
|
|
266
|
-
const connectionId =
|
|
257
|
+
const connectionId = this._requestIdToConnectionId.get(id);
|
|
267
258
|
if (connectionId === void 0) {
|
|
268
259
|
return null;
|
|
269
260
|
}
|
|
270
|
-
return
|
|
261
|
+
return this._agent.getConnection(connectionId) ?? null;
|
|
271
262
|
}
|
|
272
263
|
// All messages received here. This is currently never called
|
|
273
264
|
async onMessage(connection, event) {
|
|
274
|
-
if (
|
|
265
|
+
if (this._transportType !== "streamable-http") {
|
|
275
266
|
const err = new Error(
|
|
276
267
|
"Internal Server Error: Expected streamable-http protocol"
|
|
277
268
|
);
|
|
278
|
-
|
|
269
|
+
this._transport?.onerror?.(err);
|
|
279
270
|
return;
|
|
280
271
|
}
|
|
281
272
|
let message;
|
|
@@ -283,21 +274,21 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
283
274
|
const data = typeof event === "string" ? event : new TextDecoder().decode(event);
|
|
284
275
|
message = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
285
276
|
} catch (error) {
|
|
286
|
-
|
|
277
|
+
this._transport?.onerror?.(error);
|
|
287
278
|
return;
|
|
288
279
|
}
|
|
289
280
|
if (isJSONRPCRequest(message)) {
|
|
290
|
-
|
|
281
|
+
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
291
282
|
}
|
|
292
|
-
|
|
283
|
+
this._transport?.onmessage?.(message);
|
|
293
284
|
}
|
|
294
285
|
// All messages received over SSE after the initial connection has been established
|
|
295
286
|
// will be passed here
|
|
296
287
|
async onSSEMcpMessage(sessionId, request) {
|
|
297
|
-
if (
|
|
298
|
-
await
|
|
288
|
+
if (this._status !== "started") {
|
|
289
|
+
await this._initialize();
|
|
299
290
|
}
|
|
300
|
-
if (
|
|
291
|
+
if (this._transportType !== "sse") {
|
|
301
292
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
302
293
|
}
|
|
303
294
|
try {
|
|
@@ -306,35 +297,36 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
306
297
|
try {
|
|
307
298
|
parsedMessage = JSONRPCMessageSchema.parse(message);
|
|
308
299
|
} catch (error) {
|
|
309
|
-
|
|
300
|
+
this._transport?.onerror?.(error);
|
|
310
301
|
throw error;
|
|
311
302
|
}
|
|
312
|
-
|
|
303
|
+
this._transport?.onmessage?.(parsedMessage);
|
|
313
304
|
return null;
|
|
314
305
|
} catch (error) {
|
|
315
|
-
|
|
306
|
+
console.error("Error forwarding message to SSE:", error);
|
|
307
|
+
this._transport?.onerror?.(error);
|
|
316
308
|
return error;
|
|
317
309
|
}
|
|
318
310
|
}
|
|
319
311
|
// Delegate all websocket events to the underlying agent
|
|
320
312
|
async webSocketMessage(ws, event) {
|
|
321
|
-
if (
|
|
322
|
-
await
|
|
313
|
+
if (this._status !== "started") {
|
|
314
|
+
await this._initialize();
|
|
323
315
|
}
|
|
324
|
-
return await
|
|
316
|
+
return await this._agent.webSocketMessage(ws, event);
|
|
325
317
|
}
|
|
326
318
|
// WebSocket event handlers for hibernation support
|
|
327
319
|
async webSocketError(ws, error) {
|
|
328
|
-
if (
|
|
329
|
-
await
|
|
320
|
+
if (this._status !== "started") {
|
|
321
|
+
await this._initialize();
|
|
330
322
|
}
|
|
331
|
-
return await
|
|
323
|
+
return await this._agent.webSocketError(ws, error);
|
|
332
324
|
}
|
|
333
325
|
async webSocketClose(ws, code, reason, wasClean) {
|
|
334
|
-
if (
|
|
335
|
-
await
|
|
326
|
+
if (this._status !== "started") {
|
|
327
|
+
await this._initialize();
|
|
336
328
|
}
|
|
337
|
-
return await
|
|
329
|
+
return await this._agent.webSocketClose(ws, code, reason, wasClean);
|
|
338
330
|
}
|
|
339
331
|
static mount(path, {
|
|
340
332
|
binding = "MCP_OBJECT",
|
|
@@ -353,18 +345,32 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
353
345
|
const basePattern = new URLPattern({ pathname });
|
|
354
346
|
const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
|
|
355
347
|
return {
|
|
356
|
-
|
|
348
|
+
async fetch(request, env, ctx) {
|
|
357
349
|
const corsResponse = handleCORS(request, corsOptions);
|
|
358
350
|
if (corsResponse) return corsResponse;
|
|
359
351
|
const url = new URL(request.url);
|
|
360
|
-
const
|
|
352
|
+
const bindingValue = env[binding];
|
|
353
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
354
|
+
console.error(
|
|
355
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
356
|
+
);
|
|
357
|
+
return new Response("Invalid binding", { status: 500 });
|
|
358
|
+
}
|
|
359
|
+
if (bindingValue.toString() !== "[object DurableObjectNamespace]") {
|
|
360
|
+
return new Response("Invalid binding", { status: 500 });
|
|
361
|
+
}
|
|
362
|
+
const namespace = bindingValue;
|
|
361
363
|
if (request.method === "GET" && basePattern.test(url)) {
|
|
362
364
|
const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
|
|
363
365
|
const { readable, writable } = new TransformStream();
|
|
364
366
|
const writer = writable.getWriter();
|
|
365
367
|
const encoder = new TextEncoder();
|
|
368
|
+
const endpointUrl = new URL(request.url);
|
|
369
|
+
endpointUrl.pathname = encodeURI(`${pathname}/message`);
|
|
370
|
+
endpointUrl.searchParams.set("sessionId", sessionId);
|
|
371
|
+
const relativeUrlWithSession = endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;
|
|
366
372
|
const endpointMessage = `event: endpoint
|
|
367
|
-
data: ${
|
|
373
|
+
data: ${relativeUrlWithSession}
|
|
368
374
|
|
|
369
375
|
`;
|
|
370
376
|
writer.write(encoder.encode(endpointMessage));
|
|
@@ -392,40 +398,49 @@ data: ${encodeURI(`${pathname}/message`)}?sessionId=${sessionId}
|
|
|
392
398
|
}
|
|
393
399
|
ws.accept();
|
|
394
400
|
ws.addEventListener("message", (event) => {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
401
|
+
async function onMessage(event2) {
|
|
402
|
+
try {
|
|
403
|
+
const message = JSON.parse(event2.data);
|
|
404
|
+
const result = JSONRPCMessageSchema.safeParse(message);
|
|
405
|
+
if (!result.success) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const messageText = `event: message
|
|
402
409
|
data: ${JSON.stringify(result.data)}
|
|
403
410
|
|
|
404
411
|
`;
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
412
|
+
await writer.write(encoder.encode(messageText));
|
|
413
|
+
} catch (error) {
|
|
414
|
+
console.error("Error forwarding message to SSE:", error);
|
|
415
|
+
}
|
|
408
416
|
}
|
|
417
|
+
onMessage(event).catch(console.error);
|
|
409
418
|
});
|
|
410
419
|
ws.addEventListener("error", (error) => {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
420
|
+
async function onError(error2) {
|
|
421
|
+
try {
|
|
422
|
+
await writer.close();
|
|
423
|
+
} catch (e) {
|
|
424
|
+
}
|
|
414
425
|
}
|
|
426
|
+
onError(error).catch(console.error);
|
|
415
427
|
});
|
|
416
428
|
ws.addEventListener("close", () => {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
429
|
+
async function onClose() {
|
|
430
|
+
try {
|
|
431
|
+
await writer.close();
|
|
432
|
+
} catch (error) {
|
|
433
|
+
console.error("Error closing SSE connection:", error);
|
|
434
|
+
}
|
|
421
435
|
}
|
|
436
|
+
onClose().catch(console.error);
|
|
422
437
|
});
|
|
423
438
|
return new Response(readable, {
|
|
424
439
|
headers: {
|
|
425
440
|
"Content-Type": "text/event-stream",
|
|
426
441
|
"Cache-Control": "no-cache",
|
|
427
442
|
Connection: "keep-alive",
|
|
428
|
-
|
|
443
|
+
...corsHeaders(request, corsOptions)
|
|
429
444
|
}
|
|
430
445
|
});
|
|
431
446
|
}
|
|
@@ -465,7 +480,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
465
480
|
"Content-Type": "text/event-stream",
|
|
466
481
|
"Cache-Control": "no-cache",
|
|
467
482
|
Connection: "keep-alive",
|
|
468
|
-
|
|
483
|
+
...corsHeaders(request, corsOptions)
|
|
469
484
|
}
|
|
470
485
|
});
|
|
471
486
|
}
|
|
@@ -475,7 +490,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
475
490
|
"Content-Type": "text/event-stream",
|
|
476
491
|
"Cache-Control": "no-cache",
|
|
477
492
|
Connection: "keep-alive",
|
|
478
|
-
|
|
493
|
+
...corsHeaders(request, corsOptions)
|
|
479
494
|
}
|
|
480
495
|
});
|
|
481
496
|
}
|
|
@@ -493,13 +508,23 @@ data: ${JSON.stringify(result.data)}
|
|
|
493
508
|
}
|
|
494
509
|
const basePattern = new URLPattern({ pathname });
|
|
495
510
|
return {
|
|
496
|
-
|
|
511
|
+
async fetch(request, env, ctx) {
|
|
497
512
|
const corsResponse = handleCORS(request, corsOptions);
|
|
498
513
|
if (corsResponse) {
|
|
499
514
|
return corsResponse;
|
|
500
515
|
}
|
|
501
516
|
const url = new URL(request.url);
|
|
502
|
-
const
|
|
517
|
+
const bindingValue = env[binding];
|
|
518
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
519
|
+
console.error(
|
|
520
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
521
|
+
);
|
|
522
|
+
return new Response("Invalid binding", { status: 500 });
|
|
523
|
+
}
|
|
524
|
+
if (bindingValue.toString() !== "[object DurableObjectNamespace]") {
|
|
525
|
+
return new Response("Invalid binding", { status: 500 });
|
|
526
|
+
}
|
|
527
|
+
const namespace = bindingValue;
|
|
503
528
|
if (request.method === "POST" && basePattern.test(url)) {
|
|
504
529
|
const acceptHeader = request.headers.get("accept");
|
|
505
530
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
@@ -618,6 +643,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
618
643
|
const isInitialized = await doStub.isInitialized();
|
|
619
644
|
if (isInitializationRequest) {
|
|
620
645
|
await doStub._init(ctx.props);
|
|
646
|
+
await doStub.setInitialized();
|
|
621
647
|
} else if (!isInitialized) {
|
|
622
648
|
const body2 = JSON.stringify({
|
|
623
649
|
jsonrpc: "2.0",
|
|
@@ -660,40 +686,49 @@ data: ${JSON.stringify(result.data)}
|
|
|
660
686
|
const requestIds = /* @__PURE__ */ new Set();
|
|
661
687
|
ws.accept();
|
|
662
688
|
ws.addEventListener("message", (event) => {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
689
|
+
async function onMessage(event2) {
|
|
690
|
+
try {
|
|
691
|
+
const data = typeof event2.data === "string" ? event2.data : new TextDecoder().decode(event2.data);
|
|
692
|
+
const message = JSON.parse(data);
|
|
693
|
+
const result = JSONRPCMessageSchema.safeParse(message);
|
|
694
|
+
if (!result.success) {
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
if (isJSONRPCResponse(result.data) || isJSONRPCError(result.data)) {
|
|
698
|
+
requestIds.delete(result.data.id);
|
|
699
|
+
}
|
|
700
|
+
const messageText = `event: message
|
|
674
701
|
data: ${JSON.stringify(result.data)}
|
|
675
702
|
|
|
676
703
|
`;
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
704
|
+
await writer.write(encoder.encode(messageText));
|
|
705
|
+
if (requestIds.size === 0) {
|
|
706
|
+
ws.close();
|
|
707
|
+
}
|
|
708
|
+
} catch (error) {
|
|
709
|
+
console.error("Error forwarding message to SSE:", error);
|
|
680
710
|
}
|
|
681
|
-
} catch (error) {
|
|
682
|
-
console.error("Error forwarding message to SSE:", error);
|
|
683
711
|
}
|
|
712
|
+
onMessage(event).catch(console.error);
|
|
684
713
|
});
|
|
685
714
|
ws.addEventListener("error", (error) => {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
715
|
+
async function onError(error2) {
|
|
716
|
+
try {
|
|
717
|
+
await writer.close();
|
|
718
|
+
} catch (e) {
|
|
719
|
+
}
|
|
689
720
|
}
|
|
721
|
+
onError(error).catch(console.error);
|
|
690
722
|
});
|
|
691
723
|
ws.addEventListener("close", () => {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
724
|
+
async function onClose() {
|
|
725
|
+
try {
|
|
726
|
+
await writer.close();
|
|
727
|
+
} catch (error) {
|
|
728
|
+
console.error("Error closing SSE connection:", error);
|
|
729
|
+
}
|
|
696
730
|
}
|
|
731
|
+
onClose().catch(console.error);
|
|
697
732
|
});
|
|
698
733
|
const hasOnlyNotificationsOrResponses = messages.every(
|
|
699
734
|
(msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)
|
|
@@ -703,7 +738,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
703
738
|
ws.send(JSON.stringify(message));
|
|
704
739
|
}
|
|
705
740
|
ws.close();
|
|
706
|
-
return new Response(null, {
|
|
741
|
+
return new Response(null, {
|
|
742
|
+
status: 202,
|
|
743
|
+
headers: corsHeaders(request, corsOptions)
|
|
744
|
+
});
|
|
707
745
|
}
|
|
708
746
|
for (const message of messages) {
|
|
709
747
|
if (isJSONRPCRequest(message)) {
|
|
@@ -717,7 +755,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
717
755
|
"Cache-Control": "no-cache",
|
|
718
756
|
Connection: "keep-alive",
|
|
719
757
|
"mcp-session-id": sessionId,
|
|
720
|
-
|
|
758
|
+
...corsHeaders(request, corsOptions)
|
|
721
759
|
},
|
|
722
760
|
status: 200
|
|
723
761
|
});
|
|
@@ -735,20 +773,6 @@ data: ${JSON.stringify(result.data)}
|
|
|
735
773
|
};
|
|
736
774
|
}
|
|
737
775
|
};
|
|
738
|
-
_status = new WeakMap();
|
|
739
|
-
_transport = new WeakMap();
|
|
740
|
-
_transportType = new WeakMap();
|
|
741
|
-
_requestIdToConnectionId = new WeakMap();
|
|
742
|
-
_agent = new WeakMap();
|
|
743
|
-
_McpAgent_instances = new WeakSet();
|
|
744
|
-
initialize_fn = async function() {
|
|
745
|
-
await this.ctx.blockConcurrencyWhile(async () => {
|
|
746
|
-
__privateSet(this, _status, "starting");
|
|
747
|
-
await this.onStart();
|
|
748
|
-
__privateSet(this, _status, "started");
|
|
749
|
-
});
|
|
750
|
-
};
|
|
751
|
-
var McpAgent = _McpAgent;
|
|
752
776
|
export {
|
|
753
777
|
McpAgent
|
|
754
778
|
};
|