chaimi-keep-mcp 3.3.3-beta.13 → 3.3.3-beta.14
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/package.json +1 -1
- package/server.js +20 -12
package/README.md
CHANGED
|
@@ -89,6 +89,12 @@ export MCP_PROMPT_URL="你的Prompt服务地址"
|
|
|
89
89
|
|
|
90
90
|
## Changelog
|
|
91
91
|
|
|
92
|
+
### v3.3.3-beta.13 (2026-04-30)
|
|
93
|
+
- **变更** 多端记账分类统一 - 支持商品分类和记账分类分离
|
|
94
|
+
- 保持 `category`(记账分类,43个标准分类)
|
|
95
|
+
- 新增 `productCategory`(商品一级分类,展示用)
|
|
96
|
+
- 新增 `productSubCategory`(商品子分类,展示用)
|
|
97
|
+
|
|
92
98
|
### v3.3.3-beta.8 (2026-04-30)
|
|
93
99
|
- **变更** 配置存储路径迁移 - 从 `~/.mcporter/` 迁移到 `~/.chaimi-keep/`,避免与其他 MCP 工具冲突
|
|
94
100
|
- **优化** 安全权限 - 新增目录权限控制(0700),敏感文件权限控制(0600)
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -265,8 +265,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
265
265
|
properties: {
|
|
266
266
|
name: { type: 'string', description: '商品名称(必填)' },
|
|
267
267
|
amount: { type: 'number', description: '金额(必填)' },
|
|
268
|
-
category: { type: 'string', description: '
|
|
269
|
-
subCategory: { type: 'string', description: '子分类(可选)' },
|
|
268
|
+
category: { type: 'string', description: '【必填】支出分类(43个标准分类之一,如:餐饮、食品、交通、蔬菜)' },
|
|
270
269
|
unit: { type: 'string', description: '单位(可选)' },
|
|
271
270
|
marketPrice: { type: 'string', description: '市场单价(可选)' },
|
|
272
271
|
store: { type: 'string', description: '商家名称(可选)' },
|
|
@@ -314,10 +313,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
314
313
|
amount: { type: 'number', description: '【必填】金额,必须等于 price × quantity' },
|
|
315
314
|
weight: { type: 'string', description: '重量' },
|
|
316
315
|
marketPrice: { type: 'string', description: '【必填】单价数值,根据unit计算,如unit=元/500g,则marketPrice=金额÷重量(g)×500' },
|
|
317
|
-
|
|
318
|
-
|
|
316
|
+
// 【改造】商品分类字段
|
|
317
|
+
productCategory: { type: 'string', description: '【必填】商品一级分类(如:蔬菜、肉类、水果、日化用品)' },
|
|
318
|
+
productSubCategory: { type: 'string', description: '商品二级分类(如:叶菜类、根茎类、家居清洁)' },
|
|
319
|
+
// 【改造】记账分类字段
|
|
320
|
+
category: { type: 'string', description: '【必填】记账分类(43个标准分类之一,如:蔬菜、购物、餐饮)' },
|
|
319
321
|
},
|
|
320
|
-
required: ['name', 'amount', 'price', 'quantity', 'unit', 'marketPrice', 'category'],
|
|
322
|
+
required: ['name', 'amount', 'price', 'quantity', 'unit', 'marketPrice', 'productCategory', 'category'],
|
|
321
323
|
},
|
|
322
324
|
},
|
|
323
325
|
agentType: { type: 'string', description: '【必填】Agent类型:claude-desktop、cursor、openclaw、workbuddy、trae' },
|
|
@@ -340,7 +342,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
340
342
|
startDate: { type: 'string', description: '开始日期(ISO格式,如:2026-04-01)' },
|
|
341
343
|
endDate: { type: 'string', description: '结束日期(ISO格式,如:2026-04-30)' },
|
|
342
344
|
category: { type: 'string', description: '按分类筛选(如:餐饮、食品、交通)' },
|
|
343
|
-
subCategory: { type: 'string', description: '按子分类筛选(如:叶菜类、猪肉类)' },
|
|
344
345
|
store: { type: 'string', description: '按商家名称筛选' },
|
|
345
346
|
source: { type: 'string', description: '按来源筛选(如:mcp_txt_expense、mcp_receipt)' },
|
|
346
347
|
keyword: { type: 'string', description: '按商品名称关键词搜索' },
|
|
@@ -411,13 +412,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
411
412
|
},
|
|
412
413
|
{
|
|
413
414
|
name: 'save_income',
|
|
414
|
-
description: '【文本记账-收入】用户提及收入关键词(工资、红包、转账、退款等)时用此工具。前置:必须先调用get_skill获取规范,再调用get_text_parse_prompt获取凭证和解析模板。用法:mcporter call 柴米AI记账.save_income _flowmate="SOLINWANG..." name="红包" amount=100 category="
|
|
415
|
+
description: '【文本记账-收入】用户提及收入关键词(工资、红包、转账、退款等)时用此工具。前置:必须先调用get_skill获取规范,再调用get_text_parse_prompt获取凭证和解析模板。用法:mcporter call 柴米AI记账.save_income _flowmate="SOLINWANG..." name="红包" amount=100 category="红包" rawInput="收红包100元"',
|
|
415
416
|
inputSchema: {
|
|
416
417
|
type: 'object',
|
|
417
418
|
properties: {
|
|
418
419
|
name: { type: 'string', description: '收入来源(如:工资、奖金、红包)(必填)' },
|
|
419
420
|
amount: { type: 'number', description: '收入金额(必填)' },
|
|
420
|
-
category: { type: 'string', description: '
|
|
421
|
+
category: { type: 'string', description: '【必填】收入分类(8个标准分类之一:工资、兼职、奖金、红包、退款、理财、转账、其他)' },
|
|
421
422
|
store: { type: 'string', description: '付款方(如:公司名称)(可选)' },
|
|
422
423
|
date: { type: 'number', description: '【必填】收入时间(毫秒级时间戳,13位数字。必须根据实际年月日时分秒计算,不允许复制示例数字)' },
|
|
423
424
|
note: { type: 'string', description: '备注(可选)' },
|
|
@@ -1169,7 +1170,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1169
1170
|
break;
|
|
1170
1171
|
}
|
|
1171
1172
|
|
|
1172
|
-
// 检查 items
|
|
1173
|
+
// 检查 items 中每个商品的必填字段(包括分类字段)
|
|
1173
1174
|
const invalidItems = [];
|
|
1174
1175
|
processedArgs.items.forEach((item, index) => {
|
|
1175
1176
|
const itemMissingFields = [];
|
|
@@ -1177,7 +1178,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1177
1178
|
if (!item.hasOwnProperty('amount') || item.amount === undefined) itemMissingFields.push('amount');
|
|
1178
1179
|
if (!item.hasOwnProperty('price') || item.price === undefined) itemMissingFields.push('price');
|
|
1179
1180
|
if (!item.hasOwnProperty('quantity') || item.quantity === undefined) itemMissingFields.push('quantity');
|
|
1180
|
-
|
|
1181
|
+
// 【改造】检查新字段 productCategory 和 category
|
|
1182
|
+
if (!item.hasOwnProperty('productCategory') || item.productCategory === '') {
|
|
1183
|
+
itemMissingFields.push('productCategory');
|
|
1184
|
+
}
|
|
1185
|
+
if (!item.hasOwnProperty('category') || item.category === '') {
|
|
1186
|
+
itemMissingFields.push('category');
|
|
1187
|
+
}
|
|
1181
1188
|
|
|
1182
1189
|
if (itemMissingFields.length > 0) {
|
|
1183
1190
|
invalidItems.push(`商品${index + 1}(${item.name || '未命名'})缺少字段: ${itemMissingFields.join(', ')}`);
|
|
@@ -2111,7 +2118,6 @@ function convertParams(toolName, args) {
|
|
|
2111
2118
|
price: amount,
|
|
2112
2119
|
quantity: 1,
|
|
2113
2120
|
category: sanitizeString(args.category, 50) || '其他',
|
|
2114
|
-
subCategory: sanitizeString(args.subCategory, 50) || '',
|
|
2115
2121
|
unit: sanitizeString(args.unit, 20) || '',
|
|
2116
2122
|
weight: '',
|
|
2117
2123
|
marketPrice: sanitizeString(args.marketPrice, 50) || '',
|
|
@@ -2152,8 +2158,10 @@ function convertParams(toolName, args) {
|
|
|
2152
2158
|
name: sanitizeString(item.name, 100),
|
|
2153
2159
|
originalName: sanitizeString(item.originalName, 200) || sanitizeString(item.name, 100),
|
|
2154
2160
|
amount: amount,
|
|
2161
|
+
// 【改造】新字段
|
|
2162
|
+
productCategory: sanitizeString(item.productCategory, 50) || '其他',
|
|
2163
|
+
productSubCategory: sanitizeString(item.productSubCategory, 50) || '',
|
|
2155
2164
|
category: sanitizeString(item.category, 50) || '其他',
|
|
2156
|
-
subCategory: sanitizeString(item.subCategory, 50) || '',
|
|
2157
2165
|
transactionType: sanitizeString(item.transactionType, 50) || 'expense',
|
|
2158
2166
|
price: validateAmount(item.price),
|
|
2159
2167
|
quantity: item.quantity ? String(item.quantity).substring(0, 20) : '1',
|