# cityengine-mcp — CityEngine 云端能力 MCP Server

把 CityEngine 云端插件网关（`https://api.cityengine.cn`）的 CGA 解析 / NL2CGA /
一句话生成三维模型能力封装成 [MCP](https://modelcontextprotocol.io) 工具，
让 kimi code / codex / Claude Desktop 等大模型客户端直接调用。

- 传输：stdio（本机子进程）
- 依赖：Python ≥ 3.10，`mcp` 1.x（FastMCP）、`httpx`
- 性质：只调用计算型只读端点（生成/解析/查询），无任何写操作，不改官网数据

## 工具清单

| 工具 | 说明 | 计费 |
|---|---|---|
| `generate_cga` | 自然语言 → CGA 规则源码（同步，不渲染）；支持 `base_cga + instruction` 二次修改 | nl2cga 额度 |
| `parse_cga` | CGA 源码 + 属性 → 引擎解析 → 三维模型统计 + glb 下载（sha256 校验） | generate 额度 |
| `generate_model` | 自然语言 → 一键出三维模型（NL2CGA + 解析串联），同时返回 cga_source | nl2cga + generate |
| `list_demos` | 列出官网首页 demo 案例（id/名称/引擎/属性数） | 免费 |
| `get_demo` | 查看 demo 属性面板定义、节点/材质数、引擎耗时（CGA 源码为付费内容，不返回） | 免费 |
| `get_quota` | 查询当前 key 的套餐与额度用量 | 免费 |

## 安装

方式一：pip 包（推荐）

```bash
python3 -m venv ~/.venvs/cityengine-mcp
~/.venvs/cityengine-mcp/bin/pip install /path/to/cityengine-mcp   # 或 dist/cityengine_mcp-0.1.0-py3-none-any.whl
# 安装后得到命令 cityengine-mcp
```

方式二：源码直跑

```bash
python3 -m venv .venv && .venv/bin/pip install "mcp>=1.9,<2" httpx
PYTHONPATH=. .venv/bin/python -m cityengine_mcp.server
```

## 获取 API Key

两种方式（得到 `cvk_` 前缀的插件 Key）：

1. 官网用户中心：注册/登录 <https://www.cityengine.cn> → 用户中心「插件 Key」→ 签发
   （完整 Key 只显示一次，立即保存）。
2. 网关自助注册（命令行）：

```bash
curl -X POST https://api.cityengine.cn/v1/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"强密码","nickname":"可选昵称"}'
# 响应里的 api_key 即插件 Key（仅此一次完整显示）
```

额度：免费版 NL 生成 5 次/月、模型生成 100 次/日；付费会员 NL 不限。

## 配置

环境变量：

| 变量 | 必填 | 默认 | 说明 |
|---|---|---|---|
| `CITYENGINE_API_KEY` | 是 | — | 插件 API Key |
| `CITYENGINE_GATEWAY_BASE` | 否 | `https://api.cityengine.cn` | 网关地址（UAT 可改 `https://gen.uat.cityengine.cn`） |
| `CITYENGINE_DEMOS_BASE` | 否 | `https://www.cityengine.cn` | demo 清单来源站 |
| `CITYENGINE_OUTPUT_DIR` | 否 | `./cityengine_mcp_output` | glb 落盘目录 |
| `CITYENGINE_MAX_POLL_S` | 否 | `300` | 渲染 job 轮询上限（秒） |

### kimi code

项目级：把 `config-examples/kimi-code.mcp.json` 复制为项目根目录 `.kimi-code/mcp.json`，
填入 Key 与绝对路径（首次启动需在信任提示中确认；headless 模式设
`KIMI_CODE_TRUST_WORKSPACE=1`）。用户级：放 `~/.kimi-code/mcp.json`。
TUI 内 `/mcp` 查看连接状态。工具名形如 `mcp__cityengine__generate_model`。

### codex

把 `config-examples/codex.config.toml` 内容追加到 `~/.codex/config.toml`，改路径与 Key。

### Claude Desktop

把 `config-examples/claude_desktop_config.json` 的 `mcpServers` 段合并进
`claude_desktop_config.json`（macOS `~/Library/Application Support/Claude/`），
改路径与 Key 后重启客户端。

## 故障排查

- `NO_API_KEY`：环境变量没传进子进程。kimi/Claude 用配置里的 `env` 段；codex 用
  `[mcp_servers.cityengine.env]` 表。确认填的是完整 `cvk_` Key。
- `401 UNAUTHORIZED`：Key 已吊销/过期，重新签发。
- `402 QUOTA_EXHAUSTED`：套餐额度耗尽（NL 5/月 或 generate 100/日），等重置或升级。
- `429 RATE_LIMITED / QUEUE_FULL`：限流，server 已内置按 Retry-After 退避重试；
  仍失败就等一分钟。
- `504 UPSTREAM_LLM_TIMEOUT`：NL2CGA 走了 LLM 兜底且超时，换个更具体的描述重试。
- `CGA_COMPILE_ERROR / CGA_EXECUTION_ERROR`：CGA 源码问题，按 message 修规则再试。
- 工具一直没返回：渲染 job 在排队/解析中，默认最长等 300s；复杂规则请控制规模
  （勿用帕特农级大场景做试测）。
- glb 下载报 `SHA256_MISMATCH`：传输损坏，重试即可（下载地址 24h 有效）。

## 目录

```
cityengine_mcp/server.py      MCP server 单文件实现（FastMCP, stdio）
pyproject.toml                pip 包定义（console script: cityengine-mcp）
config-examples/              kimi-code / codex / Claude Desktop 配置示例
tests/stdio_smoke.py          stdio 客户端冒烟（真实 MCP 协议逐工具调用）
tests/evidence-*/             实测证据（输入/输出 JSON + 下载的 glb）
kimi-recognition-test/        kimi CLI 实测识别记录
```
