chaimi-keep-mcp 3.1.39 → 3.1.40-beta.2

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 (4) hide show
  1. package/README.md +7 -0
  2. package/SKILL.md +38 -11
  3. package/package.json +1 -1
  4. package/server.js +71 -11
package/README.md CHANGED
@@ -141,6 +141,13 @@ AI 会自动调用 `save_income` 工具记录收入。
141
141
 
142
142
  ## 更新日志
143
143
 
144
+ ### v3.1.39 (2026-04-18)
145
+ - **新增** 店铺分类字段支持:`storeCategory`(一级分类)、`storeSubCategory`(二级分类)
146
+ - 小票记账时自动识别店铺分类(购物/美食/生活服务/其他)
147
+ - 支持二级细分类目(超市/便利店/中餐厅/药店等)
148
+ - 数据存储到 receipts 和 receipt_items 表,支持后续查询分析
149
+ - **修复** 日期格式提示:统一改为"毫秒级时间戳(13位数字)",与实际校验逻辑保持一致
150
+
144
151
  ### v3.1.38 (2026-04-16)
145
152
  - **优化** SKILL.md 时间戳说明:使用占位符避免 AI 抄写
146
153
  - 将示例时间戳改为占位符格式 `[毫秒时间戳]`
package/SKILL.md CHANGED
@@ -84,15 +84,9 @@ Agent 必须输出:
84
84
  为数据安全起见,我已暂停记账操作。
85
85
 
86
86
  请开启新会话后重新触发记账。
87
- ```
88
87
 
89
- Agent 根据当前环境,向用户说明开启新会话的具体操作方式:
90
- - **Cursor**: 按 `Cmd+N` (Mac) / `Ctrl+N` (Windows)
91
- - **Claude Desktop**: 点击 `+ New Chat`
92
- - **OpenClaw**: 输入 `/new`
93
- - **WorkBuddy**: 输入 `/clear`
94
- - **Trae**: 按 `Cmd/Ctrl + N` 或点击 `+` 按钮
95
- - **其他**: 输入 `/new` 或菜单"新建会话"
88
+ (操作方式见上方「遇到问题时-方案1」)
89
+ ```
96
90
 
97
91
  ---
98
92
 
@@ -157,14 +151,45 @@ Agent 根据当前环境,向用户说明开启新会话的具体操作方式
157
151
  - **save_income** - 文字记账(收入)
158
152
  - **save_receipt** - 小票记账(需先调用 get_parse_prompt)
159
153
 
154
+ ### 智能查询工具(新功能)
155
+ - **get_insights** - 【推荐使用】获取消费洞察(零AI成本!)
156
+ - 返回消费趋势、模式、优化建议
157
+ - 让 Agent 结合用户的大模型分析
158
+ - **export_data** - 【深度分析用】导出完整消费数据
159
+ - 用于 Agent 深度分析
160
+ - **get_statistics** - 获取消费统计(支持周/月周期!)
161
+ - 新增 `period` 参数:支持 `this_week`、`last_week`、`this_month`、`last_month`
162
+
160
163
  ### 辅助工具
161
164
  - **get_skill** - 【记账前必须调用】获取 Skill 文档
162
165
  - **get_parse_prompt** - 获取小票解析模板
163
- - **get_expenses** - 查询支出记录
166
+ - **get_expenses** - 查询支出记录(支持周/月周期!)
167
+ - 新增 `period` 参数:支持 `this_week`、`last_week`、`this_month`、`last_month`
164
168
  - **get_receipt_list** - 查询小票列表
165
- - **get_statistics** - 获取统计信息
166
169
  - **submit_feedback** - 提交反馈
167
170
 
171
+ ---
172
+
173
+ ## 📊 场景说明(智能分析)
174
+
175
+ ### 场景 1:用户问「帮我看看这周花了多少钱」
176
+ **推荐工具:`get_statistics` 搭配 `period: this_week`**
177
+ 参数示例:
178
+ ```
179
+ get_statistics period="this_week"
180
+ ```
181
+
182
+ ### 场景 2:用户问「分析一下消费习惯」
183
+ **推荐工具:`get_insights` + `export_data`**
184
+ 1. 先用 `get_insights` 获取洞察
185
+ 2. 再用 `export_data` 获取完整数据
186
+ 3. 用用户的大模型进行深度分析
187
+
188
+ ### 场景 3:用户问「最近的消费记录」
189
+ **推荐工具:`get_expenses`**
190
+ - 也可以搭配 `period: this_week` 使用
191
+
192
+
168
193
  ---
