mingpan 0.1.1 → 0.1.3

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 (239) hide show
  1. package/README.md +116 -42
  2. package/dist/core/bazi/types.d.ts +0 -1
  3. package/dist/core/bazi/types.d.ts.map +1 -1
  4. package/dist/core/qimen/FlyingRule.d.ts +60 -0
  5. package/dist/core/qimen/FlyingRule.d.ts.map +1 -0
  6. package/dist/core/qimen/FlyingRule.js +94 -0
  7. package/dist/core/qimen/FlyingRule.js.map +1 -0
  8. package/dist/core/qimen/GongMapping.d.ts +29 -0
  9. package/dist/core/qimen/GongMapping.d.ts.map +1 -0
  10. package/dist/core/qimen/GongMapping.js +83 -0
  11. package/dist/core/qimen/GongMapping.js.map +1 -0
  12. package/dist/core/qimen/RotatingRule.d.ts +76 -0
  13. package/dist/core/qimen/RotatingRule.d.ts.map +1 -0
  14. package/dist/core/qimen/RotatingRule.js +126 -0
  15. package/dist/core/qimen/RotatingRule.js.map +1 -0
  16. package/dist/core/qimen/YinYangDunCalculator.d.ts +28 -0
  17. package/dist/core/qimen/YinYangDunCalculator.d.ts.map +1 -0
  18. package/dist/core/qimen/YinYangDunCalculator.js +79 -0
  19. package/dist/core/qimen/YinYangDunCalculator.js.map +1 -0
  20. package/dist/core/qimen/index.d.ts +10 -0
  21. package/dist/core/qimen/index.d.ts.map +1 -0
  22. package/dist/core/qimen/index.js +58 -0
  23. package/dist/core/qimen/index.js.map +1 -0
  24. package/dist/core/qimen/types.d.ts +19 -0
  25. package/dist/core/qimen/types.d.ts.map +1 -0
  26. package/dist/core/qimen/types.js +7 -0
  27. package/dist/core/qimen/types.js.map +1 -0
  28. package/dist/index.js +665 -164
  29. package/dist/index.js.map +1 -1
  30. package/dist/output/daliurenTextRenderer.d.ts +23 -0
  31. package/dist/output/daliurenTextRenderer.d.ts.map +1 -0
  32. package/dist/output/daliurenTextRenderer.js +109 -0
  33. package/dist/output/daliurenTextRenderer.js.map +1 -0
  34. package/dist/output/liuyaoTextRenderer.d.ts +12 -0
  35. package/dist/output/liuyaoTextRenderer.d.ts.map +1 -0
  36. package/dist/output/liuyaoTextRenderer.js +148 -0
  37. package/dist/output/liuyaoTextRenderer.js.map +1 -0
  38. package/dist/output/meihuaTextRenderer.d.ts +12 -0
  39. package/dist/output/meihuaTextRenderer.d.ts.map +1 -0
  40. package/dist/output/meihuaTextRenderer.js +53 -0
  41. package/dist/output/meihuaTextRenderer.js.map +1 -0
  42. package/dist/output/qimenTextRenderer.d.ts +40 -0
  43. package/dist/output/qimenTextRenderer.d.ts.map +1 -0
  44. package/dist/output/qimenTextRenderer.js +363 -0
  45. package/dist/output/qimenTextRenderer.js.map +1 -0
  46. package/dist/services/bazi/types.d.ts +0 -2
  47. package/dist/services/bazi/types.d.ts.map +1 -1
  48. package/dist/services/bazi/types.js.map +1 -1
  49. package/dist/services/daliuren/DaliurenService.d.ts +24 -0
  50. package/dist/services/daliuren/DaliurenService.d.ts.map +1 -0
  51. package/dist/services/daliuren/DaliurenService.js +67 -0
  52. package/dist/services/daliuren/DaliurenService.js.map +1 -0
  53. package/dist/services/daliuren/calculators/SanChuanCalculator.d.ts +87 -0
  54. package/dist/services/daliuren/calculators/SanChuanCalculator.d.ts.map +1 -0
  55. package/dist/services/daliuren/calculators/SanChuanCalculator.js +443 -0
  56. package/dist/services/daliuren/calculators/SanChuanCalculator.js.map +1 -0
  57. package/dist/services/daliuren/calculators/ShenShaCalculator.d.ts +33 -0
  58. package/dist/services/daliuren/calculators/ShenShaCalculator.d.ts.map +1 -0
  59. package/dist/services/daliuren/calculators/ShenShaCalculator.js +92 -0
  60. package/dist/services/daliuren/calculators/ShenShaCalculator.js.map +1 -0
  61. package/dist/services/daliuren/calculators/SiKeCalculator.d.ts +35 -0
  62. package/dist/services/daliuren/calculators/SiKeCalculator.d.ts.map +1 -0
  63. package/dist/services/daliuren/calculators/SiKeCalculator.js +121 -0
  64. package/dist/services/daliuren/calculators/SiKeCalculator.js.map +1 -0
  65. package/dist/services/daliuren/calculators/TianDiPanCalculator.d.ts +41 -0
  66. package/dist/services/daliuren/calculators/TianDiPanCalculator.d.ts.map +1 -0
  67. package/dist/services/daliuren/calculators/TianDiPanCalculator.js +138 -0
  68. package/dist/services/daliuren/calculators/TianDiPanCalculator.js.map +1 -0
  69. package/dist/services/daliuren/data/constants.d.ts +62 -0
  70. package/dist/services/daliuren/data/constants.d.ts.map +1 -0
  71. package/dist/services/daliuren/data/constants.js +240 -0
  72. package/dist/services/daliuren/data/constants.js.map +1 -0
  73. package/dist/services/daliuren/index.d.ts +11 -0
  74. package/dist/services/daliuren/index.d.ts.map +1 -0
  75. package/dist/services/daliuren/index.js +33 -0
  76. package/dist/services/daliuren/index.js.map +1 -0
  77. package/dist/services/daliuren/types.d.ts +152 -0
  78. package/dist/services/daliuren/types.d.ts.map +1 -0
  79. package/dist/services/daliuren/types.js +17 -0
  80. package/dist/services/daliuren/types.js.map +1 -0
  81. package/dist/services/liuyao/LiuyaoService.d.ts +37 -0
  82. package/dist/services/liuyao/LiuyaoService.d.ts.map +1 -0
  83. package/dist/services/liuyao/LiuyaoService.js +214 -0
  84. package/dist/services/liuyao/LiuyaoService.js.map +1 -0
  85. package/dist/services/liuyao/calculators/FushenCalculator.d.ts +40 -0
  86. package/dist/services/liuyao/calculators/FushenCalculator.d.ts.map +1 -0
  87. package/dist/services/liuyao/calculators/FushenCalculator.js +124 -0
  88. package/dist/services/liuyao/calculators/FushenCalculator.js.map +1 -0
  89. package/dist/services/liuyao/calculators/JintuishenCalculator.d.ts +37 -0
  90. package/dist/services/liuyao/calculators/JintuishenCalculator.d.ts.map +1 -0
  91. package/dist/services/liuyao/calculators/JintuishenCalculator.js +86 -0
  92. package/dist/services/liuyao/calculators/JintuishenCalculator.js.map +1 -0
  93. package/dist/services/liuyao/calculators/LiuqinCalculator.d.ts +24 -0
  94. package/dist/services/liuyao/calculators/LiuqinCalculator.d.ts.map +1 -0
  95. package/dist/services/liuyao/calculators/LiuqinCalculator.js +75 -0
  96. package/dist/services/liuyao/calculators/LiuqinCalculator.js.map +1 -0
  97. package/dist/services/liuyao/calculators/LiushenCalculator.d.ts +29 -0
  98. package/dist/services/liuyao/calculators/LiushenCalculator.d.ts.map +1 -0
  99. package/dist/services/liuyao/calculators/LiushenCalculator.js +58 -0
  100. package/dist/services/liuyao/calculators/LiushenCalculator.js.map +1 -0
  101. package/dist/services/liuyao/calculators/NajiaCalculator.d.ts +55 -0
  102. package/dist/services/liuyao/calculators/NajiaCalculator.d.ts.map +1 -0
  103. package/dist/services/liuyao/calculators/NajiaCalculator.js +87 -0
  104. package/dist/services/liuyao/calculators/NajiaCalculator.js.map +1 -0
  105. package/dist/services/liuyao/calculators/WangshuaiCalculator.d.ts +43 -0
  106. package/dist/services/liuyao/calculators/WangshuaiCalculator.d.ts.map +1 -0
  107. package/dist/services/liuyao/calculators/WangshuaiCalculator.js +100 -0
  108. package/dist/services/liuyao/calculators/WangshuaiCalculator.js.map +1 -0
  109. package/dist/services/liuyao/calculators/XunkongCalculator.d.ts +30 -0
  110. package/dist/services/liuyao/calculators/XunkongCalculator.d.ts.map +1 -0
  111. package/dist/services/liuyao/calculators/XunkongCalculator.js +58 -0
  112. package/dist/services/liuyao/calculators/XunkongCalculator.js.map +1 -0
  113. package/dist/services/liuyao/data/guagong.d.ts +94 -0
  114. package/dist/services/liuyao/data/guagong.d.ts.map +1 -0
  115. package/dist/services/liuyao/data/guagong.js +317 -0
  116. package/dist/services/liuyao/data/guagong.js.map +1 -0
  117. package/dist/services/liuyao/index.d.ts +13 -0
  118. package/dist/services/liuyao/index.d.ts.map +1 -0
  119. package/dist/services/liuyao/index.js +29 -0
  120. package/dist/services/liuyao/index.js.map +1 -0
  121. package/dist/services/liuyao/types.d.ts +154 -0
  122. package/dist/services/liuyao/types.d.ts.map +1 -0
  123. package/dist/services/liuyao/types.js +11 -0
  124. package/dist/services/liuyao/types.js.map +1 -0
  125. package/dist/services/meihua/MeihuaService.d.ts +32 -0
  126. package/dist/services/meihua/MeihuaService.d.ts.map +1 -0
  127. package/dist/services/meihua/MeihuaService.js +176 -0
  128. package/dist/services/meihua/MeihuaService.js.map +1 -0
  129. package/dist/services/meihua/calculators/BianguaCalculator.d.ts +21 -0
  130. package/dist/services/meihua/calculators/BianguaCalculator.d.ts.map +1 -0
  131. package/dist/services/meihua/calculators/BianguaCalculator.js +46 -0
  132. package/dist/services/meihua/calculators/BianguaCalculator.js.map +1 -0
  133. package/dist/services/meihua/calculators/HuguaCalculator.d.ts +22 -0
  134. package/dist/services/meihua/calculators/HuguaCalculator.d.ts.map +1 -0
  135. package/dist/services/meihua/calculators/HuguaCalculator.js +46 -0
  136. package/dist/services/meihua/calculators/HuguaCalculator.js.map +1 -0
  137. package/dist/services/meihua/calculators/QiguaCalculator.d.ts +40 -0
  138. package/dist/services/meihua/calculators/QiguaCalculator.d.ts.map +1 -0
  139. package/dist/services/meihua/calculators/QiguaCalculator.js +105 -0
  140. package/dist/services/meihua/calculators/QiguaCalculator.js.map +1 -0
  141. package/dist/services/meihua/calculators/TiyongCalculator.d.ts +34 -0
  142. package/dist/services/meihua/calculators/TiyongCalculator.d.ts.map +1 -0
  143. package/dist/services/meihua/calculators/TiyongCalculator.js +105 -0
  144. package/dist/services/meihua/calculators/TiyongCalculator.js.map +1 -0
  145. package/dist/services/meihua/data/bagua.d.ts +19 -0
  146. package/dist/services/meihua/data/bagua.d.ts.map +1 -0
  147. package/dist/services/meihua/data/bagua.js +81 -0
  148. package/dist/services/meihua/data/bagua.js.map +1 -0
  149. package/dist/services/meihua/index.d.ts +11 -0
  150. package/dist/services/meihua/index.d.ts.map +1 -0
  151. package/dist/services/meihua/index.js +27 -0
  152. package/dist/services/meihua/index.js.map +1 -0
  153. package/dist/services/meihua/types.d.ts +95 -0
  154. package/dist/services/meihua/types.d.ts.map +1 -0
  155. package/dist/services/meihua/types.js +6 -0
  156. package/dist/services/meihua/types.js.map +1 -0
  157. package/dist/services/qimen/QimenService.d.ts +93 -0
  158. package/dist/services/qimen/QimenService.d.ts.map +1 -0
  159. package/dist/services/qimen/QimenService.js +427 -0
  160. package/dist/services/qimen/QimenService.js.map +1 -0
  161. package/dist/services/qimen/calculators/BaMenCalculator.d.ts +53 -0
  162. package/dist/services/qimen/calculators/BaMenCalculator.d.ts.map +1 -0
  163. package/dist/services/qimen/calculators/BaMenCalculator.js +105 -0
  164. package/dist/services/qimen/calculators/BaMenCalculator.js.map +1 -0
  165. package/dist/services/qimen/calculators/BaShenCalculator.d.ts +34 -0
  166. package/dist/services/qimen/calculators/BaShenCalculator.d.ts.map +1 -0
  167. package/dist/services/qimen/calculators/BaShenCalculator.js +57 -0
  168. package/dist/services/qimen/calculators/BaShenCalculator.js.map +1 -0
  169. package/dist/services/qimen/calculators/GeJuCalculator.d.ts +141 -0
  170. package/dist/services/qimen/calculators/GeJuCalculator.d.ts.map +1 -0
  171. package/dist/services/qimen/calculators/GeJuCalculator.js +711 -0
  172. package/dist/services/qimen/calculators/GeJuCalculator.js.map +1 -0
  173. package/dist/services/qimen/calculators/JiuGongCalculator.d.ts +56 -0
  174. package/dist/services/qimen/calculators/JiuGongCalculator.d.ts.map +1 -0
  175. package/dist/services/qimen/calculators/JiuGongCalculator.js +98 -0
  176. package/dist/services/qimen/calculators/JiuGongCalculator.js.map +1 -0
  177. package/dist/services/qimen/calculators/JiuXingCalculator.d.ts +54 -0
  178. package/dist/services/qimen/calculators/JiuXingCalculator.d.ts.map +1 -0
  179. package/dist/services/qimen/calculators/JiuXingCalculator.js +117 -0
  180. package/dist/services/qimen/calculators/JiuXingCalculator.js.map +1 -0
  181. package/dist/services/qimen/calculators/JuShuCalculator.d.ts +57 -0
  182. package/dist/services/qimen/calculators/JuShuCalculator.d.ts.map +1 -0
  183. package/dist/services/qimen/calculators/JuShuCalculator.js +115 -0
  184. package/dist/services/qimen/calculators/JuShuCalculator.js.map +1 -0
  185. package/dist/services/qimen/calculators/PanTypeCalculator.d.ts +117 -0
  186. package/dist/services/qimen/calculators/PanTypeCalculator.d.ts.map +1 -0
  187. package/dist/services/qimen/calculators/PanTypeCalculator.js +237 -0
  188. package/dist/services/qimen/calculators/PanTypeCalculator.js.map +1 -0
  189. package/dist/services/qimen/calculators/SanQiLiuYiCalculator.d.ts +50 -0
  190. package/dist/services/qimen/calculators/SanQiLiuYiCalculator.d.ts.map +1 -0
  191. package/dist/services/qimen/calculators/SanQiLiuYiCalculator.js +86 -0
  192. package/dist/services/qimen/calculators/SanQiLiuYiCalculator.js.map +1 -0
  193. package/dist/services/qimen/calculators/ShenShaCalculator.d.ts +80 -0
  194. package/dist/services/qimen/calculators/ShenShaCalculator.d.ts.map +1 -0
  195. package/dist/services/qimen/calculators/ShenShaCalculator.js +300 -0
  196. package/dist/services/qimen/calculators/ShenShaCalculator.js.map +1 -0
  197. package/dist/services/qimen/calculators/YongShenCalculator.d.ts +78 -0
  198. package/dist/services/qimen/calculators/YongShenCalculator.d.ts.map +1 -0
  199. package/dist/services/qimen/calculators/YongShenCalculator.js +497 -0
  200. package/dist/services/qimen/calculators/YongShenCalculator.js.map +1 -0
  201. package/dist/services/qimen/calculators/ZeRiCalculator.d.ts +78 -0
  202. package/dist/services/qimen/calculators/ZeRiCalculator.d.ts.map +1 -0
  203. package/dist/services/qimen/calculators/ZeRiCalculator.js +431 -0
  204. package/dist/services/qimen/calculators/ZeRiCalculator.js.map +1 -0
  205. package/dist/services/qimen/calculators/ZhuanPanCalculator.d.ts +118 -0
  206. package/dist/services/qimen/calculators/ZhuanPanCalculator.d.ts.map +1 -0
  207. package/dist/services/qimen/calculators/ZhuanPanCalculator.js +260 -0
  208. package/dist/services/qimen/calculators/ZhuanPanCalculator.js.map +1 -0
  209. package/dist/services/qimen/data/constants.d.ts +105 -0
  210. package/dist/services/qimen/data/constants.d.ts.map +1 -0
  211. package/dist/services/qimen/data/constants.js +295 -0
  212. package/dist/services/qimen/data/constants.js.map +1 -0
  213. package/dist/services/qimen/data/shensha-rules.d.ts +177 -0
  214. package/dist/services/qimen/data/shensha-rules.d.ts.map +1 -0
  215. package/dist/services/qimen/data/shensha-rules.js +397 -0
  216. package/dist/services/qimen/data/shensha-rules.js.map +1 -0
  217. package/dist/services/qimen/data/yongshen-rules.d.ts +115 -0
  218. package/dist/services/qimen/data/yongshen-rules.d.ts.map +1 -0
  219. package/dist/services/qimen/data/yongshen-rules.js +365 -0
  220. package/dist/services/qimen/data/yongshen-rules.js.map +1 -0
  221. package/dist/services/qimen/index.d.ts +20 -0
  222. package/dist/services/qimen/index.d.ts.map +1 -0
  223. package/dist/services/qimen/index.js +43 -0
  224. package/dist/services/qimen/index.js.map +1 -0
  225. package/dist/services/qimen/types.d.ts +390 -0
  226. package/dist/services/qimen/types.d.ts.map +1 -0
  227. package/dist/services/qimen/types.js +20 -0
  228. package/dist/services/qimen/types.js.map +1 -0
  229. package/dist/services/qimen/utils/gongUtils.d.ts +80 -0
  230. package/dist/services/qimen/utils/gongUtils.d.ts.map +1 -0
  231. package/dist/services/qimen/utils/gongUtils.js +164 -0
  232. package/dist/services/qimen/utils/gongUtils.js.map +1 -0
  233. package/dist/shared/types.d.ts +0 -1
  234. package/dist/shared/types.d.ts.map +1 -1
  235. package/dist/utils/timeNormalization.d.ts +48 -0
  236. package/dist/utils/timeNormalization.d.ts.map +1 -0
  237. package/dist/utils/timeNormalization.js +69 -0
  238. package/dist/utils/timeNormalization.js.map +1 -0
  239. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10,6 +10,39 @@
