@zltquant/zlt-mcp 0.4.2 → 0.5.0-beta.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 +6 -0
- package/package.json +1 -1
- package/zlt-mcp-proxy.bundle.cjs +74 -5
package/README.md
CHANGED
|
@@ -14,6 +14,12 @@ npx -y @zltquant/zlt-mcp list --json
|
|
|
14
14
|
npx -y @zltquant/zlt-mcp call zlt-runtime-doctor --args-json '{}'
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
业务调用支持 `call --output-json <新文件路径>`:完整 JSON 写入文件,stdout 返回含
|
|
18
|
+
`ok`、`tool`、`resultFile`、`cliProvenance`、精简 `data` 的回执。
|
|
19
|
+
输出目录须已存在,已有文件会在执行工具前报错;每次使用新文件名。完整参数与大段数据从结果文件读取。
|
|
20
|
+
stderr 保留诊断,失败返回非零退出码。工具执行后若写文件失败,完整结果会输出到 stdout;先核对结果,不要自动重复执行。
|
|
21
|
+
不传该参数时保持原有完整 stdout。
|
|
22
|
+
|
|
17
23
|
其他支持原生 MCP 的客户端(Trae / Claude Code / Cursor 等)可以使用下面的配置:
|
|
18
24
|
|
|
19
25
|
```json
|
package/package.json
CHANGED
package/zlt-mcp-proxy.bundle.cjs
CHANGED
|
@@ -24936,6 +24936,12 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
|
|
|
24936
24936
|
const echoedRunId = typeof parsed.Data.runId === "string" ? parsed.Data.runId.trim() : "";
|
|
24937
24937
|
const runId = echoedRunId || (tool.name === "mcp-re-backtest" && typeof args.runId === "string" ? args.runId.trim() : "");
|
|
24938
24938
|
const context = runId ? contexts.get(runId) : void 0;
|
|
24939
|
+
if (runId) echo.runId = runId;
|
|
24940
|
+
if (context?.codePath) {
|
|
24941
|
+
echo.codePath = context.codePath;
|
|
24942
|
+
echo.runDir = context.codePath;
|
|
24943
|
+
}
|
|
24944
|
+
if (context?.runParams) echo.runParams = { ...context.runParams };
|
|
24939
24945
|
if (context?.attemptStartedAtMs) {
|
|
24940
24946
|
echo.attemptFence = {
|
|
24941
24947
|
attemptStartedAtMs: context.attemptStartedAtMs,
|
|
@@ -27501,7 +27507,7 @@ function runtimeRecoveryStopData(message, extra = {}, handler = "runtimeStart")
|
|
|
27501
27507
|
// src/index.ts
|
|
27502
27508
|
var CLI_NAME = "zlt-mcp";
|
|
27503
27509
|
var CLI_FALLBACK_PACKAGE_NAME = "@zltquant/zlt-mcp";
|
|
27504
|
-
var CLI_FALLBACK_VERSION = "0.
|
|
27510
|
+
var CLI_FALLBACK_VERSION = "0.5.0-beta.0";
|
|
27505
27511
|
if (process.argv.length <= 2) {
|
|
27506
27512
|
startMcpServer();
|
|
27507
27513
|
} else {
|
|
@@ -27511,21 +27517,44 @@ if (process.argv.length <= 2) {
|
|
|
27511
27517
|
if (kind !== "backtest") throw new Error(`Unsupported keepalive kind: ${kind}`);
|
|
27512
27518
|
await keepMcpBacktestAlive(id, codePath);
|
|
27513
27519
|
});
|
|
27514
|
-
program2.command("call <tool>").description("Call any MCP tool through the bundled MCP server").option("--args-json <json>", "JSON object containing tool arguments").option("--args-file <path>", "Read the JSON argument object from a file").option("--timeout-ms <ms>", "MCP request inactivity timeout in milliseconds").option("--max-total-timeout-ms <ms>", "Optional hard upper bound for the request").option("--no-progress", "Suppress progress diagnostics on stderr").action(async (tool, options) => {
|
|
27520
|
+
program2.command("call <tool>").description("Call any MCP tool through the bundled MCP server").option("--args-json <json>", "JSON object containing tool arguments").option("--args-file <path>", "Read the JSON argument object from a file").option("--output-json <path>", "Save the complete result to a new JSON file and print a compact receipt").option("--timeout-ms <ms>", "MCP request inactivity timeout in milliseconds").option("--max-total-timeout-ms <ms>", "Optional hard upper bound for the request").option("--no-progress", "Suppress progress diagnostics on stderr").action(async (tool, options) => {
|
|
27521
|
+
let outputFd;
|
|
27515
27522
|
try {
|
|
27516
27523
|
const args = parseMcpArgs(options.argsJson, options.argsFile);
|
|
27524
|
+
const timeoutMs = parseTimeoutOption(options.timeoutMs, "--timeout-ms");
|
|
27525
|
+
const maxTotalTimeoutMs = parseTimeoutOption(options.maxTotalTimeoutMs, "--max-total-timeout-ms");
|
|
27526
|
+
const resultFile = options.outputJson === void 0 ? void 0 : path14.resolve(options.outputJson);
|
|
27527
|
+
if (resultFile !== void 0) outputFd = fs13.openSync(resultFile, "wx");
|
|
27517
27528
|
const result = await callMcpTool(tool, args, {
|
|
27518
|
-
timeoutMs
|
|
27519
|
-
maxTotalTimeoutMs
|
|
27529
|
+
timeoutMs,
|
|
27530
|
+
maxTotalTimeoutMs,
|
|
27520
27531
|
showProgress: options.progress !== false
|
|
27521
27532
|
});
|
|
27522
|
-
|
|
27533
|
+
const complete = withCliProvenance(result);
|
|
27534
|
+
const serialized = JSON.stringify(complete) + "\n";
|
|
27535
|
+
if (outputFd !== void 0 && resultFile !== void 0) {
|
|
27536
|
+
try {
|
|
27537
|
+
fs13.writeFileSync(outputFd, serialized, "utf-8");
|
|
27538
|
+
fs13.closeSync(outputFd);
|
|
27539
|
+
outputFd = void 0;
|
|
27540
|
+
} catch (error2) {
|
|
27541
|
+
process.stdout.write(serialized);
|
|
27542
|
+
throw new Error(`Tool returned a result, but saving ${resultFile} failed; complete result is on stdout. Do not repeat the tool automatically. ${String(error2)}`);
|
|
27543
|
+
}
|
|
27544
|
+
const receipt = compactCliReceipt(tool, complete, resultFile);
|
|
27545
|
+
process.stdout.write(JSON.stringify(receipt) + "\n");
|
|
27546
|
+
if (!receipt.ok) process.exitCode = 1;
|
|
27547
|
+
} else {
|
|
27548
|
+
process.stdout.write(serialized);
|
|
27549
|
+
}
|
|
27523
27550
|
if (result.isError === true) process.exitCode = 1;
|
|
27524
27551
|
} catch (error2) {
|
|
27525
27552
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
27526
27553
|
process.stderr.write(`Error: ${message}
|
|
27527
27554
|
`);
|
|
27528
27555
|
process.exitCode = 1;
|
|
27556
|
+
} finally {
|
|
27557
|
+
if (outputFd !== void 0) fs13.closeSync(outputFd);
|
|
27529
27558
|
}
|
|
27530
27559
|
});
|
|
27531
27560
|
program2.command("list").description("List MCP tools exposed by the bundled server").option("--json", "Emit the complete tools/list response as JSON").action(async (options) => {
|
|
@@ -27619,6 +27648,46 @@ function resolveCliPackageProvenance() {
|
|
|
27619
27648
|
function withCliProvenance(result) {
|
|
27620
27649
|
return { ...result, cliProvenance: resolveCliPackageProvenance() };
|
|
27621
27650
|
}
|
|
27651
|
+
function compactCliReceipt(tool, result, resultFile) {
|
|
27652
|
+
const payload = parseMcpResult(result);
|
|
27653
|
+
const code = payload?.ErrNo;
|
|
27654
|
+
const ok = result.isError !== true && (code === void 0 || code === null || Number(code) === 0);
|
|
27655
|
+
const source = payload?.Data;
|
|
27656
|
+
const data = {};
|
|
27657
|
+
if (source && typeof source === "object" && !Array.isArray(source)) {
|
|
27658
|
+
const fields = source;
|
|
27659
|
+
for (const key of [
|
|
27660
|
+
"runId",
|
|
27661
|
+
"backtestId",
|
|
27662
|
+
"strategyId",
|
|
27663
|
+
"localPath",
|
|
27664
|
+
"codePath",
|
|
27665
|
+
"runDir",
|
|
27666
|
+
"attemptFence",
|
|
27667
|
+
"status",
|
|
27668
|
+
"progress",
|
|
27669
|
+
"available",
|
|
27670
|
+
"runtimeReady",
|
|
27671
|
+
"backtestReady",
|
|
27672
|
+
"nextAction",
|
|
27673
|
+
"recommendedAction",
|
|
27674
|
+
"error_code",
|
|
27675
|
+
"error_msg"
|
|
27676
|
+
]) {
|
|
27677
|
+
if (fields[key] !== void 0) {
|
|
27678
|
+
data[key] = key === "error_msg" && typeof fields[key] === "string" ? fields[key].slice(0, 512) : fields[key];
|
|
27679
|
+
}
|
|
27680
|
+
}
|
|
27681
|
+
}
|
|
27682
|
+
return {
|
|
27683
|
+
ok,
|
|
27684
|
+
tool,
|
|
27685
|
+
resultFile,
|
|
27686
|
+
cliProvenance: result.cliProvenance,
|
|
27687
|
+
data,
|
|
27688
|
+
...!ok ? { error: { code: code ?? null, message: String(payload?.ErrMsg ?? "Tool reported an error; see resultFile").slice(0, 512) } } : {}
|
|
27689
|
+
};
|
|
27690
|
+
}
|
|
27622
27691
|
function parseTimeoutOption(value, flag) {
|
|
27623
27692
|
if (value === void 0) return void 0;
|
|
27624
27693
|
const parsed = Number(value);
|