@easynet/agent-tool 1.0.74 → 1.0.75
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 +10 -5
- package/dist/api/adapters/LangChainToolsHub.d.ts +1 -1
- package/dist/api/createAgentTools.d.ts +8 -10
- package/dist/api/createAgentTools.d.ts.map +1 -1
- package/dist/api/expose/index.d.ts +2 -2
- package/dist/api/expose/index.d.ts.map +1 -1
- package/dist/api/expose/mcpServer.d.ts +3 -4
- package/dist/api/expose/mcpServer.d.ts.map +1 -1
- package/dist/api/expose/openapiHttp.d.ts +15 -31
- package/dist/api/expose/openapiHttp.d.ts.map +1 -1
- package/dist/api/main.cjs +18 -22
- package/dist/api/main.d.ts +6 -7
- package/dist/api/main.d.ts.map +1 -1
- package/dist/api/main.js +2 -2
- package/dist/api/runtimeFromConfig.d.ts +1 -1
- package/dist/api/runtimeFromConfig.d.ts.map +1 -1
- package/dist/{chunk-JYADGZQP.js → chunk-MBCFJBZY.js} +298 -268
- package/dist/chunk-MBCFJBZY.js.map +1 -0
- package/dist/{chunk-SE6IMOIE.cjs → chunk-PYTHEY6A.cjs} +301 -269
- package/dist/chunk-PYTHEY6A.cjs.map +1 -0
- package/dist/{chunk-KTQTDKWU.cjs → chunk-SR53PQTG.cjs} +97 -78
- package/dist/chunk-SR53PQTG.cjs.map +1 -0
- package/dist/{chunk-ECHW6AWF.js → chunk-XS26ZNYC.js} +84 -65
- package/dist/chunk-XS26ZNYC.js.map +1 -0
- package/dist/index.cjs +17 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/util/toolConfig.d.ts +13 -0
- package/dist/tools/util/toolConfig.d.ts.map +1 -1
- package/dist/utils/cli/index.cjs +12 -12
- package/dist/utils/cli/index.js +1 -1
- package/package.json +4 -1
- package/dist/chunk-ECHW6AWF.js.map +0 -1
- package/dist/chunk-JYADGZQP.js.map +0 -1
- package/dist/chunk-KTQTDKWU.cjs.map +0 -1
- package/dist/chunk-SE6IMOIE.cjs.map +0 -1
|
@@ -18,7 +18,7 @@ var pTimeout = require('p-timeout');
|
|
|
18
18
|
var module$1 = require('module');
|
|
19
19
|
var url = require('url');
|
|
20
20
|
var npm = require('@easynet/agent-common/npm');
|
|
21
|
-
var
|
|
21
|
+
var express = require('express');
|
|
22
22
|
|
|
23
23
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
24
24
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -26,7 +26,27 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
26
26
|
var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
27
27
|
var addFormats__default = /*#__PURE__*/_interopDefault(addFormats);
|
|
28
28
|
var pTimeout__default = /*#__PURE__*/_interopDefault(pTimeout);
|
|
29
|
+
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
29
30
|
|
|
31
|
+
function normalizeMcpConfig(raw) {
|
|
32
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
33
|
+
const source = raw;
|
|
34
|
+
const out = {};
|
|
35
|
+
if (typeof source.name === "string" && source.name.trim()) out.name = source.name.trim();
|
|
36
|
+
if (typeof source.version === "string" && source.version.trim()) out.version = source.version.trim();
|
|
37
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
38
|
+
}
|
|
39
|
+
function normalizeOpenApiConfig(raw) {
|
|
40
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
41
|
+
const source = raw;
|
|
42
|
+
const out = {};
|
|
43
|
+
if (typeof source.host === "string" && source.host.trim()) out.host = source.host.trim();
|
|
44
|
+
if (typeof source.basePath === "string") out.basePath = source.basePath;
|
|
45
|
+
if (typeof source.title === "string" && source.title.trim()) out.title = source.title.trim();
|
|
46
|
+
if (typeof source.version === "string" && source.version.trim()) out.version = source.version.trim();
|
|
47
|
+
if (typeof source.port === "number" && Number.isFinite(source.port)) out.port = source.port;
|
|
48
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
49
|
+
}
|
|
30
50
|
function loadToolConfig(toolYamlPath) {
|
|
31
51
|
const abs = path.resolve(toolYamlPath);
|
|
32
52
|
const raw = fs.readFileSync(abs, "utf8");
|
|
@@ -35,6 +55,8 @@ function loadToolConfig(toolYamlPath) {
|
|
|
35
55
|
});
|
|
36
56
|
if (!parsed || typeof parsed !== "object") return {};
|
|
37
57
|
const source = parsed.spec && typeof parsed.spec === "object" && !Array.isArray(parsed.spec) ? parsed.spec : parsed;
|
|
58
|
+
const mcpConfig = normalizeMcpConfig(source.expose?.mcp ?? source.mcp);
|
|
59
|
+
const openApiConfig = normalizeOpenApiConfig(source.expose?.openapi ?? source.openapi);
|
|
38
60
|
const toolsBlock = source.tools;
|
|
39
61
|
if (toolsBlock != null && typeof toolsBlock === "object" && !Array.isArray(toolsBlock)) {
|
|
40
62
|
const toolDefaults = toolsBlock.defaults != null && typeof toolsBlock.defaults === "object" && !Array.isArray(toolsBlock.defaults) ? toolsBlock.defaults : void 0;
|
|
@@ -48,7 +70,9 @@ function loadToolConfig(toolYamlPath) {
|
|
|
48
70
|
blockedHosts: Array.isArray(toolsBlock.blockedHosts) ? toolsBlock.blockedHosts : source.blockedHosts,
|
|
49
71
|
blockedCidrs: Array.isArray(toolsBlock.blockedCidrs) ? toolsBlock.blockedCidrs : source.blockedCidrs,
|
|
50
72
|
toolDefaults,
|
|
51
|
-
packageToolDefaults: packageToolDefaults2
|
|
73
|
+
packageToolDefaults: packageToolDefaults2,
|
|
74
|
+
mcp: mcpConfig,
|
|
75
|
+
openapi: openApiConfig
|
|
52
76
|
};
|
|
53
77
|
}
|
|
54
78
|
const packageToolDefaults = typeof source.packageToolDefaults === "object" && !Array.isArray(source.packageToolDefaults) ? source.packageToolDefaults : void 0;
|
|
@@ -61,7 +85,9 @@ function loadToolConfig(toolYamlPath) {
|
|
|
61
85
|
blockedHosts: Array.isArray(source.blockedHosts) ? source.blockedHosts : void 0,
|
|
62
86
|
blockedCidrs: Array.isArray(source.blockedCidrs) ? source.blockedCidrs : void 0,
|
|
63
87
|
toolDefaults: typeof source.toolDefaults === "object" && !Array.isArray(source.toolDefaults) ? source.toolDefaults : void 0,
|
|
64
|
-
packageToolDefaults
|
|
88
|
+
packageToolDefaults,
|
|
89
|
+
mcp: mcpConfig,
|
|
90
|
+
openapi: openApiConfig
|
|
65
91
|
};
|
|
66
92
|
}
|
|
67
93
|
function resolveSandboxedPath(toolYamlPath, sandboxedPath) {
|
|
@@ -1727,7 +1753,7 @@ function buildInputSchemaHint(inputSchema) {
|
|
|
1727
1753
|
if (names.length === 0) return null;
|
|
1728
1754
|
return `This tool expects input property ${names.length === 1 ? `'${names[0]}'` : `one of [${names.map((n) => `'${n}'`).join(", ")}]`}. Use the exact property names from the tool schema.`;
|
|
1729
1755
|
}
|
|
1730
|
-
var requireFromPackage = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
1756
|
+
var requireFromPackage = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-PYTHEY6A.cjs', document.baseURI).href)));
|
|
1731
1757
|
function getProjectRequire() {
|
|
1732
1758
|
const cwd = process.cwd();
|
|
1733
1759
|
if (fs.existsSync(path.join(cwd, "package.json"))) return module$1.createRequire(path.join(cwd, "package.json"));
|
|
@@ -1893,7 +1919,7 @@ function parseNpmDescriptor(entry) {
|
|
|
1893
1919
|
}
|
|
1894
1920
|
|
|
1895
1921
|
// src/api/runtimeFromConfig.ts
|
|
1896
|
-
var requireFromPackage2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
1922
|
+
var requireFromPackage2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-PYTHEY6A.cjs', document.baseURI).href)));
|
|
1897
1923
|
var DEFAULT_EXTENSION_PACKAGES = [];
|
|
1898
1924
|
function resolveFileDescriptorPath(descriptor, configFilePath) {
|
|
1899
1925
|
const parsed = parseToolPath(descriptor.trim());
|
|
@@ -2204,6 +2230,137 @@ async function createRuntimeFromConfig(options = {}) {
|
|
|
2204
2230
|
return createRuntimeFromConfigSync(options);
|
|
2205
2231
|
}
|
|
2206
2232
|
|
|
2233
|
+
// src/api/expose/mcpServer.ts
|
|
2234
|
+
var DEFAULT_CTX = {
|
|
2235
|
+
requestId: `mcp-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
2236
|
+
taskId: `task-${Date.now()}`,
|
|
2237
|
+
permissions: [
|
|
2238
|
+
"read:web",
|
|
2239
|
+
"read:fs",
|
|
2240
|
+
"write:fs",
|
|
2241
|
+
"read:db",
|
|
2242
|
+
"write:db",
|
|
2243
|
+
"network",
|
|
2244
|
+
"workflow",
|
|
2245
|
+
"danger:destructive"
|
|
2246
|
+
]
|
|
2247
|
+
};
|
|
2248
|
+
function toMcpToolName(registryName) {
|
|
2249
|
+
return chunkQEJF3KDV_cjs.normalizeToolName(registryName);
|
|
2250
|
+
}
|
|
2251
|
+
async function createMcpServerWithTools(runtime, options) {
|
|
2252
|
+
const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
2253
|
+
const name = options.name ?? "agent-tool";
|
|
2254
|
+
const version = options.version ?? "1.0.0";
|
|
2255
|
+
const ctxFactory = options.execContextFactory ?? (() => ({ ...DEFAULT_CTX }));
|
|
2256
|
+
const server = new McpServer({ name, version });
|
|
2257
|
+
const registry = runtime.getRegistry();
|
|
2258
|
+
const specs = registry.snapshot();
|
|
2259
|
+
for (const spec of specs) {
|
|
2260
|
+
const mcpName = toMcpToolName(spec.name);
|
|
2261
|
+
server.registerTool(
|
|
2262
|
+
mcpName,
|
|
2263
|
+
{
|
|
2264
|
+
description: spec.description ?? `Tool: ${spec.name}`,
|
|
2265
|
+
inputSchema: spec.inputSchema,
|
|
2266
|
+
_meta: spec._meta
|
|
2267
|
+
},
|
|
2268
|
+
async (args) => {
|
|
2269
|
+
const ctx = ctxFactory();
|
|
2270
|
+
const result = await runtime.invoke(
|
|
2271
|
+
{ tool: spec.name, args: args ?? {}, purpose: chunk33N4Y6IS_cjs.MCP_KIND },
|
|
2272
|
+
ctx
|
|
2273
|
+
);
|
|
2274
|
+
if (result.ok) {
|
|
2275
|
+
return { content: [{ type: "text", text: JSON.stringify(result.result) }] };
|
|
2276
|
+
}
|
|
2277
|
+
const err = result.error;
|
|
2278
|
+
return {
|
|
2279
|
+
content: [
|
|
2280
|
+
{
|
|
2281
|
+
type: "text",
|
|
2282
|
+
text: JSON.stringify({ error: err?.message ?? "Tool failed", kind: err?.kind })
|
|
2283
|
+
}
|
|
2284
|
+
],
|
|
2285
|
+
isError: true
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
);
|
|
2289
|
+
}
|
|
2290
|
+
return { server };
|
|
2291
|
+
}
|
|
2292
|
+
async function createMCPServer(runtimeOrConfig, options = {}) {
|
|
2293
|
+
const runtime = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? runtimeOrConfig : (await createRuntimeFromConfig(runtimeOrConfig)).runtime;
|
|
2294
|
+
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
2295
|
+
const { server } = await createMcpServerWithTools(runtime, options);
|
|
2296
|
+
return {
|
|
2297
|
+
server,
|
|
2298
|
+
async connectStdio() {
|
|
2299
|
+
const transport = new StdioServerTransport();
|
|
2300
|
+
await server.connect(transport);
|
|
2301
|
+
}
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
function createMCPStreamableHttpHandler(runtimeOrConfig, options = {}) {
|
|
2305
|
+
if ("invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function") {
|
|
2306
|
+
const runtime = runtimeOrConfig;
|
|
2307
|
+
return async function streamableHttpHandler(req, res, parsedBody) {
|
|
2308
|
+
const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
2309
|
+
const { server } = await createMcpServerWithTools(runtime, options);
|
|
2310
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
|
|
2311
|
+
await server.connect(transport);
|
|
2312
|
+
const onClose = () => {
|
|
2313
|
+
transport.close().catch(() => {
|
|
2314
|
+
});
|
|
2315
|
+
server.close().catch(() => {
|
|
2316
|
+
});
|
|
2317
|
+
res.removeListener("close", onClose);
|
|
2318
|
+
res.removeListener("finish", onClose);
|
|
2319
|
+
};
|
|
2320
|
+
res.once("close", onClose);
|
|
2321
|
+
res.once("finish", onClose);
|
|
2322
|
+
await transport.handleRequest(
|
|
2323
|
+
req,
|
|
2324
|
+
res,
|
|
2325
|
+
parsedBody
|
|
2326
|
+
);
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
return (async () => {
|
|
2330
|
+
const { runtime } = await createRuntimeFromConfig(runtimeOrConfig);
|
|
2331
|
+
return createMCPStreamableHttpHandler(runtime, options);
|
|
2332
|
+
})();
|
|
2333
|
+
}
|
|
2334
|
+
async function createMCPServerStreamableHttp(runtimeOrConfig, options = {}) {
|
|
2335
|
+
const path = options.path ?? "/mcp";
|
|
2336
|
+
const host = options.host ?? "127.0.0.1";
|
|
2337
|
+
const port = options.port ?? 3e3;
|
|
2338
|
+
const { createMcpExpressApp } = await import('@modelcontextprotocol/sdk/server/express.js');
|
|
2339
|
+
const handler = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? createMCPStreamableHttpHandler(runtimeOrConfig, options) : await createMCPStreamableHttpHandler(runtimeOrConfig, options);
|
|
2340
|
+
const app = createMcpExpressApp({ host });
|
|
2341
|
+
app.post(path, handler);
|
|
2342
|
+
return {
|
|
2343
|
+
app,
|
|
2344
|
+
path,
|
|
2345
|
+
async listen(listenPort, listenHost) {
|
|
2346
|
+
const p = listenPort ?? port;
|
|
2347
|
+
const h = listenHost ?? host;
|
|
2348
|
+
return new Promise((resolve4, reject) => {
|
|
2349
|
+
const server = app.listen(p, h, () => {
|
|
2350
|
+
const addr = server.address();
|
|
2351
|
+
const actualPort = typeof addr === "object" && addr !== null && "port" in addr ? addr.port : p;
|
|
2352
|
+
resolve4({ url: `http://${h}:${actualPort}${path}`, port: actualPort });
|
|
2353
|
+
});
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
2358
|
+
async function runMCPServerOverStdio(runtime, options = {}) {
|
|
2359
|
+
const result = await createMCPServer(runtime, options);
|
|
2360
|
+
await result.connectStdio();
|
|
2361
|
+
return result;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2207
2364
|
// src/api/expose/openapi.ts
|
|
2208
2365
|
function toolNameToSlug(name) {
|
|
2209
2366
|
return name.replace(/\./g, "~");
|
|
@@ -2341,7 +2498,7 @@ function createPerToolPathSpec(spec, key) {
|
|
|
2341
2498
|
}
|
|
2342
2499
|
|
|
2343
2500
|
// src/api/expose/openapiHttp.ts
|
|
2344
|
-
var
|
|
2501
|
+
var DEFAULT_CTX2 = {
|
|
2345
2502
|
requestId: `http-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
2346
2503
|
taskId: `task-${Date.now()}`,
|
|
2347
2504
|
permissions: [
|
|
@@ -2355,8 +2512,17 @@ var DEFAULT_CTX = {
|
|
|
2355
2512
|
"danger:destructive"
|
|
2356
2513
|
]
|
|
2357
2514
|
};
|
|
2515
|
+
var BodyParseError = class extends Error {
|
|
2516
|
+
hint;
|
|
2517
|
+
constructor(message, hint) {
|
|
2518
|
+
super(message);
|
|
2519
|
+
this.name = "BodyParseError";
|
|
2520
|
+
this.hint = hint;
|
|
2521
|
+
}
|
|
2522
|
+
};
|
|
2358
2523
|
function safeParseToolArgs(raw) {
|
|
2359
2524
|
const text = String(raw ?? "").trim();
|
|
2525
|
+
if (!text) return { ok: true, value: {} };
|
|
2360
2526
|
const firstBrace = text.indexOf("{");
|
|
2361
2527
|
if (firstBrace === -1) {
|
|
2362
2528
|
return {
|
|
@@ -2366,9 +2532,7 @@ function safeParseToolArgs(raw) {
|
|
|
2366
2532
|
}
|
|
2367
2533
|
let jsonText = text.slice(firstBrace);
|
|
2368
2534
|
const lastBrace = jsonText.lastIndexOf("}");
|
|
2369
|
-
if (lastBrace !== -1)
|
|
2370
|
-
jsonText = jsonText.slice(0, lastBrace + 1);
|
|
2371
|
-
}
|
|
2535
|
+
if (lastBrace !== -1) jsonText = jsonText.slice(0, lastBrace + 1);
|
|
2372
2536
|
try {
|
|
2373
2537
|
return { ok: true, value: JSON.parse(jsonText) };
|
|
2374
2538
|
} catch {
|
|
@@ -2378,37 +2542,8 @@ function safeParseToolArgs(raw) {
|
|
|
2378
2542
|
};
|
|
2379
2543
|
}
|
|
2380
2544
|
}
|
|
2381
|
-
var BodyParseError = class extends Error {
|
|
2382
|
-
hint;
|
|
2383
|
-
constructor(message, hint) {
|
|
2384
|
-
super(message);
|
|
2385
|
-
this.name = "BodyParseError";
|
|
2386
|
-
this.hint = hint;
|
|
2387
|
-
}
|
|
2388
|
-
};
|
|
2389
|
-
function parseBody(req) {
|
|
2390
|
-
return new Promise((resolve4, reject) => {
|
|
2391
|
-
const chunks = [];
|
|
2392
|
-
req.on("data", (chunk) => chunks.push(chunk));
|
|
2393
|
-
req.on("end", () => {
|
|
2394
|
-
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
2395
|
-
if (!raw.trim()) {
|
|
2396
|
-
resolve4({});
|
|
2397
|
-
return;
|
|
2398
|
-
}
|
|
2399
|
-
const parsed = safeParseToolArgs(raw);
|
|
2400
|
-
if (parsed.ok) {
|
|
2401
|
-
resolve4(parsed.value);
|
|
2402
|
-
return;
|
|
2403
|
-
}
|
|
2404
|
-
reject(new BodyParseError("Invalid JSON body", parsed.hint));
|
|
2405
|
-
});
|
|
2406
|
-
req.on("error", reject);
|
|
2407
|
-
});
|
|
2408
|
-
}
|
|
2409
2545
|
function sendJson(res, status, data) {
|
|
2410
|
-
res.
|
|
2411
|
-
res.end(JSON.stringify(data));
|
|
2546
|
+
res.status(status).json(data);
|
|
2412
2547
|
}
|
|
2413
2548
|
function swaggerUiHtml(specUrl) {
|
|
2414
2549
|
const specUrlEscaped = specUrl.replace(/"/g, """);
|
|
@@ -2441,99 +2576,13 @@ function swaggerUiHtml(specUrl) {
|
|
|
2441
2576
|
</body>
|
|
2442
2577
|
</html>`;
|
|
2443
2578
|
}
|
|
2444
|
-
function
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
const
|
|
2448
|
-
|
|
2449
|
-
);
|
|
2450
|
-
|
|
2451
|
-
}
|
|
2452
|
-
async function handleOpenApiHttpRequest(input) {
|
|
2453
|
-
const norm = normalizePath(input.req.url, input.basePath);
|
|
2454
|
-
try {
|
|
2455
|
-
if (await maybeHandleDocsRoute(input, norm)) return;
|
|
2456
|
-
if (await maybeHandleToolsRoute(input, norm)) return;
|
|
2457
|
-
if (await maybeHandleInvokeRoute(input, norm)) return;
|
|
2458
|
-
sendJson(input.res, 404, { error: "Not found", path: norm });
|
|
2459
|
-
} catch (err) {
|
|
2460
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
2461
|
-
sendJson(input.res, 500, { error: message, kind: "INTERNAL_ERROR" });
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
function normalizePath(url, basePath) {
|
|
2465
|
-
const path = (url ?? "/").split("?")[0] ?? "/";
|
|
2466
|
-
return basePath ? path === basePath ? "" : path.replace(basePath, "") || "/" : path;
|
|
2467
|
-
}
|
|
2468
|
-
async function maybeHandleDocsRoute(input, norm) {
|
|
2469
|
-
if (input.req.method === "GET" && (norm === "/" || norm === "/swagger")) {
|
|
2470
|
-
const specPath = input.basePath ? `${input.basePath}/openapi.json` : "/openapi.json";
|
|
2471
|
-
input.res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
2472
|
-
input.res.end(swaggerUiHtml(specPath));
|
|
2473
|
-
return true;
|
|
2474
|
-
}
|
|
2475
|
-
if (input.req.method === "GET" && (norm === "/openapi.json" || norm === "/spec")) {
|
|
2476
|
-
sendJson(
|
|
2477
|
-
input.res,
|
|
2478
|
-
200,
|
|
2479
|
-
toolsToOpenAPISpec(input.runtime.getRegistry(), {
|
|
2480
|
-
title: "Tool API",
|
|
2481
|
-
version: "1.0.0",
|
|
2482
|
-
basePath: input.basePath || void 0
|
|
2483
|
-
})
|
|
2484
|
-
);
|
|
2485
|
-
return true;
|
|
2486
|
-
}
|
|
2487
|
-
return false;
|
|
2488
|
-
}
|
|
2489
|
-
async function maybeHandleToolsRoute(input, norm) {
|
|
2490
|
-
if (input.req.method !== "GET" || norm !== "/tools") return false;
|
|
2491
|
-
const { enrichSpecWithCanonicalSchema: enrichSpecWithCanonicalSchema2 } = await import('./canonicalCoreSchemas-TY7NCWCC.cjs');
|
|
2492
|
-
const tools = input.runtime.getRegistry().snapshot().map(enrichSpecWithCanonicalSchema2).map((s) => ({
|
|
2493
|
-
name: s.name,
|
|
2494
|
-
description: s.description,
|
|
2495
|
-
kind: s.kind,
|
|
2496
|
-
inputSchema: s.inputSchema
|
|
2497
|
-
}));
|
|
2498
|
-
sendJson(input.res, 200, { tools });
|
|
2499
|
-
return true;
|
|
2500
|
-
}
|
|
2501
|
-
async function maybeHandleInvokeRoute(input, norm) {
|
|
2502
|
-
if (input.req.method !== "POST") return false;
|
|
2503
|
-
if (norm === "/invoke") {
|
|
2504
|
-
const body = await parseBodyOrSendError(input.req, input.res);
|
|
2505
|
-
if (!body) return true;
|
|
2506
|
-
const tool = body.tool;
|
|
2507
|
-
if (typeof tool !== "string" || !tool.trim()) {
|
|
2508
|
-
sendJson(input.res, 400, { error: "Missing or invalid 'tool' in body", kind: "BAD_REQUEST" });
|
|
2509
|
-
return true;
|
|
2510
|
-
}
|
|
2511
|
-
await invokeAndSend(input.runtime, input.ctxFactory(input.req), input.res, tool.trim(), body.args ?? {});
|
|
2512
|
-
return true;
|
|
2513
|
-
}
|
|
2514
|
-
if (norm.startsWith("/invoke/") && norm.length > "/invoke/".length) {
|
|
2515
|
-
const args = await parseArgsOrSendError(input.req, input.res);
|
|
2516
|
-
if (args === void 0) return true;
|
|
2517
|
-
await invokeAndSend(input.runtime, input.ctxFactory(input.req), input.res, slugToToolName(norm.slice(8)), args);
|
|
2518
|
-
return true;
|
|
2519
|
-
}
|
|
2520
|
-
return false;
|
|
2521
|
-
}
|
|
2522
|
-
async function parseBodyOrSendError(req, res) {
|
|
2523
|
-
try {
|
|
2524
|
-
return await parseBody(req);
|
|
2525
|
-
} catch (err) {
|
|
2526
|
-
sendBadJsonBody(res, err);
|
|
2527
|
-
return null;
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
async function parseArgsOrSendError(req, res) {
|
|
2531
|
-
try {
|
|
2532
|
-
return await parseBody(req) ?? {};
|
|
2533
|
-
} catch (err) {
|
|
2534
|
-
sendBadJsonBody(res, err);
|
|
2535
|
-
return void 0;
|
|
2536
|
-
}
|
|
2579
|
+
function parseBodyFromExpress(raw) {
|
|
2580
|
+
if (raw == null) return {};
|
|
2581
|
+
if (typeof raw === "object") return raw;
|
|
2582
|
+
const text = Buffer.isBuffer(raw) ? raw.toString("utf-8") : String(raw);
|
|
2583
|
+
const parsed = safeParseToolArgs(text);
|
|
2584
|
+
if (parsed.ok) return parsed.value;
|
|
2585
|
+
throw new BodyParseError("Invalid JSON body", parsed.hint);
|
|
2537
2586
|
}
|
|
2538
2587
|
function sendBadJsonBody(res, err) {
|
|
2539
2588
|
const hint = err instanceof BodyParseError ? err.hint : void 0;
|
|
@@ -2556,16 +2605,117 @@ async function invokeAndSend(runtime, ctx, res, tool, args) {
|
|
|
2556
2605
|
details: result.error?.details
|
|
2557
2606
|
});
|
|
2558
2607
|
}
|
|
2559
|
-
function
|
|
2608
|
+
function createOpenAPIHttpServer(runtime, options = {}) {
|
|
2609
|
+
const app = express__default.default();
|
|
2610
|
+
const router = express__default.default.Router();
|
|
2611
|
+
const basePath = (options.basePath ?? "").replace(/\/$/, "");
|
|
2612
|
+
const ctxFactory = options.execContextFactory ?? (() => ({ ...DEFAULT_CTX2 }));
|
|
2613
|
+
app.use(express__default.default.text({ type: "*/*" }));
|
|
2614
|
+
router.get("/", (_req, res) => {
|
|
2615
|
+
const specPath = basePath ? `${basePath}/openapi.json` : "/openapi.json";
|
|
2616
|
+
res.type("text/html; charset=utf-8").send(swaggerUiHtml(specPath));
|
|
2617
|
+
});
|
|
2618
|
+
router.get("/swagger", (_req, res) => {
|
|
2619
|
+
const specPath = basePath ? `${basePath}/openapi.json` : "/openapi.json";
|
|
2620
|
+
res.type("text/html; charset=utf-8").send(swaggerUiHtml(specPath));
|
|
2621
|
+
});
|
|
2622
|
+
router.get("/openapi.json", (_req, res) => {
|
|
2623
|
+
sendJson(
|
|
2624
|
+
res,
|
|
2625
|
+
200,
|
|
2626
|
+
toolsToOpenAPISpec(runtime.getRegistry(), {
|
|
2627
|
+
title: "Tool API",
|
|
2628
|
+
version: "1.0.0",
|
|
2629
|
+
basePath: basePath || void 0
|
|
2630
|
+
})
|
|
2631
|
+
);
|
|
2632
|
+
});
|
|
2633
|
+
router.get("/spec", (_req, res) => {
|
|
2634
|
+
sendJson(
|
|
2635
|
+
res,
|
|
2636
|
+
200,
|
|
2637
|
+
toolsToOpenAPISpec(runtime.getRegistry(), {
|
|
2638
|
+
title: "Tool API",
|
|
2639
|
+
version: "1.0.0",
|
|
2640
|
+
basePath: basePath || void 0
|
|
2641
|
+
})
|
|
2642
|
+
);
|
|
2643
|
+
});
|
|
2644
|
+
router.get("/tools", async (_req, res, next) => {
|
|
2645
|
+
try {
|
|
2646
|
+
const { enrichSpecWithCanonicalSchema: enrichSpecWithCanonicalSchema2 } = await import('./canonicalCoreSchemas-TY7NCWCC.cjs');
|
|
2647
|
+
const tools = runtime.getRegistry().snapshot().map(enrichSpecWithCanonicalSchema2).map((s) => ({
|
|
2648
|
+
name: s.name,
|
|
2649
|
+
description: s.description,
|
|
2650
|
+
kind: s.kind,
|
|
2651
|
+
inputSchema: s.inputSchema
|
|
2652
|
+
}));
|
|
2653
|
+
sendJson(res, 200, { tools });
|
|
2654
|
+
} catch (error) {
|
|
2655
|
+
next(error);
|
|
2656
|
+
}
|
|
2657
|
+
});
|
|
2658
|
+
router.post("/invoke", async (req, res) => {
|
|
2659
|
+
let body = null;
|
|
2660
|
+
try {
|
|
2661
|
+
body = parseBodyFromExpress(req.body);
|
|
2662
|
+
} catch (err) {
|
|
2663
|
+
sendBadJsonBody(res, err);
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
const tool = body.tool;
|
|
2667
|
+
if (typeof tool !== "string" || !tool.trim()) {
|
|
2668
|
+
sendJson(res, 400, { error: "Missing or invalid 'tool' in body", kind: "BAD_REQUEST" });
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
await invokeAndSend(runtime, ctxFactory(req), res, tool.trim(), body.args ?? {});
|
|
2672
|
+
});
|
|
2673
|
+
router.post("/invoke/:slug", async (req, res) => {
|
|
2674
|
+
let args;
|
|
2675
|
+
try {
|
|
2676
|
+
args = parseBodyFromExpress(req.body);
|
|
2677
|
+
} catch (err) {
|
|
2678
|
+
sendBadJsonBody(res, err);
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
await invokeAndSend(runtime, ctxFactory(req), res, slugToToolName(req.params?.slug ?? ""), args);
|
|
2682
|
+
});
|
|
2683
|
+
if (basePath) {
|
|
2684
|
+
app.use(basePath, router);
|
|
2685
|
+
} else {
|
|
2686
|
+
app.use(router);
|
|
2687
|
+
}
|
|
2688
|
+
app.use((req, res) => {
|
|
2689
|
+
sendJson(res, 404, { error: "Not found", path: req.url ?? "/" });
|
|
2690
|
+
});
|
|
2691
|
+
app.use((err, _req, res, _next) => {
|
|
2692
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2693
|
+
sendJson(res, 500, { error: message, kind: "INTERNAL_ERROR" });
|
|
2694
|
+
});
|
|
2695
|
+
const originalListen = app.listen.bind(app);
|
|
2696
|
+
const defaultPort = options.port;
|
|
2697
|
+
const defaultHost = options.host;
|
|
2698
|
+
app.listen = ((...args) => {
|
|
2699
|
+
if (args.length === 0) {
|
|
2700
|
+
return originalListen(defaultPort ?? 0, defaultHost ?? "localhost");
|
|
2701
|
+
}
|
|
2702
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
2703
|
+
return originalListen(defaultPort ?? 0, defaultHost ?? "localhost", args[0]);
|
|
2704
|
+
}
|
|
2705
|
+
return originalListen(...args);
|
|
2706
|
+
});
|
|
2707
|
+
return app;
|
|
2708
|
+
}
|
|
2709
|
+
function listenOpenAPIHttpServer(app, options = {}) {
|
|
2560
2710
|
return new Promise((resolve4, reject) => {
|
|
2561
2711
|
const port = options.port ?? 0;
|
|
2562
2712
|
const host = options.host ?? "localhost";
|
|
2563
|
-
|
|
2564
|
-
const addr =
|
|
2713
|
+
const httpServer = app.listen(port, host, () => {
|
|
2714
|
+
const addr = httpServer.address();
|
|
2565
2715
|
const actualPort = typeof addr === "object" && addr?.port != null ? addr.port : port;
|
|
2566
|
-
resolve4({ port: actualPort, host });
|
|
2716
|
+
resolve4({ port: actualPort, host, httpServer });
|
|
2567
2717
|
});
|
|
2568
|
-
|
|
2718
|
+
httpServer.on("error", reject);
|
|
2569
2719
|
});
|
|
2570
2720
|
}
|
|
2571
2721
|
async function createHttpService(runtimeOrConfig, options = {}) {
|
|
@@ -2576,149 +2726,31 @@ async function createHttpService(runtimeOrConfig, options = {}) {
|
|
|
2576
2726
|
version: options.version ?? "1.0.0",
|
|
2577
2727
|
basePath: options.basePath
|
|
2578
2728
|
});
|
|
2729
|
+
let activeHttpServer = null;
|
|
2579
2730
|
return {
|
|
2580
2731
|
server,
|
|
2581
2732
|
openApiSpec,
|
|
2582
|
-
listen: (listenOpts) =>
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
"read:web",
|
|
2592
|
-
"read:fs",
|
|
2593
|
-
"write:fs",
|
|
2594
|
-
"read:db",
|
|
2595
|
-
"write:db",
|
|
2596
|
-
"network",
|
|
2597
|
-
"workflow",
|
|
2598
|
-
"danger:destructive"
|
|
2599
|
-
]
|
|
2600
|
-
};
|
|
2601
|
-
function toMcpToolName(registryName) {
|
|
2602
|
-
return chunkQEJF3KDV_cjs.normalizeToolName(registryName);
|
|
2603
|
-
}
|
|
2604
|
-
async function createMcpServerWithTools(runtime, options) {
|
|
2605
|
-
const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
2606
|
-
const name = options.name ?? "agent-tool";
|
|
2607
|
-
const version = options.version ?? "1.0.0";
|
|
2608
|
-
const ctxFactory = options.execContextFactory ?? (() => ({ ...DEFAULT_CTX2 }));
|
|
2609
|
-
const server = new McpServer({ name, version });
|
|
2610
|
-
const registry = runtime.getRegistry();
|
|
2611
|
-
const specs = registry.snapshot();
|
|
2612
|
-
for (const spec of specs) {
|
|
2613
|
-
const mcpName = toMcpToolName(spec.name);
|
|
2614
|
-
server.registerTool(
|
|
2615
|
-
mcpName,
|
|
2616
|
-
{
|
|
2617
|
-
description: spec.description ?? `Tool: ${spec.name}`,
|
|
2618
|
-
inputSchema: spec.inputSchema,
|
|
2619
|
-
_meta: spec._meta
|
|
2620
|
-
},
|
|
2621
|
-
async (args) => {
|
|
2622
|
-
const ctx = ctxFactory();
|
|
2623
|
-
const result = await runtime.invoke(
|
|
2624
|
-
{ tool: spec.name, args: args ?? {}, purpose: chunk33N4Y6IS_cjs.MCP_KIND },
|
|
2625
|
-
ctx
|
|
2626
|
-
);
|
|
2627
|
-
if (result.ok) {
|
|
2628
|
-
return { content: [{ type: "text", text: JSON.stringify(result.result) }] };
|
|
2629
|
-
}
|
|
2630
|
-
const err = result.error;
|
|
2631
|
-
return {
|
|
2632
|
-
content: [
|
|
2633
|
-
{
|
|
2634
|
-
type: "text",
|
|
2635
|
-
text: JSON.stringify({ error: err?.message ?? "Tool failed", kind: err?.kind })
|
|
2636
|
-
}
|
|
2637
|
-
],
|
|
2638
|
-
isError: true
|
|
2639
|
-
};
|
|
2640
|
-
}
|
|
2641
|
-
);
|
|
2642
|
-
}
|
|
2643
|
-
return { server };
|
|
2644
|
-
}
|
|
2645
|
-
async function createMCPServer(runtimeOrConfig, options = {}) {
|
|
2646
|
-
const runtime = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? runtimeOrConfig : (await createRuntimeFromConfig(runtimeOrConfig)).runtime;
|
|
2647
|
-
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
2648
|
-
const { server } = await createMcpServerWithTools(runtime, options);
|
|
2649
|
-
return {
|
|
2650
|
-
server,
|
|
2651
|
-
async connectStdio() {
|
|
2652
|
-
const transport = new StdioServerTransport();
|
|
2653
|
-
await server.connect(transport);
|
|
2654
|
-
}
|
|
2655
|
-
};
|
|
2656
|
-
}
|
|
2657
|
-
function createMCPStreamableHttpHandler(runtimeOrConfig, options = {}) {
|
|
2658
|
-
if ("invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function") {
|
|
2659
|
-
const runtime = runtimeOrConfig;
|
|
2660
|
-
return async function streamableHttpHandler(req, res, parsedBody) {
|
|
2661
|
-
const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
2662
|
-
const { server } = await createMcpServerWithTools(runtime, options);
|
|
2663
|
-
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
|
|
2664
|
-
await server.connect(transport);
|
|
2665
|
-
const onClose = () => {
|
|
2666
|
-
transport.close().catch(() => {
|
|
2667
|
-
});
|
|
2668
|
-
server.close().catch(() => {
|
|
2669
|
-
});
|
|
2670
|
-
res.removeListener("close", onClose);
|
|
2671
|
-
res.removeListener("finish", onClose);
|
|
2672
|
-
};
|
|
2673
|
-
res.once("close", onClose);
|
|
2674
|
-
res.once("finish", onClose);
|
|
2675
|
-
await transport.handleRequest(
|
|
2676
|
-
req,
|
|
2677
|
-
res,
|
|
2678
|
-
parsedBody
|
|
2679
|
-
);
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
|
-
return (async () => {
|
|
2683
|
-
const { runtime } = await createRuntimeFromConfig(runtimeOrConfig);
|
|
2684
|
-
return createMCPStreamableHttpHandler(runtime, options);
|
|
2685
|
-
})();
|
|
2686
|
-
}
|
|
2687
|
-
async function createMCPServerStreamableHttp(runtimeOrConfig, options = {}) {
|
|
2688
|
-
const path = options.path ?? "/mcp";
|
|
2689
|
-
const host = options.host ?? "127.0.0.1";
|
|
2690
|
-
const port = options.port ?? 3e3;
|
|
2691
|
-
const { createMcpExpressApp } = await import('@modelcontextprotocol/sdk/server/express.js');
|
|
2692
|
-
const handler = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? createMCPStreamableHttpHandler(runtimeOrConfig, options) : await createMCPStreamableHttpHandler(runtimeOrConfig, options);
|
|
2693
|
-
const app = createMcpExpressApp({ host });
|
|
2694
|
-
app.post(path, handler);
|
|
2695
|
-
return {
|
|
2696
|
-
app,
|
|
2697
|
-
path,
|
|
2698
|
-
async listen(listenPort, listenHost) {
|
|
2699
|
-
const p = listenPort ?? port;
|
|
2700
|
-
const h = listenHost ?? host;
|
|
2701
|
-
return new Promise((resolve4, reject) => {
|
|
2702
|
-
const server = app.listen(p, h, () => {
|
|
2703
|
-
const addr = server.address();
|
|
2704
|
-
const actualPort = typeof addr === "object" && addr !== null && "port" in addr ? addr.port : p;
|
|
2705
|
-
resolve4({ url: `http://${h}:${actualPort}${path}`, port: actualPort });
|
|
2706
|
-
});
|
|
2733
|
+
listen: async (listenOpts) => {
|
|
2734
|
+
const { port, host, httpServer } = await listenOpenAPIHttpServer(server, listenOpts);
|
|
2735
|
+
activeHttpServer = httpServer;
|
|
2736
|
+
return { port, host };
|
|
2737
|
+
},
|
|
2738
|
+
close: async () => {
|
|
2739
|
+
if (!activeHttpServer) return;
|
|
2740
|
+
await new Promise((resolve4, reject) => {
|
|
2741
|
+
activeHttpServer.close((err) => err ? reject(err) : resolve4());
|
|
2707
2742
|
});
|
|
2743
|
+
activeHttpServer = null;
|
|
2708
2744
|
}
|
|
2709
2745
|
};
|
|
2710
2746
|
}
|
|
2711
|
-
async function runMCPServerOverStdio(runtime, options = {}) {
|
|
2712
|
-
const result = await createMCPServer(runtime, options);
|
|
2713
|
-
await result.connectStdio();
|
|
2714
|
-
return result;
|
|
2715
|
-
}
|
|
2716
2747
|
|
|
2717
2748
|
exports.PTCRuntime = PTCRuntime;
|
|
2718
2749
|
exports.createHttpService = createHttpService;
|
|
2719
2750
|
exports.createMCPServer = createMCPServer;
|
|
2720
2751
|
exports.createMCPServerStreamableHttp = createMCPServerStreamableHttp;
|
|
2721
2752
|
exports.createMCPStreamableHttpHandler = createMCPStreamableHttpHandler;
|
|
2753
|
+
exports.createOpenAPIHttpServer = createOpenAPIHttpServer;
|
|
2722
2754
|
exports.createRuntimeFromConfig = createRuntimeFromConfig;
|
|
2723
2755
|
exports.createRuntimeFromConfigSync = createRuntimeFromConfigSync;
|
|
2724
2756
|
exports.expandToolDescriptorsToRegistryNames = expandToolDescriptorsToRegistryNames;
|
|
@@ -2731,5 +2763,5 @@ exports.npmDescriptorToPackagePrefixWithVersion = npmDescriptorToPackagePrefixWi
|
|
|
2731
2763
|
exports.resolveSandboxedPath = resolveSandboxedPath;
|
|
2732
2764
|
exports.resolveToolDescriptor = resolveToolDescriptor;
|
|
2733
2765
|
exports.runMCPServerOverStdio = runMCPServerOverStdio;
|
|
2734
|
-
//# sourceMappingURL=chunk-
|
|
2735
|
-
//# sourceMappingURL=chunk-
|
|
2766
|
+
//# sourceMappingURL=chunk-PYTHEY6A.cjs.map
|
|
2767
|
+
//# sourceMappingURL=chunk-PYTHEY6A.cjs.map
|