chaimi-keep-mcp 3.1.34 → 3.1.36-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +6 -0
  2. package/SKILL.md +34 -0
  3. package/package.json +1 -1
  4. package/server.js +20 -15
package/README.md CHANGED
@@ -141,6 +141,12 @@ AI 会自动调用 `save_income` 工具记录收入。
141
141
 
142
142
  ## 更新日志
143
143
 
144
+ ### v3.1.35 (2026-04-15)
145
+ - **新增** 商品子分类支持:`subCategory` 字段,支持叶菜类、根茎类、猪肉类等超市细分类目
146
+ - **新增** 计价单位支持:`unit` 字段,支持元/500g、元/个、元/盒、元/袋等多种单位
147
+ - **新增** 市场单价支持:`marketPrice` 字段,用于记录单价数值
148
+ - **优化** 字段描述:更贴近超市购物场景的分类描述
149
+
144
150
  ### v3.1.34 (2026-04-14)
145
151
  - **修复** 日期/时区处理:纯日期格式默认使用12:00,不再使用当前服务器时间
146
152
  - **优化** SKILL.md 精简:从385行精简到176行,聚焦Agent必须执行的行为规范
package/SKILL.md CHANGED
@@ -99,6 +99,36 @@ argument-hint: "[记账内容]"
99
99
 
100
100
  **必填字段:** `name`、`amount`、`category`、`date`
101
101
 
102
+ **可选字段:**
103
+ - `subCategory`:子分类(如:叶菜类、根茎类、猪肉类,超市细分类目),推荐填写
104
+ - `unit`:计价单位(如:元/500g、元/个、元/盒、元/袋)
105
+ - `marketPrice`:单价,根据 unit 计算
106
+
107
+ ---
108
+
109
+ ### 收入记账(save_income)
110
+
111
+ **流程:**
112
+ 1. 调用 `get_text_parse_prompt()` 获取解析 Prompt
113
+ 2. 使用 Prompt 解析用户输入,获取 JSON 结果
114
+ 3. 调用 `save_income` 保存(传入所有解析结果字段)
115
+
116
+ **Agent 必须执行的时间语义解析:**
117
+ | 用户说法 | 解析为 |
118
+ |---------|--------|
119
+ | "工资"、"收入" | 09:00(默认工作时间) |
120
+ | "红包"、"奖金" | 具体时间或当前时间 |
121
+ | 无时间信息 | 使用当前时间 |
122
+
123
+ **重要:** 最终传入的 `date` 参数必须包含时间部分,格式:`2026-04-14T09:00:00+08:00`
124
+
125
+ **必填字段:** `name`、`amount`、`category`、`date`
126
+
127
+ **可选字段:**
128
+ - `subCategory`:子分类(如:叶菜类、根茎类、猪肉类,超市细分类目),推荐填写
129
+ - `unit`:计价单位(如:元/500g、元/个、元/盒、元/袋)
130
+ - `marketPrice`:单价,根据 unit 计算
131
+
102
132
  ---
103
133
 
104
134
  ### 小票记账(save_receipt)
@@ -117,6 +147,10 @@ argument-hint: "[记账内容]"
117
147
  - `originalAmount`:原价(优惠前)
118
148
  - `discountAmount`:优惠金额
119
149
  - `items`:商品数组,每个商品必须有 `name`、`amount`、`price`、`quantity`、`category`
150
+ - `category`:主分类(如:蔬菜、肉类、水果、水产,常见超市购物分类)
151
+ - `subCategory`:子分类(如:叶菜类、根茎类、猪肉类,超市细分类目),推荐填写
152
+ - `unit`:计价单位(如:元/500g、元/个、元/盒、元/袋)
153
+ - `marketPrice`:单价,根据 unit 计算,如 unit=元/500g,则 marketPrice=金额÷重量(g)×500
120
154
 
121
155
  ---
122
156
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaimi-keep-mcp",
3
- "version": "3.1.34",
3
+ "version": "3.1.36-beta.0",
4
4
  "description": "柴米记账 MCP Server - 支持 Claude、Cursor、OpenClaw、WorkBuddy 等 AI 工具直接记账",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -139,7 +139,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
