内容
# icount-mcp
iCount 的多租户 **MCP 服务器** (适用于 [icount.co.il](https://www.icount.co.il/))—— 提供 29 种工具,用于发票、收据、客户、费用和供应商管理。
- **可流式传输的 HTTP** 传输,基于 **Cloudflare Workers** (共享一个 URL,任何拥有 iCount API 令牌的人都可以使用)。
- **无状态多租户**:每个请求都携带自己的 `Authorization: Bearer <icount_token>` 和 `X-Icount-Cid: <company_id>` 头部。服务器不存储任何数据。
- **Dry-run 沙盒**,通过 `X-Icount-Dry-Run: 1` 实现——写入工具记录将要发送的负载,而不是实际发送。
- **本地标准输入/输出模拟**,用于个人使用,无需部署。
---
## 快速部署
```bash
git clone <此仓库>
cd icount-mcp
npm install
npx wrangler login # 一次性浏览器流程
# 必需:生成 OAuth 加密密钥(32 个随机字节,base64)。
node -e 'console.log(crypto.randomBytes(32).toString("base64"))'
npx wrangler secret put OAUTH_ENCRYPTION_KEY # 粘贴密钥
npx wrangler deploy
```
这将为您提供 `https://icount-mcp.<您的子域名>.workers.dev`。OAuth 加密密钥允许 Worker 发布和验证 Claude Desktop 的“添加自定义连接器”对话框的访问令牌。
### 可选:使用共享密钥保护 URL
```bash
npx wrangler secret put MCP_ACCESS_KEY
# 粘贴任意随机字符串
```
客户端现在必须在每个请求中发送 `X-Mcp-Key: <该字符串>`。
---
## 连接 MCP 客户端
每个用户提供自己的 iCount 凭证——服务器永远不会存储它们。
### 获取 iCount API 令牌
1. 登录 iCount。
2. **设置 → API** (אזור הגדרות → API)。
3. 生成令牌。复制同一页面上显示的公司 ID(`cid`)。
### 选项 1(推荐)—— Claude Desktop “添加自定义连接器”
Worker 支持 OAuth 2.1,具有一个巧妙的转折:对话框的 `OAuth Client ID` 字段是 **iCount API 令牌**,而 `OAuth Client Secret` 是 **iCount CID**。实际上没有 OAuth 提供程序——Worker 只需将您的两个值加密成一个自包含的访问令牌,并在每个请求中解密。
在 Claude Desktop 中,**设置 → 连接器 → 添加自定义连接器**:
- **网址:** `https://icount-mcp.<您的子域名>.workers.dev`
- **OAuth 客户端 ID:** 您的 iCount API 令牌
- **OAuth 客户端密钥:** 您的 iCount CID
点击连接。OAuth 握手完成后,29 个 `icount_*` 工具将出现在聊天工具选择器中。
### 选项 2 — 直接持有者(curl、脚本、Cursor 等)
对于非 OAuth 客户端,直接在头部发送凭证:
```http
POST https://icount-mcp.<您的子域名>.workers.dev
Authorization: Bearer 您的 ICOUNT_API_TOKEN
X-Icount-Cid: 您的 ICOUNT_COMPANY_ID
```
如果您设置了 URL 网关,请添加 `X-Mcp-Key: ...`,或添加 `X-Icount-Dry-Run: 1` 以测试无写入。
对于支持 HTTP 的 JSON 配置客户端(例如,通过 `mcp-remote`):
```json
{
"mcpServers": {
"icount": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://icount-mcp.<您的子域名>.workers.dev",
"--header", "Authorization: Bearer ${ICOUNT_API_TOKEN}",
"--header", "X-Icount-Cid: ${ICOUNT_CID}"
],
"env": { "ICOUNT_API_TOKEN": "...", "ICOUNT_CID": "..." }
}
}
}
```
---
## 本地开发
### 在本地运行 Worker
```bash
npm run dev # 在 http://localhost:8787 上启动 wrangler dev
```
将 [MCP Inspector](https://github.com/modelcontextprotocol/inspector) 指向 `http://localhost:8787`,并使用上述相同的头部。使用 `X-Icount-Dry-Run: 1` 开发工具,而不消耗实际的 iCount 积分。
要仅为本地开发设置 `MCP_ACCESS_KEY`,请创建 `.dev.vars` 文件:
```
MCP_ACCESS_KEY=本地开发密钥
```
Wrangler 会自动读取 `.dev.vars` 文件。不要提交它。
### 作为本地标准输入/输出运行(无 HTTP)
```bash
cp .env.example .env
# 填写 ICOUNT_API_TOKEN、ICOUNT_CID
npm run stdio
```
或直接在支持标准输入/输出的 MCP 客户端中注册:
```json
{
"mcpServers": {
"icount": {
"command": "npx",
"args": ["tsx", "/绝对路径/to/icount-mcp/src/stdio.ts"],
"env": {
"ICOUNT_API_TOKEN": "...",
"ICOUNT_CID": "...",
"ICOUNT_DRY_RUN": "0"
}
}
}
}
```
---
## 工具目录(30)
所有工具均以 `icount_` 为前缀。注释(`readOnlyHint`、`destructiveHint`、`idempotentHint`)已设置,以便客户端可以决定何时确认。
### 文档(10)
- `icount_doc_create` — 创建发票 / 收据 / 费用凭证 / 退款 / 订单 / 报价 / 交付 / 交易
- `icount_doc_get` — 按 ID 或 docnum 获取
- `icount_doc_search` — 日期范围、客户、状态、自由文本
- `icount_doc_list` — 分页(别名:doc_search)
- `icount_doc_get_url` — 主机 PDF URL
- `icount_doc_send_email` — (重新)通过电子邮件发送现有文档
- `icount_doc_cancel` — 销毁(对税务发票颁发信用凭证)
- `icount_doc_close` — 标记为已支付 / 已关闭
- `icount_doc_convert` — 报价 → 订单 → 发票
- `icount_doc_update_income_type`
### 客户(11)
- `icount_client_create` / `_update` / `_upsert`(按 vat_id 或 email)
- `icount_client_get` / `_delete` / `_list`
- `icount_client_get_open_docs`
- `icount_client_get_contacts` / `_add_contact` / `_update_contact` / `_delete_contact`
### 费用(4)
- `icount_expense_create`
- `icount_expense_search`
- `icount_expense_types` (列出类别)
- `icount_expense_doctypes` (列出供应商文档类型)
### 供应商(4)
- `icount_supplier_get` / `_list` / `_add` / `_update`
### 账户(1)
- `icount_account_info` — 连接性检查
---
## 注意事项和限制
- **速率限制:** iCount 限制为 **每分钟 30 个请求/令牌**。客户端以 `Retry-After` 值显示 429;客户端应退避或批量处理。
- **Dry-run 范围:** 写入被短路(返回 `DRY-*` 合成负载);读取仍然命中真实 API。这允许您在不冒修改风险的情况下测试连接。
- **税务发票取消:** `icount_doc_cancel` 从代理的角度是不可逆的——对于税务发票,iCount 在后台颁发信用凭证。始终与用户确认。
- **货币和增值税:** 项目按 **增值税前** 单位价格发送;iCount 根据您的账户增值税率计算总额。使用 `vat_excluded:true` 每项标记免税行。
- **希伯来语字符串** 不更改。RTL 格式化由调用者负责。
## 许可证
MIT。