harmony-build 0.2.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.
Files changed (72) hide show
  1. package/README.md +265 -0
  2. package/dist/packages/arkanalyzer-mcp/src/index.d.ts +5 -0
  3. package/dist/packages/arkanalyzer-mcp/src/index.js +220 -0
  4. package/dist/packages/arkanalyzer-mcp/src/index.js.map +1 -0
  5. package/dist/packages/arkcheck-mcp/src/index.d.ts +5 -0
  6. package/dist/packages/arkcheck-mcp/src/index.js +160 -0
  7. package/dist/packages/arkcheck-mcp/src/index.js.map +1 -0
  8. package/dist/packages/arkcheck-mcp/src/rules.d.ts +15 -0
  9. package/dist/packages/arkcheck-mcp/src/rules.js +90 -0
  10. package/dist/packages/arkcheck-mcp/src/rules.js.map +1 -0
  11. package/dist/packages/dev-mcp/src/hvigor-bridge.d.ts +31 -0
  12. package/dist/packages/dev-mcp/src/hvigor-bridge.js +179 -0
  13. package/dist/packages/dev-mcp/src/hvigor-bridge.js.map +1 -0
  14. package/dist/packages/dev-mcp/src/index.d.ts +5 -0
  15. package/dist/packages/dev-mcp/src/index.js +256 -0
  16. package/dist/packages/dev-mcp/src/index.js.map +1 -0
  17. package/dist/packages/dev-mcp/src/log-stream.d.ts +56 -0
  18. package/dist/packages/dev-mcp/src/log-stream.js +147 -0
  19. package/dist/packages/dev-mcp/src/log-stream.js.map +1 -0
  20. package/dist/packages/harmony-knowledge-mcp/src/index.d.ts +5 -0
  21. package/dist/packages/harmony-knowledge-mcp/src/index.js +164 -0
  22. package/dist/packages/harmony-knowledge-mcp/src/index.js.map +1 -0
  23. package/dist/packages/hdc-mcp/src/hdc-runner.d.ts +32 -0
  24. package/dist/packages/hdc-mcp/src/hdc-runner.js +60 -0
  25. package/dist/packages/hdc-mcp/src/hdc-runner.js.map +1 -0
  26. package/dist/packages/hdc-mcp/src/index.d.ts +5 -0
  27. package/dist/packages/hdc-mcp/src/index.js +155 -0
  28. package/dist/packages/hdc-mcp/src/index.js.map +1 -0
  29. package/dist/packages/hvigor-mcp/src/index.d.ts +5 -0
  30. package/dist/packages/hvigor-mcp/src/index.js +300 -0
  31. package/dist/packages/hvigor-mcp/src/index.js.map +1 -0
  32. package/dist/packages/hvigor-mcp/src/log-parser.d.ts +28 -0
  33. package/dist/packages/hvigor-mcp/src/log-parser.js +65 -0
  34. package/dist/packages/hvigor-mcp/src/log-parser.js.map +1 -0
  35. package/dist/packages/mcp-common/src/entry.d.ts +1 -0
  36. package/dist/packages/mcp-common/src/entry.js +22 -0
  37. package/dist/packages/mcp-common/src/entry.js.map +1 -0
  38. package/dist/packages/mcp-common/src/errors.d.ts +13 -0
  39. package/dist/packages/mcp-common/src/errors.js +23 -0
  40. package/dist/packages/mcp-common/src/errors.js.map +1 -0
  41. package/dist/packages/mcp-common/src/index.d.ts +6 -0
  42. package/dist/packages/mcp-common/src/index.js +7 -0
  43. package/dist/packages/mcp-common/src/index.js.map +1 -0
  44. package/dist/packages/mcp-common/src/logger.d.ts +11 -0
  45. package/dist/packages/mcp-common/src/logger.js +32 -0
  46. package/dist/packages/mcp-common/src/logger.js.map +1 -0
  47. package/dist/packages/mcp-common/src/mcp-helpers.d.ts +41 -0
  48. package/dist/packages/mcp-common/src/mcp-helpers.js +94 -0
  49. package/dist/packages/mcp-common/src/mcp-helpers.js.map +1 -0
  50. package/dist/packages/mcp-common/src/safe-exec.d.ts +23 -0
  51. package/dist/packages/mcp-common/src/safe-exec.js +74 -0
  52. package/dist/packages/mcp-common/src/safe-exec.js.map +1 -0
  53. package/dist/packages/mcp-common/src/sandbox.d.ts +31 -0
  54. package/dist/packages/mcp-common/src/sandbox.js +96 -0
  55. package/dist/packages/mcp-common/src/sandbox.js.map +1 -0
  56. package/dist/packages/profiler-mcp/src/index.d.ts +5 -0
  57. package/dist/packages/profiler-mcp/src/index.js +148 -0
  58. package/dist/packages/profiler-mcp/src/index.js.map +1 -0
  59. package/dist/packages/profiler-mcp/src/trace-analyzer.d.ts +38 -0
  60. package/dist/packages/profiler-mcp/src/trace-analyzer.js +95 -0
  61. package/dist/packages/profiler-mcp/src/trace-analyzer.js.map +1 -0
  62. package/dist/src/index.d.ts +17 -0
  63. package/dist/src/index.js +61 -0
  64. package/dist/src/index.js.map +1 -0
  65. package/dist/src/server/handlers.d.ts +11 -0
  66. package/dist/src/server/handlers.js +33 -0
  67. package/dist/src/server/handlers.js.map +1 -0
  68. package/dist/src/server/tools.d.ts +23 -0
  69. package/dist/src/server/tools.js +57 -0
  70. package/dist/src/server/tools.js.map +1 -0
  71. package/package.json +54 -0
  72. package//345/217/221/345/270/203/346/214/207/345/215/227.md +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/hdc-mcp/src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAW,MAAM,qBAAqB,CAAC;AAC1G,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AACvC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAEtC,gCAAgC;AAEhC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE5E,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEvC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACnD,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IACrE,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAC9D,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjD,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;SAC9D,QAAQ,CAAC,gBAAgB,CAAC;IAC7B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;SAClE,QAAQ,CAAC,QAAQ,CAAC;IACrB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC/C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;IACvD,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC9B,QAAQ,CAAC,qBAAqB,CAAC;IAClC,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH,8BAA8B;AAE9B,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAC/B,MAAM,CAAC,MAAM,KAAK,GAA0C;IAC1D;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,uBAAuB;QACpC,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;KAC5D;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,eAAe;QAC5B,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YACrD,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7F,CAAC;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,mBAAmB;QAChC,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YACvD,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7F,CAAC;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,iDAAiD;QAC9D,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CACvB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,EAC1D,CAAC,CAAC,MAAM,CACT,CAAC;YACF,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACtE,CAAC;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,oCAAoC;QACjD,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YACzE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACtE,CAAC;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,wCAAwC;QACrD,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC,CAAC,KAAK;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,CAAC,CAAC,GAAG;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3E,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;QACzF,CAAC;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,UAAU;QACvB,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACnB,MAAM,SAAS,GACb,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,qBAAqB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAChF,MAAM,SAAS,GAAG,iCAAiC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;YACpE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,kBAAkB,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACrF,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,IAAI,yBAAyB,CAAC,CAAC;YACzF,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YAChE,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,IAAI,CAAC,MAAM,IAAI,kBAAkB,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACrD,CAAC;KACF;CACF,CAAC;AAEF,6BAA6B;AAE7B,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IACF,aAAa,CACX,MAAM,EACN,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,EACjD,KAAK,CACN,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;AACjD,CAAC;AAED,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { z } from "zod";
