chaimi-keep-mcp 3.1.34 → 3.1.36-beta.1
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.
- package/README.md +6 -0
- package/SKILL.md +34 -0
- package/package.json +1 -1
- package/server.js +60 -36
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`:单位(可选)
|
|
105
|
+
- `marketPrice`:市场单价(可选)
|
|
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`:单位(可选)
|
|
130
|
+
- `marketPrice`:市场单价(可选)
|
|
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
package/server.js
CHANGED
|
@@ -139,16 +139,19 @@ 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: '单位(可选)' },
|
|
145
|
+
marketPrice: { type: 'string', description: '市场单价(可选)' },
|
|
143
146
|
store: { type: 'string', description: '商家名称(可选)' },
|
|
144
147
|
date: { type: 'string', description: '消费时间(ISO格式)(可选)' },
|
|
145
148
|
note: { type: 'string', description: '备注(可选)' },
|
|
146
|
-
agentType: { type: 'string', description: '
|
|
147
|
-
apiProvider: { type: 'string', description: '
|
|
148
|
-
rawInput: { type: 'string', description: '
|
|
149
|
+
agentType: { type: 'string', description: '【必填】Agent类型,如:claude-desktop、cursor、openclaw、workbuddy、trae' },
|
|
150
|
+
apiProvider: { type: 'string', description: '【必填】AI服务提供商,如:anthropic、openai、doubao、aliyun' },
|
|
151
|
+
rawInput: { type: 'string', description: '【必填】用户的原始输入内容,用于记录用户原始请求' },
|
|
149
152
|
mcp_version: { type: 'string', description: 'MCP Server 版本号(自动填充)' },
|
|
150
153
|
},
|
|
151
|
-
required: ['name', 'amount'],
|
|
154
|
+
required: ['name', 'amount', 'category', 'agentType', 'apiProvider', 'rawInput'],
|
|
152
155
|
},
|
|
153
156
|
},
|
|
154
157
|
{
|
|
@@ -175,74 +178,94 @@ 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: '
|
|
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
|
-
required: ['name', 'amount', 'price', 'quantity'],
|
|
188
|
+
required: ['name', 'amount', 'price', 'quantity', 'unit', 'marketPrice', 'category'],
|
|
185
189
|
},
|
|
186
190
|
},
|
|
187
|
-
agentType: { type: 'string', description: '
|
|
188
|
-
apiProvider: { type: 'string', description: '
|
|
189
|
-
rawInput: { type: 'string', description: '
|
|
191
|
+
agentType: { type: 'string', description: '【必填】Agent类型:claude-desktop、cursor、openclaw、workbuddy、trae' },
|
|
192
|
+
apiProvider: { type: 'string', description: '【必填】AI服务提供商:anthropic、openai、doubao、aliyun' },
|
|
193
|
+
rawInput: { type: 'string', description: '【必填】用户的原始输入内容' },
|
|
190
194
|
mcp_version: { type: 'string', description: '【自动填充】MCP Server版本号' },
|
|
191
195
|
},
|
|
192
|
-
required: ['store', 'items'],
|
|
196
|
+
required: ['store', 'items', 'agentType', 'apiProvider', 'rawInput'],
|
|
193
197
|
},
|
|
194
198
|
},
|
|
195
199
|
{
|
|
196
200
|
name: 'get_expenses',
|
|
197
|
-
description: '
|
|
201
|
+
description: '查询消费记录。支持按日期范围、分类、商家、来源等多维度筛选',
|
|
198
202
|
inputSchema: {
|
|
199
203
|
type: 'object',
|
|
200
204
|
properties: {
|
|
201
|
-
limit: { type: 'number', description: '
|
|
202
|
-
|
|
205
|
+
limit: { type: 'number', description: '返回数量限制,默认10条,最大100', default: 10 },
|
|
206
|
+
skip: { type: 'number', description: '跳过条数,用于分页', default: 0 },
|
|
207
|
+
startDate: { type: 'string', description: '开始日期(ISO格式,如:2026-04-01)' },
|
|
208
|
+
endDate: { type: 'string', description: '结束日期(ISO格式,如:2026-04-30)' },
|
|
209
|
+
category: { type: 'string', description: '按分类筛选(如:餐饮、食品、交通)' },
|
|
210
|
+
subCategory: { type: 'string', description: '按子分类筛选(如:叶菜类、猪肉类)' },
|
|
211
|
+
store: { type: 'string', description: '按商家名称筛选' },
|
|
212
|
+
source: { type: 'string', description: '按来源筛选(如:mcp_txt_expense、mcp_receipt)' },
|
|
213
|
+
keyword: { type: 'string', description: '按商品名称关键词搜索' },
|
|
214
|
+
orderBy: { type: 'string', description: '排序方式:date_desc(默认)、date_asc、amount_desc、amount_asc', enum: ['date_desc', 'date_asc', 'amount_desc', 'amount_asc'], default: 'date_desc' },
|
|
203
215
|
},
|
|
204
216
|
},
|
|
205
217
|
},
|
|
206
218
|
{
|
|
207
219
|
name: 'get_receipt_list',
|
|
208
|
-
description: '
|
|
220
|
+
description: '获取小票列表。支持按日期范围、商家、金额等多维度筛选',
|
|
209
221
|
inputSchema: {
|
|
210
222
|
type: 'object',
|
|
211
223
|
properties: {
|
|
212
|
-
limit: { type: 'number', description: '
|
|
224
|
+
limit: { type: 'number', description: '返回数量限制,默认5条,最大50', default: 5 },
|
|
225
|
+
skip: { type: 'number', description: '跳过条数,用于分页', default: 0 },
|
|
226
|
+
startDate: { type: 'string', description: '开始日期(ISO格式,如:2026-04-01)' },
|
|
227
|
+
endDate: { type: 'string', description: '结束日期(ISO格式,如:2026-04-30)' },
|
|
228
|
+
store: { type: 'string', description: '按商家名称筛选' },
|
|
229
|
+
minAmount: { type: 'number', description: '最小金额筛选' },
|
|
230
|
+
maxAmount: { type: 'number', description: '最大金额筛选' },
|
|
231
|
+
orderBy: { type: 'string', description: '排序方式:date_desc(默认)、date_asc、amount_desc、amount_asc', enum: ['date_desc', 'date_asc', 'amount_desc', 'amount_asc'], default: 'date_desc' },
|
|
213
232
|
},
|
|
214
233
|
},
|
|
215
234
|
},
|
|
216
235
|
{
|
|
217
236
|
name: 'get_statistics',
|
|
218
|
-
description: '
|
|
237
|
+
description: '获取消费统计。支持按年月、日期范围统计,可查看分类占比、消费趋势等',
|
|
219
238
|
inputSchema: {
|
|
220
239
|
type: 'object',
|
|
221
240
|
properties: {
|
|
222
|
-
yearMonth: { type: 'string', description: '年月(如:2026-03
|
|
223
|
-
|
|
241
|
+
yearMonth: { type: 'string', description: '年月(如:2026-03),与startDate/endDate二选一' },
|
|
242
|
+
startDate: { type: 'string', description: '开始日期(ISO格式),与yearMonth二选一' },
|
|
243
|
+
endDate: { type: 'string', description: '结束日期(ISO格式),与yearMonth二选一' },
|
|
244
|
+
type: { type: 'string', description: '统计维度:item(商品明细)、receipt(小票汇总)、category(分类统计)、daily(每日趋势)、store(商家统计)', enum: ['item', 'receipt', 'category', 'daily', 'store'], default: 'category' },
|
|
245
|
+
category: { type: 'string', description: '按特定分类筛选统计' },
|
|
246
|
+
store: { type: 'string', description: '按特定商家筛选统计' },
|
|
247
|
+
groupBy: { type: 'string', description: '分组方式:category(分类)、date(日期)、store(商家)', enum: ['category', 'date', 'store'] },
|
|
224
248
|
},
|
|
225
|
-
required: ['yearMonth'],
|
|
226
249
|
},
|
|
227
250
|
},
|
|
228
251
|
{
|
|
229
252
|
name: 'save_income',
|
|
230
|
-
description: '
|
|
253
|
+
description: '保存收入记录(工资、奖金、红包等)。⚠️ 重要:必须先调用 get_text_parse_prompt 解析,然后传入所有解析结果字段',
|
|
231
254
|
inputSchema: {
|
|
232
255
|
type: 'object',
|
|
233
256
|
properties: {
|
|
234
|
-
name: { type: 'string', description: '
|
|
235
|
-
amount: { type: 'number', description: '
|
|
257
|
+
name: { type: 'string', description: '收入来源(如:工资、奖金、红包)(必填)' },
|
|
258
|
+
amount: { type: 'number', description: '收入金额(必填)' },
|
|
236
259
|
category: { type: 'string', description: '(必填)收入分类(如:工资、奖金、投资)' },
|
|
237
|
-
store: { type: 'string', description: '
|
|
238
|
-
date: { type: 'string', description: '收入时间(ISO
|
|
239
|
-
note: { type: 'string', description: '
|
|
240
|
-
agentType: { type: 'string', description: '
|
|
241
|
-
apiProvider: { type: 'string', description: '
|
|
242
|
-
rawInput: { type: 'string', description: '
|
|
260
|
+
store: { type: 'string', description: '付款方(如:公司名称)(可选)' },
|
|
261
|
+
date: { type: 'string', description: '收入时间(ISO格式,必须包含时间部分,如:2026-04-14T09:00:00+08:00)(可选)' },
|
|
262
|
+
note: { type: 'string', description: '备注(可选)' },
|
|
263
|
+
agentType: { type: 'string', description: '【必填】Agent类型,如:claude-desktop、cursor、openclaw、workbuddy、trae' },
|
|
264
|
+
apiProvider: { type: 'string', description: '【必填】AI服务提供商,如:anthropic、openai、doubao、aliyun' },
|
|
265
|
+
rawInput: { type: 'string', description: '【必填】用户的原始输入内容,用于记录用户原始请求' },
|
|
243
266
|
mcp_version: { type: 'string', description: 'MCP Server 版本号(自动填充)' },
|
|
244
267
|
},
|
|
245
|
-
required: ['name', 'amount'],
|
|
268
|
+
required: ['name', 'amount', 'category', 'agentType', 'apiProvider', 'rawInput'],
|
|
246
269
|
},
|
|
247
270
|
},
|
|
248
271
|
{
|
|
@@ -529,7 +552,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
529
552
|
readAt: new Date().toISOString(),
|
|
530
553
|
validFor: '5分钟'
|
|
531
554
|
},
|
|
532
|
-
message:
|
|
555
|
+
message: `✅ Skill 定义已获取,有效期5分钟\n\n【重要】完整的 Skill 文档内容在 result.data.skill 字段中,请仔细阅读以下内容,然后严格按照 Skill 文档执行记账操作:\n\n${'='.repeat(60)}\n${skillContent}\n${'='.repeat(60)}`
|
|
533
556
|
};
|
|
534
557
|
userMessage = result.message;
|
|
535
558
|
break;
|
|
@@ -1194,12 +1217,13 @@ function convertParams(toolName, args) {
|
|
|
1194
1217
|
price: amount,
|
|
1195
1218
|
quantity: 1,
|
|
1196
1219
|
category: sanitizeString(args.category, 50) || '其他',
|
|
1220
|
+
subCategory: sanitizeString(args.subCategory, 50) || '',
|
|
1221
|
+
unit: sanitizeString(args.unit, 20) || '',
|
|
1222
|
+
weight: '',
|
|
1223
|
+
marketPrice: sanitizeString(args.marketPrice, 50) || '',
|
|
1197
1224
|
store: sanitizeString(args.store, 100) || '',
|
|
1198
1225
|
date: formatDateWithTimezone(args.date),
|
|
1199
1226
|
transactionType: 'expense',
|
|
1200
|
-
unit: '',
|
|
1201
|
-
weight: '',
|
|
1202
|
-
marketPrice: '',
|
|
1203
1227
|
note: sanitizeString(args.note, 500) || '',
|
|
1204
1228
|
rawInput: sanitizeString(args.rawInput, 1000) || '',
|
|
1205
1229
|
agentType: args.agentType || '',
|