169
194
 
170
195
  ## 工具详细说明
@@ -254,8 +279,10 @@ Agent **直接使用当前时间**作为收入时间,无需进行时间语义
254
279
 
255
280
  [自定义其他内容]
256
281
 
257
- MCP Server: v【版本号】
258
282
  【友好结束语】
283
+ ------------
284
+ chaimi-keep-mcp: v【版本号】
285
+
259
286
  ```
260
287
 
261
288
  **友好结束语参考:**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaimi-keep-mcp",
3
- "version": "3.1.39",
3
+ "version": "3.1.40-beta.2",
4
4
  "description": "柴米记账 MCP Server - 支持 Claude、Cursor、OpenClaw、WorkBuddy 等 AI 工具直接记账",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -187,6 +187,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
187
187
  originalAmount: { type: 'number', description: '(必填)应付金额(优惠前)' },
188
188
  discountAmount: { type: 'number', description: '(必填)优惠金额' },
189
189
  actualAmount: { type: 'number', description: '(必填)实付金额(优惠后)' },
190
+ storeCategory: { type: 'string', description: '【必填】店铺一级分类(购物/美食/生活服务/其他)' },
191
+ storeSubCategory: { type: 'string', description: '【必填】店铺二级分类(超市/便利店/中餐厅/药店等)' },
190
192
  paymentMethod: { type: 'string', description: '支付方式,如:微信支付、支付宝' },
191
193
  receiptNo: { type: 'string', description: '小票编号' },
192
194
  items: {
@@ -214,15 +216,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
214
216
  rawInput: { type: 'string', description: '【必填】用户的原始输入内容' },
215
217
  mcp_version: { type: 'string', description: '【自动填充】MCP Server版本号' },
216
218
  },
217
- required: ['store', 'items', 'agentType', 'apiProvider', 'rawInput'],
219
+ required: ['store', 'items', 'storeCategory', 'storeSubCategory', 'agentType', 'apiProvider', 'rawInput'],
218
220
  },
219
221
  },
220
222
  {
221
223
  name: 'get_expenses',
222
- description: '查询消费记录。支持按日期范围、分类、商家、来源等多维度筛选',
224
+ description: '查询消费记录(支持周/月周期)。支持按周/月或日期范围筛选,可查看分类、商家、来源等多维度数据。新功能:新增 period 参数,以及消费模式分析(高频商家、消费时间等)',
223
225
  inputSchema: {
224
226
  type: 'object',
225
227
  properties: {
228
+ period: { type: 'string', description: '统计周期(推荐使用):this_week(本周)、last_week(上周)、this_month(本月)、last_month(上月),与startDate/endDate二选一', enum: ['this_week', 'last_week', 'this_month', 'last_month'] },
226
229
  limit: { type: 'number', description: '返回数量限制,默认10条,最大100', default: 10 },
227
230
  skip: { type: 'number', description: '跳过条数,用于分页', default: 0 },
228
231
  startDate: { type: 'string', description: '开始日期(ISO格式,如:2026-04-01)' },
@@ -233,6 +236,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
233
236
  source: { type: 'string', description: '按来源筛选(如:mcp_txt_expense、mcp_receipt)' },
234
237
  keyword: { type: 'string', description: '按商品名称关键词搜索' },
235
238
  orderBy: { type: 'string', description: '排序方式:date_desc(默认)、date_asc、amount_desc、amount_asc', enum: ['date_desc', 'date_asc', 'amount_desc', 'amount_asc'], default: 'date_desc' },
239
+ includeFlags: { type: 'boolean', description: '是否包含消费标记,默认true', default: true },
236
240
  },
237
241
  },
238
242
  },
@@ -255,13 +259,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
255
259
  },
256
260
  {
257
261
  name: 'get_statistics',
258
- description: '获取消费统计。支持按年月、日期范围统计,可查看分类占比、消费趋势等',
262
+ description: '获取消费统计(支持周/月周期)。支持按周/月或日期范围统计,可查看分类占比、消费趋势等。新功能:新增 period 参数(this_week、last_week、this_month、last_month),以及 insights 洞察数据',
259
263
  inputSchema: {
260
264
  type: 'object',
261
265
  properties: {
262
- yearMonth: { type: 'string', description: '年月(如:2026-03),与startDate/endDate二选一' },
263
- startDate: { type: 'string', description: '开始日期(ISO格式),与yearMonth二选一' },
264
- endDate: { type: 'string', description: '结束日期(ISO格式),与yearMonth二选一' },
266
+ period: { type: 'string', description: '统计周期(推荐使用):this_week(本周)、last_week(上周)、this_month(本月)、last_month(上月),与yearMonth或startDate/endDate二选一', enum: ['this_week', 'last_week', 'this_month', 'last_month'] },
267
+ yearMonth: { type: 'string', description: '年月(如:2026-03),与period或startDate/endDate二选一' },
268
+ startDate: { type: 'string', description: '开始日期(ISO格式),与period或yearMonth二选一' },
269
+ endDate: { type: 'string', description: '结束日期(ISO格式),与period或yearMonth二选一' },
270
+ includeInsights: { type: 'boolean', description: '是否包含洞察数据,默认true', default: true },
265
271
  type: { type: 'string', description: '统计维度:item(商品明细)、receipt(小票汇总)、category(分类统计)、daily(每日趋势)、store(商家统计)', enum: ['item', 'receipt', 'category', 'daily', 'store'], default: 'category' },
266
272
  category: { type: 'string', description: '按特定分类筛选统计' },
267
273
  store: { type: 'string', description: '按特定商家筛选统计' },
@@ -269,6 +275,31 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
269
275
  },
270
276
  },
271
277
  },
278
+ {
279
+ name: 'get_insights',
280
+ description: '【新功能】获取消费洞察线索(包含趋势、模式、健康、优化建议)。纯云端计算,零AI成本!返回洞察线索,供 Agent 结合用户大模型进行深度分析',
281
+ inputSchema: {
282
+ type: 'object',
283
+ properties: {
284
+ period: { type: 'string', description: '统计周期:this_week(本周)、last_week(上周)、this_month(本月)、last_month(上月)', enum: ['this_week', 'last_week', 'this_month', 'last_month'], default: 'this_week' },
285
+ types: { type: ['string', 'array'], description: '洞察类型:trend(趋势)、pattern(模式)、health(健康)、optimization(优化),默认为全部', default: ['trend', 'pattern', 'health', 'optimization'] },
286
+ },
287
+ },
288
+ },
289
+ {
290
+ name: 'export_data',
291
+ description: '【新功能】导出完整的消费数据,供 Agent 深度分析(零AI成本!)。支持导出完整的消费记录和小票数据,然后在用户侧使用大模型进行深度分析',
292
+ inputSchema: {
293
+ type: 'object',
294
+ properties: {
295
+ period: { type: 'string', description: '周期:all(全部)、this_year(今年)、last_year(去年)、custom(自定义)', enum: ['all', 'this_year', 'last_year', 'custom'], default: 'this_year' },
296
+ format: { type: 'string', description: '导出格式:json 或 csv', enum: ['json', 'csv'], default: 'json' },
297
+ includeReceipts: { type: 'boolean', description: '是否包含小票记录,默认true', default: true },
298
+ startDate: { type: 'string', description: '开始日期(period=custom时必填)' },
299
+ endDate: { type: 'string', description: '结束日期(period=custom时必填)' },
300
+ },
301
+ },
302
+ },
272
303
  {
273
304
  name: 'save_income',
274
305
  description: '保存收入记录(工资、奖金、红包等)。⚠️ 重要:必须先调用 get_text_parse_prompt 解析,然后传入所有解析结果字段',
@@ -328,6 +359,8 @@ const toolMapping = {
328
359
  'get_receipt_list': 'getExpenses',
329
360
  'get_statistics': 'getStatistics',
330
361
  'submit_feedback': 'addFeedback',
362
+ 'get_insights': 'getInsights',
363
+ 'export_data': 'exportData',
331
364
  };
332
365
 
333
366
  // 获取或刷新 Token(OAuth 2.0 Device Flow)
@@ -637,10 +670,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
637
670
  error: '日期格式无效',
638
671
  code: 400
639
672
  };
640
- userMessage = '❌ 记账失败:日期格式无效,请使用 ISO 8601 格式(如:2026-01-08T11:42:27)';
673
+ userMessage = '❌ 记账失败:日期格式无效,请使用毫秒级时间戳(13位数字,如:xxxxxxxxxxxxx)';
641
674
  break;
642
675
  }
643
-
676
+
644
677
  if (inputDate > now) {
645
678
  result = {
646
679
  success: false,
@@ -681,7 +714,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
681
714
 
682
715
  case 'save_receipt': {
683
716
  // P0: 数据完整性检查 - 必填字段验证(date 有兜底,不强制检查)
684
- const requiredFields = ['store', 'totalAmount', 'actualAmount', 'originalAmount', 'discountAmount'];
717
+ const requiredFields = ['store', 'totalAmount', 'actualAmount', 'originalAmount', 'discountAmount', 'storeCategory', 'storeSubCategory'];
685
718
  const missingFields = [];
686
719
 
687
720
  for (const field of requiredFields) {
@@ -696,7 +729,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
696
729
  error: `必填字段缺失:${missingFields.join(', ')}。请从 get_parse_prompt 的解析结果中提取并传递所有字段。`,
697
730
  code: 400
698
731
  };
699
- userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、totalAmount、actualAmount、originalAmount、discountAmount\n3. 参考 SKILL.md 中的"小票字段核对清单"`;
732
+ userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、totalAmount、actualAmount、originalAmount、discountAmount、storeCategory、storeSubCategory\n3. 参考 SKILL.md 中的"小票字段核对清单"`;
700
733
  break;
701
734
  }
702
735
 
@@ -774,7 +807,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
774
807
  error: '日期格式无效',
775
808
  code: 400
776
809
  };
777
- userMessage = '❌ 保存失败:日期格式无效,请使用 ISO 8601 格式(如:2026-01-08T11:42:27)';
810
+ userMessage = '❌ 保存失败:日期格式无效,请使用毫秒级时间戳(13位数字,如:xxxxxxxxxxxxx)';
778
811
  break;
779
812
  }
780
813
 
@@ -943,6 +976,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
943
976
  break;
944
977
  }
945
978
 
979
+ case 'get_insights': {
980
+ const toolName = toolMapping[name];
981
+ const mcpParams = convertParams(name, processedArgs);
982
+ result = await callMcpHub(toolName, mcpParams, token);
983
+
984
+ if (result.success) {
985
+ const insightsCount = result.data?.insights?.length || 0;
986
+ userMessage = `🔍 消费洞察获取成功\n共找到 ${insightsCount} 条洞察线索,供你进行深度分析!`;
987
+ }
988
+ break;
989
+ }
990
+
991
+ case 'export_data': {
992
+ const toolName = toolMapping[name];
993
+ const mcpParams = convertParams(name, processedArgs);
994
+ result = await callMcpHub(toolName, mcpParams, token);
995
+
996
+ if (result.success) {
997
+ const totalRecords = result.data?.summary?.totalRecords || 0;
998
+ const totalAmount = result.data?.summary?.totalAmount || 0;
999
+ userMessage = `📦 数据导出成功\n共导出 ${totalRecords} 条记录,总金额 ${totalAmount} 元\n数据已准备好,你可以使用大模型进行深度分析了!`;
1000
+ }
1001
+ break;
1002
+ }
1003
+
946
1004
  case 'save_income': {
947
1005
  // P0: 数据完整性检查 - 必填字段验证
948
1006
  const requiredFields = ['name', 'amount', 'category', 'date', 'rawInput'];
@@ -1372,6 +1430,8 @@ function convertParams(toolName, args) {
1372
1430
  apiProvider: args.apiProvider || '',
1373
1431
  mcp_version: args.mcp_version || MCP_VERSION,
1374
1432
  source: 'mcp_receipt',
1433
+ storeCategory: sanitizeString(args.storeCategory, 50) || '其他',
1434
+ storeSubCategory: sanitizeString(args.storeSubCategory, 50) || '其他',
1375
1435
  };
1376
1436
  }
1377
1437