139
139
  properties: {
140
140
  name: { type: 'string', description: '商品名称(必填)' },
141
141
  amount: { type: 'number', description: '金额(必填)' },
142
- category: { type: 'string', description: '分类(必填,如:餐饮、食品、交通)' },
142
+ category: { type: 'string', description: '主分类(必填,如:蔬菜、肉类、水果、水产,常见超市购物分类)' },
143
+ subCategory: { type: 'string', description: '子分类(如:叶菜类、根茎类、猪肉类,超市细分类目),推荐填写' },
144
+ unit: { type: 'string', description: '计价单位(如:元/500g、元/个、元/盒、元/袋)' },
145
+ marketPrice: { type: 'string', description: '单价数值,根据unit计算' },
143
146
  store: { type: 'string', description: '商家名称(可选)' },
144
147
  date: { type: 'string', description: '消费时间(ISO格式)(可选)' },
145
148
  note: { type: 'string', description: '备注(可选)' },
@@ -175,11 +178,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
175
178
  originalName: { type: 'string', description: '原始商品名称(含规格)' },
176
179
  price: { type: 'number', description: '【必填】单价' },
177
180
  quantity: { type: 'number', description: '【必填】数量' },
178
- unit: { type: 'string', description: '单位,如:斤、个、份' },
181
+ unit: { type: 'string', description: '计价单位(如:元/500g、元/个、元/盒、元/袋)' },
179
182
  amount: { type: 'number', description: '【必填】金额,必须等于 price × quantity' },
180
183
  weight: { type: 'string', description: '重量' },
181
- marketPrice: { type: 'string', description: '市场单价(元/500g' },
182
- category: { type: 'string', description: '(必填)分类,如:餐饮、食品、购物' },
184
+ marketPrice: { type: 'string', description: '单价数值,根据unit计算,如unit=元/500g,则marketPrice=金额÷重量(g)×500' },
185
+ category: { type: 'string', description: '(必填)主分类(如:蔬菜、肉类、水果、水产,常见超市购物分类)' },
186
+ subCategory: { type: 'string', description: '子分类(如:叶菜类、根茎类、猪肉类,超市细分类目),推荐填写' },
183
187
  },
184
188
  required: ['name', 'amount', 'price', 'quantity'],
185
189
  },
@@ -227,22 +231,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
227
231
  },
228
232
  {
229
233
  name: 'save_income',
230
- description: '保存收入记录(工资、奖金、红包等)',
234
+ description: '保存收入记录(工资、奖金、红包等)。⚠️ 重要:必须先调用 get_text_parse_prompt 解析,然后传入所有解析结果字段',
231
235
  inputSchema: {
232
236
  type: 'object',
233
237
  properties: {
234
- name: { type: 'string', description: '收入来源(如:工资、奖金、红包)' },
235
- amount: { type: 'number', description: '收入金额' },
238
+ name: { type: 'string', description: '收入来源(如:工资、奖金、红包)(必填)' },
239
+ amount: { type: 'number', description: '收入金额(必填)' },
236
240
  category: { type: 'string', description: '(必填)收入分类(如:工资、奖金、投资)' },
237
- store: { type: 'string', description: '付款方(如:公司名称)' },
238
- date: { type: 'string', description: '收入时间(ISO格式)(可选)' },
239
- note: { type: 'string', description: '备注' },
241
+ store: { type: 'string', description: '付款方(如:公司名称)(可选)' },
242
+ date: { type: 'string', description: '收入时间(ISO格式,必须包含时间部分,如:2026-04-14T09:00:00+08:00)(可选)' },
243
+ note: { type: 'string', description: '备注(可选)' },
240
244
  agentType: { type: 'string', description: '【推荐自动填充】Agent类型,如:claude-desktop、cursor、openclaw、workbuddy、trae' },
241
245
  apiProvider: { type: 'string', description: '【推荐自动填充】AI服务提供商,如:anthropic、openai、doubao、aliyun' },
242
246
  rawInput: { type: 'string', description: '【推荐自动填充】用户的原始输入内容,用于记录用户原始请求' },
243
247
  mcp_version: { type: 'string', description: 'MCP Server 版本号(自动填充)' },
244
248
  },
245
- required: ['name', 'amount'],
249
+ required: ['name', 'amount', 'category'],
246
250
  },
247
251
  },
248
252
  {
@@ -529,7 +533,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
529
533
  readAt: new Date().toISOString(),
530
534
  validFor: '5分钟'
531
535
  },
532
- message: '✅ Skill 定义已获取,有效期5分钟\n\n请仔细阅读上述 Skill 文档,然后执行记账操作。'
536
+ message: `✅ Skill 定义已获取,有效期5分钟\n\n【重要】完整的 Skill 文档内容在 result.data.skill 字段中,请仔细阅读以下内容,然后严格按照 Skill 文档执行记账操作:\n\n${'='.repeat(60)}\n${skillContent}\n${'='.repeat(60)}`
533
537
  };
534
538
  userMessage = result.message;
535
539
  break;
@@ -1194,12 +1198,13 @@ function convertParams(toolName, args) {
1194
1198
  price: amount,
1195
1199
  quantity: 1,
1196
1200
  category: sanitizeString(args.category, 50) || '其他',
1201
+ subCategory: sanitizeString(args.subCategory, 50) || '',
1202
+ unit: sanitizeString(args.unit, 20) || '',
1203
+ weight: '',
1204
+ marketPrice: sanitizeString(args.marketPrice, 50) || '',
1197
1205
  store: sanitizeString(args.store, 100) || '',
1198
1206
  date: formatDateWithTimezone(args.date),
1199
1207
  transactionType: 'expense',
1200
- unit: '',
1201
- weight: '',
1202
- marketPrice: '',
1203
1208
  note: sanitizeString(args.note, 500) || '',
1204
1209
  rawInput: sanitizeString(args.rawInput, 1000) || '',
1205
1210
  agentType: args.agentType || '',