3
+ import { ToolDef } from "@harmony-mcp/common";
4
+ export declare const NAMESPACE = "hvigor";
5
+ export declare const tools: ToolDef<z.ZodObject<z.ZodRawShape>>[];
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * hvigor-mcp: 鸿蒙 hvigor 构建系统的 MCP Server 化。
4
+ *
5
+ * 工具:
6
+ * - build_hap 编译 HAP/APP
7
+ * - clean 清理产物
8
+ * - sign_hap 签名(透传 hvigor sign 任务)
9
+ * - parse_build_log 从给定的 stdout/stderr 文本解析诊断(offline 用,便于 Self-Refine)
10
+ * - run_task 运行任意 hvigor 任务(白名单子集)
11
+ */
12
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
13
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
15
+ import { z } from "zod";
16
+ import fs from "node:fs/promises";
17
+ import fsSync from "node:fs";
18
+ import os from "node:os";
19
+ import path from "node:path";
20
+ import { createLogger, HarmonyMcpError, isMainModule, PathSandbox, registerTools, runCommand, } from "@harmony-mcp/common";
21
+ import { parseBuildLog } from "./log-parser.js";
22
+ const logger = createLogger("hvigor-mcp");
23
+ // v0.2: allowedRoots 现在只是"显式额外允许"的可选项;缺省也 OK,
24
+ // sandbox 会在收到 project_dir 时自动向上识别鸿蒙工程根并加入白名单。
25
+ const allowedRoots = (process.env.HARMONY_MCP_ALLOWED_ROOTS ?? "")
26
+ .split(path.delimiter)
27
+ .filter(Boolean);
28
+ const sandbox = new PathSandbox({ allowedRoots, autoDetectProjectRoot: true });
29
+ const HVIGOR_BIN_LEGACY_ENV = process.env.HVIGOR_BIN; // kept for backward compat, see resolveHvigorBin
30
+ void HVIGOR_BIN_LEGACY_ENV;
31
+ const TASK_WHITELIST = new Set([
32
+ "assembleHap",
33
+ "assembleApp",
34
+ "assembleHsp",
35
+ "clean",
36
+ "syncProject",
37
+ "signHap",
38
+ "test",
39
+ ]);
40
+ // ---------- Schemas ----------
41
+ const ProjectField = z
42
+ .string()
43
+ .describe("鸿蒙工程根目录绝对路径(必须在 HARMONY_MCP_ALLOWED_ROOTS 之内)");
44
+ const BuildHapSchema = z.object({
45
+ project_dir: ProjectField,
46
+ module: z.string().optional().describe("可选 module 名"),
47
+ build_mode: z.enum(["debug", "release"]).default("debug")
48
+ .describe("通过 -p buildMode=... 传给 hvigor;不是 --mode(--mode 是工程自定义 product 名)"),
49
+ product: z.string().optional()
50
+ .describe("工程 build-profile.json5 里定义的 product 名(对应 hvigor --mode 参数);不填则使用工程默认 product"),
51
+ no_daemon: z.boolean().default(true).describe("禁用 hvigor daemon,保证 CI 稳定"),
52
+ });
53
+ const CleanSchema = z.object({
54
+ project_dir: ProjectField,
55
+ });
56
+ const SignHapSchema = z.object({
57
+ project_dir: ProjectField,
58
+ module: z.string().optional(),
59
+ });
60
+ const ParseBuildLogSchema = z.object({
61
+ stdout: z.string().default("").describe("hvigor 编译过程的 stdout"),
62
+ stderr: z.string().default("").describe("hvigor 编译过程的 stderr"),
63
+ });
64
+ const RunTaskSchema = z.object({
65
+ project_dir: ProjectField,
66
+ task: z.string().describe(`hvigor 任务名,必须在白名单内:${[...TASK_WHITELIST].join(", ")}`),
67
+ });
68
+ // ---------- Helpers ----------
69
+ /**
70
+ * 解析当前应使用哪个 hvigor 可执行文件。
71
+ * 优先级(v0.2):
72
+ * 1. 工程根下的 hvigorw / hvigorw.bat(标准做法,依赖工程内 hvigor wrapper)
73
+ * 2. 环境变量 HVIGOR_BIN(用户显式指定)
74
+ * 3. DevEco-Studio 自带的 hvigorw(macOS 默认 /Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw)
75
+ * 4. PATH 里能直接找到的 hvigorw
76
+ * 全部都找不到时抛 HVIGOR_BIN_NOT_FOUND,附带可执行的修复建议。
77
+ */
78
+ function resolveHvigorBin(projectDir) {
79
+ const isWin = process.platform === "win32";
80
+ const localName = isWin ? "hvigorw.bat" : "hvigorw";
81
+ const localBin = path.join(projectDir, localName);
82
+ if (fsSync.existsSync(localBin))
83
+ return { bin: localBin, source: "project" };
84
+ if (process.env.HVIGOR_BIN) {
85
+ if (fsSync.existsSync(process.env.HVIGOR_BIN)) {
86
+ return { bin: process.env.HVIGOR_BIN, source: "env" };
87
+ }
88
+ // 环境变量给的是命令名,交给 spawn 走 PATH 解析
89
+ return { bin: process.env.HVIGOR_BIN, source: "env" };
90
+ }
91
+ // DevEco Studio 常见安装位置
92
+ const candidates = [];
93
+ if (process.platform === "darwin") {
94
+ candidates.push("/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw", path.join(os.homedir(), "Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw"));
95
+ }
96
+ else if (process.platform === "linux") {
97
+ candidates.push(path.join(os.homedir(), "DevEco-Studio/tools/hvigor/bin/hvigorw"), "/opt/DevEco-Studio/tools/hvigor/bin/hvigorw");
98
+ }
99
+ else if (isWin) {
100
+ candidates.push("C:\\Program Files\\Huawei\\DevEco Studio\\tools\\hvigor\\bin\\hvigorw.bat");
101
+ }
102
+ for (const c of candidates) {
103
+ if (fsSync.existsSync(c))
104
+ return { bin: c, source: "deveco" };
105
+ }
106
+ return { bin: "hvigorw", source: "path" };
107
+ }
108
+ async function ensureHarmonyProject(cwd) {
109
+ const hvigorFile = path.join(cwd, "hvigorfile.ts");
110
+ try {
111
+ await fs.access(hvigorFile);
112
+ }
113
+ catch {
114
+ throw new HarmonyMcpError("NOT_A_HARMONY_PROJECT", `${cwd} 下未发现 hvigorfile.ts,看起来不是鸿蒙工程`);
115
+ }
116
+ }
117
+ /**
118
+ * 候选 SDK 目录的"完整度"打分(越高越好):
119
+ * +100 含 default/hms(DevEco 整合包,含华为 HMS API,最完整)
120
+ * +50 含 default/openharmony 或顶层 openharmony
121
+ * +10 每个直接子目录下含 ets/toolchains/native 之一
122
+ * 0 表示完全不是 SDK。
123
+ */
124
+ function scoreSdkRoot(dir) {
125
+ let score = 0;
126
+ try {
127
+ if (fsSync.existsSync(path.join(dir, "default/hms")))
128
+ score += 100;
129
+ if (fsSync.existsSync(path.join(dir, "default/openharmony")))
130
+ score += 50;
131
+ if (fsSync.existsSync(path.join(dir, "openharmony")))
132
+ score += 30;
133
+ const entries = fsSync.readdirSync(dir, { withFileTypes: true });
134
+ for (const ent of entries) {
135
+ if (!ent.isDirectory())
136
+ continue;
137
+ const sub = path.join(dir, ent.name);
138
+ for (const marker of ["ets", "toolchains", "native"]) {
139
+ if (fsSync.existsSync(path.join(sub, marker))) {
140
+ score += 10;
141
+ break;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ catch {
147
+ /* fall through */
148
+ }
149
+ return score;
150
+ }
151
+ /**
152
+ * 找一个可用的 DEVECO_SDK_HOME。
153
+ * v0.2.2 策略:把所有候选都"打分",挑分数最高的(>0)。
154
+ * 这样无论本机装了多套 SDK,都会优先选**完整度最高**的——通常就是 DevEco.app 内置的整合包。
155
+ * 用户显式设置 DEVECO_SDK_HOME 时尊重用户选择。
156
+ */
157
+ function resolveDevecoSdkHome() {
158
+ const envVal = process.env.DEVECO_SDK_HOME;
159
+ if (envVal && fsSync.existsSync(envVal))
160
+ return envVal;
161
+ const home = os.homedir();
162
+ const candidates = [];
163
+ if (process.platform === "darwin") {
164
+ candidates.push("/Applications/DevEco-Studio.app/Contents/sdk", "/Applications/DevEco-Studio.app/Contents/SDK", path.join(home, "Applications/DevEco-Studio.app/Contents/sdk"), path.join(home, "Library/OpenHarmony/Sdk"), path.join(home, "Library/Huawei/Sdk"));
165
+ }
166
+ else if (process.platform === "linux") {
167
+ candidates.push("/opt/DevEco-Studio/sdk", path.join(home, "OpenHarmony/Sdk"), path.join(home, "Huawei/Sdk"));
168
+ }
169
+ else if (process.platform === "win32") {
170
+ candidates.push("C:\\Program Files\\Huawei\\DevEco Studio\\sdk", path.join(home, "AppData\\Local\\Huawei\\Sdk"));
171
+ }
172
+ let best;
173
+ for (const c of candidates) {
174
+ if (!fsSync.existsSync(c))
175
+ continue;
176
+ const s = scoreSdkRoot(c);
177
+ if (s > 0 && (!best || s > best.score))
178
+ best = { dir: c, score: s };
179
+ }
180
+ if (best)
181
+ return best.dir;
182
+ // 都打分 0:起码挑一个存在的让 hvigor 自己报更准确的错
183
+ for (const c of candidates)
184
+ if (fsSync.existsSync(c))
185
+ return c;
186
+ return undefined;
187
+ }
188
+ async function runHvigor(projectDir, args, timeoutMs = 600_000) {
189
+ const cwd = sandbox.resolve(projectDir);
190
+ await ensureHarmonyProject(cwd);
191
+ const { bin, source } = resolveHvigorBin(cwd);
192
+ const sdkHome = resolveDevecoSdkHome();
193
+ const env = {};
194
+ if (sdkHome)
195
+ env.DEVECO_SDK_HOME = sdkHome;
196
+ logger.info("invoking hvigor", { bin, source, cwd, args, sdkHome });
197
+ let r;
198
+ try {
199
+ r = await runCommand(bin, args, { cwd, timeoutMs, env });
200
+ }
201
+ catch (err) {
202
+ if (err instanceof HarmonyMcpError && err.code === "EXEC_SPAWN_FAILED") {
203
+ throw new HarmonyMcpError("HVIGOR_BIN_NOT_FOUND", `无法启动 hvigor 命令:${bin}(来源 ${source})。
204
+ 工程根 ${cwd} 下不存在 hvigorw / hvigorw.bat,且系统 PATH 与 DevEco-Studio 默认安装位置也未找到。
205
+ 修复建议(任选其一):
206
+ 1. 用 DevEco Studio 打开该工程一次,IDE 会自动生成 hvigorw、hvigorw.bat、hvigor/hvigor-wrapper.js 等文件。
207
+ 2. 从其他能正常构建的鸿蒙工程复制以下文件到本工程根:
208
+ - hvigorw(并 chmod +x hvigorw)
209
+ - hvigorw.bat
210
+ - hvigor/hvigor-wrapper.js(若缺失)
211
+ 3. 通过环境变量显式指定 hvigor 可执行路径:
212
+ export HVIGOR_BIN=/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw
213
+ 4. 将 DevEco 安装目录里的 hvigor 加入 PATH:
214
+ export PATH="/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin:$PATH"
215
+ 随后重新调用 build_hap 即可。`, { project_dir: cwd, attempted_bin: bin, source, args, original: err.message });
216
+ }
217
+ throw err;
218
+ }
219
+ const parsed = parseBuildLog(r.stdout, r.stderr);
220
+ return {
221
+ ...parsed,
222
+ exit_code: r.exitCode,
223
+ duration_ms: r.durationMs,
224
+ truncated: r.truncated,
225
+ hvigor_bin: bin,
226
+ hvigor_bin_source: source,
227
+ deveco_sdk_home: sdkHome ?? null,
228
+ };
229
+ }
230
+ // ---------- Tools ----------
231
+ export const NAMESPACE = "hvigor";
232
+ export const tools = [
233
+ {
234
+ name: "build_hap",
235
+ description: "编译 HAP/APP;返回结构化诊断(errors/warnings/hap_paths)",
236
+ schema: BuildHapSchema,
237
+ handler: async (a) => {
238
+ const args = [];
239
+ if (a.no_daemon)
240
+ args.push("--no-daemon");
241
+ args.push("assembleHap");
242
+ // hvigor 的 --mode 是工程自定义 product 名(如 default / module),不能传 debug/release
243
+ if (a.product)
244
+ args.push("--mode", "module", "-p", `product=${a.product}`);
245
+ // build_mode 走属性传递,hvigor 内部用 buildMode 区分调试/正式
246
+ args.push("-p", `buildMode=${a.build_mode}`);
247
+ if (a.module)
248
+ args.push("-p", `module=${a.module}`);
249
+ return runHvigor(a.project_dir, args);
250
+ },
251
+ },
252
+ {
253
+ name: "clean",
254
+ description: "清理工程产物(hvigorw clean)",
255
+ schema: CleanSchema,
256
+ handler: async (a) => runHvigor(a.project_dir, ["clean", "--no-daemon"]),
257
+ },
258
+ {
259
+ name: "sign_hap",
260
+ description: "对 HAP 进行签名(hvigorw signHap)",
261
+ schema: SignHapSchema,
262
+ handler: async (a) => {
263
+ const args = ["signHap", "--no-daemon"];
264
+ if (a.module)
265
+ args.push("-p", `module=${a.module}`);
266
+ return runHvigor(a.project_dir, args);
267
+ },
268
+ },
269
+ {
270
+ name: "parse_build_log",
271
+ description: "把 hvigor 编译输出解析为结构化诊断;可在 Agent 本地读到日志后调用",
272
+ schema: ParseBuildLogSchema,
273
+ handler: async (a) => parseBuildLog(a.stdout, a.stderr),
274
+ },
275
+ {
276
+ name: "run_task",
277
+ description: "运行任意 hvigor 任务(白名单受限)",
278
+ schema: RunTaskSchema,
279
+ handler: async (a) => {
280
+ if (!TASK_WHITELIST.has(a.task)) {
281
+ throw new HarmonyMcpError("TASK_NOT_ALLOWED", `task ${a.task} not in whitelist`, { allowed: [...TASK_WHITELIST] });
282
+ }
283
+ return runHvigor(a.project_dir, [a.task, "--no-daemon"]);
284
+ },
285
+ },
286
+ ];
287
+ // ---------- Boot ----------
288
+ async function main() {
289
+ const server = new Server({ name: "harmony-hvigor-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
290
+ registerTools(server, { ListToolsRequestSchema, CallToolRequestSchema }, tools);
291
+ await server.connect(new StdioServerTransport());
292
+ logger.info("hvigor-mcp server started", { allowedRoots, autoResolveHvigor: true });
293
+ }
294
+ if (isMainModule(import.meta.url)) {
295
+ main().catch((err) => {
296
+ logger.error("fatal", { err: String(err) });
297
+ process.exit(1);
298
+ });
299
+ }
300
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/hvigor-mcp/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * hvigor 编译日志解析器。
3
+ *
4
+ * 目标:把人类可读的 build 输出转成 Agent 友好的结构化对象:
5
+ * { ok, errors[], warnings[], hap_paths[] }
6
+ *
7
+ * 规则覆盖(first pass,按需扩展):
8
+ * - ArkTS / TS 编译错误: file.ets:line:col - error TSxxxx: <msg>
9
+ * - hvigor 任务错误: ERROR: ... 后跟 At <file>:<line>:<col>
10
+ * - 警告: warning|WARN
11
+ * - 输出产物: "Built successfully" / hap_path 行
12
+ */
13
+ export interface BuildDiagnostic {
14
+ severity: "error" | "warning";
15
+ file?: string;
16
+ line?: number;
17
+ column?: number;
18
+ code?: string;
19
+ message: string;
20
+ }
21
+ export interface ParsedBuildLog {
22
+ ok: boolean;
23
+ errors: BuildDiagnostic[];
24
+ warnings: BuildDiagnostic[];
25
+ hap_paths: string[];
26
+ summary: string;
27
+ }
28
+ export declare function parseBuildLog(stdout: string, stderr: string): ParsedBuildLog;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * hvigor 编译日志解析器。
3
+ *
4
+ * 目标:把人类可读的 build 输出转成 Agent 友好的结构化对象:
5
+ * { ok, errors[], warnings[], hap_paths[] }
6
+ *
7
+ * 规则覆盖(first pass,按需扩展):
8
+ * - ArkTS / TS 编译错误: file.ets:line:col - error TSxxxx: <msg>
9
+ * - hvigor 任务错误: ERROR: ... 后跟 At <file>:<line>:<col>
10
+ * - 警告: warning|WARN
11
+ * - 输出产物: "Built successfully" / hap_path 行
12
+ */
13
+ const TS_LINE = /^(.+\.(?:ets|ts)):(\d+):(\d+)\s+-\s+(error|warning)\s+(TS\d+):\s+(.+)$/;
14
+ const HVIGOR_ERR = /^>\s*ERROR:\s+(.+)$/;
15
+ const HVIGOR_AT = /^\s+At\s+(.+?):(\d+):(\d+)$/;
16
+ const HAP_LINE = /(?:[\w./\\-]+\/)?[\w.-]+\.hap\b/g;
17
+ const BUILT_OK = /BUILD\s+SUCCESSFUL|Built\s+successfully/i;
18
+ const BUILT_FAIL = /BUILD\s+FAILED|Build\s+failed/i;
19
+ export function parseBuildLog(stdout, stderr) {
20
+ const errors = [];
21
+ const warnings = [];
22
+ const hapPaths = [];
23
+ const lines = (stdout + "\n" + stderr).split(/\r?\n/);
24
+ let pendingHvigorErr = null;
25
+ for (const line of lines) {
26
+ const ts = TS_LINE.exec(line);
27
+ if (ts) {
28
+ const diag = {
29
+ severity: ts[4] === "error" ? "error" : "warning",
30
+ file: ts[1],
31
+ line: Number(ts[2]),
32
+ column: Number(ts[3]),
33
+ code: ts[5],
34
+ message: ts[6].trim(),
35
+ };
36
+ (diag.severity === "error" ? errors : warnings).push(diag);
37
+ continue;
38
+ }
39
+ const herr = HVIGOR_ERR.exec(line);
40
+ if (herr) {
41
+ pendingHvigorErr = herr[1].trim();
42
+ errors.push({ severity: "error", message: pendingHvigorErr });
43
+ continue;
44
+ }
45
+ const at = HVIGOR_AT.exec(line);
46
+ if (at && errors.length > 0) {
47
+ const last = errors[errors.length - 1];
48
+ last.file = at[1];
49
+ last.line = Number(at[2]);
50
+ last.column = Number(at[3]);
51
+ continue;
52
+ }
53
+ for (const m of line.matchAll(HAP_LINE)) {
54
+ const p = m[0];
55
+ if (!hapPaths.includes(p))
56
+ hapPaths.push(p);
57
+ }
58
+ }
59
+ const ok = errors.length === 0 && (BUILT_OK.test(stdout + stderr) || !BUILT_FAIL.test(stdout + stderr));
60
+ const summary = ok
61
+ ? `BUILD OK; warnings=${warnings.length}; hap=${hapPaths.length}`
62
+ : `BUILD FAILED; errors=${errors.length}; warnings=${warnings.length}`;
63
+ return { ok, errors, warnings, hap_paths: hapPaths, summary };
64
+ }
65
+ //# sourceMappingURL=log-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../../../packages/hvigor-mcp/src/log-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function isMainModule(metaUrl: string): boolean;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * "是否作为主入口运行"的 ESM 守卫工具。
3
+ *
4
+ * 用法:
5
+ * if (isMainModule(import.meta.url)) main().catch(...);
6
+ *
7
+ * 这样同一个文件,既能直接 `node dist/index.js` 启动,
8
+ * 又能被聚合包 `import` 进去复用 tools 数组而不触发 server 启动。
9
+ */
10
+ import { fileURLToPath } from "node:url";
11
+ import path from "node:path";
12
+ export function isMainModule(metaUrl) {
13
+ if (!process.argv[1])
14
+ return false;
15
+ try {
16
+ return path.resolve(process.argv[1]) === path.resolve(fileURLToPath(metaUrl));
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 统一的错误类型,便于 MCP server 把异常转成结构化响应。
3
+ */
4
+ export declare class HarmonyMcpError extends Error {
5
+ readonly code: string;
6
+ readonly details?: unknown;
7
+ constructor(code: string, message: string, details?: unknown);
8
+ }
9
+ export declare function toErrorPayload(err: unknown): {
10
+ code: string;
11
+ message: string;
12
+ details?: unknown;
13
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 统一的错误类型,便于 MCP server 把异常转成结构化响应。
3
+ */
4
+ export class HarmonyMcpError extends Error {
5
+ code;
6
+ details;
7
+ constructor(code, message, details) {
8
+ super(message);
9
+ this.name = "HarmonyMcpError";
10
+ this.code = code;
11
+ this.details = details;
12
+ }
13
+ }
14
+ export function toErrorPayload(err) {
15
+ if (err instanceof HarmonyMcpError) {
16
+ return { code: err.code, message: err.message, details: err.details };
17
+ }
18
+ if (err instanceof Error) {
19
+ return { code: "INTERNAL_ERROR", message: err.message };
20
+ }
21
+ return { code: "INTERNAL_ERROR", message: String(err) };
22
+ }
23
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,OAAO,CAAW;IAElC,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./logger.js";
2
+ export * from "./safe-exec.js";
3
+ export * from "./sandbox.js";
4
+ export * from "./errors.js";
5
+ export * from "./mcp-helpers.js";
6
+ export * from "./entry.js";
@@ -0,0 +1,7 @@
1
+ export * from "./logger.js";
2
+ export * from "./safe-exec.js";
3
+ export * from "./sandbox.js";
4
+ export * from "./errors.js";
5
+ export * from "./mcp-helpers.js";
6
+ export * from "./entry.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 极简结构化日志,写到 stderr(stdio MCP server 的约定:stdout 只能放协议消息)。
3
+ */
4
+ export type LogLevel = "debug" | "info" | "warn" | "error";
5
+ export interface Logger {
6
+ debug(msg: string, ctx?: Record<string, unknown>): void;
7
+ info(msg: string, ctx?: Record<string, unknown>): void;
8
+ warn(msg: string, ctx?: Record<string, unknown>): void;
9
+ error(msg: string, ctx?: Record<string, unknown>): void;
10
+ }
11
+ export declare function createLogger(server: string): Logger;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 极简结构化日志,写到 stderr(stdio MCP server 的约定:stdout 只能放协议消息)。
3
+ */
4
+ const LEVEL_PRIORITY = {
5
+ debug: 10,
6
+ info: 20,
7
+ warn: 30,
8
+ error: 40,
9
+ };
10
+ const envLevel = (process.env.HARMONY_MCP_LOG_LEVEL ?? "info").toLowerCase();
11
+ const threshold = LEVEL_PRIORITY[envLevel] ?? LEVEL_PRIORITY.info;
12
+ function log(server, level, msg, ctx) {
13
+ if (LEVEL_PRIORITY[level] < threshold)
14
+ return;
15
+ const record = {
16
+ ts: new Date().toISOString(),
17
+ level,
18
+ server,
19
+ msg,
20
+ ...(ctx ?? {}),
21
+ };
22
+ process.stderr.write(JSON.stringify(record) + "\n");
23
+ }
24
+ export function createLogger(server) {
25
+ return {
26
+ debug: (msg, ctx) => log(server, "debug", msg, ctx),
27
+ info: (msg, ctx) => log(server, "info", msg, ctx),
28
+ warn: (msg, ctx) => log(server, "warn", msg, ctx),
29
+ error: (msg, ctx) => log(server, "error", msg, ctx),
30
+ };
31
+ }
32
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,WAAW,EAAc,CAAC;AACzF,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC;AASlE,SAAS,GAAG,CAAC,MAAc,EAAE,KAAe,EAAE,GAAW,EAAE,GAA6B;IACtF,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS;QAAE,OAAO;IAC9C,MAAM,MAAM,GAAG;QACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK;QACL,MAAM;QACN,GAAG;QACH,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;KACf,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC;QACnD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;QACjD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;QACjD,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC;KACpD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * MCP 服务器通用脚手架:
3
+ * - registerTools(server, defs):声明式地一次性注册 ListTools / CallTool 两个处理器
4
+ * - zodToJsonSchema:把 zod 对象转成 MCP 需要的 JSON Schema(仅支持本项目用到的子集)
5
+ * - ok(data) / fail(err):MCP tool 响应的便捷构造器
6
+ *
7
+ * 该模块只依赖 zod 的类型;@modelcontextprotocol/sdk 由调用方注入,避免 common 强耦合。
8
+ */
9
+ import { z } from "zod";
10
+ export interface ToolDef<TSchema extends z.ZodObject<z.ZodRawShape>> {
11
+ name: string;
12
+ description: string;
13
+ schema: TSchema;
14
+ handler: (args: z.infer<TSchema>) => Promise<unknown>;
15
+ }
16
+ export interface McpServerLike {
17
+ setRequestHandler: (schema: any, handler: (req: any) => Promise<any>) => void;
18
+ }
19
+ export interface RegisterToolsDeps {
20
+ ListToolsRequestSchema: any;
21
+ CallToolRequestSchema: any;
22
+ }
23
+ export declare function registerTools(server: McpServerLike, deps: RegisterToolsDeps, tools: ToolDef<z.ZodObject<z.ZodRawShape>>[]): void;
24
+ export declare function ok(data: unknown): {
25
+ content: {
26
+ type: "text";
27
+ text: string;
28
+ }[];
29
+ };
30
+ export declare function fail(payload: {
31
+ code: string;
32
+ message: string;
33
+ details?: unknown;
34
+ }): {
35
+ isError: boolean;
36
+ content: {
37
+ type: "text";
38
+ text: string;
39
+ }[];
40
+ };
41
+ export declare function zodToJsonSchema(schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown>;