@lemonbeijing/lemonclaw-mcp-service 0.1.2 → 0.1.3
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 +24 -18
- package/dist/lemonclaw-mcp.cjs +231 -171
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# LemonClaw MCP Service
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
面向柠檬云的本地 STDIO MCP 服务,支持 ACC 财务、SCM 进销存、ERP 业财和独立开票。可查询客户、供应商、商品、仓库等基础资料,以及采购、销售、库存、收付款、往来、凭证、账簿、发票和经营或财务报表;对于 Action 文档明确支持的写操作,会在用户确认后执行。
|
|
4
|
+
|
|
5
|
+
MCP 包内嵌共享 Runtime 管理组件并直接启动 Runtime Python,不安装、解析或执行 WorkBuddy Launcher 包。要求 Node.js 20 或更高版本;首次相关 Tool 调用时安装 Runtime,之后按策略检查更新。MCP 服务与 WorkBuddy Launcher 共用 `~/.lemonclaw-cli` 中的 Runtime 指针、安装锁、认证、账套上下文、文档、下载和开票文件。
|
|
6
|
+
|
|
7
|
+
必须在 MCP 服务环境中配置 `LEMONCLAW_API_KEY`,该凭据不会作为 Tool 参数暴露。每次 Tool 执行前,MCP 会先解析或安装 Runtime,再通过 Runtime 认证模块同步发生变化的 API Key,最后调用目标业务操作;API Key 未变化时不会重复写入。
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Run from this repository
|
|
9
|
+
## 从仓库运行
|
|
8
10
|
|
|
9
11
|
```text
|
|
10
12
|
npm install
|
|
@@ -12,27 +14,31 @@ npm run build
|
|
|
12
14
|
node dist/lemonclaw-mcp.cjs
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
MCP Host 配置示例:
|
|
16
18
|
|
|
17
19
|
```json
|
|
18
20
|
{
|
|
19
21
|
"mcpServers": {
|
|
20
22
|
"lemonclaw": {
|
|
21
|
-
"type": "stdio",
|
|
22
|
-
"command": "node",
|
|
23
|
-
"args": ["D:/VSProject/lemonscmskills/mcp-service/dist/lemonclaw-mcp.cjs"]
|
|
23
|
+
"type": "stdio",
|
|
24
|
+
"command": "node",
|
|
25
|
+
"args": ["D:/VSProject/lemonscmskills/mcp-service/dist/lemonclaw-mcp.cjs"],
|
|
26
|
+
"env": {
|
|
27
|
+
"LEMONCLAW_API_KEY": "<在 MCP Host 中配置为密钥>"
|
|
28
|
+
}
|
|
24
29
|
}
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
```
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
## Tool
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
发布后可使用 `npx --yes --prefer-online @lemonbeijing/lemonclaw-mcp-service@latest`。MCP Host 重连或重启服务时,`npx` 会刷新 MCP 包;Runtime 更新与 MCP 包更新相互独立。
|
|
35
|
+
|
|
36
|
+
## Tool 分组
|
|
37
|
+
|
|
38
|
+
- 账套上下文:`lemon_account_current`、`lemon_account_list`、`lemon_account_switch`、`lemon_account_select`、`lemon_account_clear`
|
|
39
|
+
- ACC/SCM/ERP 业务:`lemon_action_search`、`lemon_action_show`、`lemon_action_read_doc`、`lemon_action_run`
|
|
40
|
+
- 独立开票:`lemon_invoice_read_doc`、`lemon_invoice_api`、`lemon_invoice_run_helper`
|
|
41
|
+
|
|
42
|
+
`stdout` 仅用于 MCP JSON-RPC。CLI 和 Runtime 输出会被捕获并作为 MCP Tool 内容返回;服务诊断只使用 `stderr`。
|
|
43
|
+
|
|
44
|
+
认证是 Tool 的内部前置条件。不要通过提示词或 Tool 输入发送 API Key;需要更换凭据时,应更新 MCP Host 中的 `LEMONCLAW_API_KEY` 并重新连接。
|
package/dist/lemonclaw-mcp.cjs
CHANGED
|
@@ -3279,8 +3279,8 @@ var require_package = __commonJS({
|
|
|
3279
3279
|
"package.json"(exports2, module2) {
|
|
3280
3280
|
module2.exports = {
|
|
3281
3281
|
name: "@lemonbeijing/lemonclaw-mcp-service",
|
|
3282
|
-
version: "0.1.
|
|
3283
|
-
description: "
|
|
3282
|
+
version: "0.1.3",
|
|
3283
|
+
description: "\u7528\u4E8E\u67E5\u8BE2\u548C\u64CD\u4F5C\u67E0\u6AAC\u4E91 Lemon Cloud \u4E1A\u52A1\u6570\u636E\u7684 MCP \u670D\u52A1\uFF0C\u8986\u76D6\u8D26\u5957\u3001\u8FDB\u9500\u5B58 SCM\u3001\u4E1A\u8D22 ERP\u3001\u8D22\u52A1 ACC \u548C\u72EC\u7ACB\u5F00\u7968\uFF1B\u652F\u6301\u5BA2\u6237\u3001\u4F9B\u5E94\u5546\u3001\u5546\u54C1\u3001\u4ED3\u5E93\u3001\u91C7\u8D2D\u3001\u9500\u552E\u3001\u5E93\u5B58\u3001\u6536\u4ED8\u6B3E\u3001\u5F80\u6765\u3001\u51ED\u8BC1\u3001\u8D26\u7C3F\u3001\u53D1\u7968\u53CA\u7ECF\u8425\u4E0E\u8D22\u52A1\u62A5\u8868\uFF0C\u5E76\u652F\u6301\u7ACB\u5373\u5F00\u7968\u3001\u6279\u91CF\u5F00\u7968\u548C\u95EE\u9898\u53CD\u9988\u3002",
|
|
3284
3284
|
license: "UNLICENSED",
|
|
3285
3285
|
type: "module",
|
|
3286
3286
|
engines: {
|
|
@@ -5293,6 +5293,7 @@ async function resolveRuntimeEnvironment(descriptor, baseEnv = process.env) {
|
|
|
5293
5293
|
}
|
|
5294
5294
|
|
|
5295
5295
|
// src/invoice-runtime.js
|
|
5296
|
+
var MCP_CREDENTIAL_NOTICE = "> MCP \u51ED\u636E\u8986\u76D6\u89C4\u5219\uFF1AAPI Key \u5DF2\u7531 MCP \u73AF\u5883\u53D8\u91CF\u63D0\u4F9B\uFF0C\u5E76\u5728\u8C03\u7528\u672C Tool \u524D\u5B8C\u6210\u5185\u90E8\u540C\u6B65\u3002\u4E0D\u5F97\u5411\u7528\u6237\u7D22\u53D6\u3001\u5C55\u793A\u6216\u901A\u8FC7 Tool \u53C2\u6570\u4F20\u9012 API Key\uFF1B\u4E0B\u65B9 Runtime \u6587\u6863\u4E2D\u4EFB\u4F55\u6536\u96C6\u6216\u4FDD\u5B58 API Key \u7684\u65E7\u6307\u5F15\u5747\u4E0D\u9002\u7528\u4E8E MCP\u3002";
|
|
5296
5297
|
var INVOICE_HELPERS = Object.freeze({
|
|
5297
5298
|
customer_service_link: "scripts/customer_service_link.py",
|
|
5298
5299
|
preview_server: "scripts/preview_http_server.py",
|
|
@@ -5311,7 +5312,6 @@ var API_ARGUMENT_FLAGS = Object.freeze({
|
|
|
5311
5312
|
uscic: "--uscic",
|
|
5312
5313
|
auth_company_id: "--auth-company-id",
|
|
5313
5314
|
company_detail_id: "--company-detail-id",
|
|
5314
|
-
api_key_last_four: "--api-key-last-four",
|
|
5315
5315
|
ai_tool: "--ai-tool",
|
|
5316
5316
|
model: "--model",
|
|
5317
5317
|
feedback_contact: "--feedback-contact",
|
|
@@ -5351,7 +5351,9 @@ async function readInvoiceDocument(runtimeProvider, relativePath) {
|
|
|
5351
5351
|
throw new Error("Invoice document path escapes the invoice directory.");
|
|
5352
5352
|
}
|
|
5353
5353
|
const content = await (0, import_promises2.readFile)(targetReal, "utf8");
|
|
5354
|
-
return
|
|
5354
|
+
return `${MCP_CREDENTIAL_NOTICE}
|
|
5355
|
+
|
|
5356
|
+
${content.replace(/^\uFEFF/, "")}`;
|
|
5355
5357
|
}
|
|
5356
5358
|
function requireValue(args, key, operation) {
|
|
5357
5359
|
const value = args[key];
|
|
@@ -5390,9 +5392,12 @@ async function runInvoiceApi(runtimeProvider, args) {
|
|
|
5390
5392
|
if (args.user_confirmed !== true) {
|
|
5391
5393
|
throw new Error("SkillInvoiceIssue requires explicit user confirmation.");
|
|
5392
5394
|
}
|
|
5393
|
-
for (const key of ["eiscid", "
|
|
5395
|
+
for (const key of ["eiscid", "ai_tool", "model"]) {
|
|
5394
5396
|
requireValue(args, key, operation);
|
|
5395
5397
|
}
|
|
5398
|
+
if (!String(runtime.apiKeyLastFour || "").trim()) {
|
|
5399
|
+
throw new Error("SkillInvoiceIssue requires the configured MCP API Key.");
|
|
5400
|
+
}
|
|
5396
5401
|
if (args.payload === void 0 && !args.payload_path) {
|
|
5397
5402
|
throw new Error("SkillInvoiceIssue requires payload or payload_path.");
|
|
5398
5403
|
}
|
|
@@ -5401,7 +5406,9 @@ async function runInvoiceApi(runtimeProvider, args) {
|
|
|
5401
5406
|
const command = [script, "--action", operation];
|
|
5402
5407
|
appendApiArguments(command, args);
|
|
5403
5408
|
if (payloadPath) command.push("--payload-path", String(payloadPath));
|
|
5404
|
-
if (operation === "SkillInvoiceIssue")
|
|
5409
|
+
if (operation === "SkillInvoiceIssue") {
|
|
5410
|
+
command.push("--api-key-last-four", runtime.apiKeyLastFour, "--issue-confirm", "1");
|
|
5411
|
+
}
|
|
5405
5412
|
return runProcess(runtime.python, command, {
|
|
5406
5413
|
cwd: runtime.runtimeRoot,
|
|
5407
5414
|
env: runtime.env,
|
|
@@ -5427,6 +5434,155 @@ var invoiceHelperNames = Object.freeze(Object.keys(INVOICE_HELPERS));
|
|
|
5427
5434
|
|
|
5428
5435
|
// src/runtime-manager.js
|
|
5429
5436
|
var import_runtime_core2 = __toESM(require_runtime_core(), 1);
|
|
5437
|
+
|
|
5438
|
+
// src/runtime-auth.js
|
|
5439
|
+
var API_KEY_ENVIRONMENT_VARIABLE = "LEMONCLAW_API_KEY";
|
|
5440
|
+
var ENSURE_API_KEY_PROGRAM = String.raw`
|
|
5441
|
+
import base64
|
|
5442
|
+
import ctypes
|
|
5443
|
+
import hmac
|
|
5444
|
+
import json
|
|
5445
|
+
import os
|
|
5446
|
+
import sys
|
|
5447
|
+
from pathlib import Path
|
|
5448
|
+
|
|
5449
|
+
skill_root = sys.argv[1]
|
|
5450
|
+
sys.path.insert(0, skill_root)
|
|
5451
|
+
from auth import auth as lemon_auth
|
|
5452
|
+
|
|
5453
|
+
|
|
5454
|
+
def credential_path():
|
|
5455
|
+
if os.name == "nt":
|
|
5456
|
+
appdata = os.environ.get("APPDATA")
|
|
5457
|
+
return Path(appdata) / "LemonAuthAgent" / "api-key.dat" if appdata else None
|
|
5458
|
+
config_root = os.environ.get("XDG_CONFIG_HOME")
|
|
5459
|
+
root = Path(config_root) if config_root else Path.home() / ".config"
|
|
5460
|
+
return root / "lemon-auth-agent" / "api-key.dat"
|
|
5461
|
+
|
|
5462
|
+
|
|
5463
|
+
def unprotect_windows(value):
|
|
5464
|
+
try:
|
|
5465
|
+
from ctypes import wintypes
|
|
5466
|
+
|
|
5467
|
+
encrypted = base64.b64decode(value.strip(), validate=True)
|
|
5468
|
+
if not encrypted:
|
|
5469
|
+
return None
|
|
5470
|
+
|
|
5471
|
+
class DataBlob(ctypes.Structure):
|
|
5472
|
+
_fields_ = [
|
|
5473
|
+
("cbData", wintypes.DWORD),
|
|
5474
|
+
("pbData", ctypes.POINTER(ctypes.c_ubyte)),
|
|
5475
|
+
]
|
|
5476
|
+
|
|
5477
|
+
source_buffer = (ctypes.c_ubyte * len(encrypted)).from_buffer_copy(encrypted)
|
|
5478
|
+
source = DataBlob(
|
|
5479
|
+
len(encrypted), ctypes.cast(source_buffer, ctypes.POINTER(ctypes.c_ubyte))
|
|
5480
|
+
)
|
|
5481
|
+
target = DataBlob()
|
|
5482
|
+
crypt32 = ctypes.WinDLL("crypt32", use_last_error=True)
|
|
5483
|
+
crypt32.CryptUnprotectData.argtypes = [
|
|
5484
|
+
ctypes.POINTER(DataBlob),
|
|
5485
|
+
ctypes.c_void_p,
|
|
5486
|
+
ctypes.c_void_p,
|
|
5487
|
+
ctypes.c_void_p,
|
|
5488
|
+
ctypes.c_void_p,
|
|
5489
|
+
wintypes.DWORD,
|
|
5490
|
+
ctypes.POINTER(DataBlob),
|
|
5491
|
+
]
|
|
5492
|
+
crypt32.CryptUnprotectData.restype = wintypes.BOOL
|
|
5493
|
+
if not crypt32.CryptUnprotectData(
|
|
5494
|
+
ctypes.byref(source), None, None, None, None, 1, ctypes.byref(target)
|
|
5495
|
+
):
|
|
5496
|
+
return None
|
|
5497
|
+
try:
|
|
5498
|
+
return ctypes.string_at(target.pbData, target.cbData).decode("utf-8")
|
|
5499
|
+
finally:
|
|
5500
|
+
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
|
|
5501
|
+
kernel32.LocalFree.argtypes = [ctypes.c_void_p]
|
|
5502
|
+
kernel32.LocalFree.restype = ctypes.c_void_p
|
|
5503
|
+
kernel32.LocalFree(ctypes.cast(target.pbData, ctypes.c_void_p))
|
|
5504
|
+
except Exception:
|
|
5505
|
+
return None
|
|
5506
|
+
|
|
5507
|
+
|
|
5508
|
+
def current_api_key():
|
|
5509
|
+
path = credential_path()
|
|
5510
|
+
if path is None or not path.is_file():
|
|
5511
|
+
return None
|
|
5512
|
+
try:
|
|
5513
|
+
stored = path.read_text(encoding="utf-8").strip()
|
|
5514
|
+
except (OSError, UnicodeError):
|
|
5515
|
+
return None
|
|
5516
|
+
if not stored:
|
|
5517
|
+
return None
|
|
5518
|
+
return unprotect_windows(stored) if os.name == "nt" else stored
|
|
5519
|
+
|
|
5520
|
+
|
|
5521
|
+
api_key = sys.stdin.read().strip()
|
|
5522
|
+
if not api_key:
|
|
5523
|
+
print(json.dumps({"ok": False, "error": "missing_api_key", "message": "Missing LEMONCLAW_API_KEY."}))
|
|
5524
|
+
raise SystemExit(2)
|
|
5525
|
+
|
|
5526
|
+
existing = current_api_key()
|
|
5527
|
+
if existing is not None and hmac.compare_digest(existing, api_key):
|
|
5528
|
+
result = {"ok": True, "data": {"saved": False, "unchanged": True}}
|
|
5529
|
+
else:
|
|
5530
|
+
result = lemon_auth.save_api_key(api_key)
|
|
5531
|
+
|
|
5532
|
+
print(json.dumps(result, ensure_ascii=False, separators=(",", ":")))
|
|
5533
|
+
`;
|
|
5534
|
+
function withoutApiKey(environment = {}) {
|
|
5535
|
+
const sanitized = { ...environment };
|
|
5536
|
+
delete sanitized[API_KEY_ENVIRONMENT_VARIABLE];
|
|
5537
|
+
return sanitized;
|
|
5538
|
+
}
|
|
5539
|
+
function authenticationFailure(result) {
|
|
5540
|
+
if (result.timedOut) return "LemonClaw API Key setup timed out.";
|
|
5541
|
+
if (result.outputLimitExceeded) return "LemonClaw API Key setup returned too much output.";
|
|
5542
|
+
if (result.spawnError) return `Unable to start LemonClaw authentication: ${result.spawnError.message}`;
|
|
5543
|
+
return String(result.stderr || result.stdout || "LemonClaw API Key setup failed.").trim().slice(0, 2e3);
|
|
5544
|
+
}
|
|
5545
|
+
async function ensureRuntimeApiKey(runtime, options = {}) {
|
|
5546
|
+
if (!runtime?.python || !runtime?.runtimeRoot || !runtime?.skillRoot) {
|
|
5547
|
+
throw new Error("Resolved Runtime environment is incomplete.");
|
|
5548
|
+
}
|
|
5549
|
+
const sourceEnvironment = options.env || process.env;
|
|
5550
|
+
const apiKey = String(sourceEnvironment[API_KEY_ENVIRONMENT_VARIABLE] || "").trim();
|
|
5551
|
+
if (!apiKey) {
|
|
5552
|
+
throw new Error(
|
|
5553
|
+
`Missing ${API_KEY_ENVIRONMENT_VARIABLE}. Configure it in the LemonClaw MCP environment and reconnect.`
|
|
5554
|
+
);
|
|
5555
|
+
}
|
|
5556
|
+
const run = options.run || runProcess;
|
|
5557
|
+
const result = await run(runtime.python, ["-c", ENSURE_API_KEY_PROGRAM, runtime.skillRoot], {
|
|
5558
|
+
cwd: runtime.runtimeRoot,
|
|
5559
|
+
env: withoutApiKey(runtime.env),
|
|
5560
|
+
stdin: apiKey,
|
|
5561
|
+
timeoutMs: Math.max(1, Number(options.timeoutMs || 6e4))
|
|
5562
|
+
});
|
|
5563
|
+
if (result.code !== 0 || result.timedOut || result.outputLimitExceeded || result.spawnError) {
|
|
5564
|
+
throw new Error(authenticationFailure(result));
|
|
5565
|
+
}
|
|
5566
|
+
let payload;
|
|
5567
|
+
try {
|
|
5568
|
+
payload = JSON.parse(String(result.stdout || "").trim());
|
|
5569
|
+
} catch {
|
|
5570
|
+
throw new Error("LemonClaw authentication returned an invalid response.");
|
|
5571
|
+
}
|
|
5572
|
+
if (payload?.ok !== true) {
|
|
5573
|
+
throw new Error(String(payload?.message || payload?.error || "LemonClaw API Key setup failed."));
|
|
5574
|
+
}
|
|
5575
|
+
return {
|
|
5576
|
+
apiKeyLastFour: apiKey.slice(-4),
|
|
5577
|
+
saved: payload?.data?.saved === true,
|
|
5578
|
+
unchanged: payload?.data?.unchanged === true
|
|
5579
|
+
};
|
|
5580
|
+
}
|
|
5581
|
+
function removeApiKeyFromEnvironment(environment) {
|
|
5582
|
+
return withoutApiKey(environment);
|
|
5583
|
+
}
|
|
5584
|
+
|
|
5585
|
+
// src/runtime-manager.js
|
|
5430
5586
|
var { publicError } = import_runtime_core2.default.errors;
|
|
5431
5587
|
var {
|
|
5432
5588
|
bootstrapRuntime,
|
|
@@ -5464,6 +5620,8 @@ function createRuntimeManager(options = {}) {
|
|
|
5464
5620
|
};
|
|
5465
5621
|
const run = options.runProcess || runProcess;
|
|
5466
5622
|
const makeEnvironment = options.resolveRuntimeEnvironment || resolveRuntimeEnvironment;
|
|
5623
|
+
const ensureApiKey = options.ensureRuntimeApiKey || ensureRuntimeApiKey;
|
|
5624
|
+
let authenticationQueue = Promise.resolve();
|
|
5467
5625
|
install.cleanupAbandonedInstallLock({ env });
|
|
5468
5626
|
async function resolveDescriptor(mode = "current-or-install") {
|
|
5469
5627
|
if (mode === "auto") return install.maybeAutoUpdate({ env });
|
|
@@ -5472,7 +5630,18 @@ function createRuntimeManager(options = {}) {
|
|
|
5472
5630
|
return install.bootstrapRuntime({ env, waitForPeer: true });
|
|
5473
5631
|
}
|
|
5474
5632
|
async function resolveEnvironment(mode = "current-or-install") {
|
|
5475
|
-
|
|
5633
|
+
const runtime = await makeEnvironment(await resolveDescriptor(mode), env);
|
|
5634
|
+
const authenticationTask = authenticationQueue.then(() => ensureApiKey(runtime, { env, run }));
|
|
5635
|
+
authenticationQueue = authenticationTask.then(
|
|
5636
|
+
() => void 0,
|
|
5637
|
+
() => void 0
|
|
5638
|
+
);
|
|
5639
|
+
const authentication = await authenticationTask;
|
|
5640
|
+
return {
|
|
5641
|
+
...runtime,
|
|
5642
|
+
apiKeyLastFour: authentication.apiKeyLastFour,
|
|
5643
|
+
env: removeApiKeyFromEnvironment(runtime.env)
|
|
5644
|
+
};
|
|
5476
5645
|
}
|
|
5477
5646
|
async function runCli(args, runOptions = {}) {
|
|
5478
5647
|
try {
|
|
@@ -5491,47 +5660,6 @@ function createRuntimeManager(options = {}) {
|
|
|
5491
5660
|
return { resolveDescriptor, resolveEnvironment, runCli };
|
|
5492
5661
|
}
|
|
5493
5662
|
|
|
5494
|
-
// src/runtime-auth.js
|
|
5495
|
-
var AUTH_PROGRAM = String.raw`
|
|
5496
|
-
import json
|
|
5497
|
-
import sys
|
|
5498
|
-
|
|
5499
|
-
operation = sys.argv[1]
|
|
5500
|
-
skill_root = sys.argv[2]
|
|
5501
|
-
sys.path.insert(0, skill_root)
|
|
5502
|
-
from auth import auth as lemon_auth
|
|
5503
|
-
|
|
5504
|
-
if operation == "status":
|
|
5505
|
-
result = lemon_auth.auth_status()
|
|
5506
|
-
elif operation == "save_api_key":
|
|
5507
|
-
result = lemon_auth.save_api_key(sys.stdin.read())
|
|
5508
|
-
elif operation == "clear":
|
|
5509
|
-
result = lemon_auth.clear_auth()
|
|
5510
|
-
else:
|
|
5511
|
-
raise SystemExit("unsupported auth operation")
|
|
5512
|
-
|
|
5513
|
-
print(json.dumps(result, ensure_ascii=False, separators=(",", ":")))
|
|
5514
|
-
`;
|
|
5515
|
-
async function runRuntimeAuth(runtimeProvider, args, options = {}) {
|
|
5516
|
-
const resolveRuntime = options.resolveRuntime || runtimeProvider;
|
|
5517
|
-
const run = options.run || runProcess;
|
|
5518
|
-
if (typeof resolveRuntime !== "function") throw new Error("Runtime provider is required.");
|
|
5519
|
-
const runtime = await resolveRuntime("current-or-install");
|
|
5520
|
-
const operation = String(args.operation || "");
|
|
5521
|
-
if (!["status", "save_api_key", "clear"].includes(operation)) {
|
|
5522
|
-
throw new Error("Unsupported Runtime authentication operation.");
|
|
5523
|
-
}
|
|
5524
|
-
if (operation === "save_api_key" && !String(args.api_key || "").trim()) {
|
|
5525
|
-
throw new Error("API Key is required.");
|
|
5526
|
-
}
|
|
5527
|
-
return run(runtime.python, ["-c", AUTH_PROGRAM, operation, runtime.skillRoot], {
|
|
5528
|
-
cwd: runtime.runtimeRoot,
|
|
5529
|
-
env: runtime.env,
|
|
5530
|
-
stdin: operation === "save_api_key" ? String(args.api_key) : void 0,
|
|
5531
|
-
timeoutMs: Math.max(1, Number(args.timeout_seconds || 60)) * 1e3
|
|
5532
|
-
});
|
|
5533
|
-
}
|
|
5534
|
-
|
|
5535
5663
|
// src/tool-result.js
|
|
5536
5664
|
function publicFailure(result) {
|
|
5537
5665
|
if (result.timedOut) return "LemonClaw command timed out.";
|
|
@@ -5566,8 +5694,8 @@ function toolError(error) {
|
|
|
5566
5694
|
}
|
|
5567
5695
|
|
|
5568
5696
|
// src/server.js
|
|
5569
|
-
var productSchema = z.enum(["acc", "scm", "erp"]);
|
|
5570
|
-
var timeoutSchema = z.number().int().min(1).max(600).default(120);
|
|
5697
|
+
var productSchema = z.enum(["acc", "scm", "erp"]).describe("\u4E1A\u52A1\u4EA7\u54C1\uFF1Aacc=\u8D22\u52A1\uFF0Cscm=\u8FDB\u9500\u5B58\uFF0Cerp=\u4E1A\u8D22\uFF1B\u5FC5\u987B\u4E0E\u5F53\u524D\u6240\u9009\u8D26\u5957\u4EA7\u54C1\u4E00\u81F4\u3002");
|
|
5698
|
+
var timeoutSchema = z.number().int().min(1).max(600).default(120).describe("\u672C\u6B21\u64CD\u4F5C\u7684\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u4E3A\u79D2\uFF0C\u53D6\u503C\u8303\u56F4 1 \u81F3 600\u3002");
|
|
5571
5699
|
var optionalText = z.string().min(1).optional();
|
|
5572
5700
|
var readOnlyAnnotations = {
|
|
5573
5701
|
readOnlyHint: true,
|
|
@@ -5602,76 +5730,9 @@ function createLemonClawServer(options = {}) {
|
|
|
5602
5730
|
const runCli = options.runCli || runtimeManager.runCli;
|
|
5603
5731
|
const resolveRuntime = options.resolveRuntime || runtimeManager.resolveEnvironment;
|
|
5604
5732
|
const server = new import_server.McpServer(
|
|
5605
|
-
{ name: "lemonclaw", version: "0.1.
|
|
5733
|
+
{ name: "lemonclaw", version: "0.1.3" },
|
|
5606
5734
|
{
|
|
5607
|
-
instructions: "
|
|
5608
|
-
}
|
|
5609
|
-
);
|
|
5610
|
-
server.registerTool(
|
|
5611
|
-
"lemon_auth_status",
|
|
5612
|
-
{
|
|
5613
|
-
title: "Check LemonClaw API Key authentication",
|
|
5614
|
-
description: "Check whether the current user's standard LemonClaw API Key can provide a token. This uses the Runtime authentication helper and never returns the API Key or token.",
|
|
5615
|
-
inputSchema: z.object({
|
|
5616
|
-
timeout_seconds: z.number().int().min(1).max(120).default(60)
|
|
5617
|
-
}),
|
|
5618
|
-
annotations: readOnlyAnnotations
|
|
5619
|
-
},
|
|
5620
|
-
async (args) => {
|
|
5621
|
-
try {
|
|
5622
|
-
return cliToolResult(await runRuntimeAuth(resolveRuntime, { ...args, operation: "status" }));
|
|
5623
|
-
} catch (error) {
|
|
5624
|
-
return toolError(error);
|
|
5625
|
-
}
|
|
5626
|
-
}
|
|
5627
|
-
);
|
|
5628
|
-
server.registerTool(
|
|
5629
|
-
"lemon_auth_save_api_key",
|
|
5630
|
-
{
|
|
5631
|
-
title: "Save LemonClaw API Key",
|
|
5632
|
-
description: "Save an API Key with the standard Runtime authentication helper for the current operating-system user. The key is sent to Runtime through stdin, is not placed in process arguments, and is never returned.",
|
|
5633
|
-
inputSchema: z.object({
|
|
5634
|
-
api_key: z.string().min(1),
|
|
5635
|
-
timeout_seconds: z.number().int().min(1).max(120).default(60)
|
|
5636
|
-
}),
|
|
5637
|
-
annotations: {
|
|
5638
|
-
readOnlyHint: false,
|
|
5639
|
-
destructiveHint: false,
|
|
5640
|
-
idempotentHint: false,
|
|
5641
|
-
openWorldHint: false
|
|
5642
|
-
}
|
|
5643
|
-
},
|
|
5644
|
-
async (args) => {
|
|
5645
|
-
try {
|
|
5646
|
-
return cliToolResult(
|
|
5647
|
-
await runRuntimeAuth(resolveRuntime, { ...args, operation: "save_api_key" })
|
|
5648
|
-
);
|
|
5649
|
-
} catch (error) {
|
|
5650
|
-
return toolError(error);
|
|
5651
|
-
}
|
|
5652
|
-
}
|
|
5653
|
-
);
|
|
5654
|
-
server.registerTool(
|
|
5655
|
-
"lemon_auth_clear",
|
|
5656
|
-
{
|
|
5657
|
-
title: "Clear LemonClaw API Key authentication",
|
|
5658
|
-
description: "Clear the current user's standard LemonClaw API Key and token cache without clearing account context. Use only when the user explicitly requests it.",
|
|
5659
|
-
inputSchema: z.object({
|
|
5660
|
-
timeout_seconds: z.number().int().min(1).max(120).default(60)
|
|
5661
|
-
}),
|
|
5662
|
-
annotations: {
|
|
5663
|
-
readOnlyHint: false,
|
|
5664
|
-
destructiveHint: true,
|
|
5665
|
-
idempotentHint: true,
|
|
5666
|
-
openWorldHint: false
|
|
5667
|
-
}
|
|
5668
|
-
},
|
|
5669
|
-
async (args) => {
|
|
5670
|
-
try {
|
|
5671
|
-
return cliToolResult(await runRuntimeAuth(resolveRuntime, { ...args, operation: "clear" }));
|
|
5672
|
-
} catch (error) {
|
|
5673
|
-
return toolError(error);
|
|
5674
|
-
}
|
|
5735
|
+
instructions: "LemonClaw \u7684 API Key \u4EC5\u7531 MCP \u670D\u52A1\u73AF\u5883\u53D8\u91CF\u63D0\u4F9B\uFF0C\u4E0D\u5F97\u5728\u5BF9\u8BDD\u6216 Tool \u53C2\u6570\u4E2D\u7D22\u53D6\u3001\u63A5\u6536\u3001\u5C55\u793A\u6216\u4F20\u9012\u3002\u5904\u7406 ACC\u3001SCM\u3001ERP \u4E1A\u52A1\u524D\uFF0C\u5148\u786E\u5B9A\u4EA7\u54C1\u5E76\u83B7\u53D6\u6216\u5207\u6362\u8D26\u5957\uFF1B\u968F\u540E\u4F9D\u6B21\u8C03\u7528 lemon_action_search\u3001lemon_action_show\u3001lemon_action_read_doc \u8BFB\u53D6 show \u8FD4\u56DE\u7684\u5168\u90E8\u5B9E\u9645\u6587\u6863\uFF0C\u6700\u540E\u624D\u53EF\u8C03\u7528 lemon_action_run\uFF0C\u4E25\u7981\u731C\u6D4B Action \u548C\u53C2\u6570\u3002\u72EC\u7ACB\u5F00\u7968\u53EA\u4F7F\u7528 lemon_invoice_* Tools\uFF0C\u5E76\u5148\u8BFB\u53D6 Runtime \u5F00\u7968\u6587\u6863\uFF1BRuntime \u6587\u6863\u4E2D\u4EFB\u4F55\u8981\u6C42\u6536\u96C6\u6216\u4FDD\u5B58 API Key \u7684\u65E7\u6307\u5F15\u5747\u4E0D\u9002\u7528\u4E8E MCP\uFF0C\u56E0\u4E3A\u6BCF\u6B21 Tool \u8C03\u7528\u524D\u90FD\u5DF2\u5728\u5185\u90E8\u5B8C\u6210\u8BA4\u8BC1\u3002"
|
|
5675
5736
|
}
|
|
5676
5737
|
);
|
|
5677
5738
|
registerCliTool(
|
|
@@ -5679,8 +5740,8 @@ function createLemonClawServer(options = {}) {
|
|
|
5679
5740
|
runCli,
|
|
5680
5741
|
"lemon_account_current",
|
|
5681
5742
|
{
|
|
5682
|
-
title: "
|
|
5683
|
-
description: "
|
|
5743
|
+
title: "\u83B7\u53D6\u5F53\u524D\u67E0\u6AAC\u4E91\u8D26\u5957",
|
|
5744
|
+
description: "\u83B7\u53D6\u5F53\u524D\u9009\u4E2D\u7684\u67E0\u6AAC\u4E91\u4EA7\u54C1\u548C\u8D26\u5957\u4FE1\u606F\u3002\u6267\u884C ACC \u8D22\u52A1\u3001SCM \u8FDB\u9500\u5B58\u6216 ERP \u4E1A\u8D22\u4E1A\u52A1\u524D\u5E94\u5148\u8C03\u7528\u672C\u5DE5\u5177\uFF0C\u4EE5\u786E\u8BA4\u540E\u7EED Action \u4F7F\u7528\u7684 product \u4E0E\u5F53\u524D\u8D26\u5957\u4E00\u81F4\uFF1B\u672C\u5DE5\u5177\u4E0D\u4F1A\u5207\u6362\u6216\u4FEE\u6539\u8D26\u5957\u3002",
|
|
5684
5745
|
inputSchema: z.object({ timeout_seconds: timeoutSchema }),
|
|
5685
5746
|
annotations: readOnlyAnnotations
|
|
5686
5747
|
},
|
|
@@ -5694,10 +5755,10 @@ function createLemonClawServer(options = {}) {
|
|
|
5694
5755
|
runCli,
|
|
5695
5756
|
"lemon_account_list",
|
|
5696
5757
|
{
|
|
5697
|
-
title: "
|
|
5698
|
-
description: "
|
|
5758
|
+
title: "\u5217\u51FA\u67E0\u6AAC\u4E91\u8D26\u5957",
|
|
5759
|
+
description: "\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u7528\u7684\u67E0\u6AAC\u4E91\u8D26\u5957\uFF0C\u5E76\u7F13\u5B58\u8FD4\u56DE\u7684\u5019\u9009\u5E8F\u53F7\u4F9B lemon_account_select \u4F7F\u7528\u3002\u4EC5\u5F53 lemon_account_switch \u6CA1\u6709\u8FD4\u56DE\u53EF\u7528\u5019\u9009\uFF0C\u6216\u7528\u6237\u660E\u786E\u8981\u6C42\u67E5\u770B\u8D26\u5957\u5217\u8868\u65F6\u8C03\u7528\uFF1B\u4E0D\u8981\u4E3A\u4E86\u9009\u62E9\u5DF2\u6709\u5019\u9009\u800C\u91CD\u590D\u5237\u65B0\u5217\u8868\u3002",
|
|
5699
5760
|
inputSchema: z.object({
|
|
5700
|
-
dry_run: z.boolean().default(false),
|
|
5761
|
+
dry_run: z.boolean().default(false).describe("\u662F\u5426\u4EC5\u68C0\u67E5\u6D41\u7A0B\u800C\u4E0D\u5B9E\u9645\u66F4\u65B0\u672C\u5730\u5019\u9009\u7F13\u5B58\u3002"),
|
|
5701
5762
|
timeout_seconds: timeoutSchema
|
|
5702
5763
|
}),
|
|
5703
5764
|
annotations: readOnlyAnnotations
|
|
@@ -5713,16 +5774,16 @@ function createLemonClawServer(options = {}) {
|
|
|
5713
5774
|
runCli,
|
|
5714
5775
|
"lemon_account_switch",
|
|
5715
5776
|
{
|
|
5716
|
-
title: "
|
|
5717
|
-
description: "
|
|
5777
|
+
title: "\u5339\u914D\u5E76\u5207\u6362\u67E0\u6AAC\u4E91\u8D26\u5957",
|
|
5778
|
+
description: "\u6839\u636E\u4EA7\u54C1\u3001\u8D26\u5957\u540D\u79F0\u3001\u7F16\u53F7\u6216\u7248\u672C\u7B49\u7EBF\u7D22\u5339\u914D\u5E76\u5207\u6362\u67E0\u6AAC\u4E91\u8D26\u5957\u3002\u552F\u4E00\u5339\u914D\u65F6\u53EF\u76F4\u63A5\u5207\u6362\uFF1B\u8FD4\u56DE\u591A\u4E2A\u5019\u9009\u65F6\uFF0C\u5E94\u5411\u7528\u6237\u5C55\u793A\u5E76\u901A\u8FC7 lemon_account_select \u4ECE\u540C\u4E00\u6279\u5019\u9009\u4E2D\u9009\u62E9\uFF0C\u4E0D\u8981\u8C03\u7528 lemon_account_list \u5237\u65B0\u5019\u9009\u3002",
|
|
5718
5779
|
inputSchema: z.object({
|
|
5719
|
-
query: optionalText,
|
|
5780
|
+
query: optionalText.describe("\u7528\u4E8E\u5339\u914D\u4EA7\u54C1\u3001\u8D26\u5957\u540D\u79F0\u3001\u7F16\u53F7\u6216\u7248\u672C\u7684\u7528\u6237\u7EBF\u7D22\u3002"),
|
|
5720
5781
|
product: productSchema.optional(),
|
|
5721
5782
|
asid: optionalText,
|
|
5722
5783
|
serviceid: optionalText,
|
|
5723
5784
|
name: optionalText,
|
|
5724
5785
|
edition: optionalText,
|
|
5725
|
-
dry_run: z.boolean().default(false),
|
|
5786
|
+
dry_run: z.boolean().default(false).describe("\u662F\u5426\u53EA\u9884\u89C8\u5339\u914D\u7ED3\u679C\u800C\u4E0D\u5B9E\u9645\u5207\u6362\u8D26\u5957\u3002"),
|
|
5726
5787
|
timeout_seconds: timeoutSchema
|
|
5727
5788
|
}),
|
|
5728
5789
|
annotations: {
|
|
@@ -5750,10 +5811,10 @@ function createLemonClawServer(options = {}) {
|
|
|
5750
5811
|
runCli,
|
|
5751
5812
|
"lemon_account_select",
|
|
5752
5813
|
{
|
|
5753
|
-
title: "
|
|
5754
|
-
description: "
|
|
5814
|
+
title: "\u9009\u62E9\u67E0\u6AAC\u4E91\u8D26\u5957\u5019\u9009",
|
|
5815
|
+
description: "\u4ECE\u6700\u8FD1\u4E00\u6B21 lemon_account_switch \u6216 lemon_account_list \u7F13\u5B58\u7684\u5019\u9009\u4E2D\u9009\u62E9\u8D26\u5957\u3002\u4F18\u5148\u4F7F\u7528\u5019\u9009\u8FD4\u56DE\u7684 index\uFF0C\u5E76\u4FDD\u6301\u5019\u9009\u4E2D\u7684 product \u548C\u6807\u8BC6\u4E0D\u53D8\uFF1B\u4E0D\u5F97\u7F16\u9020\u5E8F\u53F7\uFF0C\u4E5F\u4E0D\u5F97\u5728\u91CD\u540D\u8D26\u5957\u4E4B\u95F4\u9759\u9ED8\u9009\u62E9\u3002",
|
|
5755
5816
|
inputSchema: z.object({
|
|
5756
|
-
index: z.number().int().positive().optional(),
|
|
5817
|
+
index: z.number().int().positive().optional().describe("\u6700\u8FD1\u4E00\u6B21\u5019\u9009\u5217\u8868\u8FD4\u56DE\u7684\u5E8F\u53F7\u3002"),
|
|
5757
5818
|
product: productSchema.optional(),
|
|
5758
5819
|
asid: optionalText,
|
|
5759
5820
|
serviceid: optionalText,
|
|
@@ -5761,7 +5822,7 @@ function createLemonClawServer(options = {}) {
|
|
|
5761
5822
|
timeout_seconds: timeoutSchema
|
|
5762
5823
|
}).refine(
|
|
5763
5824
|
(value) => value.index !== void 0 || value.asid || value.serviceid || value.name,
|
|
5764
|
-
"
|
|
5825
|
+
"\u5FC5\u987B\u63D0\u4F9B\u6700\u8FD1\u4E00\u6B21\u5019\u9009\u5217\u8868\u4E2D\u7684 index\u3001asid\u3001serviceid \u6216 name\u3002"
|
|
5765
5826
|
),
|
|
5766
5827
|
annotations: {
|
|
5767
5828
|
readOnlyHint: false,
|
|
@@ -5786,11 +5847,11 @@ function createLemonClawServer(options = {}) {
|
|
|
5786
5847
|
runCli,
|
|
5787
5848
|
"lemon_account_clear",
|
|
5788
5849
|
{
|
|
5789
|
-
title: "
|
|
5790
|
-
description: "
|
|
5850
|
+
title: "\u6E05\u9664\u67E0\u6AAC\u4E91\u8D26\u5957\u4E0A\u4E0B\u6587",
|
|
5851
|
+
description: "\u6E05\u9664\u5DF2\u4FDD\u5B58\u7684\u67E0\u6AAC\u4E91\u8D26\u5957\u4E0A\u4E0B\u6587\uFF0C\u4F46\u4E0D\u4F1A\u6E05\u9664 API Key \u6216\u8BA4\u8BC1\u4FE1\u606F\u3002\u9ED8\u8BA4\u4EC5\u6E05\u9664\u6307\u5B9A\u6216\u5F53\u524D\u4EA7\u54C1\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u6E05\u9664\u5168\u90E8\u4EA7\u54C1\u8D26\u5957\u65F6\uFF0C\u624D\u53EF\u5C06 all_products \u8BBE\u4E3A true\u3002",
|
|
5791
5852
|
inputSchema: z.object({
|
|
5792
5853
|
product: productSchema.optional(),
|
|
5793
|
-
all_products: z.boolean().default(false),
|
|
5854
|
+
all_products: z.boolean().default(false).describe("\u662F\u5426\u6E05\u9664 ACC\u3001SCM\u3001ERP \u7684\u5168\u90E8\u8D26\u5957\u4E0A\u4E0B\u6587\u3002"),
|
|
5794
5855
|
timeout_seconds: timeoutSchema
|
|
5795
5856
|
}),
|
|
5796
5857
|
annotations: {
|
|
@@ -5813,12 +5874,12 @@ function createLemonClawServer(options = {}) {
|
|
|
5813
5874
|
runCli,
|
|
5814
5875
|
"lemon_action_search",
|
|
5815
5876
|
{
|
|
5816
|
-
title: "
|
|
5817
|
-
description: "
|
|
5877
|
+
title: "\u641C\u7D22\u67E0\u6AAC\u4E91\u4E1A\u52A1\u80FD\u529B",
|
|
5878
|
+
description: "\u5728\u6307\u5B9A\u7684\u67E0\u6AAC\u4E91 ACC\u3001SCM \u6216 ERP \u4EA7\u54C1\u4E2D\u641C\u7D22\u4E0E\u7528\u6237\u9700\u6C42\u5339\u914D\u7684\u4E1A\u52A1\u80FD\u529B\u3002\u53EF\u641C\u7D22\u5BA2\u6237\u3001\u4F9B\u5E94\u5546\u3001\u5546\u54C1\u3001\u4ED3\u5E93\u7B49\u57FA\u7840\u8D44\u6599\uFF0C\u4EE5\u53CA\u91C7\u8D2D\u8BA2\u5355\u3001\u9500\u552E\u8BA2\u5355\u3001\u5E93\u5B58\u3001\u6536\u4ED8\u6B3E\u3001\u5F80\u6765\u3001\u51ED\u8BC1\u3001\u8D26\u7C3F\u3001\u53D1\u7968\u548C\u7ECF\u8425\u6216\u8D22\u52A1\u62A5\u8868\u7B49\u80FD\u529B\uFF1BERP \u8FD8\u8986\u76D6\u9500\u552E\u62A5\u4EF7\u3001\u4EF7\u683C\u8D44\u6599\u3001\u8BA2\u5355\u6C47\u603B\u3001\u5E93\u5B58\u8D26\u9F84\u3001\u6682\u4F30\u8C03\u6574\u548C\u5E94\u6536\u5E94\u4ED8\u9884\u8B66\u3002\u672C\u5DE5\u5177\u53EA\u8FD4\u56DE\u5F53\u524D\u4EA7\u54C1\u7684 Action \u5019\u9009\uFF0C\u4E0D\u9009\u62E9 Action\u3001\u4E0D\u751F\u6210\u4E1A\u52A1\u53C2\u6570\uFF0C\u4E5F\u4E0D\u6267\u884C\u67E5\u8BE2\u6216\u5199\u64CD\u4F5C\u3002",
|
|
5818
5879
|
inputSchema: z.object({
|
|
5819
5880
|
product: productSchema,
|
|
5820
|
-
query: z.string().min(1),
|
|
5821
|
-
limit: z.number().int().min(1).max(20).default(5)
|
|
5881
|
+
query: z.string().min(1).describe("\u7528\u6237\u7684\u81EA\u7136\u8BED\u8A00\u4E1A\u52A1\u9700\u6C42\uFF0C\u4F8B\u5982\u201C\u67E5\u8BE2\u672C\u6708\u91C7\u8D2D\u8BA2\u5355\u201D\u3002"),
|
|
5882
|
+
limit: z.number().int().min(1).max(20).default(5).describe("\u6700\u591A\u8FD4\u56DE\u7684\u5019\u9009\u6570\u91CF\u3002")
|
|
5822
5883
|
}),
|
|
5823
5884
|
annotations: readOnlyAnnotations
|
|
5824
5885
|
},
|
|
@@ -5840,11 +5901,11 @@ function createLemonClawServer(options = {}) {
|
|
|
5840
5901
|
runCli,
|
|
5841
5902
|
"lemon_action_show",
|
|
5842
5903
|
{
|
|
5843
|
-
title: "
|
|
5844
|
-
description: "
|
|
5904
|
+
title: "\u67E5\u770B\u67E0\u6AAC\u4E91\u4E1A\u52A1\u80FD\u529B\u5951\u7EA6",
|
|
5905
|
+
description: "\u67E5\u770B\u6307\u5B9A\u67E0\u6AAC\u4E91\u4E1A\u52A1 Action \u7684\u516C\u5F00\u8C03\u7528\u5951\u7EA6\u3001\u53C2\u6570\u7ED3\u6784\u53CA\u5B9E\u9645\u5B58\u5728\u7684\u8BF4\u660E\u6587\u6863\u3002\u67E5\u770B\u6210\u529F\u4E0D\u4EE3\u8868\u8BE5 Action \u5DF2\u7ECF\u662F\u7528\u6237\u9700\u6C42\u7684\u552F\u4E00\u5339\u914D\uFF1B\u5B58\u5728\u591A\u4E2A\u5408\u7406\u5019\u9009\u65F6\u4ECD\u9700\u7EE7\u7EED\u6BD4\u8F83\uFF0C\u5FC5\u8981\u65F6\u8BF7\u7528\u6237\u786E\u8BA4\u3002",
|
|
5845
5906
|
inputSchema: z.object({
|
|
5846
5907
|
product: productSchema,
|
|
5847
|
-
action: z.string().min(1)
|
|
5908
|
+
action: z.string().min(1).describe("lemon_action_search \u5019\u9009\u8FD4\u56DE\u7684\u7CBE\u786E Action \u540D\u79F0\u3002")
|
|
5848
5909
|
}),
|
|
5849
5910
|
annotations: readOnlyAnnotations
|
|
5850
5911
|
},
|
|
@@ -5858,12 +5919,12 @@ function createLemonClawServer(options = {}) {
|
|
|
5858
5919
|
runCli,
|
|
5859
5920
|
"lemon_action_read_doc",
|
|
5860
5921
|
{
|
|
5861
|
-
title: "
|
|
5862
|
-
description: "
|
|
5922
|
+
title: "\u8BFB\u53D6\u67E0\u6AAC\u4E91\u4E1A\u52A1\u80FD\u529B\u6587\u6863",
|
|
5923
|
+
description: "\u8BFB\u53D6\u6307\u5B9A\u4E1A\u52A1 Action \u5DF2\u6CE8\u518C\u7684\u529F\u80FD\u8BF4\u660E\u3001\u8F93\u5165\u53C2\u6570\u6216\u8F93\u51FA\u7ED3\u679C\u6587\u6863\u3002\u6700\u7EC8\u9009\u62E9 Action \u540E\uFF0C\u5FC5\u987B\u5728\u6267\u884C\u524D\u8BFB\u53D6 lemon_action_show \u5B9E\u9645\u8FD4\u56DE\u7684\u5168\u90E8\u6587\u6863\uFF0C\u5E76\u4EE5\u6587\u6863\u5B9A\u4E49\u4E3A\u51C6\u6784\u9020\u53C2\u6570\u548C\u5C55\u793A\u7ED3\u679C\uFF1B\u4E0D\u5F97\u731C\u6D4B\u4E0D\u5B58\u5728\u7684\u6587\u6863\u6216\u5B57\u6BB5\u3002",
|
|
5863
5924
|
inputSchema: z.object({
|
|
5864
5925
|
product: productSchema,
|
|
5865
|
-
action: z.string().min(1),
|
|
5866
|
-
document: z.enum(["action", "input", "output"])
|
|
5926
|
+
action: z.string().min(1).describe("\u5DF2\u7ECF\u6838\u9A8C\u7684\u7CBE\u786E Action \u540D\u79F0\u3002"),
|
|
5927
|
+
document: z.enum(["action", "input", "output"]).describe("\u8981\u8BFB\u53D6\u7684\u6587\u6863\u7C7B\u578B\uFF1B\u53EA\u80FD\u9009\u62E9 lemon_action_show \u8FD4\u56DE\u4E3A\u5B9E\u9645\u5B58\u5728\u7684\u7C7B\u578B\u3002")
|
|
5867
5928
|
}),
|
|
5868
5929
|
annotations: readOnlyAnnotations
|
|
5869
5930
|
},
|
|
@@ -5884,19 +5945,19 @@ function createLemonClawServer(options = {}) {
|
|
|
5884
5945
|
runCli,
|
|
5885
5946
|
"lemon_action_run",
|
|
5886
5947
|
{
|
|
5887
|
-
title: "
|
|
5888
|
-
description: "
|
|
5948
|
+
title: "\u67E5\u8BE2\u6216\u6267\u884C\u67E0\u6AAC\u4E91\u4E1A\u52A1\u64CD\u4F5C",
|
|
5949
|
+
description: "\u6267\u884C\u5DF2\u901A\u8FC7\u68C0\u7D22\u548C\u6587\u6863\u6838\u9A8C\u7684\u67E0\u6AAC\u4E91 ACC\u3001SCM \u6216 ERP \u4E1A\u52A1\u64CD\u4F5C\u3002\u652F\u6301\u67E5\u8BE2\u5BA2\u6237\u3001\u4F9B\u5E94\u5546\u3001\u5546\u54C1\u3001\u4ED3\u5E93\u7B49\u57FA\u7840\u8D44\u6599\uFF0C\u4EE5\u53CA\u91C7\u8D2D\u8BA2\u5355\u3001\u9500\u552E\u8BA2\u5355\u3001\u5E93\u5B58\u3001\u6536\u4ED8\u6B3E\u3001\u5F80\u6765\u3001\u51ED\u8BC1\u3001\u8D26\u7C3F\u3001\u53D1\u7968\u548C\u7ECF\u8425\u6216\u8D22\u52A1\u62A5\u8868\uFF1BERP \u8FD8\u652F\u6301\u9500\u552E\u62A5\u4EF7\u3001\u4EF7\u683C\u8D44\u6599\u3001\u8BA2\u5355\u6C47\u603B\u3001\u5E93\u5B58\u8D26\u9F84\u3001\u6682\u4F30\u8C03\u6574\u548C\u5E94\u6536\u5E94\u4ED8\u9884\u8B66\u3002\u5BF9\u4E8E Action \u6587\u6863\u660E\u786E\u652F\u6301\u7684\u65B0\u589E\u3001\u4FEE\u6539\u3001\u63D0\u4EA4\u7B49\u5199\u64CD\u4F5C\uFF0C\u4EC5\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u6267\u884C\u3002\u8C03\u7528\u524D\u5FC5\u987B\u5B8C\u6210 search\u3001show \u548C\u5168\u90E8\u6587\u6863\u8BFB\u53D6\uFF0C\u4E0D\u5F97\u731C\u6D4B\u53C2\u6570\uFF1B\u672C\u5DE5\u5177\u4E0D\u7528\u4E8E\u72EC\u7ACB\u5F00\u7968\u3002",
|
|
5889
5950
|
inputSchema: z.object({
|
|
5890
5951
|
product: productSchema,
|
|
5891
|
-
action: z.string().min(1),
|
|
5952
|
+
action: z.string().min(1).describe("\u5DF2\u901A\u8FC7 search\u3001show \u548C\u6587\u6863\u6838\u9A8C\u7684\u7CBE\u786E Action \u540D\u79F0\u3002"),
|
|
5892
5953
|
payload: z.object({
|
|
5893
|
-
query: z.record(z.string(), z.unknown()).optional(),
|
|
5894
|
-
body: z.union([z.record(z.string(), z.unknown()), z.array(z.unknown())]).optional(),
|
|
5895
|
-
_outputMode: z.enum(["basic", "full"]).optional(),
|
|
5896
|
-
_extraDisplayFields: z.array(z.string().min(1)).min(1).optional()
|
|
5897
|
-
}).strict(),
|
|
5898
|
-
user_confirmed: z.boolean().default(false),
|
|
5899
|
-
dry_run: z.boolean().default(false),
|
|
5954
|
+
query: z.record(z.string(), z.unknown()).optional().describe("Action \u6587\u6863\u5B9A\u4E49\u7684 URL \u67E5\u8BE2\u53C2\u6570\uFF1B\u65E0\u53C2\u6570\u65F6\u6309\u6587\u6863\u8981\u6C42\u7701\u7565\u6216\u4F20\u7A7A\u5BF9\u8C61\u3002"),
|
|
5955
|
+
body: z.union([z.record(z.string(), z.unknown()), z.array(z.unknown())]).optional().describe("Action \u6587\u6863\u5B9A\u4E49\u7684\u8BF7\u6C42\u4F53\uFF0C\u5FC5\u987B\u4FDD\u6301\u6587\u6863\u89C4\u5B9A\u7684\u5BF9\u8C61\u6216\u6570\u7EC4\u7ED3\u6784\u3002"),
|
|
5956
|
+
_outputMode: z.enum(["basic", "full"]).optional().describe("\u6587\u6863\u5141\u8BB8\u65F6\u9009\u62E9\u57FA\u7840\u7ED3\u679C basic \u6216\u5B8C\u6574\u7ED3\u679C full\u3002"),
|
|
5957
|
+
_extraDisplayFields: z.array(z.string().min(1)).min(1).optional().describe("\u7528\u6237\u660E\u786E\u8981\u6C42\u989D\u5916\u5C55\u793A\u4E14 Action \u6587\u6863\u652F\u6301\u7684\u5B57\u6BB5\u540D\u79F0\u3002")
|
|
5958
|
+
}).strict().describe("\u4E25\u683C\u6309\u7167 Action \u6587\u6863\u6784\u9020\u7684\u5D4C\u5957 query/body \u8BF7\u6C42\u5305\u3002"),
|
|
5959
|
+
user_confirmed: z.boolean().default(false).describe("\u53EA\u6709\u7528\u6237\u660E\u786E\u786E\u8BA4\u8BE5 Action \u6587\u6863\u6807\u6CE8\u7684\u5199\u64CD\u4F5C\u65F6\u624D\u80FD\u8BBE\u4E3A true\u3002"),
|
|
5960
|
+
dry_run: z.boolean().default(false).describe("\u662F\u5426\u4EC5\u6821\u9A8C\u5E76\u9884\u6F14\uFF0C\u800C\u4E0D\u5B9E\u9645\u6267\u884C\u4E1A\u52A1\u8BF7\u6C42\u3002"),
|
|
5900
5961
|
timeout_seconds: timeoutSchema
|
|
5901
5962
|
}),
|
|
5902
5963
|
annotations: {
|
|
@@ -5928,10 +5989,10 @@ function createLemonClawServer(options = {}) {
|
|
|
5928
5989
|
server.registerTool(
|
|
5929
5990
|
"lemon_invoice_read_doc",
|
|
5930
5991
|
{
|
|
5931
|
-
title: "
|
|
5932
|
-
description: "
|
|
5992
|
+
title: "\u8BFB\u53D6\u67E0\u6AAC\u4E91\u72EC\u7ACB\u5F00\u7968\u6587\u6863",
|
|
5993
|
+
description: "\u8BFB\u53D6 LemonClaw Runtime \u72EC\u7ACB\u5F00\u7968\u76EE\u5F55\u5185\u7684\u56FA\u5B9A\u6D41\u7A0B\u6587\u6863\uFF0C\u53EA\u5141\u8BB8\u8BBF\u95EE\u8BE5\u76EE\u5F55\u4E2D\u7684 Markdown\u3001JSON \u6216\u6587\u672C\u6587\u4EF6\uFF0C\u4E0D\u80FD\u8BFB\u53D6\u4EFB\u610F\u672C\u5730\u6587\u4EF6\u3002\u5E94\u5148\u8BFB\u53D6 SKILL.md\uFF0C\u518D\u6309\u5176\u6307\u5F15\u8BFB\u53D6\u7ACB\u5373\u5F00\u7968\u3001\u6279\u91CF\u5F00\u7968\u3001\u95EE\u9898\u53CD\u9988\u53CA\u5171\u4EAB\u89C4\u5219\u6587\u6863\u3002",
|
|
5933
5994
|
inputSchema: z.object({
|
|
5934
|
-
path: z.string().min(1).describe("
|
|
5995
|
+
path: z.string().min(1).describe("\u5F00\u7968\u76EE\u5F55\u5185\u7684\u76F8\u5BF9\u6587\u6863\u8DEF\u5F84\uFF0C\u4F8B\u5982 SKILL.md \u6216 references/immediate/flow.md\u3002")
|
|
5935
5996
|
}),
|
|
5936
5997
|
annotations: readOnlyAnnotations
|
|
5937
5998
|
},
|
|
@@ -5947,8 +6008,8 @@ function createLemonClawServer(options = {}) {
|
|
|
5947
6008
|
server.registerTool(
|
|
5948
6009
|
"lemon_invoice_api",
|
|
5949
6010
|
{
|
|
5950
|
-
title: "
|
|
5951
|
-
description: "
|
|
6011
|
+
title: "\u8C03\u7528\u67E0\u6AAC\u4E91\u72EC\u7ACB\u5F00\u7968\u63A5\u53E3",
|
|
6012
|
+
description: "\u6309\u7167\u72EC\u7ACB\u5F00\u7968\u6D41\u7A0B\u6587\u6863\u8C03\u7528\u56FA\u5B9A\u7684\u5F00\u7968\u63A5\u53E3\uFF0C\u652F\u6301\u516C\u53F8\u548C\u5BA2\u6237\u67E5\u8BE2\u3001\u767B\u5F55\u4EFB\u52A1\u72B6\u6001\u3001\u7A0E\u5C40\u8BA4\u8BC1\u72B6\u6001\u3001\u5269\u4F59\u989D\u5EA6\u3001\u7A0E\u76EE\u89E3\u6790\u3001\u7A0E\u5C40\u8BA4\u8BC1\u94FE\u3001\u6B63\u5F0F\u5F00\u7968\u53CA\u95EE\u9898\u53CD\u9988\u3002\u8C03\u7528\u524D\u5FC5\u987B\u8BFB\u53D6\u5BF9\u5E94\u6D41\u7A0B\u6587\u6863\u3002\u6B63\u5F0F\u5F00\u7968\u4EC5\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u4E14\u5FC5\u9700\u4E0A\u4E0B\u6587\u5B8C\u6574\u65F6\u6267\u884C\uFF1B\u4E0D\u5F97\u901A\u8FC7\u53C2\u6570\u4F20\u9012 API Key\u3001Token \u6216\u5176\u4ED6\u8BA4\u8BC1\u51ED\u636E\u3002",
|
|
5952
6013
|
inputSchema: z.object({
|
|
5953
6014
|
operation: z.enum([
|
|
5954
6015
|
"CompanyFullList",
|
|
@@ -5962,7 +6023,7 @@ function createLemonClawServer(options = {}) {
|
|
|
5962
6023
|
"TaxBureauAuthChain",
|
|
5963
6024
|
"SkillInvoiceIssue",
|
|
5964
6025
|
"FeedbackSubmit"
|
|
5965
|
-
]),
|
|
6026
|
+
]).describe("\u8981\u6267\u884C\u7684\u56FA\u5B9A\u5F00\u7968\u64CD\u4F5C\uFF0C\u5FC5\u987B\u6765\u81EA\u5DF2\u8BFB\u53D6\u7684\u5BF9\u5E94\u6D41\u7A0B\u6587\u6863\u3002"),
|
|
5966
6027
|
eiscid: optionalText,
|
|
5967
6028
|
filter_word: optionalText,
|
|
5968
6029
|
company_name: optionalText,
|
|
@@ -5971,9 +6032,8 @@ function createLemonClawServer(options = {}) {
|
|
|
5971
6032
|
uscic: optionalText,
|
|
5972
6033
|
auth_company_id: optionalText,
|
|
5973
6034
|
company_detail_id: optionalText,
|
|
5974
|
-
payload: z.record(z.string(), z.unknown()).optional(),
|
|
5975
|
-
payload_path: optionalText,
|
|
5976
|
-
api_key_last_four: optionalText,
|
|
6035
|
+
payload: z.record(z.string(), z.unknown()).optional().describe("\u5BF9\u5E94\u64CD\u4F5C\u6587\u6863\u5B9A\u4E49\u7684\u8BF7\u6C42\u6570\u636E\uFF0C\u4E0D\u5F97\u6DFB\u52A0\u8BA4\u8BC1\u51ED\u636E\u3002"),
|
|
6036
|
+
payload_path: optionalText.describe("\u5BF9\u5E94\u6D41\u7A0B\u6587\u6863\u5141\u8BB8\u8BFB\u53D6\u7684\u672C\u5730\u8BF7\u6C42\u6570\u636E\u6587\u4EF6\u8DEF\u5F84\u3002"),
|
|
5977
6037
|
ai_tool: optionalText,
|
|
5978
6038
|
model: optionalText,
|
|
5979
6039
|
feedback_contact: optionalText,
|
|
@@ -5984,7 +6044,7 @@ function createLemonClawServer(options = {}) {
|
|
|
5984
6044
|
message_id: optionalText,
|
|
5985
6045
|
context: optionalText,
|
|
5986
6046
|
upload_file_path: optionalText,
|
|
5987
|
-
user_confirmed: z.boolean().default(false),
|
|
6047
|
+
user_confirmed: z.boolean().default(false).describe("\u4EC5\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u6B63\u5F0F\u5F00\u7968\u6216\u6587\u6863\u6807\u6CE8\u7684\u5199\u64CD\u4F5C\u540E\u8BBE\u4E3A true\u3002"),
|
|
5988
6048
|
timeout_seconds: timeoutSchema
|
|
5989
6049
|
}),
|
|
5990
6050
|
annotations: {
|
|
@@ -6005,12 +6065,12 @@ function createLemonClawServer(options = {}) {
|
|
|
6005
6065
|
server.registerTool(
|
|
6006
6066
|
"lemon_invoice_run_helper",
|
|
6007
6067
|
{
|
|
6008
|
-
title: "
|
|
6009
|
-
description: "
|
|
6068
|
+
title: "\u8FD0\u884C\u67E0\u6AAC\u4E91\u72EC\u7ACB\u5F00\u7968\u8F85\u52A9\u7A0B\u5E8F",
|
|
6069
|
+
description: "\u8FD0\u884C\u72EC\u7ACB\u5F00\u7968\u6D41\u7A0B\u5185\u7F6E\u7684\u56FA\u5B9A\u767D\u540D\u5355\u8F85\u52A9\u7A0B\u5E8F\uFF0C\u7528\u4E8E Excel \u6216\u6570\u636E\u6587\u4EF6\u89E3\u6790\u3001JSON \u6821\u9A8C\u3001\u53D1\u7968\u9884\u89C8\u751F\u6210\u3001\u9884\u89C8\u670D\u52A1\u3001\u5BA2\u6237\u67E5\u8BE2\u53CA\u5BA2\u670D\u4FE1\u606F\u8F93\u51FA\u3002\u672C\u5DE5\u5177\u4E0D\u80FD\u6267\u884C\u4EFB\u610F\u7CFB\u7EDF\u547D\u4EE4\u3001\u4EFB\u610F Python \u811A\u672C\u6216\u767D\u540D\u5355\u4E4B\u5916\u7684\u7A0B\u5E8F\uFF1Boperation \u548C\u53C2\u6570\u5FC5\u987B\u6765\u81EA\u5DF2\u8BFB\u53D6\u7684\u5F00\u7968\u6D41\u7A0B\u6587\u6863\u3002",
|
|
6010
6070
|
inputSchema: z.object({
|
|
6011
|
-
operation: z.enum(invoiceHelperNames),
|
|
6012
|
-
arguments: z.array(z.string()).max(30).default([]),
|
|
6013
|
-
stdin: z.string().optional(),
|
|
6071
|
+
operation: z.enum(invoiceHelperNames).describe("\u8981\u8FD0\u884C\u7684\u767D\u540D\u5355\u8F85\u52A9\u64CD\u4F5C\uFF0C\u5FC5\u987B\u6765\u81EA\u5DF2\u8BFB\u53D6\u7684\u5F00\u7968\u6D41\u7A0B\u6587\u6863\u3002"),
|
|
6072
|
+
arguments: z.array(z.string()).max(30).default([]).describe("\u6309\u5BF9\u5E94\u6D41\u7A0B\u6587\u6863\u987A\u5E8F\u63D0\u4F9B\u7684\u8F85\u52A9\u7A0B\u5E8F\u53C2\u6570\uFF0C\u6700\u591A 30 \u9879\u3002"),
|
|
6073
|
+
stdin: z.string().optional().describe("\u4EC5\u5728\u5BF9\u5E94\u6D41\u7A0B\u6587\u6863\u8981\u6C42\u65F6\u4F20\u5165\u7684\u6807\u51C6\u8F93\u5165\u6587\u672C\u3002"),
|
|
6014
6074
|
timeout_seconds: timeoutSchema
|
|
6015
6075
|
}),
|
|
6016
6076
|
annotations: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lemonbeijing/lemonclaw-mcp-service",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "用于查询和操作柠檬云 Lemon Cloud 业务数据的 MCP 服务,覆盖账套、进销存 SCM、业财 ERP、财务 ACC 和独立开票;支持客户、供应商、商品、仓库、采购、销售、库存、收付款、往来、凭证、账簿、发票及经营与财务报表,并支持立即开票、批量开票和问题反馈。",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|