imean-service-engine 1.4.0 → 1.4.2
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 +582 -582
- package/dist/mod.cjs +121 -0
- package/dist/mod.d.cts +8 -1
- package/dist/mod.d.ts +8 -1
- package/dist/mod.js +121 -1
- package/package.json +7 -8
package/dist/mod.cjs
CHANGED
@@ -13,6 +13,10 @@ var prettier = require('prettier');
|
|
13
13
|
var crypto2 = require('crypto');
|
14
14
|
var zlib = require('zlib');
|
15
15
|
var nodeWs = require('@hono/node-ws');
|
16
|
+
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
17
|
+
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
18
|
+
var streaming = require('hono/streaming');
|
19
|
+
var ulid = require('ulid');
|
16
20
|
var dayjs = require('dayjs');
|
17
21
|
|
18
22
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
@@ -523,6 +527,7 @@ var ActionHandler = class {
|
|
523
527
|
const now = Date.now();
|
524
528
|
if (cached !== null && (!this.metadata.ttl || cached?.expireAt > now)) {
|
525
529
|
span?.setAttribute("cacheHit", true);
|
530
|
+
span?.setAttribute("cacheKey", cacheKey);
|
526
531
|
return cached.data;
|
527
532
|
}
|
528
533
|
}
|
@@ -1236,6 +1241,121 @@ async function startCheck(checkers, pass) {
|
|
1236
1241
|
logger_default.info("[ \u9884\u68C0\u5B8C\u6210 ]");
|
1237
1242
|
if (pass) await pass();
|
1238
1243
|
}
|
1244
|
+
var HonoTransport = class {
|
1245
|
+
constructor(url, stream, closeStream) {
|
1246
|
+
this.url = url;
|
1247
|
+
this.stream = stream;
|
1248
|
+
this.closeStream = closeStream;
|
1249
|
+
this.sessionId = ulid.ulid();
|
1250
|
+
}
|
1251
|
+
sessionId;
|
1252
|
+
onclose;
|
1253
|
+
onerror;
|
1254
|
+
onmessage;
|
1255
|
+
async start() {
|
1256
|
+
await this.stream.writeSSE({
|
1257
|
+
event: "endpoint",
|
1258
|
+
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1259
|
+
});
|
1260
|
+
this.stream.onAbort(() => {
|
1261
|
+
this.close();
|
1262
|
+
});
|
1263
|
+
}
|
1264
|
+
async handleMessage(message) {
|
1265
|
+
let parsedMessage;
|
1266
|
+
try {
|
1267
|
+
parsedMessage = types_js.JSONRPCMessageSchema.parse(message);
|
1268
|
+
} catch (error) {
|
1269
|
+
this.onerror?.(error);
|
1270
|
+
throw error;
|
1271
|
+
}
|
1272
|
+
this.onmessage?.(parsedMessage);
|
1273
|
+
}
|
1274
|
+
async send(message) {
|
1275
|
+
await this.stream.writeln(
|
1276
|
+
`event: message
|
1277
|
+
data: ${JSON.stringify(message)}
|
1278
|
+
|
1279
|
+
`
|
1280
|
+
);
|
1281
|
+
}
|
1282
|
+
async close() {
|
1283
|
+
this.onclose?.();
|
1284
|
+
this.closeStream();
|
1285
|
+
}
|
1286
|
+
};
|
1287
|
+
var ModelContextProtocolPlugin = class extends Plugin {
|
1288
|
+
mcpServer;
|
1289
|
+
transports = {};
|
1290
|
+
registerMcpTools(engine) {
|
1291
|
+
const modules = engine.getModules(true);
|
1292
|
+
for (const module of Object.values(modules)) {
|
1293
|
+
for (const action of Object.values(module.actions)) {
|
1294
|
+
if (action.mcp?.type !== "tool") {
|
1295
|
+
continue;
|
1296
|
+
}
|
1297
|
+
const args = {};
|
1298
|
+
const argsIndex = {};
|
1299
|
+
for (const [index, param] of (action.params ?? []).entries()) {
|
1300
|
+
args[param.description] = param;
|
1301
|
+
argsIndex[param.description] = index;
|
1302
|
+
}
|
1303
|
+
this.mcpServer.tool(
|
1304
|
+
`${module.name}.${action.name}`,
|
1305
|
+
action.description ?? "",
|
1306
|
+
args,
|
1307
|
+
async (params) => {
|
1308
|
+
const argsList = [];
|
1309
|
+
for (const [key, value] of Object.entries(params)) {
|
1310
|
+
argsList[argsIndex[key]] = value;
|
1311
|
+
}
|
1312
|
+
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1313
|
+
return {
|
1314
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
1315
|
+
};
|
1316
|
+
}
|
1317
|
+
);
|
1318
|
+
}
|
1319
|
+
}
|
1320
|
+
}
|
1321
|
+
initialize = async (engine) => {
|
1322
|
+
const app = engine.getApp();
|
1323
|
+
this.mcpServer = new mcp_js.McpServer({
|
1324
|
+
name: engine.options.name,
|
1325
|
+
version: engine.options.version
|
1326
|
+
});
|
1327
|
+
this.registerMcpTools(engine);
|
1328
|
+
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1329
|
+
return streaming.streamSSE(ctx, async (stream) => {
|
1330
|
+
return new Promise(async (resolve) => {
|
1331
|
+
const transport = new HonoTransport(
|
1332
|
+
`${engine.options.prefix}/mcp_messages`,
|
1333
|
+
stream,
|
1334
|
+
() => {
|
1335
|
+
delete this.transports[transport.sessionId];
|
1336
|
+
resolve();
|
1337
|
+
}
|
1338
|
+
);
|
1339
|
+
this.transports[transport.sessionId] = transport;
|
1340
|
+
await this.mcpServer.connect(transport);
|
1341
|
+
});
|
1342
|
+
});
|
1343
|
+
});
|
1344
|
+
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1345
|
+
const sessionId = ctx.req.query("sessionId");
|
1346
|
+
if (!sessionId) {
|
1347
|
+
return ctx.text("No transport found for sessionId", 400);
|
1348
|
+
}
|
1349
|
+
const transport = this.transports[sessionId];
|
1350
|
+
const message = await ctx.req.json();
|
1351
|
+
await transport.handleMessage(message);
|
1352
|
+
return ctx.text("Accepted", 202);
|
1353
|
+
});
|
1354
|
+
logger_default.info(
|
1355
|
+
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1356
|
+
);
|
1357
|
+
};
|
1358
|
+
};
|
1239
1359
|
|
1240
1360
|
Object.defineProperty(exports, "dayjs", {
|
1241
1361
|
enumerable: true,
|
@@ -1245,6 +1365,7 @@ exports.Action = Action;
|
|
1245
1365
|
exports.CacheAdapter = CacheAdapter;
|
1246
1366
|
exports.MemoryCacheAdapter = MemoryCacheAdapter;
|
1247
1367
|
exports.Microservice = Microservice;
|
1368
|
+
exports.ModelContextProtocolPlugin = ModelContextProtocolPlugin;
|
1248
1369
|
exports.Module = Module;
|
1249
1370
|
exports.Plugin = Plugin;
|
1250
1371
|
exports.RedisCacheAdapter = RedisCacheAdapter;
|
package/dist/mod.d.cts
CHANGED
@@ -260,6 +260,13 @@ interface PreStartChecker {
|
|
260
260
|
}
|
261
261
|
declare function startCheck(checkers: PreStartChecker[], pass?: () => void | Promise<void>): Promise<void>;
|
262
262
|
|
263
|
+
declare class ModelContextProtocolPlugin extends Plugin {
|
264
|
+
private mcpServer;
|
265
|
+
private transports;
|
266
|
+
private registerMcpTools;
|
267
|
+
initialize: (engine: Microservice) => Promise<void>;
|
268
|
+
}
|
269
|
+
|
263
270
|
/**
|
264
271
|
* 用于给微服务模块方法添加的注解
|
265
272
|
*/
|
@@ -279,4 +286,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
279
286
|
|
280
287
|
declare const logger: winston.Logger;
|
281
288
|
|
282
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
289
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.d.ts
CHANGED
@@ -260,6 +260,13 @@ interface PreStartChecker {
|
|
260
260
|
}
|
261
261
|
declare function startCheck(checkers: PreStartChecker[], pass?: () => void | Promise<void>): Promise<void>;
|
262
262
|
|
263
|
+
declare class ModelContextProtocolPlugin extends Plugin {
|
264
|
+
private mcpServer;
|
265
|
+
private transports;
|
266
|
+
private registerMcpTools;
|
267
|
+
initialize: (engine: Microservice) => Promise<void>;
|
268
|
+
}
|
269
|
+
|
263
270
|
/**
|
264
271
|
* 用于给微服务模块方法添加的注解
|
265
272
|
*/
|
@@ -279,4 +286,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
279
286
|
|
280
287
|
declare const logger: winston.Logger;
|
281
288
|
|
282
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
289
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.js
CHANGED
@@ -13,6 +13,10 @@ import crypto2 from 'node:crypto';
|
|
13
13
|
import { brotliDecompress } from 'node:zlib';
|
14
14
|
import { brotliCompress, constants } from 'zlib';
|
15
15
|
import { createNodeWebSocket } from '@hono/node-ws';
|
16
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
17
|
+
import { JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
|
18
|
+
import { streamSSE } from 'hono/streaming';
|
19
|
+
import { ulid } from 'ulid';
|
16
20
|
export { default as dayjs } from 'dayjs';
|
17
21
|
|
18
22
|
// mod.ts
|
@@ -514,6 +518,7 @@ var ActionHandler = class {
|
|
514
518
|
const now = Date.now();
|
515
519
|
if (cached !== null && (!this.metadata.ttl || cached?.expireAt > now)) {
|
516
520
|
span?.setAttribute("cacheHit", true);
|
521
|
+
span?.setAttribute("cacheKey", cacheKey);
|
517
522
|
return cached.data;
|
518
523
|
}
|
519
524
|
}
|
@@ -1227,5 +1232,120 @@ async function startCheck(checkers, pass) {
|
|
1227
1232
|
logger_default.info("[ \u9884\u68C0\u5B8C\u6210 ]");
|
1228
1233
|
if (pass) await pass();
|
1229
1234
|
}
|
1235
|
+
var HonoTransport = class {
|
1236
|
+
constructor(url, stream, closeStream) {
|
1237
|
+
this.url = url;
|
1238
|
+
this.stream = stream;
|
1239
|
+
this.closeStream = closeStream;
|
1240
|
+
this.sessionId = ulid();
|
1241
|
+
}
|
1242
|
+
sessionId;
|
1243
|
+
onclose;
|
1244
|
+
onerror;
|
1245
|
+
onmessage;
|
1246
|
+
async start() {
|
1247
|
+
await this.stream.writeSSE({
|
1248
|
+
event: "endpoint",
|
1249
|
+
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1250
|
+
});
|
1251
|
+
this.stream.onAbort(() => {
|
1252
|
+
this.close();
|
1253
|
+
});
|
1254
|
+
}
|
1255
|
+
async handleMessage(message) {
|
1256
|
+
let parsedMessage;
|
1257
|
+
try {
|
1258
|
+
parsedMessage = JSONRPCMessageSchema.parse(message);
|
1259
|
+
} catch (error) {
|
1260
|
+
this.onerror?.(error);
|
1261
|
+
throw error;
|
1262
|
+
}
|
1263
|
+
this.onmessage?.(parsedMessage);
|
1264
|
+
}
|
1265
|
+
async send(message) {
|
1266
|
+
await this.stream.writeln(
|
1267
|
+
`event: message
|
1268
|
+
data: ${JSON.stringify(message)}
|
1269
|
+
|
1270
|
+
`
|
1271
|
+
);
|
1272
|
+
}
|
1273
|
+
async close() {
|
1274
|
+
this.onclose?.();
|
1275
|
+
this.closeStream();
|
1276
|
+
}
|
1277
|
+
};
|
1278
|
+
var ModelContextProtocolPlugin = class extends Plugin {
|
1279
|
+
mcpServer;
|
1280
|
+
transports = {};
|
1281
|
+
registerMcpTools(engine) {
|
1282
|
+
const modules = engine.getModules(true);
|
1283
|
+
for (const module of Object.values(modules)) {
|
1284
|
+
for (const action of Object.values(module.actions)) {
|
1285
|
+
if (action.mcp?.type !== "tool") {
|
1286
|
+
continue;
|
1287
|
+
}
|
1288
|
+
const args = {};
|
1289
|
+
const argsIndex = {};
|
1290
|
+
for (const [index, param] of (action.params ?? []).entries()) {
|
1291
|
+
args[param.description] = param;
|
1292
|
+
argsIndex[param.description] = index;
|
1293
|
+
}
|
1294
|
+
this.mcpServer.tool(
|
1295
|
+
`${module.name}.${action.name}`,
|
1296
|
+
action.description ?? "",
|
1297
|
+
args,
|
1298
|
+
async (params) => {
|
1299
|
+
const argsList = [];
|
1300
|
+
for (const [key, value] of Object.entries(params)) {
|
1301
|
+
argsList[argsIndex[key]] = value;
|
1302
|
+
}
|
1303
|
+
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1304
|
+
return {
|
1305
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
1306
|
+
};
|
1307
|
+
}
|
1308
|
+
);
|
1309
|
+
}
|
1310
|
+
}
|
1311
|
+
}
|
1312
|
+
initialize = async (engine) => {
|
1313
|
+
const app = engine.getApp();
|
1314
|
+
this.mcpServer = new McpServer({
|
1315
|
+
name: engine.options.name,
|
1316
|
+
version: engine.options.version
|
1317
|
+
});
|
1318
|
+
this.registerMcpTools(engine);
|
1319
|
+
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1320
|
+
return streamSSE(ctx, async (stream) => {
|
1321
|
+
return new Promise(async (resolve) => {
|
1322
|
+
const transport = new HonoTransport(
|
1323
|
+
`${engine.options.prefix}/mcp_messages`,
|
1324
|
+
stream,
|
1325
|
+
() => {
|
1326
|
+
delete this.transports[transport.sessionId];
|
1327
|
+
resolve();
|
1328
|
+
}
|
1329
|
+
);
|
1330
|
+
this.transports[transport.sessionId] = transport;
|
1331
|
+
await this.mcpServer.connect(transport);
|
1332
|
+
});
|
1333
|
+
});
|
1334
|
+
});
|
1335
|
+
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1336
|
+
const sessionId = ctx.req.query("sessionId");
|
1337
|
+
if (!sessionId) {
|
1338
|
+
return ctx.text("No transport found for sessionId", 400);
|
1339
|
+
}
|
1340
|
+
const transport = this.transports[sessionId];
|
1341
|
+
const message = await ctx.req.json();
|
1342
|
+
await transport.handleMessage(message);
|
1343
|
+
return ctx.text("Accepted", 202);
|
1344
|
+
});
|
1345
|
+
logger_default.info(
|
1346
|
+
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1347
|
+
);
|
1348
|
+
};
|
1349
|
+
};
|
1230
1350
|
|
1231
|
-
export { Action, CacheAdapter, MemoryCacheAdapter, Microservice, Module, Plugin, RedisCacheAdapter, Schedule, ScheduleMode, ServiceContext, logger_default as logger, startCheck };
|
1351
|
+
export { Action, CacheAdapter, MemoryCacheAdapter, Microservice, ModelContextProtocolPlugin, Module, Plugin, RedisCacheAdapter, Schedule, ScheduleMode, ServiceContext, logger_default as logger, startCheck };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "imean-service-engine",
|
3
|
-
"version": "1.4.
|
3
|
+
"version": "1.4.2",
|
4
4
|
"description": "microservice engine",
|
5
5
|
"keywords": [
|
6
6
|
"microservice",
|
@@ -30,12 +30,6 @@
|
|
30
30
|
"README.md",
|
31
31
|
"LICENSE"
|
32
32
|
],
|
33
|
-
"scripts": {
|
34
|
-
"dev": "tsx watch dev/index.ts",
|
35
|
-
"build": "tsup",
|
36
|
-
"test": "vitest run",
|
37
|
-
"prepublishOnly": "npm run build && npm run test"
|
38
|
-
},
|
39
33
|
"dependencies": {
|
40
34
|
"@hono/node-server": "^1.13.7",
|
41
35
|
"@hono/node-ws": "^1.0.6",
|
@@ -83,5 +77,10 @@
|
|
83
77
|
},
|
84
78
|
"engines": {
|
85
79
|
"node": ">=20"
|
80
|
+
},
|
81
|
+
"scripts": {
|
82
|
+
"dev": "tsx watch dev/index.ts",
|
83
|
+
"build": "tsup",
|
84
|
+
"test": "vitest run"
|
86
85
|
}
|
87
|
-
}
|
86
|
+
}
|