kingdee-mcp
# Kingdee MCP
[English](README.en.md) | [中文](README.md)
金蝶云星空(K3Cloud)MCP Server。通过 [Model Context Protocol](https://modelcontextprotocol.io/) 让 AI 助手(Cursor、Claude Desktop、Claude Code、Cline、Cherry Studio 等)用自然语言查询和操作金蝶 ERP。已验证部署通过
```
AI 助手(Cursor / Claude / …)
│ MCP(stdio / SSE)
▼
kingdee-mcp
│ Kingdee Web API SDK
▼
金蝶云星空 K3Cloud
```
## 功能特性
- **15 个 MCP 工具**:查询、翻页/落盘/日期分片、查看详情、元数据;以及保存、提交、审核、反审核、删除、下推等
- **通用 `form_id`**:同一套工具适配物料、客户、销售/采购订单、出入库等表单
- **只读 / 读写模式**:`readonly` 时写入工具会从工具列表中移除(并保留运行时守卫)
- **自动会话恢复**:会话超时后自动重新登录
- **多传输协议**:`stdio`(本地 IDE)、`sse` / `streamable-http`(远程)
- **Docker 友好**:默认监听 `0.0.0.0:8181`,可对接阿里云 CLB 等负载均衡
## 环境要求
- Python 3.10+
- 可访问的金蝶云星空环境
- 集成用户账号(建议专用账号,按最小权限授权)
## 快速开始
### 1. 安装
```bash
git clone https://github.com/YanSir1999/kingdee-mcp.git
cd kingdee-mcp
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -e .
```
### 2. 配置环境变量
```bash
cp .env.example .env
```
编辑 `.env`:
| 变量 | 必填 | 说明 |
|------|------|------|
| `KD_SERVER_URL` | 是 | 金蝶地址,建议以 `/k3cloud/` 结尾 |
| `KD_ACCT_ID` | 是 | 账套 ID |
| `KD_USERNAME` | 是 | 集成用户账号 |
| `KD_PASSWORD` | 建议 | 密码(`ValidateUser` 登录) |
| `FASTMCP_HOST` | 否 | SSE 监听地址;Docker/CLB 用 `0.0.0.0` |
| `FASTMCP_PORT` | 否 | SSE 端口,默认 `8181` |
| `MCP_MODE` | 否 | `readonly`(默认)或 `readwrite` |
| `MCP_API_KEY` | 否 | SSE/HTTP Bearer Token;不设则不鉴权 |
| `MCP_ISSUER_URL` | 否 | 鉴权元数据对外 URL(启用 `MCP_API_KEY` 时) |
| `MCP_ALLOWED_HOSTS` | 否 | SSE Host 白名单,逗号分隔;解决远程 `421 Invalid Host header` |
### 3. 本地启动(stdio)
```bash
kingdee-mcp
# 或
kingdee-mcp --transport stdio --mode readonly
```
## 客户端配置
### Cursor(本地 stdio)
项目内 `.cursor/mcp.json` 示例:
```json
{
"mcpServers": {
"kingdee-mcp": {
"command": "D:\\workspace\\kingdee-mcp\\.venv\\Scripts\\kingdee-mcp.exe",
"cwd": "D:\\workspace\\kingdee-mcp"
}
}
}
```
凭证从项目根目录 `.env` 加载,无需写进 JSON。
### Cursor(远程 SSE)
```json
{
"mcpServers": {
"kingdee-mcp-remote": {
"url": "https://your-domain.example.com/sse"
}
}
}
```
若启用了 `MCP_API_KEY`:
```json
{
"mcpServers": {
"kingdee-mcp-remote": {
"url": "https://your-domain.example.com/sse",
"headers": {
"Authorization": "Bearer your-secret-api-key"
}
}
}
}
```
### Claude Desktop / 其他 MCP 客户端
```json
{
"mcpServers": {
"kingdee-mcp": {
"command": "kingdee-mcp",
"args": ["--mode", "readonly"],
"env": {
"KD_SERVER_URL": "https://your-server/k3cloud/",
"KD_ACCT_ID": "your_acct_id",
"KD_USERNAME": "your_username",
"KD_PASSWORD": "your_password"
}
}
}
}
```
## Docker 部署
### 构建镜像
```bash
docker build -t kingdee-mcp:local .
```
镜像默认:
- 传输:`sse`
- 模式:`readonly`
- 端口:`8181`
- 监听:`0.0.0.0`
### Compose
仓库已提供通用 `docker-compose.yml`(本地 `build`,无内网镜像地址):
```bash
docker compose up -d --build
```
### 阿里云 CLB
典型拓扑:
```
客户端 https://your-domain/sse
→ CLB(443)
→ 后端 ECS/容器 :8181
→ kingdee-mcp(SSE)
```
建议在 `.env` 中设置:
```env
FASTMCP_HOST=0.0.0.0
FASTMCP_PORT=8181
MCP_ALLOWED_HOSTS=your-domain.example.com,localhost:*,127.0.0.1:*
MCP_ISSUER_URL=https://your-domain.example.com
MCP_MODE=readonly
```
连通性自检:
```bash
curl -i -N -H "Accept: text/event-stream" https://your-domain.example.com/sse
```
正常应返回 `200` 与 `event: endpoint`。
## 可用工具
### 查询工具(`readonly` / `readwrite`)
| 工具 | 说明 |
|------|------|
| `query_bill` | 查询单据(二维数组) |
| `query_bill_json` | 查询单据(JSON,字段名为 key) |
| `count_bill` | 估算行数 |
| `query_bill_all` | 自动翻页拉取 |
| `query_bill_to_file` | 翻页流式落盘(ndjson/csv) |
| `query_bill_range` | 按日期分片 + 翻页 |
| `view_bill` | 单条详情 |
| `query_metadata` | 表单元数据 |
### 写入工具(仅 `readwrite`)
| 工具 | 说明 |
|------|------|
| `save_bill` | 保存/新增 |
| `submit_bill` | 提交 |
| `audit_bill` | 审核 |
| `unaudit_bill` | 反审核 |
| `delete_bill` | 删除 |
| `execute_operation` | 自定义操作(禁用/反禁用等) |
| `push_bill` | 下推 |
常用 `form_id` 示例:
| FormId | 说明 |
|--------|------|
| `BD_MATERIAL` | 物料 |
| `BD_Customer` | 客户 |
| `BD_Supplier` | 供应商 |
| `SAL_SaleOrder` | 销售订单 |
| `PUR_PurchaseOrder` | 采购订单 |
| `PRD_MO` | 生产订单 |
| `STK_InStock` / `STK_OutStock` | 入/出库单 |
## 只读模式
默认 `MCP_MODE=readonly`(或 `--mode readonly`):
1. 写入工具从 MCP 工具列表中**移除**
2. 即使被直接调用,也会返回 `只读模式:写入操作已禁用`
```bash
kingdee-mcp --mode readonly # 仅查询
kingdee-mcp --mode readwrite # 开放写入
```
## 自然语言示例
- 「查一下昨天的销售订单」
- 「查看采购订单 20260806JX-01」
- 「付款条件编码 023 是什么」
- 「统计本月销售订单数量」
## 调试
```bash
# MCP Inspector(远程 SSE)
npx @modelcontextprotocol/inspector https://your-domain.example.com/sse
# 单元测试
pip install -e ".[dev]"
pytest
```
## 项目结构
```
kingdee-mcp/
├── src/kingdee_mcp/
│ ├── server.py # MCP Server 与工具实现
│ └── form_id_reference.py # 常用 FormId 参考
├── tests/
├── Dockerfile
├── docker-compose.yml
├── .env.example
├── LICENSE
├── NOTICE
├── SECURITY.md
├── pyproject.toml
├── README.md
└── README.en.md
```
## 安全建议
- 不要将 `.env` 提交到 Git(详见 [SECURITY.md](SECURITY.md))
- 生产环境优先 `MCP_MODE=readonly`
- 远程 SSE 建议设置 `MCP_API_KEY`,并配置 `MCP_ALLOWED_HOSTS`
- 金蝶侧使用专用集成用户,按模块与数据范围最小化授权
## 致谢
核心能力与工具设计参考并受益于上游开源项目:
- [adamzhang1987/kingdee-k3cloud-mcp](https://github.com/adamzhang1987/kingdee-k3cloud-mcp)
- [Model Context Protocol Python SDK](https://github.com/modelcontextprotocol/python-sdk)
- [kingdee-cdp-webapi-sdk](https://pypi.org/project/kingdee-cdp-webapi-sdk/)
详见 [NOTICE](NOTICE)。
## 许可证
[Apache License 2.0](LICENSE)
TDQS
Scored across 8 tools
The query_bill family contains five tools (query_bill, query_bill_json, query_bill_all, query_bill_to_file, query_bill_range) with heavily overlapping purposes; query_bill and query_bill_json are completely undifferentiated and have no descriptions. While some tools have mode-specific suffixes, an agent could easily select the wrong one without deep inspection.
Tool names follow a consistent lowercase verb_noun pattern (query_, count_, view_), and the query_bill_* variants share a clear prefix. However, the naming doesn't fully clarify the differences between _all, _range, _to_file, and _json, and query_bill vs query_bill_json is ambiguous.
Eight tools is well-scoped for a specialized ERP data access server. Each tool serves a distinct operational mode (basic query, paginated query, date-range query, file export, count, detail, metadata), and the count feels neither thin nor bloated.
The read-query surface is comprehensive: multiple query modes, row counting, single-record detail, and metadata retrieval cover the expected needs for a Kingdee data query MCP. Minor gaps include a lack of form discovery (listing available form IDs) and no write/update operations, but these may be intentionally outside scope.