chaimi-keep-mcp 3.3.1-beta.0 → 3.3.1-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.
- package/bin/cli.js +23 -7
- package/package.json +1 -1
- package/server.js +18 -5
package/bin/cli.js
CHANGED
|
@@ -293,16 +293,32 @@ function configureAllAgents() {
|
|
|
293
293
|
* 注意:使用 console.error,避免污染 stdout(MCP 协议通信使用 stdout)
|
|
294
294
|
*/
|
|
295
295
|
function showWelcome() {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
console.error('
|
|
296
|
+
const ver = CURRENT_VERSION;
|
|
297
|
+
const title = `柴米记账 MCP Server v${ver}`;
|
|
298
|
+
const pad = (76 - getDisplayWidth(title)) / 2;
|
|
299
|
+
const leftPad = ' '.repeat(Math.floor(pad));
|
|
300
|
+
const rightPad = ' '.repeat(Math.ceil(pad));
|
|
301
|
+
|
|
302
|
+
console.error('╔════════════════════════════════════════════════════════════════════════════╗');
|
|
303
|
+
console.error('║ ║');
|
|
304
|
+
console.error(`║${leftPad}${title}${rightPad}║`);
|
|
305
|
+
console.error('║ ║');
|
|
306
|
+
console.error('║ 支持: OpenClaw|hermes|WorkBuddy 等国产小龙虾 ║');
|
|
307
|
+
console.error('║ Claude|Cursor 等支持 MCP 的 Agent ║');
|
|
308
|
+
console.error('║ ║');
|
|
309
|
+
console.error('╚════════════════════════════════════════════════════════════════════════════╝');
|
|
303
310
|
console.error('');
|
|
304
311
|
}
|
|
305
312
|
|
|
313
|
+
// 计算字符串显示宽度(中文字符=2,英文=1)
|
|
314
|
+
function getDisplayWidth(str) {
|
|
315
|
+
let width = 0;
|
|
316
|
+
for (const char of str) {
|
|
317
|
+
width += (char.charCodeAt(0) > 127) ? 2 : 1;
|
|
318
|
+
}
|
|
319
|
+
return width;
|
|
320
|
+
}
|
|
321
|
+
|
|
306
322
|
// 主程序
|
|
307
323
|
showWelcome();
|
|
308
324
|
configureAllAgents();
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -23,9 +23,18 @@ const os = require('os');
|
|
|
23
23
|
const fs = require('fs');
|
|
24
24
|
const crypto = require('crypto');
|
|
25
25
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
// 读取版本文件获取版本号
|
|
27
|
+
function getVersion() {
|
|
28
|
+
try {
|
|
29
|
+
const verFilePath = path.join(__dirname, 'VERSION');
|
|
30
|
+
return fs.readFileSync(verFilePath, 'utf8').trim();
|
|
31
|
+
} catch (e) {
|
|
32
|
+
// 如果版本文件不存在,从 package.json 兜底
|
|
33
|
+
const pkgJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
34
|
+
return pkgJson.version;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const MCP_VERSION = getVersion();
|
|
29
38
|
|
|
30
39
|
// 导入 OAuth 模块
|
|
31
40
|
const { OAuthManager, FileTokenStorage } = require('./oauth.js');
|
|
@@ -266,7 +275,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
266
275
|
},
|
|
267
276
|
{
|
|
268
277
|
name: 'save_receipt',
|
|
269
|
-
description: '【强制验证Token】【必须上传图片】保存购物小票/发票/收据图片。⚠️ 注意:必须是图片才能使用此工具记账,文字描述请用 save_expense。前置要求:先调用 get_skill 和 get_parse_prompt。items为商品数组,字段列表见 get_parse_prompt 返回的模板.'
|
|
278
|
+
description: '【强制验证Token】【必须上传图片】保存购物小票/发票/收据图片。⚠️ 注意:必须是图片才能使用此工具记账,文字描述请用 save_expense。前置要求:先调用 get_skill 和 get_parse_prompt。items为商品数组,字段列表见 get_parse_prompt 返回的模板.',
|
|
270
279
|
inputSchema: {
|
|
271
280
|
type: 'object',
|
|
272
281
|
properties: {
|
|
@@ -1073,7 +1082,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1073
1082
|
docs: '调用 get_skill() 获取详细使用指南'
|
|
1074
1083
|
}
|
|
1075
1084
|
};
|
|
1076
|
-
userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、totalAmount、actualAmount、originalAmount、discountAmount、storeCategory、storeSubCategory\n3. 参考 SKILL.md
|
|
1085
|
+
userMessage = `❌ 保存失败\n\n错误:缺少必填字段:${missingFields.join(', ')}\n\n💡 解决方案:\n1. 请检查是否从 get_parse_prompt 的解析结果中提取了所有信息\n2. 确保传递以下字段:store、totalAmount、actualAmount、originalAmount、discountAmount、storeCategory、storeSubCategory\n3. 参考 SKILL.md 中的小票字段核对清单`;
|
|
1086
|
+
break;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// 数值校验
|
|
1077
1090
|
const amountFields = ['totalAmount', 'actualAmount', 'originalAmount'];
|
|
1078
1091
|
for (const field of amountFields) {
|
|
1079
1092
|
if (typeof processedArgs[field] !== 'number' || processedArgs[field] <= 0) {
|