使用说明
Odoo MCP连接器
该项目是一个MCP(模型上下文协议)连接器,它允许大型语言模型(LLM)代理与Odoo Online(SaaS)API交互。它充当一个安全的桥梁,暴露了一组受控的“工具”,LLM可以使用这些工具在Odoo中执行操作。
📝 概述
目标是使LLM能够安全有效地管理Odoo资源。这是通过创建一个中间MCP服务器来实现的,该服务器将代理的意图转换为对Odoo的经过验证的、安全的API调用。这种方法避免了将Odoo的原始API暴露给代理,并强制执行严格的治理。
🎯 目标体系结构
数据从LLM代理流到Odoo,并通过MCP堆栈返回:
LLM Agent ⇄ MCP Client ⇄ Odoo MCP Server ⇄ Odoo Online API (JSON-RPC)
在引擎盖下,服务器启动了一个自包含的 模型上下文协议 具有内存事件存储的主机。本地运行连接器不需要额外的服务——MCP 客户端可以直接指向提供的WebSocket端点。
🔑 主要特点
- 安全第一:所有操作都受严格的安全策略控制,包括模型、字段和方法的白名单。写入操作需要
plan → dry_run → confirm在Odoo发生突变之前。 - 执行模式:确认流在工具中以本机方式实现:代理必须执行操作(
plan),请求人工批准(dry_run),并最终执行(confirm)与返回action_id. - 抽象层:连接器仅通过JSON-RPC传输与Odoo通信,向代理隐藏身份验证、重试和错误处理细节。
- 控制活动:只有精心策划的MCP工具列表(例如。,
odoo.search_read,odoo.create)暴露。每个工具在点击Odoo之前都会根据本地白名单验证模型、字段和参数。 - LLM友好界面:MCP工具声明指导代理的JSON模式。响应通过隐藏配置的字段自动屏蔽PII(个人身份信息)。
- 可审计性:对Odoo的所有请求都使用确定性请求标识符进行记录,内存中的操作存储跟踪谁计划、批准和确认了每个突变。
- 独立的MCP运行时:轻量级主机和事件存储被捆绑在一起,因此连接器可以在没有外部SDK依赖的情况下运行。在持久事件存储(例如Postgres)中进行交换只需要更新主机引导程序。
🚀 入门指南
先决条件
- A. Node.js 环境(v18或更高版本)。
- 一 Odoo在线 具有API访问权限的订阅(通常为“自定义”计划)。
- 一 API密钥 对于具有必要权限的Odoo用户。
安装
- 克隆存储库:
git clone <repository-url> cd odoo-mcp-connector - 安装依赖项:
npm install
配置
-
创建一个
.env项目根目录中的文件。连接器在启动时会自动加载它。 -
将您的Odoo连接详细信息添加到
.env文件:ODOO_URL=https://your-company.odoo.com ODOO_DB=your-company-db ODOO_USERNAME=your-service-user@example.com ODOO_API_KEY=your-super-secret-api-key
运行服务器
要启动MCP服务器,请运行:
npm run dev
默认情况下,连接器在以下位置公开一个符合MCP的WebSocket端点 ws://localhost:3000/mcp.以下环境
变量可用于调整监听器:
| 变量 | 默认值 | 描述 |
|---|---|---|
PORT |
3000 |
用于绑定HTTP服务器的TCP端口。 |
HOST |
0.0.0.0 |
绑定侦听器的接口地址。 |
MCP_PATH |
/mcp |
升级到MCP WebSocket传输的HTTP路径。 |
HTTP服务器还公开了一个 GET /health 可用于准备状态检查的端点。每个WebSocket客户端必须发送一个
initialize 发出请求之前(根据模型上下文协议) tools/list 或 tools/call 请求:工具调用
通过以下方式流式传输回客户端 tools/stream 当发生以下情况时,会发出通知,随后是终端JSON-RPC响应
执行完成。
运行测试
该项目依赖于Node的内置测试运行器以及 ts-node 支持TypeScript。执行完整的单元测试
套房,运行:
npm test
该命令发现所有 *.test.ts 文件下 tests/ 目录并执行它们。包含 npm test 作为你的一部分
CI管道,以确保Odoo连接器、屏蔽逻辑和确认工作流程仍由自动回归覆盖
测验。
🧰 已实施的工具
以下MCP工具随连接器一起提供。标记为的参数 * 是必需的。
| 工具 | 类别 | 重要参数 | 执行模式 |
|---|---|---|---|
odoo.version |
阅读 | (无) | plan 不需要-即发即弃 |
odoo.models |
阅读 | (无) | plan 不需要 |
odoo.me |
阅读 | (无) | plan 不需要 |
odoo.search_read |
阅读 | model*, domain, fields, limit, order |
plan 不需要 |
odoo.get |
阅读 | model*, id*, fields |
plan 不需要 |
odoo.count |
阅读 | model*, domain |
plan 不需要 |
odoo.create |
写 | model*, values*, mode*, action_id |
plan → dry_run → confirm |
odoo.write |
写 | model*, ids*, values*, mode*, action_id |
plan → dry_run → confirm |
odoo.unlink |
写 | model*, ids*, mode*, action_id |
plan → dry_run → confirm |
odoo.call_kw |
商业 | model*, method*, args, kwargs, mode*, action_id |
plan → dry_run → confirm |
当工具支持执行模式时,代理必须:
- 调用该工具
mode="plan"接收摘要和action_id. - 重新播放该工具
mode="dry_run"请求批准。响应包括批准元数据并屏蔽PII字段。 - 最后执行
mode="confirm"和原件action_id。在调用Odoo之前,操作存储会强制有效载荷与批准的模拟运行相匹配。
内存中存储了使用MCP客户端元数据启动和批准每个步骤的记录。时间戳以ISO-8601格式返回以供审核。
🛡️ 安全与治理
- 白名单:只能访问预先批准的模型、字段和方法。这
src/config.ts文件定义ALLOWED_MODELS,WRITABLE_MODELS,以及BUSINESS_METHOD_WHITELIST工具使用的列表。 - 确认流程:所有写入操作(
create,write,unlink)以及敏感的业务逻辑调用(call_kw)需要确认序列。每个阶段都会记录发起它的参与者,如果自模拟运行以来有效载荷发生了变化,则确认拒绝运行。 - PII屏蔽:连接器在将个人身份信息返回给代理之前会屏蔽该信息。配置
PII_FIELDS数组src/config.ts扩展或缩小掩码字段。 - 日志记录:对Odoo的每次调用都会记录一个确定性的SHA-256请求指纹,这使得端到端跟踪请求变得容易。
- 访问验证:试运行阶段调用
checkAccessRights在确认之前,验证当前服务帐户是否可以执行所请求的写入。
配置参考
您可以通过编辑来定制代理可以做什么 src/config.ts:
ALLOWED_MODELS–定义每个模型公开的字段及其是否可写。BUSINESS_METHOD_WHITELIST–枚举可通过调用的模型方法odoo.call_kw.PII_FIELDS–列出响应中应屏蔽的字段名。MAX_LIMIT/DEFAULT_LIMIT–读取操作的大写分页。
修改配置以获取更改后重新部署服务器。典型的治理调整不需要修改代码。
🗺️ 路线图
- [x] 第一阶段:核心读写功能
- [x] 实现为连接器供电的经过身份验证的Odoo JSON-RPC客户端。
- [x] 定义并实施只读工具(
search_read,get,version). - [x] 使用内存中的事件存储设置MCP服务器。
- [x] 实施写入工具(
create,write)与aplan → dry_run → confirm机制。
- [ ] 第二阶段:高级功能和安全
- [x] 实施
unlink和call_kw严格的白名单。 - [x] 为所有响应添加强大的PII屏蔽。
- []实施全面的日志记录和速率限制。
- [x] 具有确定性请求标识符的结构化请求/响应日志记录。
- []MCP工具调用的速率限制。
- [x] 实施
- [ ] 第3阶段:测试和部署
- [x] 添加执行现场清理和确认工作流程的单元测试。
- []添加针对演示Odoo实例的集成测试。
- []将应用程序Docker化以进行部署。
- []记录如何将服务器连接到MCP客户端(例如Claude Desktop)。
- [ ] 第4阶段:API发展
- [x] 添加对JSON-RPC作为主要传输层的支持。
- []通过设计一个抽象来为Odoo 20做准备,该抽象可以适应未来的REST或GraphQL API。
🤝 贡献
欢迎投稿!请打开一个问题来讨论您的想法或提交一个pull请求。
