@actiondock/mcp 2.5.0 → 2.6.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/dist/adapter.js +69 -3
- package/dist/register-tasks-extension.js +2 -1
- package/dist/stdio.js +2 -1
- package/dist/types.d.ts +4 -0
- package/package.json +11 -3
package/dist/adapter.js
CHANGED
|
@@ -177,8 +177,39 @@ export async function resolveTarget(options) {
|
|
|
177
177
|
storage: appStorage,
|
|
178
178
|
customHome: options.customHome,
|
|
179
179
|
configOverrides: options.configOverrides,
|
|
180
|
+
dataDir: options.dataDir,
|
|
180
181
|
});
|
|
181
182
|
}
|
|
183
|
+
let platform = options.platform;
|
|
184
|
+
if (!platform && typeof process !== "undefined" && process.versions?.node) {
|
|
185
|
+
try {
|
|
186
|
+
const { createNodePlatform } = await import("@actiondock/runtime-node");
|
|
187
|
+
platform = createNodePlatform({
|
|
188
|
+
customHome: options.customHome,
|
|
189
|
+
dataDir: options.dataDir,
|
|
190
|
+
rootDir: projectRoot,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
// 仅「模块不存在」类错误允许降级回退 core 默认平台;
|
|
195
|
+
// 其余异常(加载后初始化失败等)原样上抛,避免吞没真实故障
|
|
196
|
+
const isModuleMissing = err?.code === "ERR_MODULE_NOT_FOUND" ||
|
|
197
|
+
/Cannot find (?:package|module)/i.test(String(err?.message || ""));
|
|
198
|
+
if (!isModuleMissing) {
|
|
199
|
+
throw err;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
for (const pkg of packages) {
|
|
204
|
+
if (typeof pkg === "object" && pkg !== null && !("info" in pkg)) {
|
|
205
|
+
if (platform && !pkg.platform) {
|
|
206
|
+
pkg.platform = platform;
|
|
207
|
+
}
|
|
208
|
+
if (!pkg.dataDir && options.dataDir) {
|
|
209
|
+
pkg.dataDir = options.dataDir;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
182
213
|
const target = await createActionDockTarget({
|
|
183
214
|
type: "local",
|
|
184
215
|
projectRoot,
|
|
@@ -187,7 +218,12 @@ export async function resolveTarget(options) {
|
|
|
187
218
|
hostOptions: {
|
|
188
219
|
autoLoadCurrentProject: packages.length === 0,
|
|
189
220
|
},
|
|
221
|
+
// MCP 服务进程是长驻执行宿主,声明数据目录持有者身份,
|
|
222
|
+
// 打开时收割遗留孤儿运行记录
|
|
223
|
+
recoverOrphans: true,
|
|
190
224
|
customHome: options.customHome,
|
|
225
|
+
dataDir: options.dataDir,
|
|
226
|
+
platform,
|
|
191
227
|
});
|
|
192
228
|
return { target, ownsTarget: true };
|
|
193
229
|
}
|
|
@@ -219,7 +255,36 @@ export async function createActionDockMcpServer(options = {}) {
|
|
|
219
255
|
// 任务规范扩展注册集中隔离在独立模块,本层不再直接操作 SDK 内层实例
|
|
220
256
|
registerTasksExtension(server, target);
|
|
221
257
|
// 工具注册与模式映射:tools/list 纯粹委托 target.listActions()
|
|
222
|
-
const
|
|
258
|
+
const rawActions = await target.listActions();
|
|
259
|
+
const seenActionKeys = new Map();
|
|
260
|
+
for (const act of rawActions) {
|
|
261
|
+
let pkgId = act.packageId || "";
|
|
262
|
+
let actId = act.id;
|
|
263
|
+
if (act.id.includes("/")) {
|
|
264
|
+
try {
|
|
265
|
+
const parsed = ActionResolver.parseRef(act.id);
|
|
266
|
+
pkgId = pkgId || parsed.packageId || "";
|
|
267
|
+
actId = parsed.actionId;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
const idx = act.id.lastIndexOf("/");
|
|
271
|
+
pkgId = pkgId || act.id.slice(0, idx);
|
|
272
|
+
actId = act.id.slice(idx + 1);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const key = `${pkgId}:${actId}`;
|
|
276
|
+
const existing = seenActionKeys.get(key);
|
|
277
|
+
if (existing) {
|
|
278
|
+
// 若已存在的项是全限定名(含 /),而当前项是短名(不含 /),优先保留短名项
|
|
279
|
+
if (existing.id.includes("/") && !act.id.includes("/")) {
|
|
280
|
+
seenActionKeys.set(key, act);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
seenActionKeys.set(key, act);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const actions = Array.from(seenActionKeys.values());
|
|
223
288
|
// 统计 Action 基础 ID 出现频次,用于同名冲突命名空间隔离
|
|
224
289
|
const baseCounts = new Map();
|
|
225
290
|
for (const act of actions) {
|
|
@@ -360,8 +425,9 @@ export async function createActionDockMcpServer(options = {}) {
|
|
|
360
425
|
});
|
|
361
426
|
}
|
|
362
427
|
}
|
|
363
|
-
catch {
|
|
364
|
-
//
|
|
428
|
+
catch (err) {
|
|
429
|
+
// 规程获取或注册失败不中断适配器启动,但输出诊断行保留排障线索
|
|
430
|
+
console.error(`[actiondock-mcp] Failed to register playbook resources/prompts: ${err?.message || String(err)}`);
|
|
365
431
|
}
|
|
366
432
|
// 服务生命周期:默认 close 仅关闭 MCP 服务本身,不级联 target——
|
|
367
433
|
// SDK 传输层(HTTP 每请求 / stdio 探测回落)会销毁工厂产物,若 close 级联会误杀共享 target;
|
|
@@ -96,8 +96,9 @@ export function registerTasksExtension(server, target) {
|
|
|
96
96
|
limit = Math.min(Math.max(params.limit, 1), MAX_TASK_LIST_LIMIT);
|
|
97
97
|
}
|
|
98
98
|
const actionId = params.actionId;
|
|
99
|
+
// limit 单处截断:下推到 target.listRuns 的 limit 参数,此处不再重复 slice
|
|
99
100
|
const runs = await target.listRuns({ limit, actionId });
|
|
100
101
|
const ordered = [...runs].sort((a, b) => toTimeMillis(b.startedAt) - toTimeMillis(a.startedAt));
|
|
101
|
-
return { tasks: ordered.
|
|
102
|
+
return { tasks: ordered.map(toMcpTaskPayload) };
|
|
102
103
|
});
|
|
103
104
|
}
|
package/dist/stdio.js
CHANGED
|
@@ -18,7 +18,7 @@ export async function startMcpStdio(options = {}) {
|
|
|
18
18
|
let targetToUse;
|
|
19
19
|
let childProcess;
|
|
20
20
|
// 若显式传入了已构造的 target 或不可序列化的内存对象,直接复用或解析目标实例
|
|
21
|
-
if (options.target || options.actions || options.storage || options.app || options.host) {
|
|
21
|
+
if (options.target || options.actions || options.storage || options.app || options.host || options.platform) {
|
|
22
22
|
targetToUse = options.target ?? (await resolveTarget(options)).target;
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
@@ -36,6 +36,7 @@ export async function startMcpStdio(options = {}) {
|
|
|
36
36
|
packageIds: options.packageIds,
|
|
37
37
|
all: options.all,
|
|
38
38
|
customHome: options.customHome,
|
|
39
|
+
dataDir: options.dataDir,
|
|
39
40
|
configOverrides: options.configOverrides,
|
|
40
41
|
timeoutMs: options.timeoutMs,
|
|
41
42
|
}),
|
package/dist/types.d.ts
CHANGED
|
@@ -47,6 +47,10 @@ export interface ActionDockMcpOptions {
|
|
|
47
47
|
all?: boolean;
|
|
48
48
|
/** 自定义家目录路径 */
|
|
49
49
|
customHome?: string;
|
|
50
|
+
/** 自定义全局数据存储目录 */
|
|
51
|
+
dataDir?: string;
|
|
52
|
+
/** 运行时底层平台适配(如提供 NodeProcessDriver 的平台实例) */
|
|
53
|
+
platform?: import("@actiondock/core").RuntimePlatform;
|
|
50
54
|
/** 配置动态覆盖项 */
|
|
51
55
|
configOverrides?: Record<string, unknown>;
|
|
52
56
|
/** 单个 Tool 执行超时时间(毫秒) */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "ActionDock MCP Adapter for exposing Actions as Model Context Protocol (MCP) Tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,10 +29,18 @@
|
|
|
29
29
|
"test": "node ../../scripts/run-tests.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@actiondock/core": "^2.
|
|
33
|
-
"@actiondock/sdk": "^2.
|
|
32
|
+
"@actiondock/core": "^2.6.0",
|
|
33
|
+
"@actiondock/sdk": "^2.6.0",
|
|
34
34
|
"@modelcontextprotocol/server": "^2.0.0"
|
|
35
35
|
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@actiondock/runtime-node": "^2.6.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"@actiondock/runtime-node": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
36
44
|
"devDependencies": {
|
|
37
45
|
"typescript": "^5.7.0"
|
|
38
46
|
},
|