agents 0.0.0-9dbe072 → 0.0.0-9e2f4e7
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 +28 -3
- package/dist/ai-chat-agent.js +99 -103
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +13 -0
- package/dist/ai-react.js +3 -3
- package/dist/ai-react.js.map +1 -1
- package/dist/chunk-BZXOAZUX.js +106 -0
- package/dist/chunk-BZXOAZUX.js.map +1 -0
- package/dist/{chunk-AV3OMRR4.js → chunk-MXJNY43J.js} +328 -140
- package/dist/chunk-MXJNY43J.js.map +1 -0
- package/dist/{chunk-YZNSS675.js → chunk-OYJXQRRH.js} +56 -26
- package/dist/chunk-OYJXQRRH.js.map +1 -0
- package/dist/chunk-VCSB47AK.js +116 -0
- package/dist/chunk-VCSB47AK.js.map +1 -0
- package/dist/client.d.ts +15 -1
- package/dist/client.js +6 -126
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +111 -13
- package/dist/index.js +8 -7
- package/dist/mcp/client.d.ts +30 -15
- package/dist/mcp/client.js +1 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +3 -3
- package/dist/mcp/do-oauth-client-provider.js +3 -103
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +16 -5
- package/dist/mcp/index.js +135 -139
- package/dist/mcp/index.js.map +1 -1
- package/dist/react.d.ts +85 -5
- 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/dist/serializable.d.ts +32 -0
- package/dist/serializable.js +1 -0
- package/package.json +10 -7
- package/src/index.ts +392 -56
- package/dist/chunk-AV3OMRR4.js.map +0 -1
- package/dist/chunk-HMLY7DHA.js +0 -16
- package/dist/chunk-YZNSS675.js.map +0 -1
- /package/dist/{chunk-HMLY7DHA.js.map → serializable.js.map} +0 -0
package/dist/mcp/index.d.ts
CHANGED
|
@@ -18,9 +18,19 @@ interface CORSOptions {
|
|
|
18
18
|
methods?: string;
|
|
19
19
|
headers?: string;
|
|
20
20
|
maxAge?: number;
|
|
21
|
+
exposeHeaders?: string;
|
|
21
22
|
}
|
|
23
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
22
24
|
declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Record<string, unknown> = Record<string, unknown>> extends DurableObject<Env> {
|
|
23
|
-
|
|
25
|
+
private _status;
|
|
26
|
+
private _transport?;
|
|
27
|
+
private _transportType;
|
|
28
|
+
private _requestIdToConnectionId;
|
|
29
|
+
/**
|
|
30
|
+
* Since McpAgent's _aren't_ yet real "Agents", let's only expose a couple of the methods
|
|
31
|
+
* to the outer class: initialState/state/setState/onStateUpdate/sql
|
|
32
|
+
*/
|
|
33
|
+
private _agent;
|
|
24
34
|
get mcp(): MCPClientManager;
|
|
25
35
|
protected constructor(ctx: DurableObjectState, env: Env);
|
|
26
36
|
/**
|
|
@@ -35,13 +45,14 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
|
|
|
35
45
|
/**
|
|
36
46
|
* McpAgent API
|
|
37
47
|
*/
|
|
38
|
-
abstract server: McpServer | Server
|
|
48
|
+
abstract server: MaybePromise<McpServer | Server>;
|
|
39
49
|
props: Props;
|
|
40
50
|
initRun: boolean;
|
|
41
51
|
abstract init(): Promise<void>;
|
|
42
52
|
_init(props: Props): Promise<void>;
|
|
43
53
|
setInitialized(): Promise<void>;
|
|
44
54
|
isInitialized(): Promise<boolean>;
|
|
55
|
+
private _initialize;
|
|
45
56
|
fetch(request: Request): Promise<Response>;
|
|
46
57
|
getWebSocket(): WebSocket | null;
|
|
47
58
|
getWebSocketForResponseID(id: string): WebSocket | null;
|
|
@@ -54,19 +65,19 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
|
|
|
54
65
|
binding?: string;
|
|
55
66
|
corsOptions?: CORSOptions;
|
|
56
67
|
}): {
|
|
57
|
-
fetch:
|
|
68
|
+
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
58
69
|
};
|
|
59
70
|
static serveSSE(path: string, { binding, corsOptions, }?: {
|
|
60
71
|
binding?: string;
|
|
61
72
|
corsOptions?: CORSOptions;
|
|
62
73
|
}): {
|
|
63
|
-
fetch:
|
|
74
|
+
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
64
75
|
};
|
|
65
76
|
static serve(path: string, { binding, corsOptions, }?: {
|
|
66
77
|
binding?: string;
|
|
67
78
|
corsOptions?: CORSOptions;
|
|
68
79
|
}): {
|
|
69
|
-
fetch:
|
|
80
|
+
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
70
81
|
};
|
|
71
82
|
}
|
|
72
83
|
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
__privateGet,
|
|
8
|
-
__privateMethod,
|
|
9
|
-
__privateSet
|
|
10
|
-
} from "../chunk-HMLY7DHA.js";
|
|
3
|
+
} from "../chunk-MXJNY43J.js";
|
|
4
|
+
import "../chunk-OYJXQRRH.js";
|
|
5
|
+
import "../chunk-BZXOAZUX.js";
|
|
6
|
+
import "../chunk-VCSB47AK.js";
|
|
11
7
|
|
|
12
8
|
// src/mcp/index.ts
|
|
13
9
|
import { DurableObject } from "cloudflare:workers";
|
|
@@ -20,37 +16,41 @@ import {
|
|
|
20
16
|
JSONRPCMessageSchema
|
|
21
17
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
22
18
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
23
|
-
function
|
|
24
|
-
const origin =
|
|
25
|
-
|
|
26
|
-
"Access-Control-Allow-Origin": corsOptions
|
|
27
|
-
"Access-Control-Allow-Methods": corsOptions
|
|
28
|
-
"Access-Control-Allow-Headers": corsOptions
|
|
29
|
-
"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"
|
|
30
27
|
};
|
|
28
|
+
}
|
|
29
|
+
function isDurableObjectNamespace(namespace) {
|
|
30
|
+
return typeof namespace === "object" && namespace !== null && "newUniqueId" in namespace && typeof namespace.newUniqueId === "function" && "idFromName" in namespace && typeof namespace.idFromName === "function";
|
|
31
|
+
}
|
|
32
|
+
function handleCORS(request, corsOptions) {
|
|
31
33
|
if (request.method === "OPTIONS") {
|
|
32
|
-
return new Response(null, { headers: corsHeaders });
|
|
34
|
+
return new Response(null, { headers: corsHeaders(request, corsOptions) });
|
|
33
35
|
}
|
|
34
36
|
return null;
|
|
35
37
|
}
|
|
36
|
-
var _getWebSocket, _started;
|
|
37
38
|
var McpSSETransport = class {
|
|
38
39
|
constructor(getWebSocket) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
__privateSet(this, _getWebSocket, getWebSocket);
|
|
40
|
+
this._started = false;
|
|
41
|
+
this._getWebSocket = getWebSocket;
|
|
42
42
|
}
|
|
43
43
|
async start() {
|
|
44
|
-
if (
|
|
44
|
+
if (this._started) {
|
|
45
45
|
throw new Error("Transport already started");
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
this._started = true;
|
|
48
48
|
}
|
|
49
49
|
async send(message) {
|
|
50
|
-
if (!
|
|
50
|
+
if (!this._started) {
|
|
51
51
|
throw new Error("Transport not started");
|
|
52
52
|
}
|
|
53
|
-
const websocket =
|
|
53
|
+
const websocket = this._getWebSocket();
|
|
54
54
|
if (!websocket) {
|
|
55
55
|
throw new Error("WebSocket not connected");
|
|
56
56
|
}
|
|
@@ -65,52 +65,40 @@ var McpSSETransport = class {
|
|
|
65
65
|
this.onclose?.();
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
|
-
_getWebSocket = new WeakMap();
|
|
69
|
-
_started = new WeakMap();
|
|
70
|
-
var _getWebSocketForGetRequest, _getWebSocketForMessageID, _notifyResponseIdSent, _started2;
|
|
71
68
|
var McpStreamableHttpTransport = class {
|
|
72
69
|
constructor(getWebSocketForMessageID, notifyResponseIdSent) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
__privateAdd(this, _getWebSocketForMessageID);
|
|
78
|
-
// Notify the server that a response has been sent for a given message id
|
|
79
|
-
// so that it may clean up it's mapping of message ids to connections
|
|
80
|
-
// once they are no longer needed
|
|
81
|
-
__privateAdd(this, _notifyResponseIdSent);
|
|
82
|
-
__privateAdd(this, _started2, false);
|
|
83
|
-
__privateSet(this, _getWebSocketForMessageID, getWebSocketForMessageID);
|
|
84
|
-
__privateSet(this, _notifyResponseIdSent, notifyResponseIdSent);
|
|
85
|
-
__privateSet(this, _getWebSocketForGetRequest, () => null);
|
|
70
|
+
this._started = false;
|
|
71
|
+
this._getWebSocketForMessageID = getWebSocketForMessageID;
|
|
72
|
+
this._notifyResponseIdSent = notifyResponseIdSent;
|
|
73
|
+
this._getWebSocketForGetRequest = () => null;
|
|
86
74
|
}
|
|
87
75
|
async start() {
|
|
88
|
-
if (
|
|
76
|
+
if (this._started) {
|
|
89
77
|
throw new Error("Transport already started");
|
|
90
78
|
}
|
|
91
|
-
|
|
79
|
+
this._started = true;
|
|
92
80
|
}
|
|
93
81
|
async send(message) {
|
|
94
|
-
if (!
|
|
82
|
+
if (!this._started) {
|
|
95
83
|
throw new Error("Transport not started");
|
|
96
84
|
}
|
|
97
85
|
let websocket = null;
|
|
98
86
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
|
|
99
|
-
websocket =
|
|
87
|
+
websocket = this._getWebSocketForMessageID(message.id.toString());
|
|
100
88
|
if (!websocket) {
|
|
101
89
|
throw new Error(
|
|
102
90
|
`Could not find WebSocket for message id: ${message.id}`
|
|
103
91
|
);
|
|
104
92
|
}
|
|
105
93
|
} else if (isJSONRPCRequest(message)) {
|
|
106
|
-
websocket =
|
|
94
|
+
websocket = this._getWebSocketForGetRequest();
|
|
107
95
|
} else if (isJSONRPCNotification(message)) {
|
|
108
96
|
websocket = null;
|
|
109
97
|
}
|
|
110
98
|
try {
|
|
111
99
|
websocket?.send(JSON.stringify(message));
|
|
112
100
|
if (isJSONRPCResponse(message)) {
|
|
113
|
-
|
|
101
|
+
this._notifyResponseIdSent(message.id.toString());
|
|
114
102
|
}
|
|
115
103
|
} catch (error) {
|
|
116
104
|
this.onerror?.(error);
|
|
@@ -121,28 +109,16 @@ var McpStreamableHttpTransport = class {
|
|
|
121
109
|
this.onclose?.();
|
|
122
110
|
}
|
|
123
111
|
};
|
|
124
|
-
|
|
125
|
-
_getWebSocketForMessageID = new WeakMap();
|
|
126
|
-
_notifyResponseIdSent = new WeakMap();
|
|
127
|
-
_started2 = new WeakMap();
|
|
128
|
-
var _status, _transport, _transportType, _requestIdToConnectionId, _agent, _McpAgent_instances, initialize_fn;
|
|
129
|
-
var _McpAgent = class _McpAgent extends DurableObject {
|
|
112
|
+
var McpAgent = class _McpAgent extends DurableObject {
|
|
130
113
|
constructor(ctx, env) {
|
|
131
114
|
var _a;
|
|
132
115
|
super(ctx, env);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
__privateAdd(this, _transportType, "unset");
|
|
137
|
-
__privateAdd(this, _requestIdToConnectionId, /* @__PURE__ */ new Map());
|
|
138
|
-
/**
|
|
139
|
-
* Since McpAgent's _aren't_ yet real "Agents", let's only expose a couple of the methods
|
|
140
|
-
* to the outer class: initialState/state/setState/onStateUpdate/sql
|
|
141
|
-
*/
|
|
142
|
-
__privateAdd(this, _agent);
|
|
116
|
+
this._status = "zero";
|
|
117
|
+
this._transportType = "unset";
|
|
118
|
+
this._requestIdToConnectionId = /* @__PURE__ */ new Map();
|
|
143
119
|
this.initRun = false;
|
|
144
120
|
const self = this;
|
|
145
|
-
|
|
121
|
+
this._agent = new (_a = class extends Agent {
|
|
146
122
|
onStateUpdate(state, source) {
|
|
147
123
|
return self.onStateUpdate(state, source);
|
|
148
124
|
}
|
|
@@ -151,26 +127,26 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
151
127
|
}
|
|
152
128
|
}, _a.options = {
|
|
153
129
|
hibernate: true
|
|
154
|
-
}, _a)(ctx, env)
|
|
130
|
+
}, _a)(ctx, env);
|
|
155
131
|
}
|
|
156
132
|
get mcp() {
|
|
157
|
-
return
|
|
133
|
+
return this._agent.mcp;
|
|
158
134
|
}
|
|
159
135
|
get state() {
|
|
160
|
-
return
|
|
136
|
+
return this._agent.state;
|
|
161
137
|
}
|
|
162
138
|
sql(strings, ...values) {
|
|
163
|
-
return
|
|
139
|
+
return this._agent.sql(strings, ...values);
|
|
164
140
|
}
|
|
165
141
|
setState(state) {
|
|
166
|
-
return
|
|
142
|
+
return this._agent.setState(state);
|
|
167
143
|
}
|
|
168
144
|
onStateUpdate(state, source) {
|
|
169
145
|
}
|
|
170
146
|
async onStart() {
|
|
171
147
|
var _a;
|
|
172
148
|
const self = this;
|
|
173
|
-
|
|
149
|
+
this._agent = new (_a = class extends Agent {
|
|
174
150
|
constructor() {
|
|
175
151
|
super(...arguments);
|
|
176
152
|
this.initialState = self.initialState;
|
|
@@ -183,21 +159,22 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
183
159
|
}
|
|
184
160
|
}, _a.options = {
|
|
185
161
|
hibernate: true
|
|
186
|
-
}, _a)(this.ctx, this.env)
|
|
162
|
+
}, _a)(this.ctx, this.env);
|
|
187
163
|
this.props = await this.ctx.storage.get("props");
|
|
188
|
-
|
|
164
|
+
this._transportType = await this.ctx.storage.get(
|
|
189
165
|
"transportType"
|
|
190
|
-
)
|
|
166
|
+
);
|
|
191
167
|
await this._init(this.props);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
168
|
+
const server = await this.server;
|
|
169
|
+
if (this._transportType === "sse") {
|
|
170
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
171
|
+
await server.connect(this._transport);
|
|
172
|
+
} else if (this._transportType === "streamable-http") {
|
|
173
|
+
this._transport = new McpStreamableHttpTransport(
|
|
197
174
|
(id) => this.getWebSocketForResponseID(id),
|
|
198
|
-
(id) =>
|
|
199
|
-
)
|
|
200
|
-
await
|
|
175
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
176
|
+
);
|
|
177
|
+
await server.connect(this._transport);
|
|
201
178
|
}
|
|
202
179
|
}
|
|
203
180
|
async _init(props) {
|
|
@@ -217,10 +194,17 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
217
194
|
async isInitialized() {
|
|
218
195
|
return await this.ctx.storage.get("initialized") === true;
|
|
219
196
|
}
|
|
197
|
+
async _initialize() {
|
|
198
|
+
await this.ctx.blockConcurrencyWhile(async () => {
|
|
199
|
+
this._status = "starting";
|
|
200
|
+
await this.onStart();
|
|
201
|
+
this._status = "started";
|
|
202
|
+
});
|
|
203
|
+
}
|
|
220
204
|
// Allow the worker to fetch a websocket connection to the agent
|
|
221
205
|
async fetch(request) {
|
|
222
|
-
if (
|
|
223
|
-
await
|
|
206
|
+
if (this._status !== "started") {
|
|
207
|
+
await this._initialize();
|
|
224
208
|
}
|
|
225
209
|
if (request.headers.get("Upgrade") !== "websocket") {
|
|
226
210
|
return new Response("Expected WebSocket Upgrade request", {
|
|
@@ -229,6 +213,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
229
213
|
}
|
|
230
214
|
const url = new URL(request.url);
|
|
231
215
|
const path = url.pathname;
|
|
216
|
+
const server = await this.server;
|
|
232
217
|
switch (path) {
|
|
233
218
|
case "/sse": {
|
|
234
219
|
const websockets = this.ctx.getWebSockets();
|
|
@@ -236,24 +221,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
236
221
|
return new Response("Websocket already connected", { status: 400 });
|
|
237
222
|
}
|
|
238
223
|
await this.ctx.storage.put("transportType", "sse");
|
|
239
|
-
|
|
240
|
-
if (!
|
|
241
|
-
|
|
242
|
-
await
|
|
224
|
+
this._transportType = "sse";
|
|
225
|
+
if (!this._transport) {
|
|
226
|
+
this._transport = new McpSSETransport(() => this.getWebSocket());
|
|
227
|
+
await server.connect(this._transport);
|
|
243
228
|
}
|
|
244
|
-
return
|
|
229
|
+
return this._agent.fetch(request);
|
|
245
230
|
}
|
|
246
231
|
case "/streamable-http": {
|
|
247
|
-
if (!
|
|
248
|
-
|
|
232
|
+
if (!this._transport) {
|
|
233
|
+
this._transport = new McpStreamableHttpTransport(
|
|
249
234
|
(id) => this.getWebSocketForResponseID(id),
|
|
250
|
-
(id) =>
|
|
251
|
-
)
|
|
252
|
-
await
|
|
235
|
+
(id) => this._requestIdToConnectionId.delete(id)
|
|
236
|
+
);
|
|
237
|
+
await server.connect(this._transport);
|
|
253
238
|
}
|
|
254
239
|
await this.ctx.storage.put("transportType", "streamable-http");
|
|
255
|
-
|
|
256
|
-
return
|
|
240
|
+
this._transportType = "streamable-http";
|
|
241
|
+
return this._agent.fetch(request);
|
|
257
242
|
}
|
|
258
243
|
default:
|
|
259
244
|
return new Response(
|
|
@@ -272,19 +257,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
272
257
|
return websockets[0];
|
|
273
258
|
}
|
|
274
259
|
getWebSocketForResponseID(id) {
|
|
275
|
-
const connectionId =
|
|
260
|
+
const connectionId = this._requestIdToConnectionId.get(id);
|
|
276
261
|
if (connectionId === void 0) {
|
|
277
262
|
return null;
|
|
278
263
|
}
|
|
279
|
-
return
|
|
264
|
+
return this._agent.getConnection(connectionId) ?? null;
|
|
280
265
|
}
|
|
281
266
|
// All messages received here. This is currently never called
|
|
282
267
|
async onMessage(connection, event) {
|
|
283
|
-
if (
|
|
268
|
+
if (this._transportType !== "streamable-http") {
|
|
284
269
|
const err = new Error(
|
|
285
270
|
"Internal Server Error: Expected streamable-http protocol"
|
|
286
271
|
);
|
|
287
|
-
|
|
272
|
+
this._transport?.onerror?.(err);
|
|
288
273
|
return;
|
|
289
274
|
}
|
|
290
275
|
let message;
|
|
@@ -292,21 +277,21 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
292
277
|
const data = typeof event === "string" ? event : new TextDecoder().decode(event);
|
|
293
278
|
message = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
294
279
|
} catch (error) {
|
|
295
|
-
|
|
280
|
+
this._transport?.onerror?.(error);
|
|
296
281
|
return;
|
|
297
282
|
}
|
|
298
283
|
if (isJSONRPCRequest(message)) {
|
|
299
|
-
|
|
284
|
+
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
300
285
|
}
|
|
301
|
-
|
|
286
|
+
this._transport?.onmessage?.(message);
|
|
302
287
|
}
|
|
303
288
|
// All messages received over SSE after the initial connection has been established
|
|
304
289
|
// will be passed here
|
|
305
290
|
async onSSEMcpMessage(sessionId, request) {
|
|
306
|
-
if (
|
|
307
|
-
await
|
|
291
|
+
if (this._status !== "started") {
|
|
292
|
+
await this._initialize();
|
|
308
293
|
}
|
|
309
|
-
if (
|
|
294
|
+
if (this._transportType !== "sse") {
|
|
310
295
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
311
296
|
}
|
|
312
297
|
try {
|
|
@@ -315,35 +300,36 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
315
300
|
try {
|
|
316
301
|
parsedMessage = JSONRPCMessageSchema.parse(message);
|
|
317
302
|
} catch (error) {
|
|
318
|
-
|
|
303
|
+
this._transport?.onerror?.(error);
|
|
319
304
|
throw error;
|
|
320
305
|
}
|
|
321
|
-
|
|
306
|
+
this._transport?.onmessage?.(parsedMessage);
|
|
322
307
|
return null;
|
|
323
308
|
} catch (error) {
|
|
324
|
-
|
|
309
|
+
console.error("Error forwarding message to SSE:", error);
|
|
310
|
+
this._transport?.onerror?.(error);
|
|
325
311
|
return error;
|
|
326
312
|
}
|
|
327
313
|
}
|
|
328
314
|
// Delegate all websocket events to the underlying agent
|
|
329
315
|
async webSocketMessage(ws, event) {
|
|
330
|
-
if (
|
|
331
|
-
await
|
|
316
|
+
if (this._status !== "started") {
|
|
317
|
+
await this._initialize();
|
|
332
318
|
}
|
|
333
|
-
return await
|
|
319
|
+
return await this._agent.webSocketMessage(ws, event);
|
|
334
320
|
}
|
|
335
321
|
// WebSocket event handlers for hibernation support
|
|
336
322
|
async webSocketError(ws, error) {
|
|
337
|
-
if (
|
|
338
|
-
await
|
|
323
|
+
if (this._status !== "started") {
|
|
324
|
+
await this._initialize();
|
|
339
325
|
}
|
|
340
|
-
return await
|
|
326
|
+
return await this._agent.webSocketError(ws, error);
|
|
341
327
|
}
|
|
342
328
|
async webSocketClose(ws, code, reason, wasClean) {
|
|
343
|
-
if (
|
|
344
|
-
await
|
|
329
|
+
if (this._status !== "started") {
|
|
330
|
+
await this._initialize();
|
|
345
331
|
}
|
|
346
|
-
return await
|
|
332
|
+
return await this._agent.webSocketClose(ws, code, reason, wasClean);
|
|
347
333
|
}
|
|
348
334
|
static mount(path, {
|
|
349
335
|
binding = "MCP_OBJECT",
|
|
@@ -362,11 +348,21 @@ var _McpAgent = class _McpAgent extends DurableObject {
|
|
|
362
348
|
const basePattern = new URLPattern({ pathname });
|
|
363
349
|
const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
|
|
364
350
|
return {
|
|
365
|
-
|
|
351
|
+
async fetch(request, env, ctx) {
|
|
366
352
|
const corsResponse = handleCORS(request, corsOptions);
|
|
367
353
|
if (corsResponse) return corsResponse;
|
|
368
354
|
const url = new URL(request.url);
|
|
369
|
-
const
|
|
355
|
+
const bindingValue = env[binding];
|
|
356
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
357
|
+
console.error(
|
|
358
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
359
|
+
);
|
|
360
|
+
return new Response("Invalid binding", { status: 500 });
|
|
361
|
+
}
|
|
362
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
363
|
+
return new Response("Invalid binding", { status: 500 });
|
|
364
|
+
}
|
|
365
|
+
const namespace = bindingValue;
|
|
370
366
|
if (request.method === "GET" && basePattern.test(url)) {
|
|
371
367
|
const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
|
|
372
368
|
const { readable, writable } = new TransformStream();
|
|
@@ -447,7 +443,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
447
443
|
"Content-Type": "text/event-stream",
|
|
448
444
|
"Cache-Control": "no-cache",
|
|
449
445
|
Connection: "keep-alive",
|
|
450
|
-
|
|
446
|
+
...corsHeaders(request, corsOptions)
|
|
451
447
|
}
|
|
452
448
|
});
|
|
453
449
|
}
|
|
@@ -487,7 +483,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
487
483
|
"Content-Type": "text/event-stream",
|
|
488
484
|
"Cache-Control": "no-cache",
|
|
489
485
|
Connection: "keep-alive",
|
|
490
|
-
|
|
486
|
+
...corsHeaders(request, corsOptions)
|
|
491
487
|
}
|
|
492
488
|
});
|
|
493
489
|
}
|
|
@@ -497,7 +493,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
497
493
|
"Content-Type": "text/event-stream",
|
|
498
494
|
"Cache-Control": "no-cache",
|
|
499
495
|
Connection: "keep-alive",
|
|
500
|
-
|
|
496
|
+
...corsHeaders(request, corsOptions)
|
|
501
497
|
}
|
|
502
498
|
});
|
|
503
499
|
}
|
|
@@ -515,13 +511,23 @@ data: ${JSON.stringify(result.data)}
|
|
|
515
511
|
}
|
|
516
512
|
const basePattern = new URLPattern({ pathname });
|
|
517
513
|
return {
|
|
518
|
-
|
|
514
|
+
async fetch(request, env, ctx) {
|
|
519
515
|
const corsResponse = handleCORS(request, corsOptions);
|
|
520
516
|
if (corsResponse) {
|
|
521
517
|
return corsResponse;
|
|
522
518
|
}
|
|
523
519
|
const url = new URL(request.url);
|
|
524
|
-
const
|
|
520
|
+
const bindingValue = env[binding];
|
|
521
|
+
if (bindingValue == null || typeof bindingValue !== "object") {
|
|
522
|
+
console.error(
|
|
523
|
+
`Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
|
|
524
|
+
);
|
|
525
|
+
return new Response("Invalid binding", { status: 500 });
|
|
526
|
+
}
|
|
527
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
528
|
+
return new Response("Invalid binding", { status: 500 });
|
|
529
|
+
}
|
|
530
|
+
const namespace = bindingValue;
|
|
525
531
|
if (request.method === "POST" && basePattern.test(url)) {
|
|
526
532
|
const acceptHeader = request.headers.get("accept");
|
|
527
533
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
@@ -639,6 +645,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
639
645
|
const doStub = namespace.get(id);
|
|
640
646
|
const isInitialized = await doStub.isInitialized();
|
|
641
647
|
if (isInitializationRequest) {
|
|
648
|
+
await doStub._init(ctx.props);
|
|
642
649
|
await doStub.setInitialized();
|
|
643
650
|
} else if (!isInitialized) {
|
|
644
651
|
const body2 = JSON.stringify({
|
|
@@ -734,7 +741,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
734
741
|
ws.send(JSON.stringify(message));
|
|
735
742
|
}
|
|
736
743
|
ws.close();
|
|
737
|
-
return new Response(null, {
|
|
744
|
+
return new Response(null, {
|
|
745
|
+
status: 202,
|
|
746
|
+
headers: corsHeaders(request, corsOptions)
|
|
747
|
+
});
|
|
738
748
|
}
|
|
739
749
|
for (const message of messages) {
|
|
740
750
|
if (isJSONRPCRequest(message)) {
|
|
@@ -748,7 +758,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
748
758
|
"Cache-Control": "no-cache",
|
|
749
759
|
Connection: "keep-alive",
|
|
750
760
|
"mcp-session-id": sessionId,
|
|
751
|
-
|
|
761
|
+
...corsHeaders(request, corsOptions)
|
|
752
762
|
},
|
|
753
763
|
status: 200
|
|
754
764
|
});
|
|
@@ -766,20 +776,6 @@ data: ${JSON.stringify(result.data)}
|
|
|
766
776
|
};
|
|
767
777
|
}
|
|
768
778
|
};
|
|
769
|
-
_status = new WeakMap();
|
|
770
|
-
_transport = new WeakMap();
|
|
771
|
-
_transportType = new WeakMap();
|
|
772
|
-
_requestIdToConnectionId = new WeakMap();
|
|
773
|
-
_agent = new WeakMap();
|
|
774
|
-
_McpAgent_instances = new WeakSet();
|
|
775
|
-
initialize_fn = async function() {
|
|
776
|
-
await this.ctx.blockConcurrencyWhile(async () => {
|
|
777
|
-
__privateSet(this, _status, "starting");
|
|
778
|
-
await this.onStart();
|
|
779
|
-
__privateSet(this, _status, "started");
|
|
780
|
-
});
|
|
781
|
-
};
|
|
782
|
-
var McpAgent = _McpAgent;
|
|
783
779
|
export {
|
|
784
780
|
McpAgent
|
|
785
781
|
};
|