Skip to main content
Glama
YanSir1999

kingdee-mcp

by YanSir1999
README.md
# 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

B3/5.0

Scored across 8 tools

Disambiguation2/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivitySlowing
ResponsivenessNo issues