chaimi-keep-mcp 3.1.36-beta.2 → 3.1.36-beta.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 (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +19 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaimi-keep-mcp",
3
- "version": "3.1.36-beta.2",
3
+ "version": "3.1.36-beta.3",
4
4
  "description": "柴米记账 MCP Server - 支持 Claude、Cursor、OpenClaw、WorkBuddy 等 AI 工具直接记账",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -144,7 +144,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
144
144
  unit: { type: 'string', description: '单位(可选)' },
145
145
  marketPrice: { type: 'string', description: '市场单价(可选)' },
146
146
  store: { type: 'string', description: '商家名称(可选)' },
147
- date: { type: 'string', description: '消费时间(ISO格式)(可选)' },
147
+ date: { type: 'string', description: '【必填】消费时间(ISO格式),如未提供则使用当前时间' },
148
148
  note: { type: 'string', description: '备注(可选)' },
149
149
  agentType: { type: 'string', description: '【必填】Agent类型,如:claude-desktop、cursor、openclaw、workbuddy、trae' },
150
150
  apiProvider: { type: 'string', description: '【必填】AI服务提供商,如:anthropic、openai、doubao、aliyun' },
@@ -258,7 +258,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
258
258
  amount: { type: 'number', description: '收入金额(必填)' },
259
259
  category: { type: 'string', description: '(必填)收入分类(如:工资、奖金、投资)' },
260
260
  store: { type: 'string', description: '付款方(如:公司名称)(可选)' },
261
- date: { type: 'string', description: '收入时间(ISO格式,必须包含时间部分,如:2026-04-14T09:00:00+08:00)(可选)' },
261
+ date: { type: 'string', description: '【必填】收入时间(ISO格式),如未提供则使用当前时间' },
262
262
  note: { type: 'string', description: '备注(可选)' },
263
263
  agentType: { type: 'string', description: '【必填】Agent类型,如:claude-desktop、cursor、openclaw、workbuddy、trae' },
264
264
  apiProvider: { type: 'string', description: '【必填】AI服务提供商,如:anthropic、openai、doubao、aliyun' },
@@ -559,8 +559,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
559
559
  }
560
560
 
561
561
  case 'save_expense': {
562
- // P0: 数据完整性检查 - 必填字段验证
563
- const requiredFields = ['name', 'amount', 'category', 'date'];
562
+ // P0: 数据完整性检查 - 必填字段验证(date 有兜底,不强制检查)
563
+ const requiredFields = ['name', 'amount', 'category'];
564
564
  const missingFields = [];
565
565
 
566
566
  for (const field of requiredFields) {
@@ -575,7 +575,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
575
575
  error: `必填字段缺失:${missingFields.join(', ')}。请从解析结果中提取并传递所有字段。`,
576
576
  code: 400
577
577
  };
578
- userMessage = `❌ 记账失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从用户输入中提取了所有信息\n2. 确保传递以下字段:name(商品名)、amount(金额)、category(分类)、date(日期)\n3. 参考 SKILL.md 中的"调用前检查清单"`;
578
+ userMessage = `❌ 记账失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从用户输入中提取了所有信息\n2. 确保传递以下字段:name(商品名)、amount(金额)、category(分类)\n3. 参考 SKILL.md 中的"调用前检查清单"`;
579
579
  break;
580
580
  }
581
581
 
@@ -646,23 +646,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
646
646
  }
647
647
 
648
648
  case 'save_receipt': {
649
- // P0: 数据完整性检查 - 必填字段验证
650
- const requiredFields = ['store', 'date', 'totalAmount', 'actualAmount', 'originalAmount', 'discountAmount'];
649
+ // P0: 数据完整性检查 - 必填字段验证(date 有兜底,不强制检查)
650
+ const requiredFields = ['store', 'totalAmount', 'actualAmount', 'originalAmount', 'discountAmount'];
651
651
  const missingFields = [];
652
-
652
+
653
653
  for (const field of requiredFields) {
654
654
  if (processedArgs[field] === undefined || processedArgs[field] === null || processedArgs[field] === '') {
655
655
  missingFields.push(field);
656
656
  }
657
657
  }
658
-
658
+
659
659
  if (missingFields.length > 0) {
660
660
  result = {
661
661
  success: false,
662
662
  error: `必填字段缺失:${missingFields.join(', ')}。请从 get_parse_prompt 的解析结果中提取并传递所有字段。`,
663
663
  code: 400
664
664
  };
665
- userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、date、totalAmount、actualAmount、originalAmount、discountAmount\n3. 参考 SKILL.md 中的"小票字段核对清单"`;
665
+ userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、totalAmount、actualAmount、originalAmount、discountAmount\n3. 参考 SKILL.md 中的"小票字段核对清单"`;
666
666
  break;
667
667
  }
668
668
 
@@ -1117,9 +1117,16 @@ function validateQuantity(quantity) {
1117
1117
  * 语义解析(如"午餐"→12:00)应由 Agent 完成
1118
1118
  */
1119
1119
  function formatDateWithTimezone(dateStr) {
1120
- // 如果未提供日期,返回空字符串(让云函数使用服务器时间)
1120
+ // 如果未提供日期,返回当前北京时间
1121
1121
  if (!dateStr) {
1122
- return '';
1122
+ const now = new Date();
1123
+ const year = now.getFullYear();
1124
+ const month = String(now.getMonth() + 1).padStart(2, '0');
1125
+ const day = String(now.getDate()).padStart(2, '0');
1126
+ const hours = String(now.getHours()).padStart(2, '0');
1127
+ const minutes = String(now.getMinutes()).padStart(2, '0');
1128
+ const seconds = String(now.getSeconds()).padStart(2, '0');
1129
+ return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}+08:00`;
1123
1130
  }
1124
1131
 
1125
1132
  try {