10
10
  * - 八字流月 uses 干支月 (solar term months)
11
11
  * - 紫微流月 uses 农历月 (lunar months)
12
12
  */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
13
46
  Object.defineProperty(exports, "__esModule", { value: true });
14
47
  const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
15
48
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
@@ -17,8 +50,17 @@ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
17
50
  const zod_1 = require("zod");
18
51
  const zod_to_json_schema_1 = require("zod-to-json-schema");
19
52
  const lunar_javascript_1 = require("lunar-javascript");
53
+ const timeNormalization_1 = require("./utils/timeNormalization");
20
54
  const BaziService_1 = require("./services/bazi/BaziService");
21
55
  const ZiweiService_1 = require("./services/ziwei/ZiweiService");
56
+ const LiuyaoService_1 = require("./services/liuyao/LiuyaoService");
57
+ const liuyaoTextRenderer_1 = require("./output/liuyaoTextRenderer");
58
+ const MeihuaService_1 = require("./services/meihua/MeihuaService");
59
+ const meihuaTextRenderer_1 = require("./output/meihuaTextRenderer");
60
+ const DaliurenService_1 = require("./services/daliuren/DaliurenService");
61
+ const daliurenTextRenderer_1 = require("./output/daliurenTextRenderer");
62
+ const QimenService_1 = require("./services/qimen/QimenService");
63
+ const qimenTextRenderer_1 = require("./output/qimenTextRenderer");
22
64
  const LiuNianCalculator_1 = require("./services/bazi/calculators/LiuNianCalculator");
