@seastudio/sdk 3.0.0
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 +108 -0
- package/bin/seastudio.js +3 -0
- package/dist/chunk-4ITOR5QE.js +901 -0
- package/dist/chunk-5QAINQWV.js +94 -0
- package/dist/chunk-6USQFZRH.js +291 -0
- package/dist/chunk-AGBZJGTY.cjs +1311 -0
- package/dist/chunk-ANWOL7SM.js +566 -0
- package/dist/chunk-BWG45ZWF.cjs +305 -0
- package/dist/chunk-CVF4QHS6.cjs +436 -0
- package/dist/chunk-DDVRUPMZ.js +1293 -0
- package/dist/chunk-DSOSHJH2.js +643 -0
- package/dist/chunk-FLATZQA2.js +174 -0
- package/dist/chunk-HJJTBVKQ.cjs +909 -0
- package/dist/chunk-ISI2OLPI.cjs +179 -0
- package/dist/chunk-MYURVLGP.cjs +165 -0
- package/dist/chunk-N33Y5NY7.cjs +105 -0
- package/dist/chunk-QD4KISXM.js +160 -0
- package/dist/chunk-SNGU4SHO.cjs +654 -0
- package/dist/chunk-TFOJLA2F.cjs +588 -0
- package/dist/chunk-Z7LV7DCO.js +429 -0
- package/dist/develop-tool/cli/index.cjs +1138 -0
- package/dist/develop-tool/cli/index.d.cts +1 -0
- package/dist/develop-tool/cli/index.d.ts +1 -0
- package/dist/develop-tool/cli/index.js +1127 -0
- package/dist/index.cjs +370 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +9 -0
- package/dist/mcp/core/index.cjs +90 -0
- package/dist/mcp/core/index.d.cts +124 -0
- package/dist/mcp/core/index.d.ts +124 -0
- package/dist/mcp/core/index.js +1 -0
- package/dist/mcp/index.cjs +317 -0
- package/dist/mcp/index.d.cts +123 -0
- package/dist/mcp/index.d.ts +123 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/plugin-editor/index.cjs +47 -0
- package/dist/mcp/plugin-editor/index.d.cts +98 -0
- package/dist/mcp/plugin-editor/index.d.ts +98 -0
- package/dist/mcp/plugin-editor/index.js +2 -0
- package/dist/mcp/plugin-excel/index.cjs +31 -0
- package/dist/mcp/plugin-excel/index.d.cts +86 -0
- package/dist/mcp/plugin-excel/index.d.ts +86 -0
- package/dist/mcp/plugin-excel/index.js +2 -0
- package/dist/mcp/plugin-preview/index.cjs +23 -0
- package/dist/mcp/plugin-preview/index.d.cts +109 -0
- package/dist/mcp/plugin-preview/index.d.ts +109 -0
- package/dist/mcp/plugin-preview/index.js +2 -0
- package/dist/mcp/plugin-seaflow/index.cjs +35 -0
- package/dist/mcp/plugin-seaflow/index.d.cts +318 -0
- package/dist/mcp/plugin-seaflow/index.d.ts +318 -0
- package/dist/mcp/plugin-seaflow/index.js +2 -0
- package/dist/mcp/seastudio/index.cjs +75 -0
- package/dist/mcp/seastudio/index.d.cts +341 -0
- package/dist/mcp/seastudio/index.d.ts +341 -0
- package/dist/mcp/seastudio/index.js +2 -0
- package/dist/tools-LMW67LIY.js +2 -0
- package/dist/tools-TU7PBMDO.cjs +23 -0
- package/dist/types-Clgf5gBf.d.cts +107 -0
- package/dist/types-Clgf5gBf.d.ts +107 -0
- package/dist/ui/index.cjs +58 -0
- package/dist/ui/index.d.cts +142 -0
- package/dist/ui/index.d.ts +142 -0
- package/dist/ui/index.js +1 -0
- package/package.json +115 -0
- package/src/develop-tool/templates/plugin/README.md.tmpl +36 -0
- package/src/develop-tool/templates/plugin/frontend/index.html.tmpl +12 -0
- package/src/develop-tool/templates/plugin/frontend/package.json.tmpl +30 -0
- package/src/develop-tool/templates/plugin/frontend/postcss.config.js +6 -0
- package/src/develop-tool/templates/plugin/frontend/src/App.css +43 -0
- package/src/develop-tool/templates/plugin/frontend/src/App.tsx.tmpl +43 -0
- package/src/develop-tool/templates/plugin/frontend/src/main.tsx +10 -0
- package/src/develop-tool/templates/plugin/frontend/src/vite-env.d.ts +1 -0
- package/src/develop-tool/templates/plugin/frontend/tsconfig.json +20 -0
- package/src/develop-tool/templates/plugin/frontend/vite.config.ts +12 -0
- package/src/develop-tool/templates/plugin/seastudio.config.json.tmpl +14 -0
- package/src/ui/cosmos.css +407 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/mcp/core/types.ts
|
|
4
|
+
function isNotification(message) {
|
|
5
|
+
return !("id" in message) && "method" in message;
|
|
6
|
+
}
|
|
7
|
+
function isMCPMessage(data) {
|
|
8
|
+
return typeof data === "object" && data !== null && data.type === "mcp" && "payload" in data;
|
|
9
|
+
}
|
|
10
|
+
function createRequest(method, params) {
|
|
11
|
+
return {
|
|
12
|
+
jsonrpc: "2.0",
|
|
13
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
14
|
+
method,
|
|
15
|
+
params
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createResponse(id, result, error) {
|
|
19
|
+
const response = { jsonrpc: "2.0", id };
|
|
20
|
+
if (error) {
|
|
21
|
+
response.error = error;
|
|
22
|
+
} else {
|
|
23
|
+
response.result = result;
|
|
24
|
+
}
|
|
25
|
+
return response;
|
|
26
|
+
}
|
|
27
|
+
function createNotification(method, params) {
|
|
28
|
+
return {
|
|
29
|
+
jsonrpc: "2.0",
|
|
30
|
+
method,
|
|
31
|
+
params
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/mcp/core/schema.ts
|
|
36
|
+
var DEFAULT_OBJECT_SCHEMA = {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {}
|
|
39
|
+
};
|
|
40
|
+
function cloneProperties(properties) {
|
|
41
|
+
if (!properties || typeof properties !== "object") {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
return Object.fromEntries(
|
|
45
|
+
Object.entries(properties).map(([key, value]) => [
|
|
46
|
+
key,
|
|
47
|
+
normalizeMCPToolInputSchema(value)
|
|
48
|
+
])
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
function readSchemaType(schema) {
|
|
52
|
+
const rawType = schema.type;
|
|
53
|
+
if (typeof rawType === "string") {
|
|
54
|
+
return rawType;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(rawType)) {
|
|
57
|
+
const supportedType = rawType.find(
|
|
58
|
+
(value) => ["object", "array", "string", "number", "integer", "boolean", "null"].includes(String(value))
|
|
59
|
+
);
|
|
60
|
+
return typeof supportedType === "string" ? supportedType : void 0;
|
|
61
|
+
}
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
function inferSchemaType(schema, fallbackType) {
|
|
65
|
+
const explicitType = readSchemaType(schema);
|
|
66
|
+
if (explicitType) {
|
|
67
|
+
return explicitType;
|
|
68
|
+
}
|
|
69
|
+
if (schema.properties || schema.required || Object.prototype.hasOwnProperty.call(schema, "additionalProperties")) {
|
|
70
|
+
return "object";
|
|
71
|
+
}
|
|
72
|
+
if (schema.items) {
|
|
73
|
+
return "array";
|
|
74
|
+
}
|
|
75
|
+
if (schema.enum || schema.oneOf || schema.anyOf || schema.allOf) {
|
|
76
|
+
return fallbackType ?? "string";
|
|
77
|
+
}
|
|
78
|
+
return fallbackType ?? "string";
|
|
79
|
+
}
|
|
80
|
+
function normalizeMCPToolInputSchema(schema, options = {}) {
|
|
81
|
+
const fallbackType = options.defaultType ?? "string";
|
|
82
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
|
|
83
|
+
return {
|
|
84
|
+
...DEFAULT_OBJECT_SCHEMA,
|
|
85
|
+
type: fallbackType
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const normalized = { ...schema };
|
|
89
|
+
normalized.type = inferSchemaType(normalized, fallbackType);
|
|
90
|
+
const properties = cloneProperties(normalized.properties);
|
|
91
|
+
if (properties) {
|
|
92
|
+
normalized.properties = properties;
|
|
93
|
+
} else if (normalized.type === "object") {
|
|
94
|
+
normalized.properties = {};
|
|
95
|
+
} else {
|
|
96
|
+
delete normalized.properties;
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(normalized.required)) {
|
|
99
|
+
normalized.required = [...normalized.required];
|
|
100
|
+
}
|
|
101
|
+
if (Array.isArray(normalized.enum)) {
|
|
102
|
+
normalized.enum = [...normalized.enum];
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(normalized.oneOf)) {
|
|
105
|
+
normalized.oneOf = normalized.oneOf.map(
|
|
106
|
+
(item) => normalizeMCPToolInputSchema(item)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(normalized.anyOf)) {
|
|
110
|
+
normalized.anyOf = normalized.anyOf.map(
|
|
111
|
+
(item) => normalizeMCPToolInputSchema(item)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (Array.isArray(normalized.allOf)) {
|
|
115
|
+
normalized.allOf = normalized.allOf.map(
|
|
116
|
+
(item) => normalizeMCPToolInputSchema(item)
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (Array.isArray(normalized.items)) {
|
|
120
|
+
normalized.items = normalized.items.map(
|
|
121
|
+
(item) => normalizeMCPToolInputSchema(item)
|
|
122
|
+
);
|
|
123
|
+
} else if (normalized.items && typeof normalized.items === "object") {
|
|
124
|
+
normalized.items = normalizeMCPToolInputSchema(normalized.items);
|
|
125
|
+
}
|
|
126
|
+
if (normalized.additionalProperties && typeof normalized.additionalProperties === "object" && !Array.isArray(normalized.additionalProperties)) {
|
|
127
|
+
normalized.additionalProperties = normalizeMCPToolInputSchema(
|
|
128
|
+
normalized.additionalProperties
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (normalized.type === "array" && !normalized.items) {
|
|
132
|
+
normalized.items = { type: "string" };
|
|
133
|
+
}
|
|
134
|
+
return normalized;
|
|
135
|
+
}
|
|
136
|
+
function normalizeMCPToolObjectSchema(schema) {
|
|
137
|
+
return normalizeMCPToolInputSchema(schema, { defaultType: "object" });
|
|
138
|
+
}
|
|
139
|
+
function normalizeMCPTool(tool) {
|
|
140
|
+
return {
|
|
141
|
+
...tool,
|
|
142
|
+
inputSchema: normalizeMCPToolObjectSchema(tool.inputSchema),
|
|
143
|
+
...tool.outputSchema ? { outputSchema: normalizeMCPToolObjectSchema(tool.outputSchema) } : {},
|
|
144
|
+
...tool.annotations ? { annotations: { ...tool.annotations } } : {}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/mcp/core/transport.ts
|
|
149
|
+
var PostMessageTransport = class {
|
|
150
|
+
constructor(options = {}) {
|
|
151
|
+
this.handlers = /* @__PURE__ */ new Set();
|
|
152
|
+
this.messageListener = null;
|
|
153
|
+
this.target = options.target ?? window.parent;
|
|
154
|
+
this.origin = options.origin ?? "*";
|
|
155
|
+
this.setupListener();
|
|
156
|
+
}
|
|
157
|
+
setupListener() {
|
|
158
|
+
this.messageListener = (event) => {
|
|
159
|
+
if (this.origin !== "*" && event.origin !== this.origin) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!isMCPMessage(event.data)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const { payload } = event.data;
|
|
166
|
+
this.handlers.forEach((handler) => {
|
|
167
|
+
try {
|
|
168
|
+
handler(payload);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("[MCPTransport] Handler error:", error);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
window.addEventListener("message", this.messageListener);
|
|
175
|
+
}
|
|
176
|
+
send(message) {
|
|
177
|
+
const envelope = {
|
|
178
|
+
type: "mcp",
|
|
179
|
+
payload: message
|
|
180
|
+
};
|
|
181
|
+
this.target.postMessage(envelope, this.origin);
|
|
182
|
+
}
|
|
183
|
+
onMessage(handler) {
|
|
184
|
+
this.handlers.add(handler);
|
|
185
|
+
return () => {
|
|
186
|
+
this.handlers.delete(handler);
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
destroy() {
|
|
190
|
+
if (this.messageListener) {
|
|
191
|
+
window.removeEventListener("message", this.messageListener);
|
|
192
|
+
this.messageListener = null;
|
|
193
|
+
}
|
|
194
|
+
this.handlers.clear();
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
var defaultTransport = null;
|
|
198
|
+
function getDefaultTransport() {
|
|
199
|
+
if (!defaultTransport) {
|
|
200
|
+
defaultTransport = new PostMessageTransport();
|
|
201
|
+
}
|
|
202
|
+
return defaultTransport;
|
|
203
|
+
}
|
|
204
|
+
function setDefaultTransport(transport) {
|
|
205
|
+
defaultTransport = transport;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/mcp/core/client.ts
|
|
209
|
+
var LONG_RUNNING_TOOL_TIMEOUTS = /* @__PURE__ */ new Set([
|
|
210
|
+
"seaflow-canvas_task_wait_result",
|
|
211
|
+
"seaflow-canvas_execute_node_and_wait",
|
|
212
|
+
"seaflow-canvas_task_reconnect"
|
|
213
|
+
]);
|
|
214
|
+
var LONG_RUNNING_TOOL_TIMEOUT_MS = 125e3;
|
|
215
|
+
var readPositiveTimeout = (value) => {
|
|
216
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
return Math.floor(value);
|
|
220
|
+
};
|
|
221
|
+
var MCPClient = class {
|
|
222
|
+
constructor(options = {}) {
|
|
223
|
+
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
224
|
+
this.notificationHandlers = /* @__PURE__ */ new Map();
|
|
225
|
+
this.unsubscribe = null;
|
|
226
|
+
this.transport = options.transport ?? getDefaultTransport();
|
|
227
|
+
this.timeout = options.timeout ?? 3e4;
|
|
228
|
+
this.setupResponseHandler();
|
|
229
|
+
}
|
|
230
|
+
setupResponseHandler() {
|
|
231
|
+
this.unsubscribe = this.transport.onMessage((message) => {
|
|
232
|
+
if (isNotification(message)) {
|
|
233
|
+
this.handleNotification(message);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (!("id" in message) || message.id === void 0) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const pending = this.pendingRequests.get(message.id);
|
|
240
|
+
if (!pending) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
clearTimeout(pending.timer);
|
|
244
|
+
this.pendingRequests.delete(message.id);
|
|
245
|
+
const response = message;
|
|
246
|
+
if (response.error) {
|
|
247
|
+
pending.reject(new Error(response.error.message));
|
|
248
|
+
} else {
|
|
249
|
+
pending.resolve(response.result);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
handleNotification(notification) {
|
|
254
|
+
const { method, params } = notification;
|
|
255
|
+
const handlers = this.notificationHandlers.get(method);
|
|
256
|
+
if (handlers) {
|
|
257
|
+
for (const handler of handlers) {
|
|
258
|
+
try {
|
|
259
|
+
handler(params ?? {});
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error(`Notification handler error for ${method}:`, error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async request(method, params, options) {
|
|
267
|
+
const req = createRequest(method, params);
|
|
268
|
+
const timeoutMs = readPositiveTimeout(options?.timeout) ?? this.timeout;
|
|
269
|
+
return new Promise((resolve, reject) => {
|
|
270
|
+
const timer = setTimeout(() => {
|
|
271
|
+
this.pendingRequests.delete(req.id);
|
|
272
|
+
reject(new Error(`Request timeout: ${method}`));
|
|
273
|
+
}, timeoutMs);
|
|
274
|
+
this.pendingRequests.set(req.id, {
|
|
275
|
+
resolve,
|
|
276
|
+
reject,
|
|
277
|
+
timer
|
|
278
|
+
});
|
|
279
|
+
this.transport.send(req);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
resolveToolCallTimeout(name, args, options) {
|
|
283
|
+
const explicitTimeout = readPositiveTimeout(options?.timeout);
|
|
284
|
+
if (explicitTimeout != null) {
|
|
285
|
+
return explicitTimeout;
|
|
286
|
+
}
|
|
287
|
+
const argTimeout = readPositiveTimeout(args.timeoutMs) ?? readPositiveTimeout(args.timeout);
|
|
288
|
+
if (argTimeout != null) {
|
|
289
|
+
return Math.max(this.timeout, argTimeout + 5e3);
|
|
290
|
+
}
|
|
291
|
+
if (LONG_RUNNING_TOOL_TIMEOUTS.has(name)) {
|
|
292
|
+
return Math.max(this.timeout, LONG_RUNNING_TOOL_TIMEOUT_MS);
|
|
293
|
+
}
|
|
294
|
+
return this.timeout;
|
|
295
|
+
}
|
|
296
|
+
async callTool(name, args = {}, options) {
|
|
297
|
+
return this.request("tools/call", {
|
|
298
|
+
name,
|
|
299
|
+
arguments: args
|
|
300
|
+
}, {
|
|
301
|
+
timeout: this.resolveToolCallTimeout(name, args, options)
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
async callToolText(name, args = {}, options) {
|
|
305
|
+
const result = await this.callTool(name, args, options);
|
|
306
|
+
if (result.isError) {
|
|
307
|
+
const errorText = result.content.find((c) => c.type === "text")?.text ?? "Unknown error";
|
|
308
|
+
throw new Error(errorText);
|
|
309
|
+
}
|
|
310
|
+
return result.content.find((c) => c.type === "text")?.text ?? "";
|
|
311
|
+
}
|
|
312
|
+
async ping() {
|
|
313
|
+
try {
|
|
314
|
+
await this.request("ping");
|
|
315
|
+
return true;
|
|
316
|
+
} catch {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async subscribe(topics) {
|
|
321
|
+
await this.request("notifications/subscribe", { topics });
|
|
322
|
+
}
|
|
323
|
+
async unsubscribeTopics(topics) {
|
|
324
|
+
await this.request("notifications/unsubscribe", { topics });
|
|
325
|
+
}
|
|
326
|
+
async publish(topic, data = {}) {
|
|
327
|
+
await this.request("notifications/publish", { topic, data });
|
|
328
|
+
}
|
|
329
|
+
onNotification(topic, handler) {
|
|
330
|
+
let handlers = this.notificationHandlers.get(topic);
|
|
331
|
+
if (!handlers) {
|
|
332
|
+
handlers = /* @__PURE__ */ new Set();
|
|
333
|
+
this.notificationHandlers.set(topic, handlers);
|
|
334
|
+
}
|
|
335
|
+
handlers.add(handler);
|
|
336
|
+
return () => {
|
|
337
|
+
handlers?.delete(handler);
|
|
338
|
+
if (handlers?.size === 0) {
|
|
339
|
+
this.notificationHandlers.delete(topic);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
offNotification(topic, handler) {
|
|
344
|
+
if (!handler) {
|
|
345
|
+
this.notificationHandlers.delete(topic);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const handlers = this.notificationHandlers.get(topic);
|
|
349
|
+
if (handlers) {
|
|
350
|
+
handlers.delete(handler);
|
|
351
|
+
if (handlers.size === 0) {
|
|
352
|
+
this.notificationHandlers.delete(topic);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
destroy() {
|
|
357
|
+
if (this.unsubscribe) {
|
|
358
|
+
this.unsubscribe();
|
|
359
|
+
this.unsubscribe = null;
|
|
360
|
+
}
|
|
361
|
+
for (const pending of this.pendingRequests.values()) {
|
|
362
|
+
clearTimeout(pending.timer);
|
|
363
|
+
pending.reject(new Error("Client destroyed"));
|
|
364
|
+
}
|
|
365
|
+
this.pendingRequests.clear();
|
|
366
|
+
this.notificationHandlers.clear();
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
var defaultClient = null;
|
|
370
|
+
function createMCPClient(options) {
|
|
371
|
+
return new MCPClient(options);
|
|
372
|
+
}
|
|
373
|
+
function getDefaultClient() {
|
|
374
|
+
if (!defaultClient) {
|
|
375
|
+
defaultClient = createMCPClient();
|
|
376
|
+
}
|
|
377
|
+
return defaultClient;
|
|
378
|
+
}
|
|
379
|
+
function setDefaultClient(client) {
|
|
380
|
+
defaultClient = client;
|
|
381
|
+
}
|
|
382
|
+
async function callHostTool(toolName, args = {}) {
|
|
383
|
+
return getDefaultClient().callTool(toolName, args);
|
|
384
|
+
}
|
|
385
|
+
async function callHostToolText(toolName, args = {}) {
|
|
386
|
+
return getDefaultClient().callToolText(toolName, args);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// src/mcp/core/server.ts
|
|
390
|
+
var MCPServer = class {
|
|
391
|
+
constructor() {
|
|
392
|
+
this.tools = /* @__PURE__ */ new Map();
|
|
393
|
+
this.notificationHandlers = /* @__PURE__ */ new Map();
|
|
394
|
+
this.unsubscribe = null;
|
|
395
|
+
}
|
|
396
|
+
registerTool(definition, handler) {
|
|
397
|
+
this.tools.set(definition.name, { definition, handler });
|
|
398
|
+
}
|
|
399
|
+
registerTools(definitions, handlers) {
|
|
400
|
+
for (const def of definitions) {
|
|
401
|
+
const handler = handlers[def.name];
|
|
402
|
+
if (handler) {
|
|
403
|
+
this.registerTool(def, handler);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
getTools() {
|
|
408
|
+
return Array.from(this.tools.values()).map((t) => t.definition);
|
|
409
|
+
}
|
|
410
|
+
async handleMessage(request) {
|
|
411
|
+
const { id, method, params } = request;
|
|
412
|
+
if (method === "tools/list") {
|
|
413
|
+
return createResponse(id, { tools: this.getTools() });
|
|
414
|
+
}
|
|
415
|
+
if (method === "tools/call") {
|
|
416
|
+
const name = params?.name;
|
|
417
|
+
const args = params?.arguments ?? {};
|
|
418
|
+
if (!name) {
|
|
419
|
+
return createResponse(id, void 0, {
|
|
420
|
+
code: -32602,
|
|
421
|
+
message: "Missing tool name"
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
const tool = this.tools.get(name);
|
|
425
|
+
if (!tool) {
|
|
426
|
+
return createResponse(id, void 0, {
|
|
427
|
+
code: -32601,
|
|
428
|
+
message: `Tool not found: ${name}`
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
const result = await tool.handler(args);
|
|
433
|
+
return createResponse(id, result);
|
|
434
|
+
} catch (error) {
|
|
435
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
436
|
+
return createResponse(id, {
|
|
437
|
+
content: [{ type: "text", text: message }],
|
|
438
|
+
isError: true
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (method === "ping") {
|
|
443
|
+
return createResponse(id, { pong: true });
|
|
444
|
+
}
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
sendNotification(method, params) {
|
|
448
|
+
const notification = createNotification(method, params);
|
|
449
|
+
window.parent.postMessage({ type: "mcp", payload: notification }, "*");
|
|
450
|
+
}
|
|
451
|
+
onNotification(topic, handler) {
|
|
452
|
+
let handlers = this.notificationHandlers.get(topic);
|
|
453
|
+
if (!handlers) {
|
|
454
|
+
handlers = /* @__PURE__ */ new Set();
|
|
455
|
+
this.notificationHandlers.set(topic, handlers);
|
|
456
|
+
}
|
|
457
|
+
handlers.add(handler);
|
|
458
|
+
return () => {
|
|
459
|
+
handlers?.delete(handler);
|
|
460
|
+
if (handlers?.size === 0) {
|
|
461
|
+
this.notificationHandlers.delete(topic);
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
offNotification(topic, handler) {
|
|
466
|
+
if (!handler) {
|
|
467
|
+
this.notificationHandlers.delete(topic);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const handlers = this.notificationHandlers.get(topic);
|
|
471
|
+
if (handlers) {
|
|
472
|
+
handlers.delete(handler);
|
|
473
|
+
if (handlers.size === 0) {
|
|
474
|
+
this.notificationHandlers.delete(topic);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
handleNotification(notification) {
|
|
479
|
+
const { method, params } = notification;
|
|
480
|
+
const handlers = this.notificationHandlers.get(method);
|
|
481
|
+
if (handlers) {
|
|
482
|
+
for (const handler of handlers) {
|
|
483
|
+
try {
|
|
484
|
+
handler(params ?? {});
|
|
485
|
+
} catch (error) {
|
|
486
|
+
console.error(`Server notification handler error for ${method}:`, error);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
start() {
|
|
492
|
+
if (this.unsubscribe) return;
|
|
493
|
+
const handler = async (event) => {
|
|
494
|
+
const data = event.data;
|
|
495
|
+
if (data?.type === "mcp:tool-call") {
|
|
496
|
+
const { callId, toolName, args } = data;
|
|
497
|
+
const tool = this.tools.get(toolName);
|
|
498
|
+
if (!tool) {
|
|
499
|
+
window.parent.postMessage(
|
|
500
|
+
{
|
|
501
|
+
type: "mcp:tool-result",
|
|
502
|
+
callId,
|
|
503
|
+
result: {
|
|
504
|
+
content: [{ type: "text", text: `Tool not found: ${toolName}` }],
|
|
505
|
+
isError: true
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
"*"
|
|
509
|
+
);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
const result = await tool.handler(args ?? {});
|
|
514
|
+
window.parent.postMessage({ type: "mcp:tool-result", callId, result }, "*");
|
|
515
|
+
} catch (error) {
|
|
516
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
517
|
+
window.parent.postMessage(
|
|
518
|
+
{
|
|
519
|
+
type: "mcp:tool-result",
|
|
520
|
+
callId,
|
|
521
|
+
result: {
|
|
522
|
+
content: [{ type: "text", text: message }],
|
|
523
|
+
isError: true
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"*"
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
if (!isMCPMessage(data)) return;
|
|
532
|
+
const { payload } = data;
|
|
533
|
+
if (isNotification(payload)) {
|
|
534
|
+
this.handleNotification(payload);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
if (!("id" in payload) || !("method" in payload)) return;
|
|
538
|
+
const response = await this.handleMessage(payload);
|
|
539
|
+
if (response) {
|
|
540
|
+
window.parent.postMessage({ type: "mcp", payload: response }, "*");
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
window.addEventListener("message", handler);
|
|
544
|
+
this.unsubscribe = () => window.removeEventListener("message", handler);
|
|
545
|
+
}
|
|
546
|
+
stop() {
|
|
547
|
+
if (this.unsubscribe) {
|
|
548
|
+
this.unsubscribe();
|
|
549
|
+
this.unsubscribe = null;
|
|
550
|
+
}
|
|
551
|
+
this.notificationHandlers.clear();
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
var defaultServer = null;
|
|
555
|
+
function createMCPServer() {
|
|
556
|
+
return new MCPServer();
|
|
557
|
+
}
|
|
558
|
+
function getDefaultServer() {
|
|
559
|
+
if (!defaultServer) {
|
|
560
|
+
defaultServer = createMCPServer();
|
|
561
|
+
}
|
|
562
|
+
return defaultServer;
|
|
563
|
+
}
|
|
564
|
+
function startDefaultServer() {
|
|
565
|
+
getDefaultServer().start();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
exports.MCPClient = MCPClient;
|
|
569
|
+
exports.MCPServer = MCPServer;
|
|
570
|
+
exports.PostMessageTransport = PostMessageTransport;
|
|
571
|
+
exports.callHostTool = callHostTool;
|
|
572
|
+
exports.callHostToolText = callHostToolText;
|
|
573
|
+
exports.createMCPClient = createMCPClient;
|
|
574
|
+
exports.createMCPServer = createMCPServer;
|
|
575
|
+
exports.createNotification = createNotification;
|
|
576
|
+
exports.createRequest = createRequest;
|
|
577
|
+
exports.createResponse = createResponse;
|
|
578
|
+
exports.getDefaultClient = getDefaultClient;
|
|
579
|
+
exports.getDefaultServer = getDefaultServer;
|
|
580
|
+
exports.getDefaultTransport = getDefaultTransport;
|
|
581
|
+
exports.isMCPMessage = isMCPMessage;
|
|
582
|
+
exports.isNotification = isNotification;
|
|
583
|
+
exports.normalizeMCPTool = normalizeMCPTool;
|
|
584
|
+
exports.normalizeMCPToolInputSchema = normalizeMCPToolInputSchema;
|
|
585
|
+
exports.normalizeMCPToolObjectSchema = normalizeMCPToolObjectSchema;
|
|
586
|
+
exports.setDefaultClient = setDefaultClient;
|
|
587
|
+
exports.setDefaultTransport = setDefaultTransport;
|
|
588
|
+
exports.startDefaultServer = startDefaultServer;
|