agents 0.0.0-2801d35 → 0.0.0-2ef5f99
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 +128 -22
- package/dist/ai-chat-agent.d.ts +8 -5
- package/dist/ai-chat-agent.js +64 -26
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +13 -10
- package/dist/ai-react.js +27 -27
- package/dist/ai-react.js.map +1 -1
- package/dist/{chunk-Y67CHZBI.js → chunk-HY7ZLHJB.js} +167 -33
- package/dist/chunk-HY7ZLHJB.js.map +1 -0
- package/dist/{chunk-J6T74FUS.js → chunk-JXN5WZFQ.js} +638 -134
- package/dist/chunk-JXN5WZFQ.js.map +1 -0
- package/dist/{chunk-QSGN3REV.js → chunk-KUH345EY.js} +8 -15
- package/dist/chunk-KUH345EY.js.map +1 -0
- package/dist/{chunk-BZXOAZUX.js → chunk-PVQZBKN7.js} +5 -5
- package/dist/chunk-PVQZBKN7.js.map +1 -0
- package/dist/client-DgyzBU_8.d.ts +4601 -0
- package/dist/client.d.ts +8 -2
- package/dist/client.js +1 -1
- package/dist/index-BCJclX6q.d.ts +615 -0
- package/dist/index.d.ts +35 -405
- package/dist/index.js +10 -4
- package/dist/mcp/client.d.ts +9 -781
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +38 -10
- package/dist/mcp/index.js +237 -61
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +14 -0
- package/dist/observability/index.js +10 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/react.d.ts +54 -37
- package/dist/react.js +16 -6
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +10 -10
- package/dist/schedule.js +4 -4
- 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 +79 -72
- package/src/index.ts +843 -176
- package/dist/chunk-BZXOAZUX.js.map +0 -1
- package/dist/chunk-J6T74FUS.js.map +0 -1
- package/dist/chunk-QSGN3REV.js.map +0 -1
- package/dist/chunk-Y67CHZBI.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
} from "../chunk-JXN5WZFQ.js";
|
|
4
|
+
import {
|
|
5
|
+
SSEEdgeClientTransport,
|
|
6
|
+
StreamableHTTPEdgeClientTransport
|
|
7
|
+
} from "../chunk-HY7ZLHJB.js";
|
|
8
|
+
import "../chunk-PVQZBKN7.js";
|
|
9
|
+
import "../chunk-KUH345EY.js";
|
|
7
10
|
|
|
8
11
|
// src/mcp/index.ts
|
|
9
12
|
import { DurableObject } from "cloudflare:workers";
|
|
10
13
|
import {
|
|
11
14
|
InitializeRequestSchema,
|
|
15
|
+
JSONRPCMessageSchema,
|
|
12
16
|
isJSONRPCError,
|
|
13
17
|
isJSONRPCNotification,
|
|
14
18
|
isJSONRPCRequest,
|
|
15
|
-
isJSONRPCResponse
|
|
16
|
-
|
|
19
|
+
isJSONRPCResponse
|
|
20
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
21
|
+
import {
|
|
22
|
+
ElicitRequestSchema
|
|
17
23
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
18
24
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
19
|
-
function corsHeaders(
|
|
25
|
+
function corsHeaders(_request, corsOptions = {}) {
|
|
20
26
|
const origin = "*";
|
|
21
27
|
return {
|
|
22
|
-
"Access-Control-Allow-
|
|
28
|
+
"Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
|
|
23
29
|
"Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
|
|
24
|
-
"Access-Control-Allow-
|
|
25
|
-
"Access-Control-
|
|
26
|
-
"Access-Control-
|
|
30
|
+
"Access-Control-Allow-Origin": corsOptions.origin || origin,
|
|
31
|
+
"Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id",
|
|
32
|
+
"Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString()
|
|
27
33
|
};
|
|
28
34
|
}
|
|
35
|
+
function isDurableObjectNamespace(namespace) {
|
|
36
|
+
return typeof namespace === "object" && namespace !== null && "newUniqueId" in namespace && typeof namespace.newUniqueId === "function" && "idFromName" in namespace && typeof namespace.idFromName === "function";
|
|
37
|
+
}
|
|
29
38
|
function handleCORS(request, corsOptions) {
|
|
30
39
|
if (request.method === "OPTIONS") {
|
|
31
40
|
return new Response(null, { headers: corsHeaders(request, corsOptions) });
|
|
@@ -138,6 +147,46 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
138
147
|
setState(state) {
|
|
139
148
|
return this._agent.setState(state);
|
|
140
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Elicit user input with a message and schema
|
|
152
|
+
*/
|
|
153
|
+
async elicitInput(params) {
|
|
154
|
+
const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;
|
|
155
|
+
await this.ctx.storage.put(`elicitation:${requestId}`, {
|
|
156
|
+
message: params.message,
|
|
157
|
+
requestedSchema: params.requestedSchema,
|
|
158
|
+
timestamp: Date.now()
|
|
159
|
+
});
|
|
160
|
+
const elicitRequest = {
|
|
161
|
+
jsonrpc: "2.0",
|
|
162
|
+
id: requestId,
|
|
163
|
+
method: "elicitation/create",
|
|
164
|
+
params: {
|
|
165
|
+
message: params.message,
|
|
166
|
+
requestedSchema: params.requestedSchema
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
if (this._transport) {
|
|
170
|
+
await this._transport.send(elicitRequest);
|
|
171
|
+
} else {
|
|
172
|
+
const connections = this._agent?.getConnections();
|
|
173
|
+
if (!connections || Array.from(connections).length === 0) {
|
|
174
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
175
|
+
throw new Error("No active connections available for elicitation");
|
|
176
|
+
}
|
|
177
|
+
const connectionList = Array.from(connections);
|
|
178
|
+
for (const connection of connectionList) {
|
|
179
|
+
try {
|
|
180
|
+
connection.send(JSON.stringify(elicitRequest));
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error("Failed to send elicitation request:", error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return this._waitForElicitationResponse(requestId);
|
|
187
|
+
}
|
|
188
|
+
// we leave the variables as unused for autocomplete purposes
|
|
189
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later
|
|
141
190
|
onStateUpdate(state, source) {
|
|
142
191
|
}
|
|
143
192
|
async onStart() {
|
|
@@ -174,15 +223,32 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
174
223
|
await server.connect(this._transport);
|
|
175
224
|
}
|
|
176
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Handle errors that occur during initialization or operation.
|
|
228
|
+
* Override this method to provide custom error handling.
|
|
229
|
+
* @param error - The error that occurred
|
|
230
|
+
* @returns An error response object with status code and message
|
|
231
|
+
*/
|
|
232
|
+
onError(error) {
|
|
233
|
+
console.error("McpAgent error:", error);
|
|
234
|
+
return {
|
|
235
|
+
status: 500,
|
|
236
|
+
message: error.message || "An unexpected error occurred during initialization"
|
|
237
|
+
};
|
|
238
|
+
}
|
|
177
239
|
async _init(props) {
|
|
178
|
-
await this.
|
|
240
|
+
await this.updateProps(props);
|
|
179
241
|
if (!this.ctx.storage.get("transportType")) {
|
|
180
242
|
await this.ctx.storage.put("transportType", "unset");
|
|
181
243
|
}
|
|
182
|
-
this.props = props;
|
|
183
244
|
if (!this.initRun) {
|
|
184
245
|
this.initRun = true;
|
|
185
|
-
|
|
246
|
+
try {
|
|
247
|
+
await this.init();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
const errorResponse = this.onError(error);
|
|
250
|
+
throw new Error(`Initialization failed: ${errorResponse.message}`);
|
|
251
|
+
}
|
|
186
252
|
}
|
|
187
253
|
}
|
|
188
254
|
async setInitialized() {
|
|
@@ -191,6 +257,10 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
191
257
|
async isInitialized() {
|
|
192
258
|
return await this.ctx.storage.get("initialized") === true;
|
|
193
259
|
}
|
|
260
|
+
async updateProps(props) {
|
|
261
|
+
await this.ctx.storage.put("props", props ?? {});
|
|
262
|
+
this.props = props;
|
|
263
|
+
}
|
|
194
264
|
async _initialize() {
|
|
195
265
|
await this.ctx.blockConcurrencyWhile(async () => {
|
|
196
266
|
this._status = "starting";
|
|
@@ -277,14 +347,78 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
277
347
|
this._transport?.onerror?.(error);
|
|
278
348
|
return;
|
|
279
349
|
}
|
|
350
|
+
if (await this._handleElicitationResponse(message)) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
280
353
|
if (isJSONRPCRequest(message)) {
|
|
281
354
|
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
282
355
|
}
|
|
283
356
|
this._transport?.onmessage?.(message);
|
|
284
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Wait for elicitation response through storage polling
|
|
360
|
+
*/
|
|
361
|
+
async _waitForElicitationResponse(requestId) {
|
|
362
|
+
const startTime = Date.now();
|
|
363
|
+
const timeout = 6e4;
|
|
364
|
+
try {
|
|
365
|
+
while (Date.now() - startTime < timeout) {
|
|
366
|
+
const response = await this.ctx.storage.get(
|
|
367
|
+
`elicitation:response:${requestId}`
|
|
368
|
+
);
|
|
369
|
+
if (response) {
|
|
370
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
371
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
372
|
+
return response;
|
|
373
|
+
}
|
|
374
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
375
|
+
}
|
|
376
|
+
throw new Error("Elicitation request timed out");
|
|
377
|
+
} finally {
|
|
378
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
379
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Handle elicitation responses */
|
|
384
|
+
async _handleElicitationResponse(message) {
|
|
385
|
+
if (isJSONRPCResponse(message) && message.result) {
|
|
386
|
+
const requestId = message.id?.toString();
|
|
387
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
388
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
389
|
+
`elicitation:${requestId}`
|
|
390
|
+
);
|
|
391
|
+
if (!pendingRequest) return false;
|
|
392
|
+
await this.ctx.storage.put(
|
|
393
|
+
`elicitation:response:${requestId}`,
|
|
394
|
+
message.result
|
|
395
|
+
);
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
if (isJSONRPCError(message)) {
|
|
399
|
+
const requestId = message.id?.toString();
|
|
400
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
401
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
402
|
+
`elicitation:${requestId}`
|
|
403
|
+
);
|
|
404
|
+
if (!pendingRequest) return false;
|
|
405
|
+
const errorResult = {
|
|
406
|
+
action: "cancel",
|
|
407
|
+
content: {
|
|
408
|
+
error: message.error.message || "Elicitation request failed"
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
await this.ctx.storage.put(
|
|
412
|
+
`elicitation:response:${requestId}`,
|
|
413
|
+
errorResult
|
|
414
|
+
);
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
285
419
|
// All messages received over SSE after the initial connection has been established
|
|
286
420
|
// will be passed here
|
|
287
|
-
async onSSEMcpMessage(
|
|
421
|
+
async onSSEMcpMessage(_sessionId, messageBody) {
|
|
288
422
|
if (this._status !== "started") {
|
|
289
423
|
await this._initialize();
|
|
290
424
|
}
|
|
@@ -292,14 +426,16 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
292
426
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
293
427
|
}
|
|
294
428
|
try {
|
|
295
|
-
const message = await request.json();
|
|
296
429
|
let parsedMessage;
|
|
297
430
|
try {
|
|
298
|
-
parsedMessage = JSONRPCMessageSchema.parse(
|
|
431
|
+
parsedMessage = JSONRPCMessageSchema.parse(messageBody);
|
|
299
432
|
} catch (error) {
|
|
300
433
|
this._transport?.onerror?.(error);
|
|
301
434
|
throw error;
|
|
302
435
|
}
|
|
436
|
+
if (await this._handleElicitationResponse(parsedMessage)) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
303
439
|
this._transport?.onmessage?.(parsedMessage);
|
|
304
440
|
return null;
|
|
305
441
|
} catch (error) {
|
|
@@ -356,7 +492,7 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
356
492
|
);
|
|
357
493
|
return new Response("Invalid binding", { status: 500 });
|
|
358
494
|
}
|
|
359
|
-
if (bindingValue
|
|
495
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
360
496
|
return new Response("Invalid binding", { status: 500 });
|
|
361
497
|
}
|
|
362
498
|
const namespace = bindingValue;
|
|
@@ -376,12 +512,26 @@ data: ${relativeUrlWithSession}
|
|
|
376
512
|
writer.write(encoder.encode(endpointMessage));
|
|
377
513
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
378
514
|
const doStub = namespace.get(id);
|
|
379
|
-
|
|
515
|
+
try {
|
|
516
|
+
await doStub._init(ctx.props);
|
|
517
|
+
} catch (error) {
|
|
518
|
+
console.error("Failed to initialize McpAgent:", error);
|
|
519
|
+
await writer.close();
|
|
520
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
521
|
+
return new Response(`Initialization failed: ${errorMessage}`, {
|
|
522
|
+
status: 500
|
|
523
|
+
});
|
|
524
|
+
}
|
|
380
525
|
const upgradeUrl = new URL(request.url);
|
|
381
526
|
upgradeUrl.pathname = "/sse";
|
|
527
|
+
const existingHeaders = {};
|
|
528
|
+
request.headers.forEach((value, key) => {
|
|
529
|
+
existingHeaders[key] = value;
|
|
530
|
+
});
|
|
382
531
|
const response = await doStub.fetch(
|
|
383
532
|
new Request(upgradeUrl, {
|
|
384
533
|
headers: {
|
|
534
|
+
...existingHeaders,
|
|
385
535
|
Upgrade: "websocket",
|
|
386
536
|
// Required by PartyServer
|
|
387
537
|
"x-partykit-room": sessionId
|
|
@@ -417,10 +567,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
417
567
|
onMessage(event).catch(console.error);
|
|
418
568
|
});
|
|
419
569
|
ws.addEventListener("error", (error) => {
|
|
420
|
-
async function onError(
|
|
570
|
+
async function onError(_error) {
|
|
421
571
|
try {
|
|
422
572
|
await writer.close();
|
|
423
|
-
} catch (
|
|
573
|
+
} catch (_e) {
|
|
424
574
|
}
|
|
425
575
|
}
|
|
426
576
|
onError(error).catch(console.error);
|
|
@@ -437,9 +587,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
437
587
|
});
|
|
438
588
|
return new Response(readable, {
|
|
439
589
|
headers: {
|
|
440
|
-
"Content-Type": "text/event-stream",
|
|
441
590
|
"Cache-Control": "no-cache",
|
|
442
591
|
Connection: "keep-alive",
|
|
592
|
+
"Content-Type": "text/event-stream",
|
|
443
593
|
...corsHeaders(request, corsOptions)
|
|
444
594
|
}
|
|
445
595
|
});
|
|
@@ -472,26 +622,28 @@ data: ${JSON.stringify(result.data)}
|
|
|
472
622
|
}
|
|
473
623
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
474
624
|
const doStub = namespace.get(id);
|
|
475
|
-
const
|
|
625
|
+
const messageBody = await request.json();
|
|
626
|
+
await doStub.updateProps(ctx.props);
|
|
627
|
+
const error = await doStub.onSSEMcpMessage(sessionId, messageBody);
|
|
476
628
|
if (error) {
|
|
477
629
|
return new Response(error.message, {
|
|
478
|
-
status: 400,
|
|
479
630
|
headers: {
|
|
480
|
-
"Content-Type": "text/event-stream",
|
|
481
631
|
"Cache-Control": "no-cache",
|
|
482
632
|
Connection: "keep-alive",
|
|
633
|
+
"Content-Type": "text/event-stream",
|
|
483
634
|
...corsHeaders(request, corsOptions)
|
|
484
|
-
}
|
|
635
|
+
},
|
|
636
|
+
status: 400
|
|
485
637
|
});
|
|
486
638
|
}
|
|
487
639
|
return new Response("Accepted", {
|
|
488
|
-
status: 202,
|
|
489
640
|
headers: {
|
|
490
|
-
"Content-Type": "text/event-stream",
|
|
491
641
|
"Cache-Control": "no-cache",
|
|
492
642
|
Connection: "keep-alive",
|
|
643
|
+
"Content-Type": "text/event-stream",
|
|
493
644
|
...corsHeaders(request, corsOptions)
|
|
494
|
-
}
|
|
645
|
+
},
|
|
646
|
+
status: 202
|
|
495
647
|
});
|
|
496
648
|
}
|
|
497
649
|
return new Response("Not Found", { status: 404 });
|
|
@@ -521,7 +673,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
521
673
|
);
|
|
522
674
|
return new Response("Invalid binding", { status: 500 });
|
|
523
675
|
}
|
|
524
|
-
if (bindingValue
|
|
676
|
+
if (!isDurableObjectNamespace(bindingValue)) {
|
|
525
677
|
return new Response("Invalid binding", { status: 500 });
|
|
526
678
|
}
|
|
527
679
|
const namespace = bindingValue;
|
|
@@ -529,24 +681,24 @@ data: ${JSON.stringify(result.data)}
|
|
|
529
681
|
const acceptHeader = request.headers.get("accept");
|
|
530
682
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
531
683
|
const body2 = JSON.stringify({
|
|
532
|
-
jsonrpc: "2.0",
|
|
533
684
|
error: {
|
|
534
685
|
code: -32e3,
|
|
535
686
|
message: "Not Acceptable: Client must accept both application/json and text/event-stream"
|
|
536
687
|
},
|
|
537
|
-
id: null
|
|
688
|
+
id: null,
|
|
689
|
+
jsonrpc: "2.0"
|
|
538
690
|
});
|
|
539
691
|
return new Response(body2, { status: 406 });
|
|
540
692
|
}
|
|
541
693
|
const ct = request.headers.get("content-type");
|
|
542
694
|
if (!ct || !ct.includes("application/json")) {
|
|
543
695
|
const body2 = JSON.stringify({
|
|
544
|
-
jsonrpc: "2.0",
|
|
545
696
|
error: {
|
|
546
697
|
code: -32e3,
|
|
547
698
|
message: "Unsupported Media Type: Content-Type must be application/json"
|
|
548
699
|
},
|
|
549
|
-
id: null
|
|
700
|
+
id: null,
|
|
701
|
+
jsonrpc: "2.0"
|
|
550
702
|
});
|
|
551
703
|
return new Response(body2, { status: 415 });
|
|
552
704
|
}
|
|
@@ -556,12 +708,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
556
708
|
);
|
|
557
709
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
|
|
558
710
|
const body2 = JSON.stringify({
|
|
559
|
-
jsonrpc: "2.0",
|
|
560
711
|
error: {
|
|
561
712
|
code: -32e3,
|
|
562
713
|
message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
|
|
563
714
|
},
|
|
564
|
-
id: null
|
|
715
|
+
id: null,
|
|
716
|
+
jsonrpc: "2.0"
|
|
565
717
|
});
|
|
566
718
|
return new Response(body2, { status: 413 });
|
|
567
719
|
}
|
|
@@ -569,14 +721,14 @@ data: ${JSON.stringify(result.data)}
|
|
|
569
721
|
let rawMessage;
|
|
570
722
|
try {
|
|
571
723
|
rawMessage = await request.json();
|
|
572
|
-
} catch (
|
|
724
|
+
} catch (_error) {
|
|
573
725
|
const body2 = JSON.stringify({
|
|
574
|
-
jsonrpc: "2.0",
|
|
575
726
|
error: {
|
|
576
727
|
code: -32700,
|
|
577
728
|
message: "Parse error: Invalid JSON"
|
|
578
729
|
},
|
|
579
|
-
id: null
|
|
730
|
+
id: null,
|
|
731
|
+
jsonrpc: "2.0"
|
|
580
732
|
});
|
|
581
733
|
return new Response(body2, { status: 400 });
|
|
582
734
|
}
|
|
@@ -590,12 +742,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
590
742
|
for (const msg of arrayMessage) {
|
|
591
743
|
if (!JSONRPCMessageSchema.safeParse(msg).success) {
|
|
592
744
|
const body2 = JSON.stringify({
|
|
593
|
-
jsonrpc: "2.0",
|
|
594
745
|
error: {
|
|
595
746
|
code: -32700,
|
|
596
747
|
message: "Parse error: Invalid JSON-RPC message"
|
|
597
748
|
},
|
|
598
|
-
id: null
|
|
749
|
+
id: null,
|
|
750
|
+
jsonrpc: "2.0"
|
|
599
751
|
});
|
|
600
752
|
return new Response(body2, { status: 400 });
|
|
601
753
|
}
|
|
@@ -606,34 +758,34 @@ data: ${JSON.stringify(result.data)}
|
|
|
606
758
|
);
|
|
607
759
|
if (isInitializationRequest && sessionId) {
|
|
608
760
|
const body2 = JSON.stringify({
|
|
609
|
-
jsonrpc: "2.0",
|
|
610
761
|
error: {
|
|
611
762
|
code: -32600,
|
|
612
763
|
message: "Invalid Request: Initialization requests must not include a sessionId"
|
|
613
764
|
},
|
|
614
|
-
id: null
|
|
765
|
+
id: null,
|
|
766
|
+
jsonrpc: "2.0"
|
|
615
767
|
});
|
|
616
768
|
return new Response(body2, { status: 400 });
|
|
617
769
|
}
|
|
618
770
|
if (isInitializationRequest && messages.length > 1) {
|
|
619
771
|
const body2 = JSON.stringify({
|
|
620
|
-
jsonrpc: "2.0",
|
|
621
772
|
error: {
|
|
622
773
|
code: -32600,
|
|
623
774
|
message: "Invalid Request: Only one initialization request is allowed"
|
|
624
775
|
},
|
|
625
|
-
id: null
|
|
776
|
+
id: null,
|
|
777
|
+
jsonrpc: "2.0"
|
|
626
778
|
});
|
|
627
779
|
return new Response(body2, { status: 400 });
|
|
628
780
|
}
|
|
629
781
|
if (!isInitializationRequest && !sessionId) {
|
|
630
782
|
const body2 = JSON.stringify({
|
|
631
|
-
jsonrpc: "2.0",
|
|
632
783
|
error: {
|
|
633
784
|
code: -32e3,
|
|
634
785
|
message: "Bad Request: Mcp-Session-Id header is required"
|
|
635
786
|
},
|
|
636
|
-
id: null
|
|
787
|
+
id: null,
|
|
788
|
+
jsonrpc: "2.0"
|
|
637
789
|
});
|
|
638
790
|
return new Response(body2, { status: 400 });
|
|
639
791
|
}
|
|
@@ -642,27 +794,48 @@ data: ${JSON.stringify(result.data)}
|
|
|
642
794
|
const doStub = namespace.get(id);
|
|
643
795
|
const isInitialized = await doStub.isInitialized();
|
|
644
796
|
if (isInitializationRequest) {
|
|
645
|
-
|
|
646
|
-
|
|
797
|
+
try {
|
|
798
|
+
await doStub._init(ctx.props);
|
|
799
|
+
await doStub.setInitialized();
|
|
800
|
+
} catch (error) {
|
|
801
|
+
console.error("Failed to initialize McpAgent:", error);
|
|
802
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
803
|
+
const body2 = JSON.stringify({
|
|
804
|
+
error: {
|
|
805
|
+
code: -32001,
|
|
806
|
+
message: `Initialization failed: ${errorMessage}`
|
|
807
|
+
},
|
|
808
|
+
id: null,
|
|
809
|
+
jsonrpc: "2.0"
|
|
810
|
+
});
|
|
811
|
+
return new Response(body2, { status: 500 });
|
|
812
|
+
}
|
|
647
813
|
} else if (!isInitialized) {
|
|
648
814
|
const body2 = JSON.stringify({
|
|
649
|
-
jsonrpc: "2.0",
|
|
650
815
|
error: {
|
|
651
816
|
code: -32001,
|
|
652
817
|
message: "Session not found"
|
|
653
818
|
},
|
|
654
|
-
id: null
|
|
819
|
+
id: null,
|
|
820
|
+
jsonrpc: "2.0"
|
|
655
821
|
});
|
|
656
822
|
return new Response(body2, { status: 404 });
|
|
823
|
+
} else {
|
|
824
|
+
await doStub.updateProps(ctx.props);
|
|
657
825
|
}
|
|
658
826
|
const { readable, writable } = new TransformStream();
|
|
659
827
|
const writer = writable.getWriter();
|
|
660
828
|
const encoder = new TextEncoder();
|
|
661
829
|
const upgradeUrl = new URL(request.url);
|
|
662
830
|
upgradeUrl.pathname = "/streamable-http";
|
|
831
|
+
const existingHeaders = {};
|
|
832
|
+
request.headers.forEach((value, key) => {
|
|
833
|
+
existingHeaders[key] = value;
|
|
834
|
+
});
|
|
663
835
|
const response = await doStub.fetch(
|
|
664
836
|
new Request(upgradeUrl, {
|
|
665
837
|
headers: {
|
|
838
|
+
...existingHeaders,
|
|
666
839
|
Upgrade: "websocket",
|
|
667
840
|
// Required by PartyServer
|
|
668
841
|
"x-partykit-room": sessionId
|
|
@@ -674,12 +847,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
674
847
|
console.error("Failed to establish WebSocket connection");
|
|
675
848
|
await writer.close();
|
|
676
849
|
const body2 = JSON.stringify({
|
|
677
|
-
jsonrpc: "2.0",
|
|
678
850
|
error: {
|
|
679
851
|
code: -32001,
|
|
680
852
|
message: "Failed to establish WebSocket connection"
|
|
681
853
|
},
|
|
682
|
-
id: null
|
|
854
|
+
id: null,
|
|
855
|
+
jsonrpc: "2.0"
|
|
683
856
|
});
|
|
684
857
|
return new Response(body2, { status: 500 });
|
|
685
858
|
}
|
|
@@ -712,10 +885,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
712
885
|
onMessage(event).catch(console.error);
|
|
713
886
|
});
|
|
714
887
|
ws.addEventListener("error", (error) => {
|
|
715
|
-
async function onError(
|
|
888
|
+
async function onError(_error) {
|
|
716
889
|
try {
|
|
717
890
|
await writer.close();
|
|
718
|
-
} catch (
|
|
891
|
+
} catch (_e) {
|
|
719
892
|
}
|
|
720
893
|
}
|
|
721
894
|
onError(error).catch(console.error);
|
|
@@ -739,8 +912,8 @@ data: ${JSON.stringify(result.data)}
|
|
|
739
912
|
}
|
|
740
913
|
ws.close();
|
|
741
914
|
return new Response(null, {
|
|
742
|
-
|
|
743
|
-
|
|
915
|
+
headers: corsHeaders(request, corsOptions),
|
|
916
|
+
status: 202
|
|
744
917
|
});
|
|
745
918
|
}
|
|
746
919
|
for (const message of messages) {
|
|
@@ -751,9 +924,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
751
924
|
}
|
|
752
925
|
return new Response(readable, {
|
|
753
926
|
headers: {
|
|
754
|
-
"Content-Type": "text/event-stream",
|
|
755
927
|
"Cache-Control": "no-cache",
|
|
756
928
|
Connection: "keep-alive",
|
|
929
|
+
"Content-Type": "text/event-stream",
|
|
757
930
|
"mcp-session-id": sessionId,
|
|
758
931
|
...corsHeaders(request, corsOptions)
|
|
759
932
|
},
|
|
@@ -761,12 +934,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
761
934
|
});
|
|
762
935
|
}
|
|
763
936
|
const body = JSON.stringify({
|
|
764
|
-
jsonrpc: "2.0",
|
|
765
937
|
error: {
|
|
766
938
|
code: -32e3,
|
|
767
939
|
message: "Method not allowed"
|
|
768
940
|
},
|
|
769
|
-
id: null
|
|
941
|
+
id: null,
|
|
942
|
+
jsonrpc: "2.0"
|
|
770
943
|
});
|
|
771
944
|
return new Response(body, { status: 405 });
|
|
772
945
|
}
|
|
@@ -774,6 +947,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
774
947
|
}
|
|
775
948
|
};
|
|
776
949
|
export {
|
|
777
|
-
|
|
950
|
+
ElicitRequestSchema,
|
|
951
|
+
McpAgent,
|
|
952
|
+
SSEEdgeClientTransport,
|
|
953
|
+
StreamableHTTPEdgeClientTransport
|
|
778
954
|
};
|
|
779
955
|
//# sourceMappingURL=index.js.map
|