agents 0.0.0-eeb70e2 → 0.0.0-f0c6dce
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 +12 -8
- package/dist/ai-chat-agent.js +166 -59
- 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-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +63 -72
- package/dist/ai-react.js +161 -54
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +36 -19
- 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-MWQSU7GK.js +1301 -0
- package/dist/chunk-MWQSU7GK.js.map +1 -0
- package/dist/{chunk-BZXOAZUX.js → chunk-PVQZBKN7.js} +5 -5
- package/dist/chunk-PVQZBKN7.js.map +1 -0
- package/dist/{chunk-VCSB47AK.js → chunk-QEVM4BVL.js} +10 -10
- 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-OYJXQRRH.js → chunk-VYENMKFS.js} +182 -35
- package/dist/chunk-VYENMKFS.js.map +1 -0
- package/dist/client-B9tFv5gX.d.ts +4607 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -1
- package/dist/index.d.ts +166 -22
- package/dist/index.js +13 -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 +233 -59
- 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 +12 -8
- package/dist/react.js +12 -10
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +81 -7
- package/dist/schedule.js +19 -6
- package/dist/schedule.js.map +1 -1
- package/package.json +83 -70
- package/src/index.ts +857 -170
- package/dist/chunk-BZXOAZUX.js.map +0 -1
- package/dist/chunk-OYJXQRRH.js.map +0 -1
- package/dist/chunk-P3RZJ72N.js +0 -783
- package/dist/chunk-P3RZJ72N.js.map +0 -1
- package/dist/chunk-VCSB47AK.js.map +0 -1
package/dist/mcp/client.js
CHANGED
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { MCPClientManager } from '
|
|
1
|
+
import { M as MCPClientManager } from '../client-B9tFv5gX.js';
|
|
2
|
+
export { S as SSEEdgeClientTransport, a as StreamableHTTPEdgeClientTransport } from '../client-B9tFv5gX.js';
|
|
2
3
|
import { DurableObject } from 'cloudflare:workers';
|
|
3
|
-
import { Connection, WSMessage } from 'partyserver';
|
|
4
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
4
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { ElicitResult } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
export { ElicitRequest, ElicitRequestSchema, ElicitResult } from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
import { Connection, WSMessage } from 'partyserver';
|
|
6
9
|
import 'zod';
|
|
7
|
-
import '@modelcontextprotocol/sdk/types.js';
|
|
8
10
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
11
|
+
import '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
12
|
+
import 'ai';
|
|
9
13
|
import '@modelcontextprotocol/sdk/client/sse.js';
|
|
14
|
+
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
10
15
|
import './do-oauth-client-provider.js';
|
|
11
16
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
12
17
|
import '@modelcontextprotocol/sdk/shared/auth.js';
|
|
13
|
-
import '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
14
|
-
import 'ai';
|
|
15
18
|
|
|
16
19
|
interface CORSOptions {
|
|
17
20
|
origin?: string;
|
|
@@ -40,6 +43,13 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
|
|
|
40
43
|
get state(): State;
|
|
41
44
|
sql<T = Record<string, string | number | boolean | null>>(strings: TemplateStringsArray, ...values: (string | number | boolean | null)[]): T[];
|
|
42
45
|
setState(state: State): void;
|
|
46
|
+
/**
|
|
47
|
+
* Elicit user input with a message and schema
|
|
48
|
+
*/
|
|
49
|
+
elicitInput(params: {
|
|
50
|
+
message: string;
|
|
51
|
+
requestedSchema: unknown;
|
|
52
|
+
}): Promise<ElicitResult>;
|
|
43
53
|
onStateUpdate(state: State | undefined, source: Connection | "server"): void;
|
|
44
54
|
onStart(): Promise<void>;
|
|
45
55
|
/**
|
|
@@ -49,31 +59,49 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
|
|
|
49
59
|
props: Props;
|
|
50
60
|
initRun: boolean;
|
|
51
61
|
abstract init(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Handle errors that occur during initialization or operation.
|
|
64
|
+
* Override this method to provide custom error handling.
|
|
65
|
+
* @param error - The error that occurred
|
|
66
|
+
* @returns An error response object with status code and message
|
|
67
|
+
*/
|
|
68
|
+
onError(error: Error): {
|
|
69
|
+
status: number;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
52
72
|
_init(props: Props): Promise<void>;
|
|
53
73
|
setInitialized(): Promise<void>;
|
|
54
74
|
isInitialized(): Promise<boolean>;
|
|
75
|
+
updateProps(props: Props): Promise<void>;
|
|
55
76
|
private _initialize;
|
|
56
77
|
fetch(request: Request): Promise<Response>;
|
|
57
78
|
getWebSocket(): WebSocket | null;
|
|
58
79
|
getWebSocketForResponseID(id: string): WebSocket | null;
|
|
59
80
|
onMessage(connection: Connection, event: WSMessage): Promise<void>;
|
|
60
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Wait for elicitation response through storage polling
|
|
83
|
+
*/
|
|
84
|
+
private _waitForElicitationResponse;
|
|
85
|
+
/**
|
|
86
|
+
* Handle elicitation responses */
|
|
87
|
+
private _handleElicitationResponse;
|
|
88
|
+
onSSEMcpMessage(_sessionId: string, messageBody: unknown): Promise<Error | null>;
|
|
61
89
|
webSocketMessage(ws: WebSocket, event: ArrayBuffer | string): Promise<void>;
|
|
62
90
|
webSocketError(ws: WebSocket, error: unknown): Promise<void>;
|
|
63
91
|
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
|
|
64
|
-
static mount(path: string, { binding, corsOptions
|
|
92
|
+
static mount(path: string, { binding, corsOptions }?: {
|
|
65
93
|
binding?: string;
|
|
66
94
|
corsOptions?: CORSOptions;
|
|
67
95
|
}): {
|
|
68
96
|
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
69
97
|
};
|
|
70
|
-
static serveSSE(path: string, { binding, corsOptions
|
|
98
|
+
static serveSSE(path: string, { binding, corsOptions }?: {
|
|
71
99
|
binding?: string;
|
|
72
100
|
corsOptions?: CORSOptions;
|
|
73
101
|
}): {
|
|
74
102
|
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
75
103
|
};
|
|
76
|
-
static serve(path: string, { binding, corsOptions
|
|
104
|
+
static serve(path: string, { binding, corsOptions }?: {
|
|
77
105
|
binding?: string;
|
|
78
106
|
corsOptions?: CORSOptions;
|
|
79
107
|
}): {
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Agent
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
} from "../chunk-MWQSU7GK.js";
|
|
4
|
+
import {
|
|
5
|
+
SSEEdgeClientTransport,
|
|
6
|
+
StreamableHTTPEdgeClientTransport
|
|
7
|
+
} from "../chunk-VYENMKFS.js";
|
|
8
|
+
import "../chunk-PVQZBKN7.js";
|
|
9
|
+
import "../chunk-QEVM4BVL.js";
|
|
10
|
+
import "../chunk-AVYJQSLW.js";
|
|
7
11
|
|
|
8
12
|
// src/mcp/index.ts
|
|
9
13
|
import { DurableObject } from "cloudflare:workers";
|
|
10
14
|
import {
|
|
11
15
|
InitializeRequestSchema,
|
|
16
|
+
JSONRPCMessageSchema,
|
|
12
17
|
isJSONRPCError,
|
|
13
18
|
isJSONRPCNotification,
|
|
14
19
|
isJSONRPCRequest,
|
|
15
|
-
isJSONRPCResponse
|
|
16
|
-
|
|
20
|
+
isJSONRPCResponse
|
|
21
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
22
|
+
import {
|
|
23
|
+
ElicitRequestSchema
|
|
17
24
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
18
25
|
var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
19
|
-
function corsHeaders(
|
|
26
|
+
function corsHeaders(_request, corsOptions = {}) {
|
|
20
27
|
const origin = "*";
|
|
21
28
|
return {
|
|
22
|
-
"Access-Control-Allow-
|
|
29
|
+
"Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
|
|
23
30
|
"Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
|
|
24
|
-
"Access-Control-Allow-
|
|
25
|
-
"Access-Control-
|
|
26
|
-
"Access-Control-
|
|
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()
|
|
27
34
|
};
|
|
28
35
|
}
|
|
29
36
|
function isDurableObjectNamespace(namespace) {
|
|
@@ -141,6 +148,46 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
141
148
|
setState(state) {
|
|
142
149
|
return this._agent.setState(state);
|
|
143
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
|
|
144
191
|
onStateUpdate(state, source) {
|
|
145
192
|
}
|
|
146
193
|
async onStart() {
|
|
@@ -177,15 +224,32 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
177
224
|
await server.connect(this._transport);
|
|
178
225
|
}
|
|
179
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
|
+
}
|
|
180
240
|
async _init(props) {
|
|
181
|
-
await this.
|
|
241
|
+
await this.updateProps(props);
|
|
182
242
|
if (!this.ctx.storage.get("transportType")) {
|
|
183
243
|
await this.ctx.storage.put("transportType", "unset");
|
|
184
244
|
}
|
|
185
|
-
this.props = props;
|
|
186
245
|
if (!this.initRun) {
|
|
187
246
|
this.initRun = true;
|
|
188
|
-
|
|
247
|
+
try {
|
|
248
|
+
await this.init();
|
|
249
|
+
} catch (error) {
|
|
250
|
+
const errorResponse = this.onError(error);
|
|
251
|
+
throw new Error(`Initialization failed: ${errorResponse.message}`);
|
|
252
|
+
}
|
|
189
253
|
}
|
|
190
254
|
}
|
|
191
255
|
async setInitialized() {
|
|
@@ -194,6 +258,10 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
194
258
|
async isInitialized() {
|
|
195
259
|
return await this.ctx.storage.get("initialized") === true;
|
|
196
260
|
}
|
|
261
|
+
async updateProps(props) {
|
|
262
|
+
await this.ctx.storage.put("props", props ?? {});
|
|
263
|
+
this.props = props;
|
|
264
|
+
}
|
|
197
265
|
async _initialize() {
|
|
198
266
|
await this.ctx.blockConcurrencyWhile(async () => {
|
|
199
267
|
this._status = "starting";
|
|
@@ -280,14 +348,78 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
280
348
|
this._transport?.onerror?.(error);
|
|
281
349
|
return;
|
|
282
350
|
}
|
|
351
|
+
if (await this._handleElicitationResponse(message)) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
283
354
|
if (isJSONRPCRequest(message)) {
|
|
284
355
|
this._requestIdToConnectionId.set(message.id.toString(), connection.id);
|
|
285
356
|
}
|
|
286
357
|
this._transport?.onmessage?.(message);
|
|
287
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Wait for elicitation response through storage polling
|
|
361
|
+
*/
|
|
362
|
+
async _waitForElicitationResponse(requestId) {
|
|
363
|
+
const startTime = Date.now();
|
|
364
|
+
const timeout = 6e4;
|
|
365
|
+
try {
|
|
366
|
+
while (Date.now() - startTime < timeout) {
|
|
367
|
+
const response = await this.ctx.storage.get(
|
|
368
|
+
`elicitation:response:${requestId}`
|
|
369
|
+
);
|
|
370
|
+
if (response) {
|
|
371
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
372
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
373
|
+
return response;
|
|
374
|
+
}
|
|
375
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
376
|
+
}
|
|
377
|
+
throw new Error("Elicitation request timed out");
|
|
378
|
+
} finally {
|
|
379
|
+
await this.ctx.storage.delete(`elicitation:${requestId}`);
|
|
380
|
+
await this.ctx.storage.delete(`elicitation:response:${requestId}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Handle elicitation responses */
|
|
385
|
+
async _handleElicitationResponse(message) {
|
|
386
|
+
if (isJSONRPCResponse(message) && message.result) {
|
|
387
|
+
const requestId = message.id?.toString();
|
|
388
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
389
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
390
|
+
`elicitation:${requestId}`
|
|
391
|
+
);
|
|
392
|
+
if (!pendingRequest) return false;
|
|
393
|
+
await this.ctx.storage.put(
|
|
394
|
+
`elicitation:response:${requestId}`,
|
|
395
|
+
message.result
|
|
396
|
+
);
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
if (isJSONRPCError(message)) {
|
|
400
|
+
const requestId = message.id?.toString();
|
|
401
|
+
if (!requestId || !requestId.startsWith("elicit_")) return false;
|
|
402
|
+
const pendingRequest = await this.ctx.storage.get(
|
|
403
|
+
`elicitation:${requestId}`
|
|
404
|
+
);
|
|
405
|
+
if (!pendingRequest) return false;
|
|
406
|
+
const errorResult = {
|
|
407
|
+
action: "cancel",
|
|
408
|
+
content: {
|
|
409
|
+
error: message.error.message || "Elicitation request failed"
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
await this.ctx.storage.put(
|
|
413
|
+
`elicitation:response:${requestId}`,
|
|
414
|
+
errorResult
|
|
415
|
+
);
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
288
420
|
// All messages received over SSE after the initial connection has been established
|
|
289
421
|
// will be passed here
|
|
290
|
-
async onSSEMcpMessage(
|
|
422
|
+
async onSSEMcpMessage(_sessionId, messageBody) {
|
|
291
423
|
if (this._status !== "started") {
|
|
292
424
|
await this._initialize();
|
|
293
425
|
}
|
|
@@ -295,14 +427,16 @@ var McpAgent = class _McpAgent extends DurableObject {
|
|
|
295
427
|
return new Error("Internal Server Error: Expected SSE protocol");
|
|
296
428
|
}
|
|
297
429
|
try {
|
|
298
|
-
const message = await request.json();
|
|
299
430
|
let parsedMessage;
|
|
300
431
|
try {
|
|
301
|
-
parsedMessage = JSONRPCMessageSchema.parse(
|
|
432
|
+
parsedMessage = JSONRPCMessageSchema.parse(messageBody);
|
|
302
433
|
} catch (error) {
|
|
303
434
|
this._transport?.onerror?.(error);
|
|
304
435
|
throw error;
|
|
305
436
|
}
|
|
437
|
+
if (await this._handleElicitationResponse(parsedMessage)) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
306
440
|
this._transport?.onmessage?.(parsedMessage);
|
|
307
441
|
return null;
|
|
308
442
|
} catch (error) {
|
|
@@ -379,12 +513,26 @@ data: ${relativeUrlWithSession}
|
|
|
379
513
|
writer.write(encoder.encode(endpointMessage));
|
|
380
514
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
381
515
|
const doStub = namespace.get(id);
|
|
382
|
-
|
|
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
|
+
}
|
|
383
526
|
const upgradeUrl = new URL(request.url);
|
|
384
527
|
upgradeUrl.pathname = "/sse";
|
|
528
|
+
const existingHeaders = {};
|
|
529
|
+
request.headers.forEach((value, key) => {
|
|
530
|
+
existingHeaders[key] = value;
|
|
531
|
+
});
|
|
385
532
|
const response = await doStub.fetch(
|
|
386
533
|
new Request(upgradeUrl, {
|
|
387
534
|
headers: {
|
|
535
|
+
...existingHeaders,
|
|
388
536
|
Upgrade: "websocket",
|
|
389
537
|
// Required by PartyServer
|
|
390
538
|
"x-partykit-room": sessionId
|
|
@@ -420,10 +568,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
420
568
|
onMessage(event).catch(console.error);
|
|
421
569
|
});
|
|
422
570
|
ws.addEventListener("error", (error) => {
|
|
423
|
-
async function onError(
|
|
571
|
+
async function onError(_error) {
|
|
424
572
|
try {
|
|
425
573
|
await writer.close();
|
|
426
|
-
} catch (
|
|
574
|
+
} catch (_e) {
|
|
427
575
|
}
|
|
428
576
|
}
|
|
429
577
|
onError(error).catch(console.error);
|
|
@@ -440,9 +588,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
440
588
|
});
|
|
441
589
|
return new Response(readable, {
|
|
442
590
|
headers: {
|
|
443
|
-
"Content-Type": "text/event-stream",
|
|
444
591
|
"Cache-Control": "no-cache",
|
|
445
592
|
Connection: "keep-alive",
|
|
593
|
+
"Content-Type": "text/event-stream",
|
|
446
594
|
...corsHeaders(request, corsOptions)
|
|
447
595
|
}
|
|
448
596
|
});
|
|
@@ -475,26 +623,28 @@ data: ${JSON.stringify(result.data)}
|
|
|
475
623
|
}
|
|
476
624
|
const id = namespace.idFromName(`sse:${sessionId}`);
|
|
477
625
|
const doStub = namespace.get(id);
|
|
478
|
-
const
|
|
626
|
+
const messageBody = await request.json();
|
|
627
|
+
await doStub.updateProps(ctx.props);
|
|
628
|
+
const error = await doStub.onSSEMcpMessage(sessionId, messageBody);
|
|
479
629
|
if (error) {
|
|
480
630
|
return new Response(error.message, {
|
|
481
|
-
status: 400,
|
|
482
631
|
headers: {
|
|
483
|
-
"Content-Type": "text/event-stream",
|
|
484
632
|
"Cache-Control": "no-cache",
|
|
485
633
|
Connection: "keep-alive",
|
|
634
|
+
"Content-Type": "text/event-stream",
|
|
486
635
|
...corsHeaders(request, corsOptions)
|
|
487
|
-
}
|
|
636
|
+
},
|
|
637
|
+
status: 400
|
|
488
638
|
});
|
|
489
639
|
}
|
|
490
640
|
return new Response("Accepted", {
|
|
491
|
-
status: 202,
|
|
492
641
|
headers: {
|
|
493
|
-
"Content-Type": "text/event-stream",
|
|
494
642
|
"Cache-Control": "no-cache",
|
|
495
643
|
Connection: "keep-alive",
|
|
644
|
+
"Content-Type": "text/event-stream",
|
|
496
645
|
...corsHeaders(request, corsOptions)
|
|
497
|
-
}
|
|
646
|
+
},
|
|
647
|
+
status: 202
|
|
498
648
|
});
|
|
499
649
|
}
|
|
500
650
|
return new Response("Not Found", { status: 404 });
|
|
@@ -532,24 +682,24 @@ data: ${JSON.stringify(result.data)}
|
|
|
532
682
|
const acceptHeader = request.headers.get("accept");
|
|
533
683
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
534
684
|
const body2 = JSON.stringify({
|
|
535
|
-
jsonrpc: "2.0",
|
|
536
685
|
error: {
|
|
537
686
|
code: -32e3,
|
|
538
687
|
message: "Not Acceptable: Client must accept both application/json and text/event-stream"
|
|
539
688
|
},
|
|
540
|
-
id: null
|
|
689
|
+
id: null,
|
|
690
|
+
jsonrpc: "2.0"
|
|
541
691
|
});
|
|
542
692
|
return new Response(body2, { status: 406 });
|
|
543
693
|
}
|
|
544
694
|
const ct = request.headers.get("content-type");
|
|
545
695
|
if (!ct || !ct.includes("application/json")) {
|
|
546
696
|
const body2 = JSON.stringify({
|
|
547
|
-
jsonrpc: "2.0",
|
|
548
697
|
error: {
|
|
549
698
|
code: -32e3,
|
|
550
699
|
message: "Unsupported Media Type: Content-Type must be application/json"
|
|
551
700
|
},
|
|
552
|
-
id: null
|
|
701
|
+
id: null,
|
|
702
|
+
jsonrpc: "2.0"
|
|
553
703
|
});
|
|
554
704
|
return new Response(body2, { status: 415 });
|
|
555
705
|
}
|
|
@@ -559,12 +709,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
559
709
|
);
|
|
560
710
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
|
|
561
711
|
const body2 = JSON.stringify({
|
|
562
|
-
jsonrpc: "2.0",
|
|
563
712
|
error: {
|
|
564
713
|
code: -32e3,
|
|
565
714
|
message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
|
|
566
715
|
},
|
|
567
|
-
id: null
|
|
716
|
+
id: null,
|
|
717
|
+
jsonrpc: "2.0"
|
|
568
718
|
});
|
|
569
719
|
return new Response(body2, { status: 413 });
|
|
570
720
|
}
|
|
@@ -572,14 +722,14 @@ data: ${JSON.stringify(result.data)}
|
|
|
572
722
|
let rawMessage;
|
|
573
723
|
try {
|
|
574
724
|
rawMessage = await request.json();
|
|
575
|
-
} catch (
|
|
725
|
+
} catch (_error) {
|
|
576
726
|
const body2 = JSON.stringify({
|
|
577
|
-
jsonrpc: "2.0",
|
|
578
727
|
error: {
|
|
579
728
|
code: -32700,
|
|
580
729
|
message: "Parse error: Invalid JSON"
|
|
581
730
|
},
|
|
582
|
-
id: null
|
|
731
|
+
id: null,
|
|
732
|
+
jsonrpc: "2.0"
|
|
583
733
|
});
|
|
584
734
|
return new Response(body2, { status: 400 });
|
|
585
735
|
}
|
|
@@ -593,12 +743,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
593
743
|
for (const msg of arrayMessage) {
|
|
594
744
|
if (!JSONRPCMessageSchema.safeParse(msg).success) {
|
|
595
745
|
const body2 = JSON.stringify({
|
|
596
|
-
jsonrpc: "2.0",
|
|
597
746
|
error: {
|
|
598
747
|
code: -32700,
|
|
599
748
|
message: "Parse error: Invalid JSON-RPC message"
|
|
600
749
|
},
|
|
601
|
-
id: null
|
|
750
|
+
id: null,
|
|
751
|
+
jsonrpc: "2.0"
|
|
602
752
|
});
|
|
603
753
|
return new Response(body2, { status: 400 });
|
|
604
754
|
}
|
|
@@ -609,34 +759,34 @@ data: ${JSON.stringify(result.data)}
|
|
|
609
759
|
);
|
|
610
760
|
if (isInitializationRequest && sessionId) {
|
|
611
761
|
const body2 = JSON.stringify({
|
|
612
|
-
jsonrpc: "2.0",
|
|
613
762
|
error: {
|
|
614
763
|
code: -32600,
|
|
615
764
|
message: "Invalid Request: Initialization requests must not include a sessionId"
|
|
616
765
|
},
|
|
617
|
-
id: null
|
|
766
|
+
id: null,
|
|
767
|
+
jsonrpc: "2.0"
|
|
618
768
|
});
|
|
619
769
|
return new Response(body2, { status: 400 });
|
|
620
770
|
}
|
|
621
771
|
if (isInitializationRequest && messages.length > 1) {
|
|
622
772
|
const body2 = JSON.stringify({
|
|
623
|
-
jsonrpc: "2.0",
|
|
624
773
|
error: {
|
|
625
774
|
code: -32600,
|
|
626
775
|
message: "Invalid Request: Only one initialization request is allowed"
|
|
627
776
|
},
|
|
628
|
-
id: null
|
|
777
|
+
id: null,
|
|
778
|
+
jsonrpc: "2.0"
|
|
629
779
|
});
|
|
630
780
|
return new Response(body2, { status: 400 });
|
|
631
781
|
}
|
|
632
782
|
if (!isInitializationRequest && !sessionId) {
|
|
633
783
|
const body2 = JSON.stringify({
|
|
634
|
-
jsonrpc: "2.0",
|
|
635
784
|
error: {
|
|
636
785
|
code: -32e3,
|
|
637
786
|
message: "Bad Request: Mcp-Session-Id header is required"
|
|
638
787
|
},
|
|
639
|
-
id: null
|
|
788
|
+
id: null,
|
|
789
|
+
jsonrpc: "2.0"
|
|
640
790
|
});
|
|
641
791
|
return new Response(body2, { status: 400 });
|
|
642
792
|
}
|
|
@@ -645,27 +795,48 @@ data: ${JSON.stringify(result.data)}
|
|
|
645
795
|
const doStub = namespace.get(id);
|
|
646
796
|
const isInitialized = await doStub.isInitialized();
|
|
647
797
|
if (isInitializationRequest) {
|
|
648
|
-
|
|
649
|
-
|
|
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
|
+
}
|
|
650
814
|
} else if (!isInitialized) {
|
|
651
815
|
const body2 = JSON.stringify({
|
|
652
|
-
jsonrpc: "2.0",
|
|
653
816
|
error: {
|
|
654
817
|
code: -32001,
|
|
655
818
|
message: "Session not found"
|
|
656
819
|
},
|
|
657
|
-
id: null
|
|
820
|
+
id: null,
|
|
821
|
+
jsonrpc: "2.0"
|
|
658
822
|
});
|
|
659
823
|
return new Response(body2, { status: 404 });
|
|
824
|
+
} else {
|
|
825
|
+
await doStub.updateProps(ctx.props);
|
|
660
826
|
}
|
|
661
827
|
const { readable, writable } = new TransformStream();
|
|
662
828
|
const writer = writable.getWriter();
|
|
663
829
|
const encoder = new TextEncoder();
|
|
664
830
|
const upgradeUrl = new URL(request.url);
|
|
665
831
|
upgradeUrl.pathname = "/streamable-http";
|
|
832
|
+
const existingHeaders = {};
|
|
833
|
+
request.headers.forEach((value, key) => {
|
|
834
|
+
existingHeaders[key] = value;
|
|
835
|
+
});
|
|
666
836
|
const response = await doStub.fetch(
|
|
667
837
|
new Request(upgradeUrl, {
|
|
668
838
|
headers: {
|
|
839
|
+
...existingHeaders,
|
|
669
840
|
Upgrade: "websocket",
|
|
670
841
|
// Required by PartyServer
|
|
671
842
|
"x-partykit-room": sessionId
|
|
@@ -677,12 +848,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
677
848
|
console.error("Failed to establish WebSocket connection");
|
|
678
849
|
await writer.close();
|
|
679
850
|
const body2 = JSON.stringify({
|
|
680
|
-
jsonrpc: "2.0",
|
|
681
851
|
error: {
|
|
682
852
|
code: -32001,
|
|
683
853
|
message: "Failed to establish WebSocket connection"
|
|
684
854
|
},
|
|
685
|
-
id: null
|
|
855
|
+
id: null,
|
|
856
|
+
jsonrpc: "2.0"
|
|
686
857
|
});
|
|
687
858
|
return new Response(body2, { status: 500 });
|
|
688
859
|
}
|
|
@@ -715,10 +886,10 @@ data: ${JSON.stringify(result.data)}
|
|
|
715
886
|
onMessage(event).catch(console.error);
|
|
716
887
|
});
|
|
717
888
|
ws.addEventListener("error", (error) => {
|
|
718
|
-
async function onError(
|
|
889
|
+
async function onError(_error) {
|
|
719
890
|
try {
|
|
720
891
|
await writer.close();
|
|
721
|
-
} catch (
|
|
892
|
+
} catch (_e) {
|
|
722
893
|
}
|
|
723
894
|
}
|
|
724
895
|
onError(error).catch(console.error);
|
|
@@ -742,8 +913,8 @@ data: ${JSON.stringify(result.data)}
|
|
|
742
913
|
}
|
|
743
914
|
ws.close();
|
|
744
915
|
return new Response(null, {
|
|
745
|
-
|
|
746
|
-
|
|
916
|
+
headers: corsHeaders(request, corsOptions),
|
|
917
|
+
status: 202
|
|
747
918
|
});
|
|
748
919
|
}
|
|
749
920
|
for (const message of messages) {
|
|
@@ -754,9 +925,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
754
925
|
}
|
|
755
926
|
return new Response(readable, {
|
|
756
927
|
headers: {
|
|
757
|
-
"Content-Type": "text/event-stream",
|
|
758
928
|
"Cache-Control": "no-cache",
|
|
759
929
|
Connection: "keep-alive",
|
|
930
|
+
"Content-Type": "text/event-stream",
|
|
760
931
|
"mcp-session-id": sessionId,
|
|
761
932
|
...corsHeaders(request, corsOptions)
|
|
762
933
|
},
|
|
@@ -764,12 +935,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
764
935
|
});
|
|
765
936
|
}
|
|
766
937
|
const body = JSON.stringify({
|
|
767
|
-
jsonrpc: "2.0",
|
|
768
938
|
error: {
|
|
769
939
|
code: -32e3,
|
|
770
940
|
message: "Method not allowed"
|
|
771
941
|
},
|
|
772
|
-
id: null
|
|
942
|
+
id: null,
|
|
943
|
+
jsonrpc: "2.0"
|
|
773
944
|
});
|
|
774
945
|
return new Response(body, { status: 405 });
|
|
775
946
|
}
|
|
@@ -777,6 +948,9 @@ data: ${JSON.stringify(result.data)}
|
|
|
777
948
|
}
|
|
778
949
|
};
|
|
779
950
|
export {
|
|
780
|
-
|
|
951
|
+
ElicitRequestSchema,
|
|
952
|
+
McpAgent,
|
|
953
|
+
SSEEdgeClientTransport,
|
|
954
|
+
StreamableHTTPEdgeClientTransport
|
|
781
955
|
};
|
|
782
956
|
//# sourceMappingURL=index.js.map
|