内容
# MCP 服务器 — Odoo SaaS
MCP(模型上下文协议)服务器,用于连接 AI 助手到任意 Odoo SaaS 实例,通过原生 JSON-2 REST API(`/json/2`,Odoo 19+)。要切换实例,只需更改两个环境变量 — 无需特定于客户的代码,也无需在 Odoo 上安装额外的模块。
请注意,此 MCP 会映射新字段和特定功能。
```
用户 → Claude → MCP 服务器(此仓库)→ Odoo SaaS(JSON-2 API)
```
服务器将 Odoo 公开为一组工具和资源,供 LLM 使用。通过自然语言,模型可以搜索、创建、更新、删除记录并调用工作流方法 — 自动链接操作。
## 差异
### 1. Odoo 19+ 的正确 API
大多数 Odoo 的 MCP 服务器使用 XML-RPC,这是一种遗留协议,Odoo 在 19.1 版本中已从 SaaS 中删除(Odoo 20 中也将从 Odoo.sh/on-prem 中删除)。此服务器使用 JSON-2(`POST {url}/json/2/{model}/{method}`,带有 `Authorization: Bearer <API_KEY>`),这是当前的官方标准 — 无需单独的 `authenticate`,无需 db/uid,无需 XML。
### 2. 按操作(动词)而非模型/端点划分工具
工具不是按每个模型或端点划分,而是按 ORM 操作(动词)划分,模型仅作为参数。分离轴是动作,而不是对象。
### 3. 运行时读取模式,从不假设
服务器不会在代码中嵌入字段/模型列表。当需要模式时,它会询问基础(`odoo_fields_get`,`odoo_list_models`,资源 `odoo://model/{model}`)。它适用于任何基础 — 带有自定义模块和字段(`x_studio_*`)— 并且永远不会过时。
### 4. 只读保护
`ODOO_MCP_READONLY=true` 在服务器级别阻止所有写操作(创建、写入、删除、调用方法)— 对演示或仅限读取的集成很有用。
### 5. 零额外模块 + 延迟连接
不需要在 Odoo 上安装额外的模块(使用标准的用户 API 密钥)。并且在启动时不会触及基础:它会在工具的第一次调用(延迟客户端)时连接。
## 工具
### 读取
| 工具 | 描述 |
| --- | --- |
| `odoo_search_read(模型, 域, 字段, 限制, 偏移, 顺序)` | 在一次调用中搜索和读取 |
| `odoo_search_count(模型, 域)` | 统计域中的记录 |
| `odoo_read(模型, id, 字段)` | 按 ID 读取字段 |
| `odoo_fields_get(模型, 属性)` | 字段模式 |
| `odoo_list_models(名称筛选, 限制)` | 列出模型(来自 `ir.model`) |
### 写入(如果 `ODOO_MCP_READONLY=true` 则被阻止)
| 工具 | 描述 |
| --- | --- |
| `odoo_create(模型, 值)` | 创建记录,返回 ID |
| `odoo_write(模型, id, 值)` | 更新记录 |
| `odoo_unlink(模型, id)` | 删除记录(**不可逆**) |
| `odoo_call_method(模型, 方法, id, 参数)` | 调用任意方法(例如 `action_confirm`) |
`odoo_call_method`:`id` 是目标记录;`参数` 是方法的其他命名参数。例如:`odoo_call_method("sale.order", "action_confirm", ids=[42])`。
## 资源
| URI | 描述 |
| --- | --- |
| `odoo://models` | 所有模型的列表(markdown) |
| `odoo://model/{model}` | 模型的模式(markdown) |
## 域(过滤器)
Odoo 语法:元组列表 `[字段, 操作符, 值]`,带有逻辑运算符 `&`(和,默认),`|`(或),`!`(非),使用波兰表示法。
```python
[["customer_rank", ">", 0], ["country_id.code", "=", "BR"]]
["|", ["state", "=", "draft"], ["state", "=", "sale"]]
```
## 快速配置
环境变量:
```env
ODOO_URL=https://您的企业.odoo.com
ODOO_API_KEY=您的 API 密钥
ODOO_MCP_READONLY=false # 可选,默认为 false
```
API 密钥在 Odoo 中生成:**首选项 → 账户安全 → 新的 API 密钥**。
Claude Desktop 的最小块(`claude_desktop_config.json`):
```json
{
"mcpServers": {
"odoo": {
"command": "python",
"args": ["C:\\path\\to\\odoo_mcp\\server.py"],
"env": {
"ODOO_URL": "https://您的企业.odoo.com",
"ODOO_API_KEY": "您的 API 密钥"
}
}
}
}
```
> 完整的逐步指南(venv、API 密钥、Claude Code via `.mcp.json`、烟雾测试、首次使用):请参阅 **[`SETUP.md`](SETUP.md)**。
## MCP 与直接访问 API
MCP 的替代方法是查询 Odoo 实例的 `/doc`(列出所有模型和字段)并手动构建 REST 调用。MCP 不止于此:
| | /doc + 手动 REST | MCP 服务器(此仓库) |
|---|---|---|
| 模式发现 | 您读取,您解释 | LLM 调用 `odoo_fields_get` 自动 |
| 执行 | 您构建请求,执行,读取响应 | LLM 直接执行工具 |
| 链接 | 您在每次响应后决定下一步 | LLM 在无干预的情况下链接操作 |
| 身份验证/标头 | 您在每次调用中包含 | 隐藏 — 在 `OdooClient` 中一次性解决 |
| 错误 | 您解释并决定 | LLM 解释并纠正路径 |
**具体示例:** 在不存在的公司中创建两个联系人。
- **通过 /doc 手动:** 打开 /doc → 查找 `res.partner` → 读取字段 → 创建公司 → 验证 ID → 创建联系人 1 → 创建联系人 2。您手动操作每一步。
- **通过 MCP:** LLM 搜索公司,确定它不存在,创建它,并关联两个联系人 — 所有操作都是自动的,无需您手动干预。
价值不仅在于语法:它是 **代理** — LLM 执行而不是简单地查询。
## 结构
```
odoo_mcp/
server.py # FastMCP:9 种工具 + 2 种资源
odoo_client.py # REST /json/2 客户端(Bearer,错误)
config.py # 环境变量(URL + API 密钥)
requirements.txt
.env.example
tools/generate_docs.py
docs/
README.md # 业务模型文档索引
*.md # 按模型文档(res.partner,sale.order,…)
generated/ # 实例模式快照(.gitignore)
.mcp.json.example # Claude Code 配置模板
```
核心业务模型的文档位于 **[`docs/README.md`](docs/README.md)**。
## 安全
- 通过环境变量进行身份验证 — 绝不写入代码。
- API 密钥继承关联的 Odoo 用户的权限;在生产环境中使用具有最小范围的专用用户。
- `ODOO_MCP_READONLY=true` 用于只读环境。
- `odoo_unlink` 永久删除 — 请确认 ID。
- 生产环境中强制使用 HTTPS(Odoo SaaS 默认)。
- `.env` 和 `.mcp.json` 位于 `.gitignore` 中 — 切勿版本控制密钥。