23
65
  const DaYunCalculator_1 = require("./services/bazi/calculators/DaYunCalculator");
24
66
  const LuckCycleCalculator_1 = require("./services/bazi/calculators/LuckCycleCalculator");
@@ -30,6 +72,14 @@ const listTextRenderer_1 = require("./output/listTextRenderer");
30
72
  const logger_1 = require("./shared/logger");
31
73
  const MutagenCore_1 = require("./core/ziwei/MutagenCore");
32
74
  const logger = new logger_1.Logger("mingpan");
75
+ // ============================================
76
+ // Timezone Configuration
77
+ // ============================================
78
+ // Force deterministic timezone behavior (Beijing Time) across environments.
79
+ // This ensures lunar-javascript and Date operations behave consistently
80
+ // regardless of the host machine's timezone setting.
81
+ // TODO: Remove when multi-timezone support is implemented (M4 milestone)
82
+ process.env.TZ = timeNormalization_1.BEIJING_TZ;
33
83
  // Helper to avoid TypeScript's excessively deep type instantiation error
34
84
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
85
  function schemaToJson(schema) {
@@ -38,6 +88,8 @@ function schemaToJson(schema) {
38
88
  // ============================================
39
89
  // Zod Schemas for Tool Inputs
40
90
  // ============================================
91
+ // isLunar field schema (reusable)
92
+ const isLunarField = zod_1.z.boolean().optional().default(false).describe("Whether the input date is in lunar calendar (農曆). If true, will be converted to solar calendar internally.");
41
93
  // Base birth info schema
42
94
  const BaseBirthInfoSchema = zod_1.z.object({
43
95
  year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
@@ -47,8 +99,33 @@ const BaseBirthInfoSchema = zod_1.z.object({
47
99
  minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
48
100
  gender: zod_1.z.enum(["male", "female"]).describe("Gender for fortune direction calculation"),
49
101
  longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
102
+ isLunar: isLunarField,
50
103
  name: zod_1.z.string().optional().describe("Subject name (optional)"),
51
104
  });
105
+ /**
106
+ * Normalize birth info: handle lunar-to-solar conversion
107
+ * Call this at the start of each handler to get consistent, normalized values
108
+ */
109
+ function normalizeBirthInfo(input) {
110
+ const normalized = (0, timeNormalization_1.normalizeBirthDateTime)({
111
+ year: input.year,
112
+ month: input.month,
113
+ day: input.day,
114
+ hour: input.hour,
115
+ minute: input.minute,
116
+ isLunar: input.isLunar,
117
+ });
118
+ return {
119
+ ...input,
120
+ year: normalized.year,
121
+ month: normalized.month,
122
+ day: normalized.day,
123
+ hour: normalized.hour,
124
+ minute: normalized.minute,
125
+ isLunar: false, // After normalization, always use solar calendar
126
+ _isLunarInput: normalized.isLunarInput,
127
+ };
128
+ }
52
129
  const BaziCalculateSchema = zod_1.z.object({
53
130
  year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
54
131
  month: zod_1.z.number().int().min(1).max(12).describe("Birth month (1-12)"),
@@ -57,7 +134,7 @@ const BaziCalculateSchema = zod_1.z.object({
57
134
  minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
58
135
  gender: zod_1.z.enum(["male", "female"]).optional().default("male").describe("Gender for DaYun calculation direction"),
59
136
  longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
60
- isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
137
+ isLunar: isLunarField,
61
138
  detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
62
139
  includeAnalysis: zod_1.z.boolean().optional().default(true).describe("Include strength and pattern analysis"),
63
140
  includeDaYun: zod_1.z.boolean().optional().default(true).describe("Include decade fortune (大運)"),
@@ -70,7 +147,7 @@ const ZiweiCalculateSchema = zod_1.z.object({
70
147
  hour: zod_1.z.number().int().min(0).max(23).describe("Birth hour in 24-hour format (0-23)"),
71
148
  minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
72
149
  gender: zod_1.z.enum(["male", "female"]).describe("Gender (required for ZiWei calculation)"),
73
- isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
150
+ isLunar: isLunarField,
74
151
  detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
75
152
  targetYear: zod_1.z.number().int().optional().describe("Calculate yearly fortune for this specific year"),
76
153
  includeDecades: zod_1.z.boolean().optional().default(true).describe("Include decade fortune (大限)"),
@@ -84,12 +161,110 @@ const CombinedCalculateSchema = zod_1.z.object({
84
161
  minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
85
162
  gender: zod_1.z.enum(["male", "female"]).describe("Gender (required for both calculations)"),
86
163
  longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
87
- isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
164
+ isLunar: isLunarField,
88
165
  detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
89
166
  targetYear: zod_1.z.number().int().optional().describe("Calculate yearly fortune for this specific year"),
90
167
  systems: zod_1.z.array(zod_1.z.enum(["bazi", "ziwei"])).optional().default(["bazi", "ziwei"]).describe("Which systems to calculate"),
91
168
  });
92
169
  // ============================================
170
+ // 六爻 Schema
171
+ // ============================================
172
+ const LiuyaoBasicSchema = zod_1.z.object({
173
+ yaoValues: zod_1.z.tuple([
174
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
175
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
176
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
177
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
178
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
179
+ zod_1.z.union([zod_1.z.literal(6), zod_1.z.literal(7), zod_1.z.literal(8), zod_1.z.literal(9)]),
180
+ ]).describe("六個爻值(自下而上,初爻到上爻)。6=老陰(動), 7=少陽(靜), 8=少陰(靜), 9=老陽(動)"),
181
+ year: zod_1.z.number().int().min(1900).max(2100).describe("起卦年份(公曆)"),
182
+ month: zod_1.z.number().int().min(1).max(12).describe("起卦月份(1-12)"),
183
+ day: zod_1.z.number().int().min(1).max(31).describe("起卦日期(1-31)"),
184
+ hour: zod_1.z.number().int().min(0).max(23).describe("起卦時辰(0-23)"),
185
+ isLunar: isLunarField,
186
+ });
187
+ // ============================================
188
+ // 梅花易數 Schema
189
+ // ============================================
190
+ const MeihuaBasicSchema = zod_1.z.object({
191
+ method: zod_1.z.enum(['time', 'number']).describe("起卦方式:time=時間起卦,number=數字起卦"),
192
+ // time 模式參數
193
+ year: zod_1.z.number().int().min(1900).max(2100).optional().describe("起卦年份(公曆,time 模式必填)"),
194
+ month: zod_1.z.number().int().min(1).max(12).optional().describe("起卦月份(1-12,time 模式必填)"),
195
+ day: zod_1.z.number().int().min(1).max(31).optional().describe("起卦日期(1-31,time 模式必填)"),
196
+ hour: zod_1.z.number().int().min(0).max(23).optional().describe("起卦時辰(0-23,time 模式必填)"),
197
+ isLunar: isLunarField,
198
+ // number 模式參數
199
+ upperNumber: zod_1.z.number().int().min(1).optional().describe("上卦數(number 模式必填)"),
200
+ lowerNumber: zod_1.z.number().int().min(1).optional().describe("下卦數(number 模式必填)"),
201
+ yaoNumber: zod_1.z.number().int().min(1).optional().describe("動爻數(可選,默認用上下卦數之和)"),
202
+ });
203
+ // ============================================
204
+ // 大六壬 Schema
205
+ // ============================================
206
+ const DaliurenBasicSchema = zod_1.z.object({
207
+ jieqi: zod_1.z.string().describe("節氣(如:立春、雨水、驚蟄等)"),
208
+ lunarMonth: zod_1.z.number().int().min(1).max(12).describe("農曆月份(1-12)"),
209
+ dayGanZhi: zod_1.z.string().describe("日干支(如:甲子、乙丑等)"),
210
+ hourGanZhi: zod_1.z.string().describe("時干支(如:甲子、乙丑等)"),
211
+ guirenMethod: zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]).optional().default(0).describe("貴人起法:0=標準, 1=另一種"),
212
+ });
213
+ // ============================================
214
+ // 奇門遁甲 Schema
215
+ // ============================================
216
+ const QimenBasicSchema = zod_1.z.object({
217
+ year: zod_1.z.number().int().min(1900).max(2100).describe("年份(公曆,1900-2100)"),
218
+ month: zod_1.z.number().int().min(1).max(12).describe("月份(1-12)"),
219
+ day: zod_1.z.number().int().min(1).max(31).describe("日期(1-31)"),
220
+ hour: zod_1.z.number().int().min(0).max(23).describe("時辰(0-23,24小時制)"),
221
+ minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("分鐘(0-59)"),
222
+ isLunar: isLunarField,
223
+ panType: zod_1.z.enum(['时盘', '日盘', '月盘', '年盘']).optional().default('时盘').describe("盤類型:时盘(默認)、日盘、月盘、年盘"),
224
+ panStyle: zod_1.z.enum(['转盘', '飞盘']).optional().default('转盘').describe("盤式:转盘(默認,遵循《神奇之門》)或飞盘"),
225
+ zhiRunMethod: zod_1.z.enum(['chaibu', 'maoshan']).optional().default('chaibu').describe("置閏方法:chaibu=拆補法(默認),maoshan=茅山法"),
226
+ });
227
+ // 奇门用神分析
228
+ const QimenYongShenSchema = zod_1.z.object({
229
+ year: zod_1.z.number().int().min(1900).max(2100).describe("年份(公曆,1900-2100)"),
230
+ month: zod_1.z.number().int().min(1).max(12).describe("月份(1-12)"),
231
+ day: zod_1.z.number().int().min(1).max(31).describe("日期(1-31)"),
232
+ hour: zod_1.z.number().int().min(0).max(23).describe("時辰(0-23,24小時制)"),
233
+ minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("分鐘(0-59)"),
234
+ isLunar: isLunarField,
235
+ panType: zod_1.z.enum(['时盘', '日盘', '月盘', '年盘']).optional().default('时盘').describe("盤類型:时盘(默認)、日盘、月盘、年盘"),
236
+ panStyle: zod_1.z.enum(['转盘', '飞盘']).optional().default('转盘').describe("盤式:转盘(默認)或飞盘"),
237
+ zhiRunMethod: zod_1.z.enum(['chaibu', 'maoshan']).optional().default('chaibu').describe("置閏方法"),
238
+ shiLei: zod_1.z.enum([
239
+ '求财', '婚姻', '疾病', '出行', '诉讼', '考试', '工作',
240
+ '失物', '置业', '求官', '孕产', '寻人', '合作', '其他'
241
+ ]).describe("事類(用於確定用神)"),
242
+ nianGan: zod_1.z.enum(['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']).optional().describe("年干(用於年命分析,可選)"),
243
+ includeShenSha: zod_1.z.boolean().optional().default(true).describe("是否包含神煞分析"),
244
+ });
245
+ // 奇门择日
246
+ const QimenZeRiSchema = zod_1.z.object({
247
+ startYear: zod_1.z.number().int().min(1900).max(2100).describe("起始年份"),
248
+ startMonth: zod_1.z.number().int().min(1).max(12).describe("起始月份"),
249
+ startDay: zod_1.z.number().int().min(1).max(31).describe("起始日期"),
250
+ endYear: zod_1.z.number().int().min(1900).max(2100).describe("結束年份"),
251
+ endMonth: zod_1.z.number().int().min(1).max(12).describe("結束月份"),
252
+ endDay: zod_1.z.number().int().min(1).max(31).describe("結束日期"),
253
+ shiLei: zod_1.z.enum([
254
+ '求财', '婚姻', '疾病', '出行', '诉讼', '考试', '工作',
255
+ '失物', '置业', '求官', '孕产', '寻人', '合作', '其他'
256
+ ]).describe("事類"),
257
+ limit: zod_1.z.number().int().min(1).max(50).optional().default(10).describe("返回數量限制(默認10)"),
258
+ minScore: zod_1.z.number().int().min(0).max(100).optional().default(60).describe("最小評分閾值(0-100,默認60)"),
259
+ includeDirection: zod_1.z.boolean().optional().default(false).describe("是否輸出方位信息"),
260
+ excludeJieQiDay: zod_1.z.boolean().optional().default(false).describe("是否排除節氣交接日"),
261
+ excludeSuiPo: zod_1.z.boolean().optional().default(false).describe("是否排除歲破日"),
262
+ excludeYuePo: zod_1.z.boolean().optional().default(false).describe("是否排除月破日"),
263
+ panType: zod_1.z.enum(['时盘', '日盘', '月盘', '年盘']).optional().default('时盘').describe("盤類型"),
264
+ panStyle: zod_1.z.enum(['转盘', '飞盘']).optional().default('转盘').describe("盤式"),
265
+ zhiRunMethod: zod_1.z.enum(['chaibu', 'maoshan']).optional().default('chaibu').describe("置閏方法"),
266
+ });
267
+ // ============================================
93
268
  // List Tool Schemas
94
269
  // ============================================
95
270
  // 八字大运列表
@@ -147,7 +322,7 @@ const ZiweiLiuRiListSchema = BaseBirthInfoSchema.extend({
147
322
  // ============================================
148
323
  const server = new index_js_1.Server({
149
324
  name: "mingpan",
150
- version: "0.1.1",
325
+ version: "0.1.3",
151
326
  }, {
152
327
  capabilities: {
153
328
  tools: {},
@@ -327,6 +502,167 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
327
502
  用于精细的日期选择。`,
328
503
  inputSchema: schemaToJson(ZiweiLiuRiListSchema),
329
504
  },
505
+ {
506
+ name: "liuyao_basic",
507
+ description: `六爻排盤(基礎排盤)。
508
+
509
+ 輸入六個爻值和起卦時間,返回完整的六爻盤面:
510
+ - 本卦/變卦(含卦名、卦宮、五行)
511
+ - 六爻納甲(每爻地支及五行)
512
+ - 六親(父母/兄弟/子孫/妻財/官鬼)
513
+ - 六神(青龍/朱雀/勾陳/螣蛇/白虎/玄武)
514
+ - 世應位置
515
+ - 動爻標註
516
+ - 日干支、月建、旬空
517
+
518
+ 爻值說明:
519
+ - 6 = 老陰(動爻,陰變陽)
520
+ - 7 = 少陽(靜爻,陽)
521
+ - 8 = 少陰(靜爻,陰)
522
+ - 9 = 老陽(動爻,陽變陰)
523
+
524
+ 輸入順序:自下而上(初爻到上爻)
525
+
526
+ 輸出為 Markdown 格式,便於 AI 分析解讀。`,
527
+ inputSchema: schemaToJson(LiuyaoBasicSchema),
528
+ },
529
+ {
530
+ name: "meihua_basic",
531
+ description: `梅花易數排盤(基礎排盤)。
532
+
533
+ 支持兩種起卦方式:
534
+ 1. 時間起卦(method='time'):根據農曆年月日時起卦
535
+ 2. 數字起卦(method='number'):根據兩個數字起卦
536
+
537
+ 返回完整的梅花盤面:
538
+ - 本卦/變卦/互卦
539
+ - 上卦/下卦(含卦象、五行)
540
+ - 動爻位置
541
+ - 體用分析(體卦、用卦、五行生剋關係)
542
+ - 起卦數據詳情
543
+
544
+ 時間起卦算法(農曆):
545
+ - 上卦 = (年干支序數 + 月 + 日) % 8
546
+ - 下卦 = (年干支序數 + 月 + 日 + 時辰序數) % 8
547
+ - 動爻 = (年干支序數 + 月 + 日 + 時辰序數) % 6
548
+
549
+ 輸出為 Markdown 格式,便於 AI 分析解讀。`,
550
+ inputSchema: schemaToJson(MeihuaBasicSchema),
551
+ },
552
+ {
553
+ name: "daliuren_basic",
554
+ description: `大六壬排盤(基礎排盤)。
555
+
556
+ 大六壬是中國古老三大占卜術之一,與奇門遁甲、太乙神數並稱三式。
557
+
558
+ 輸入節氣、農曆月、日干支、時干支,返回完整的六壬盤面:
559
+ - 天地盤(月將加時辰起盤)
560
+ - 四課(日干支推演)
561
+ - 三傳(九宗門推演:賊尅、比用、涉害、遙尅、昴星、別責、八專、伏吟、返吟)
562
+ - 十二天將(貴人、螣蛇、朱雀、六合、勾陳、青龍、天空、白虎、太常、玄武、太陰、天后)
563
+ - 格局判斷
564
+ - 神煞(日馬、月馬、丁馬、華蓋、閃電)
565
+
566
+ 注意:
567
+ - 需要提供節氣(如:立春、雨水、驚蟄等)
568
+ - 日干支和時干支需要是完整的干支(如:甲子、乙丑)
569
+ - 本工具只負責排盤,斷課解讀交給 Agent
570
+
571
+ 輸出為 Markdown 格式,便於 AI 分析解讀。`,
572
+ inputSchema: schemaToJson(DaliurenBasicSchema),
573
+ },
574
+ {
575
+ name: "qimen_basic",
576
+ description: `奇門遁甲排盤(基礎排盤)。
577
+
578
+ 奇門遁甲是中國古代三式之一,與大六壬、太乙神數並稱,用於預測和決策。
579
+
580
+ 輸入時間信息,返回完整的奇門盤面:
581
+ - 陰陽遁和局數(根據節氣判定)
582
+ - 九宮布局(地盤干、天盤干)
583
+ - 八門飛布(休、生、傷、杜、景、死、驚、開)
584
+ - 九星飛布(天蓬、天芮、天沖、天輔、天禽、天心、天柱、天任、天英)
585
+ - 八神排布(值符、螣蛇、太陰、六合、白虎、玄武、九地、九天)
586
+ - 旬首信息(符頭、值符星、值使門、空亡)
587
+ - 日干/時干落宮
588
+ - 格局判斷(吉格/凶格約20-30種)
589
+
590
+ 支持選項:
591
+ - 盤類型:時盤(默認)、日盤、月盤、年盤
592
+ - 盤式:轉盤(默認,遵循《神奇之門》)或飛盤
593
+ - 置閏法:拆補法(默認)或茅山法
594
+
595
+ 盤類型說明:
596
+ - 時盤:以時辰為主導,適用於即時預測
597
+ - 日盤:以日干支為主導,適用於當日吉凶
598
+ - 月盤:以月干支為主導,適用於月度運勢
599
+ - 年盤:以年干支為主導,適用於年度規劃
600
+
601
+ 盤式說明:
602
+ - 轉盤:天盤、八門、九星按物理方向旋轉(《神奇之門》派)
603
+ - 飛盤:天盤、八門、九星按洛書軌跡飛布(傳統飛宮法)
604
+
605
+ 輸出為 Markdown 格式,含 ASCII 九宮格,便於 AI 分析解讀。`,
606
+ inputSchema: schemaToJson(QimenBasicSchema),
607
+ },
608
+ {
609
+ name: "qimen_yongshen",
610
+ description: `奇門遁甲用神分析。
611
+
612
+ 在基礎排盤基礎上,根據事類選取用神並分析:
613
+
614
+ **支持 14 種事類**:
615
+ 求財、婚姻、疾病、出行、訴訟、考試、工作、失物、置業、求官、孕產、尋人、合作、其他
616
+
617
+ **分析內容**:
618
+ - 主用神/輔用神識別及落宮
619
+ - 用神旺相休囚死狀態
620
+ - 用神空亡、入墓、擊刑檢測
621
+ - 與日干生克關係
622
+ - 受格局影響評估
623
+ - 主客分析(涉及雙方的事類)
624
+ - 年命分析(可選)
625
+ - 神煞信息(可選)
626
+
627
+ **評分系統**:
628
+ 每個用神 0-100 分,綜合考量各因素
629
+
630
+ 輸出為結構化 Markdown,便於 AI 斷卦分析。`,
631
+ inputSchema: schemaToJson(QimenYongShenSchema),
632
+ },
633
+ {
634
+ name: "qimen_zeri",
635
+ description: `奇門遁甲擇日功能。
636
+
637
+ 在指定日期範圍內篩選吉時:
638
+
639
+ **輸入**:
640
+ - 起止日期範圍
641
+ - 事類(14 種)
642
+ - 可選過濾條件
643
+
644
+ **評分維度**:
645
+ - 格局評分(吉格加分、凶格減分)
646
+ - 用神評分(得位、空墓等)
647
+ - 神煞評分(吉神凶煞)
648
+
649
+ **過濾條件**:
650
+ - 最小評分閾值
651
+ - 排除歲破日
652
+ - 排除月破日
653
+ - 排除節氣交接日
654
+
655
+ **輸出**:
656
+ - 推薦時辰列表(含評分、評級)
657
+ - 有利因素、注意事項
658
+ - 可選方位信息(三吉門方位、用神方位)
659
+
660
+ **性能目標**:
661
+ - 7天:< 2秒
662
+ - 30天:< 5秒
663
+ - 365天:< 60秒`,
664
+ inputSchema: schemaToJson(QimenZeRiSchema),
665
+ },
330
666
  ],
331
667
  };
332
668
  });
@@ -335,6 +671,8 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
335
671
  // ============================================
336
672
  const baziService = new BaziService_1.BaziService({ debug: false });
337
673
  const ziweiService = new ZiweiService_1.ZiweiService();
674
+ const liuyaoService = new LiuyaoService_1.LiuyaoService();
675
+ const meihuaService = new MeihuaService_1.MeihuaService();
338
676
  // Helper: Calculate year stem and branch
339
677
  function getYearStemBranch(year) {
340
678
  const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
@@ -407,20 +745,21 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
407
745
  // === Existing Chart Calculation Handlers ===
408
746
  if (name === "bazi_basic") {
409
747
  const validated = BaziCalculateSchema.parse(args);
748
+ const normalized = normalizeBirthInfo(validated);
410
749
  const result = await baziService.calculate({
411
- year: validated.year,
412
- month: validated.month,
413
- day: validated.day,
414
- hour: validated.hour,
415
- minute: validated.minute,
416
- gender: validated.gender,
417
- longitude: validated.longitude,
418
- useLunar: validated.isLunar,
750
+ year: normalized.year,
751
+ month: normalized.month,
752
+ day: normalized.day,
753
+ hour: normalized.hour,
754
+ minute: normalized.minute,
755
+ gender: normalized.gender,
756
+ longitude: normalized.longitude,
757
+ useLunar: false, // Already converted to solar if needed
419
758
  });
420
759
  // If targetYear is specified, calculate LiuNian
421
760
  let liuNianInfo = "";
422
761
  if (validated.targetYear && result.chart) {
423
- const liuNians = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, validated.targetYear, validated.targetYear);
762
+ const liuNians = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, normalized.year, validated.targetYear, validated.targetYear);
424
763
  if (liuNians.length > 0) {
425
764
  const liunian = liuNians[0];
426
765
  liuNianInfo = `\n\n=== 流年 ${validated.targetYear} ===\n干支:${liunian.stem}${liunian.branch}`;
@@ -431,8 +770,8 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
431
770
  includePersonal: false,
432
771
  includeLocation: !!validated.longitude,
433
772
  };
434
- const birthDate = new Date(validated.year, validated.month - 1, validated.day, validated.hour, validated.minute);
435
- const text = (0, fortuneTextRenderer_1.renderBaziText)({ bazi: result, gender: validated.gender, birthDate }, options);
773
+ const birthDate = new Date(normalized.year, normalized.month - 1, normalized.day, normalized.hour, normalized.minute);
774
+ const text = (0, fortuneTextRenderer_1.renderBaziText)({ bazi: result, gender: normalized.gender, birthDate }, options);
436
775
  return {
437
776
  content: [
438
777
  {
@@ -444,21 +783,22 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
444
783
  }
445
784
  if (name === "ziwei_basic") {
446
785
  const validated = ZiweiCalculateSchema.parse(args);
786
+ const normalized = normalizeBirthInfo(validated);
447
787
  const result = await ziweiService.calculate({
448
- year: validated.year,
449
- month: validated.month,
450
- day: validated.day,
451
- hour: validated.hour,
452
- gender: validated.gender,
788
+ year: normalized.year,
789
+ month: normalized.month,
790
+ day: normalized.day,
791
+ hour: normalized.hour,
792
+ gender: normalized.gender,
453
793
  });
454
794
  const options = {
455
795
  detail: validated.detail,
456
796
  includePersonal: false,
457
797
  };
458
- const birthDate = new Date(validated.year, validated.month - 1, validated.day, validated.hour, validated.minute);
798
+ const birthDate = new Date(normalized.year, normalized.month - 1, normalized.day, normalized.hour, normalized.minute);
459
799
  const text = (0, fortuneTextRenderer_1.renderZiweiText)({
460
800
  ziwei: result,
461
- gender: validated.gender,
801
+ gender: normalized.gender,
462
802
  birthDate,
463
803
  mutagen: result.mutagenInfo // 傳入四化信息
464
804
  }, options);
@@ -471,36 +811,189 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
471
811
  ],
472
812
  };
473
813
  }
814
+ // === 六爻工具處理器 ===
815
+ if (name === "liuyao_basic") {
816
+ const validated = LiuyaoBasicSchema.parse(args);
817
+ const result = liuyaoService.calculate({
818
+ yaoValues: validated.yaoValues,
819
+ year: validated.year,
820
+ month: validated.month,
821
+ day: validated.day,
822
+ hour: validated.hour,
823
+ isLunar: validated.isLunar,
824
+ });
825
+ const text = (0, liuyaoTextRenderer_1.renderLiuyaoText)(result);
826
+ return {
827
+ content: [
828
+ {
829
+ type: "text",
830
+ text,
831
+ },
832
+ ],
833
+ };
834
+ }
835
+ // === 梅花易數工具處理器 ===
836
+ if (name === "meihua_basic") {
837
+ const validated = MeihuaBasicSchema.parse(args);
838
+ const result = meihuaService.calculate({
839
+ method: validated.method,
840
+ year: validated.year,
841
+ month: validated.month,
842
+ day: validated.day,
843
+ hour: validated.hour,
844
+ isLunar: validated.isLunar,
845
+ upperNumber: validated.upperNumber,
846
+ lowerNumber: validated.lowerNumber,
847
+ yaoNumber: validated.yaoNumber,
848
+ });
849
+ const text = (0, meihuaTextRenderer_1.renderMeihuaText)(result);
850
+ return {
851
+ content: [
852
+ {
853
+ type: "text",
854
+ text,
855
+ },
856
+ ],
857
+ };
858
+ }
859
+ // === 大六壬工具處理器 ===
860
+ if (name === "daliuren_basic") {
861
+ const validated = DaliurenBasicSchema.parse(args);
862
+ const daliurenService = new DaliurenService_1.DaliurenService();
863
+ const result = daliurenService.calculate({
864
+ jieqi: validated.jieqi,
865
+ lunarMonth: validated.lunarMonth,
866
+ dayGanZhi: validated.dayGanZhi,
867
+ hourGanZhi: validated.hourGanZhi,
868
+ guirenMethod: validated.guirenMethod,
869
+ });
870
+ const text = (0, daliurenTextRenderer_1.renderDaliurenText)(result);
871
+ return {
872
+ content: [
873
+ {
874
+ type: "text",
875
+ text,
876
+ },
877
+ ],
878
+ };
879
+ }
880
+ // === 奇門遁甲工具處理器 ===
881
+ if (name === "qimen_basic") {
882
+ const validated = QimenBasicSchema.parse(args);
883
+ const normalized = normalizeBirthInfo(validated);
884
+ const qimenService = new QimenService_1.QimenService();
885
+ const result = qimenService.calculate({
886
+ year: normalized.year,
887
+ month: normalized.month,
888
+ day: normalized.day,
889
+ hour: normalized.hour,
890
+ minute: normalized.minute,
891
+ isLunar: false, // Already converted to solar if needed
892
+ panType: validated.panType,
893
+ panStyle: validated.panStyle,
894
+ zhiRunMethod: validated.zhiRunMethod,
895
+ });
896
+ const text = (0, qimenTextRenderer_1.renderQimenText)(result);
897
+ return {
898
+ content: [
899
+ {
900
+ type: "text",
901
+ text,
902
+ },
903
+ ],
904
+ };
905
+ }
906
+ // === 奇門遁甲用神 ===
907
+ if (name === "qimen_yongshen") {
908
+ const validated = QimenYongShenSchema.parse(args);
909
+ const normalized = normalizeBirthInfo(validated);
910
+ const qimenService = new QimenService_1.QimenService();
911
+ const result = qimenService.calculateWithYongShen({
912
+ year: normalized.year,
913
+ month: normalized.month,
914
+ day: normalized.day,
915
+ hour: normalized.hour,
916
+ minute: normalized.minute,
917
+ isLunar: false,
918
+ panType: validated.panType,
919
+ panStyle: validated.panStyle,
920
+ zhiRunMethod: validated.zhiRunMethod,
921
+ }, validated.shiLei, {
922
+ nianGan: validated.nianGan,
923
+ includeShenSha: validated.includeShenSha,
924
+ });
925
+ // 使用渲染器生成输出
926
+ const { renderQimenYongShenText } = await Promise.resolve().then(() => __importStar(require("./output/qimenTextRenderer")));
927
+ const text = renderQimenYongShenText(result);
928
+ return {
929
+ content: [
930
+ {
931
+ type: "text",
932
+ text,
933
+ },
934
+ ],
935
+ };
936
+ }
937
+ if (name === "qimen_zeri") {
938
+ const validated = QimenZeRiSchema.parse(args);
939
+ const qimenService = new QimenService_1.QimenService();
940
+ const results = qimenService.findAuspiciousDates({
941
+ startDate: new Date(validated.startYear, validated.startMonth - 1, validated.startDay),
942
+ endDate: new Date(validated.endYear, validated.endMonth - 1, validated.endDay),
943
+ shiLei: validated.shiLei,
944
+ limit: validated.limit,
945
+ minScore: validated.minScore,
946
+ includeDirection: validated.includeDirection,
947
+ excludeJieQiDay: validated.excludeJieQiDay,
948
+ excludeSuiPo: validated.excludeSuiPo,
949
+ excludeYuePo: validated.excludeYuePo,
950
+ panType: validated.panType,
951
+ panStyle: validated.panStyle,
952
+ zhiRunMethod: validated.zhiRunMethod,
953
+ });
954
+ // 使用渲染器生成输出
955
+ const { renderQimenZeRiText } = await Promise.resolve().then(() => __importStar(require("./output/qimenTextRenderer")));
956
+ const text = renderQimenZeRiText(results, validated.shiLei);
957
+ return {
958
+ content: [
959
+ {
960
+ type: "text",
961
+ text,
962
+ },
963
+ ],
964
+ };
965
+ }
474
966
  // === BaZi List Tool Handlers ===
475
967
  if (name === "bazi_dayun") {
476
968
  const validated = BaziDaYunListSchema.parse(args);
969
+ const normalized = normalizeBirthInfo(validated);
477
970
  // Calculate BaZi chart first
478
971
  const result = await baziService.calculate({
479
- year: validated.year,
480
- month: validated.month,
481
- day: validated.day,
482
- hour: validated.hour,
483
- minute: validated.minute,
484
- gender: validated.gender,
485
- longitude: validated.longitude,
972
+ year: normalized.year,
973
+ month: normalized.month,
974
+ day: normalized.day,
975
+ hour: normalized.hour,
976
+ minute: normalized.minute,
977
+ gender: normalized.gender,
978
+ longitude: normalized.longitude,
486
979
  });
487
980
  if (!result.chart || !result.birthInfo) {
488
981
  throw new Error("Failed to calculate BaZi chart");
489
982
  }
490
983
  // Calculate DaYun
491
- const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
984
+ const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, normalized.gender, { startYear: normalized.year, endYear: normalized.year + 100 });
492
985
  // Get direction and start info
493
- const direction = LuckCycleCalculator_1.LuckCycleCalculator.calLuckySequence(validated.gender, result.chart.year.stem) === 'forward' ? '顺行' : '逆行';
986
+ const direction = LuckCycleCalculator_1.LuckCycleCalculator.calLuckySequence(normalized.gender, result.chart.year.stem) === 'forward' ? '顺行' : '逆行';
494
987
  const startAge = daYunList.length > 0 ? daYunList[0].startAge : 1;
495
- const startYear = validated.year + startAge - 1;
988
+ const startYear = normalized.year + startAge - 1;
496
989
  const options = {
497
- name: validated.name,
498
- birthYear: validated.year,
499
- birthMonth: validated.month,
500
- birthDay: validated.day,
501
- birthHour: validated.hour,
502
- birthMinute: validated.minute,
503
- gender: validated.gender,
990
+ name: normalized.name,
991
+ birthYear: normalized.year,
992
+ birthMonth: normalized.month,
993
+ birthDay: normalized.day,
994
+ birthHour: normalized.hour,
995
+ birthMinute: normalized.minute,
996
+ gender: normalized.gender,
504
997
  dayMaster: result.chart.day.stem,
505
998
  yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
506
999
  monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
@@ -515,31 +1008,32 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
515
1008
  }
516
1009
  if (name === "bazi_liunian") {
517
1010
  const validated = BaziLiuNianListSchema.parse(args);
1011
+ const normalized = normalizeBirthInfo(validated);
518
1012
  // Calculate BaZi chart first
519
1013
  const result = await baziService.calculate({
520
- year: validated.year,
521
- month: validated.month,
522
- day: validated.day,
523
- hour: validated.hour,
524
- minute: validated.minute,
525
- gender: validated.gender,
526
- longitude: validated.longitude,
1014
+ year: normalized.year,
1015
+ month: normalized.month,
1016
+ day: normalized.day,
1017
+ hour: normalized.hour,
1018
+ minute: normalized.minute,
1019
+ gender: normalized.gender,
1020
+ longitude: normalized.longitude,
527
1021
  });
528
1022
  if (!result.chart || !result.birthInfo) {
529
1023
  throw new Error("Failed to calculate BaZi chart");
530
1024
  }
531
1025
  // Calculate DaYun list to match each LiuNian to its DaYun
532
- const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
1026
+ const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, normalized.gender, { startYear: normalized.year, endYear: normalized.year + 100 });
533
1027
  // Calculate LiuNian for the range
534
- const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, validated.startYear, validated.endYear);
1028
+ const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, normalized.year, validated.startYear, validated.endYear);
535
1029
  const options = {
536
- name: validated.name,
537
- birthYear: validated.year,
538
- birthMonth: validated.month,
539
- birthDay: validated.day,
540
- birthHour: validated.hour,
541
- birthMinute: validated.minute,
542
- gender: validated.gender,
1030
+ name: normalized.name,
1031
+ birthYear: normalized.year,
1032
+ birthMonth: normalized.month,
1033
+ birthDay: normalized.day,
1034
+ birthHour: normalized.hour,
1035
+ birthMinute: normalized.minute,
1036
+ gender: normalized.gender,
543
1037
  dayMaster: result.chart.day.stem,
544
1038
  yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
545
1039
  monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
@@ -554,16 +1048,17 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
554
1048
  }
555
1049
  if (name === "bazi_liuyue") {
556
1050
  const validated = BaziLiuYueListSchema.parse(args);
1051
+ const normalized = normalizeBirthInfo(validated);
557
1052
  const { year: gregorianYear, ganzhi: ganzhiYear } = parseGanzhiYear(validated.ganzhiYear);
558
1053
  // Calculate BaZi chart first
559
1054
  const result = await baziService.calculate({
560
- year: validated.year,
561
- month: validated.month,
562
- day: validated.day,
563
- hour: validated.hour,
564
- minute: validated.minute,
565
- gender: validated.gender,
566
- longitude: validated.longitude,
1055
+ year: normalized.year,
1056
+ month: normalized.month,
1057
+ day: normalized.day,
1058
+ hour: normalized.hour,
1059
+ minute: normalized.minute,
1060
+ gender: normalized.gender,
1061
+ longitude: normalized.longitude,
567
1062
  });
568
1063
  if (!result.chart || !result.birthInfo) {
569
1064
  throw new Error("Failed to calculate BaZi chart");
@@ -571,9 +1066,9 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
571
1066
  // Get year stem and branch
572
1067
  const { stem: yearStem, branch: yearBranch } = getYearStemBranch(gregorianYear);
573
1068
  // Calculate DaYun list to find current DaYun
574
- const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
1069
+ const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, normalized.gender, { startYear: normalized.year, endYear: normalized.year + 100 });
575
1070
  // Calculate age for the target year (虛歲)
576
- const targetAge = gregorianYear - validated.year + 1;
1071
+ const targetAge = gregorianYear - normalized.year + 1;
577
1072
  // Find current DaYun
578
1073
  let currentDaYun;
579
1074
  const matchedDaYun = daYunList.find(dy => targetAge >= dy.startAge && targetAge <= dy.endAge);
@@ -586,7 +1081,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
586
1081
  };
587
1082
  }
588
1083
  // Calculate current LiuNian
589
- const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, gregorianYear, gregorianYear);
1084
+ const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, normalized.year, gregorianYear, gregorianYear);
590
1085
  let currentLiuNian;
591
1086
  if (liuNianList.length > 0) {
592
1087
  const ln = liuNianList[0];
@@ -599,20 +1094,20 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
599
1094
  // Calculate LiuYue
600
1095
  const calculator = new LiuYueCalculator_1.LiuYueCalculator();
601
1096
  const liuYueList = calculator.calculateLiuYue(yearStem, yearBranch, (result.basic?.dayMasterElement || '木'), (result.traditional?.yongShen?.yongShen || []), {
602
- year: validated.year,
603
- month: validated.month,
604
- day: validated.day,
605
- hour: validated.hour,
606
- minute: validated.minute,
1097
+ year: normalized.year,
1098
+ month: normalized.month,
1099
+ day: normalized.day,
1100
+ hour: normalized.hour,
1101
+ minute: normalized.minute,
607
1102
  }, gregorianYear);
608
1103
  const options = {
609
- name: validated.name,
610
- birthYear: validated.year,
611
- birthMonth: validated.month,
612
- birthDay: validated.day,
613
- birthHour: validated.hour,
614
- birthMinute: validated.minute,
615
- gender: validated.gender,
1104
+ name: normalized.name,
1105
+ birthYear: normalized.year,
1106
+ birthMonth: normalized.month,
1107
+ birthDay: normalized.day,
1108
+ birthHour: normalized.hour,
1109
+ birthMinute: normalized.minute,
1110
+ gender: normalized.gender,
616
1111
  dayMaster: result.chart.day.stem,
617
1112
  yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
618
1113
  monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
@@ -628,17 +1123,18 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
628
1123
  }
629
1124
  if (name === "bazi_liuri") {
630
1125
  const validated = BaziLiuRiListSchema.parse(args);
1126
+ const normalized = normalizeBirthInfo(validated);
631
1127
  const { year: gregorianYear, ganzhi: ganzhiYear } = parseGanzhiYear(validated.ganzhiYear);
632
1128
  const monthNum = parseGanzhiMonth(validated.ganzhiMonth);
633
1129
  // Calculate BaZi chart first
634
1130
  const result = await baziService.calculate({
635
- year: validated.year,
636
- month: validated.month,
637
- day: validated.day,
638
- hour: validated.hour,
639
- minute: validated.minute,
640
- gender: validated.gender,
641
- longitude: validated.longitude,
1131
+ year: normalized.year,
1132
+ month: normalized.month,
1133
+ day: normalized.day,
1134
+ hour: normalized.hour,
1135
+ minute: normalized.minute,
1136
+ gender: normalized.gender,
1137
+ longitude: normalized.longitude,
642
1138
  });
643
1139
  if (!result.chart || !result.birthInfo) {
644
1140
  throw new Error("Failed to calculate BaZi chart");
@@ -647,9 +1143,9 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
647
1143
  const { stem: yearStem, branch: yearBranch } = getYearStemBranch(gregorianYear);
648
1144
  const { stem: monthStem, branch: monthBranch } = getMonthStemBranch(gregorianYear, monthNum);
649
1145
  // Calculate DaYun list to find current DaYun
650
- const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
1146
+ const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, normalized.gender, { startYear: normalized.year, endYear: normalized.year + 100 });
651
1147
  // Calculate age for the target year (虛歲)
652
- const targetAge = gregorianYear - validated.year + 1;
1148
+ const targetAge = gregorianYear - normalized.year + 1;
653
1149
  // Find current DaYun
654
1150
  let currentDaYun;
655
1151
  const matchedDaYun = daYunList.find(dy => targetAge >= dy.startAge && targetAge <= dy.endAge);
@@ -662,7 +1158,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
662
1158
  };
663
1159
  }
664
1160
  // Calculate current LiuNian
665
- const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, gregorianYear, gregorianYear);
1161
+ const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, normalized.year, gregorianYear, gregorianYear);
666
1162
  let currentLiuNian;
667
1163
  if (liuNianList.length > 0) {
668
1164
  const ln = liuNianList[0];
@@ -685,13 +1181,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
685
1181
  const startDate = liuRiList.length > 0 ? liuRiList[0].date : new Date();
686
1182
  const endDate = liuRiList.length > 0 ? liuRiList[liuRiList.length - 1].date : new Date();
687
1183
  const options = {
688
- name: validated.name,
689
- birthYear: validated.year,
690
- birthMonth: validated.month,
691
- birthDay: validated.day,
692
- birthHour: validated.hour,
693
- birthMinute: validated.minute,
694
- gender: validated.gender,
1184
+ name: normalized.name,
1185
+ birthYear: normalized.year,
1186
+ birthMonth: normalized.month,
1187
+ birthDay: normalized.day,
1188
+ birthHour: normalized.hour,
1189
+ birthMinute: normalized.minute,
1190
+ gender: normalized.gender,
695
1191
  dayMaster: result.chart.day.stem,
696
1192
  yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
697
1193
  monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
@@ -712,13 +1208,14 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
712
1208
  // === ZiWei List Tool Handlers ===
713
1209
  if (name === "ziwei_daxian") {
714
1210
  const validated = ZiweiDaXianListSchema.parse(args);
1211
+ const normalized = normalizeBirthInfo(validated);
715
1212
  // Calculate ZiWei chart
716
1213
  const result = ziweiService.calculate({
717
- year: validated.year,
718
- month: validated.month,
719
- day: validated.day,
720
- hour: validated.hour,
721
- gender: validated.gender,
1214
+ year: normalized.year,
1215
+ month: normalized.month,
1216
+ day: normalized.day,
1217
+ hour: normalized.hour,
1218
+ gender: normalized.gender,
722
1219
  });
723
1220
  if (!result.decades || result.decades.length === 0) {
724
1221
  throw new Error("Failed to calculate ZiWei decades");
@@ -736,13 +1233,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
736
1233
  const shenGongPalace = result.palaces?.find(p => p.isBodyPalace);
737
1234
  const shenGongStars = shenGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
738
1235
  const options = {
739
- name: validated.name,
740
- birthYear: validated.year,
741
- birthMonth: validated.month,
742
- birthDay: validated.day,
743
- birthHour: validated.hour,
744
- birthMinute: validated.minute,
745
- gender: validated.gender,
1236
+ name: normalized.name,
1237
+ birthYear: normalized.year,
1238
+ birthMonth: normalized.month,
1239
+ birthDay: normalized.day,
1240
+ birthHour: normalized.hour,
1241
+ birthMinute: normalized.minute,
1242
+ gender: normalized.gender,
746
1243
  mingGong: mingGongPalace?.name || '命宮',
747
1244
  mingGongStars,
748
1245
  shenGong: shenGongPalace?.name,
@@ -756,21 +1253,22 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
756
1253
  }
757
1254
  if (name === "ziwei_xiaoxian") {
758
1255
  const validated = ZiweiXiaoXianListSchema.parse(args);
1256
+ const normalized = normalizeBirthInfo(validated);
759
1257
  const result = ziweiService.calculate({
760
- year: validated.year,
761
- month: validated.month,
762
- day: validated.day,
763
- hour: validated.hour,
764
- gender: validated.gender,
1258
+ year: normalized.year,
1259
+ month: normalized.month,
1260
+ day: normalized.day,
1261
+ hour: normalized.hour,
1262
+ gender: normalized.gender,
765
1263
  });
766
1264
  if (!result.palaces) {
767
1265
  throw new Error("Failed to calculate ZiWei chart");
768
1266
  }
769
- const minorLimitList = ziweiService.getMinorLimitRange(validated.year, validated.startAge, validated.endAge);
1267
+ const minorLimitList = ziweiService.getMinorLimitRange(normalized.year, validated.startAge, validated.endAge);
770
1268
  const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
771
1269
  const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
772
1270
  const currentYear = new Date().getFullYear();
773
- const currentAge = currentYear - validated.year + 1;
1271
+ const currentAge = currentYear - normalized.year + 1;
774
1272
  let currentDecade;
775
1273
  if (result.decades && result.decades.length > 0) {
776
1274
  const matchedDecade = result.decades.find(d => currentAge >= d.startAge && currentAge <= d.endAge);
@@ -783,13 +1281,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
783
1281
  }
784
1282
  }
785
1283
  const options = {
786
- name: validated.name,
787
- birthYear: validated.year,
788
- birthMonth: validated.month,
789
- birthDay: validated.day,
790
- birthHour: validated.hour,
791
- birthMinute: validated.minute,
792
- gender: validated.gender,
1284
+ name: normalized.name,
1285
+ birthYear: normalized.year,
1286
+ birthMonth: normalized.month,
1287
+ birthDay: normalized.day,
1288
+ birthHour: normalized.hour,
1289
+ birthMinute: normalized.minute,
1290
+ gender: normalized.gender,
793
1291
  mingGong: mingGongPalace?.name || '命宮',
794
1292
  mingGongStars,
795
1293
  palaces: result.palaces,
@@ -804,13 +1302,14 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
804
1302
  }
805
1303
  if (name === "ziwei_liunian") {
806
1304
  const validated = ZiweiLiuNianListSchema.parse(args);
1305
+ const normalized = normalizeBirthInfo(validated);
807
1306
  // Calculate ZiWei chart
808
1307
  const result = ziweiService.calculate({
809
- year: validated.year,
810
- month: validated.month,
811
- day: validated.day,
812
- hour: validated.hour,
813
- gender: validated.gender,
1308
+ year: normalized.year,
1309
+ month: normalized.month,
1310
+ day: normalized.day,
1311
+ hour: normalized.hour,
1312
+ gender: normalized.gender,
814
1313
  });
815
1314
  if (!result.palaces) {
816
1315
  throw new Error("Failed to calculate ZiWei chart");
@@ -818,7 +1317,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
818
1317
  // Calculate yearly info for each year in the range
819
1318
  const yearlyList = [];
820
1319
  for (let year = validated.startYear; year <= validated.endYear; year++) {
821
- const yearly = YearlyCalculator_1.YearlyCalculator.calculate(year, validated.year, result.palaces);
1320
+ const yearly = YearlyCalculator_1.YearlyCalculator.calculate(year, normalized.year, result.palaces);
822
1321
  if (yearly) {
823
1322
  yearlyList.push(yearly);
824
1323
  }
@@ -827,13 +1326,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
827
1326
  const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
828
1327
  const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
829
1328
  const options = {
830
- name: validated.name,
831
- birthYear: validated.year,
832
- birthMonth: validated.month,
833
- birthDay: validated.day,
834
- birthHour: validated.hour,
835
- birthMinute: validated.minute,
836
- gender: validated.gender,
1329
+ name: normalized.name,
1330
+ birthYear: normalized.year,
1331
+ birthMonth: normalized.month,
1332
+ birthDay: normalized.day,
1333
+ birthHour: normalized.hour,
1334
+ birthMinute: normalized.minute,
1335
+ gender: normalized.gender,
837
1336
  mingGong: mingGongPalace?.name || '命宮',
838
1337
  mingGongStars,
839
1338
  palaces: result.palaces, // 传入完整宫位数据
@@ -847,13 +1346,14 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
847
1346
  }
848
1347
  if (name === "ziwei_liuyue") {
849
1348
  const validated = ZiweiLiuYueListSchema.parse(args);
1349
+ const normalized = normalizeBirthInfo(validated);
850
1350
  // Calculate ZiWei chart
851
1351
  const result = ziweiService.calculate({
852
- year: validated.year,
853
- month: validated.month,
854
- day: validated.day,
855
- hour: validated.hour,
856
- gender: validated.gender,
1352
+ year: normalized.year,
1353
+ month: normalized.month,
1354
+ day: normalized.day,
1355
+ hour: normalized.hour,
1356
+ gender: normalized.gender,
857
1357
  });
858
1358
  // Get yearly months (农历月)
859
1359
  const monthlyList = ziweiService.getYearlyMonths(validated.lunarYear);
@@ -865,7 +1365,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
865
1365
  const leapMonth = lunar.getYear() === validated.lunarYear ?
866
1366
  lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, 6, 1).getLeapMonth?.() : undefined;
867
1367
  // Calculate age for the target year (虛歲)
868
- const targetAge = validated.lunarYear - validated.year + 1;
1368
+ const targetAge = validated.lunarYear - normalized.year + 1;
869
1369
  // Find current decade (大限)
870
1370
  let currentDecade;
871
1371
  if (result.decades && result.decades.length > 0) {
@@ -879,7 +1379,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
879
1379
  }
880
1380
  }
881
1381
  // Calculate current yearly (流年)
882
- const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, validated.year, result.palaces);
1382
+ const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, normalized.year, result.palaces);
883
1383
  let currentYearly;
884
1384
  if (yearlyInfo) {
885
1385
  const { stem: yearStem, branch: yearBranch } = getYearStemBranch(validated.lunarYear);
@@ -892,7 +1392,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
892
1392
  };
893
1393
  }
894
1394
  // Calculate current minor limit (小限)
895
- const minorLimitInfo = ziweiService.getMinorLimitInfo(validated.year, validated.lunarYear);
1395
+ const minorLimitInfo = ziweiService.getMinorLimitInfo(normalized.year, validated.lunarYear);
896
1396
  let currentMinorLimit;
897
1397
  if (minorLimitInfo) {
898
1398
  currentMinorLimit = {
@@ -908,13 +1408,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
908
1408
  enhancedMutagenInfo.minorLimit = MutagenCore_1.MutagenCore.getMutagen(minorLimitInfo.heavenlyStem) || undefined;
909
1409
  }
910
1410
  const options = {
911
- name: validated.name,
912
- birthYear: validated.year,
913
- birthMonth: validated.month,
914
- birthDay: validated.day,
915
- birthHour: validated.hour,
916
- birthMinute: validated.minute,
917
- gender: validated.gender,
1411
+ name: normalized.name,
1412
+ birthYear: normalized.year,
1413
+ birthMonth: normalized.month,
1414
+ birthDay: normalized.day,
1415
+ birthHour: normalized.hour,
1416
+ birthMinute: normalized.minute,
1417
+ gender: normalized.gender,
918
1418
  mingGong: mingGongPalace?.name || '命宮',
919
1419
  mingGongStars,
920
1420
  palaces: result.palaces,
@@ -931,13 +1431,14 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
931
1431
  }
932
1432
  if (name === "ziwei_liuri") {
933
1433
  const validated = ZiweiLiuRiListSchema.parse(args);
1434
+ const normalized = normalizeBirthInfo(validated);
934
1435
  // Calculate ZiWei chart
935
1436
  const result = ziweiService.calculate({
936
- year: validated.year,
937
- month: validated.month,
938
- day: validated.day,
939
- hour: validated.hour,
940
- gender: validated.gender,
1437
+ year: normalized.year,
1438
+ month: normalized.month,
1439
+ day: normalized.day,
1440
+ hour: normalized.hour,
1441
+ gender: normalized.gender,
941
1442
  });
942
1443
  // Handle leap month (negative number)
943
1444
  const isLeapMonth = validated.lunarMonth < 0;
@@ -989,7 +1490,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
989
1490
  const monthlyInfo = ziweiService.getMonthlyInfo(validated.lunarYear, actualMonth - 1, actualMonth, isLeapMonth);
990
1491
  const monthlyPalace = monthlyInfo ? result.palaces?.[monthlyInfo.palaceIndex]?.name : undefined;
991
1492
  // Calculate age for the target year (虛歲)
992
- const targetAge = validated.lunarYear - validated.year + 1;
1493
+ const targetAge = validated.lunarYear - normalized.year + 1;
993
1494
  // Find current decade (大限)
994
1495
  let currentDecade;
995
1496
  if (result.decades && result.decades.length > 0) {
@@ -1003,7 +1504,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1003
1504
  }
1004
1505
  }
1005
1506
  // Calculate current yearly (流年)
1006
- const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, validated.year, result.palaces);
1507
+ const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, normalized.year, result.palaces);
1007
1508
  let currentYearly;
1008
1509
  if (yearlyInfo) {
1009
1510
  const { stem: yearStem, branch: yearBranch } = getYearStemBranch(validated.lunarYear);
@@ -1026,7 +1527,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1026
1527
  };
1027
1528
  }
1028
1529
  // Calculate current minor limit (小限)
1029
- const minorLimitInfo = ziweiService.getMinorLimitInfo(validated.year, validated.lunarYear);
1530
+ const minorLimitInfo = ziweiService.getMinorLimitInfo(normalized.year, validated.lunarYear);
1030
1531
  let currentMinorLimit;
1031
1532
  if (minorLimitInfo) {
1032
1533
  currentMinorLimit = {
@@ -1045,13 +1546,13 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1045
1546
  enhancedMutagenInfo.monthly = MutagenCore_1.MutagenCore.getMutagen(monthlyInfo.heavenlyStem) || undefined;
1046
1547
  }
1047
1548
  const options = {
1048
- name: validated.name,
1049
- birthYear: validated.year,
1050
- birthMonth: validated.month,
1051
- birthDay: validated.day,
1052
- birthHour: validated.hour,
1053
- birthMinute: validated.minute,
1054
- gender: validated.gender,
1549
+ name: normalized.name,
1550
+ birthYear: normalized.year,
1551
+ birthMonth: normalized.month,
1552
+ birthDay: normalized.day,
1553
+ birthHour: normalized.hour,
1554
+ birthMinute: normalized.minute,
1555
+ gender: normalized.gender,
1055
1556
  mingGong: mingGongPalace?.name || '命宮',
1056
1557
  mingGongStars,
1057
1558
  palaces: result.palaces,
@@ -1092,7 +1593,7 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1092
1593
  async function main() {
1093
1594
  const transport = new stdio_js_1.StdioServerTransport();
1094
1595
  await server.connect(transport);
1095
- logger.info("Mingpan MCP server started (v0.1.1)");
1596
+ logger.info("Mingpan MCP server started (v0.1.3)");
1096
1597
  }
1097
1598
  main().catch((error) => {
1098
1599
  logger.error("Server failed to start", error);