mcpField
O
Odoo Mcp Gateway

Odoo Mcp Gateway

本地服务
github.com/parth-unjiya商业与营销423 周前更新

关于 Odoo Mcp Gateway

Odoo Mcp Gateway 是面向 Odoo 17、18、19 的 MCP 网关,供需要通过 AI 客户端查询或修改 Odoo 数据的团队使用。它以 YAML 配置访问控制,并在网关限制之外保留 Odoo 自身的 ACL 检查,无需安装 Odoo 插件。

主要功能

  1. 01兼容 Odoo 17、18、19
  2. 02YAML 模型、字段与 RBAC 限制
  3. 03限流、审计日志和安全校验
  4. 04支持自定义模块模型发现
  5. 05记录查询、创建、更新与删除
  6. 06提供 MCP 工具、资源和提示词

适用场景

  1. 01通过 MCP 客户端查询 Odoo 记录
  2. 02按角色限制模型和字段访问
  3. 03在写入前预览默认值或执行 dry run
  4. 04为自定义模块配置访问规则

MCP 相关

它作为 MCP 服务连接 Odoo,并向客户端提供记录操作等工具、资源和提示词。支持 stdio 与 streamable-http 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"odoo-mcp-gateway": {
"command": "uvx",
"args": [
"odoo-mcp-gateway"
]
}
}
}
启动命令uvx odoo-mcp-gateway

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiodoo-mcp-gateway0.1.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

odoo-mcp-gateway

以安全为先、版本无关的 Odoo 17/18/19 MCP 网关。通过 YAML 配置即可支持标准模块和自定义模块,无需编写任何 Odoo 端代码。

Python 3.10+ License: MIT Odoo Tests Coverage

30 秒快速开始

pip install odoo-mcp-gateway

添加到 Claude Desktop 配置(claude_desktop_config.json):

{
  "mcpServers": {
    "odoo": {
      "command": "python",
      "args": ["-m", "odoo_mcp_gateway"],
      "env": {
        "ODOO_URL": "http://localhost:8069",
        "ODOO_DB": "your_database"
      }
    }
  }
}

重启 Claude Desktop。在任意对话中:

login with method "password", username "admin", credential "your_password"

连接成功。让 Claude 查询、创建或更新 Odoo 记录——每次调用都会受到速率限制、记录审计日志,并在到达 Odoo 前经过两层安全检查。

无需 Odoo 插件,也无需编写 Python 代码。 只需使用 YAML 配置进行精细的访问控制(可选——默认安全设置开箱即用)。

v0.2.1 新增内容

  • 暴力破解防护——按用户名(5 次/5 分钟)和来源(30 次/15 分钟)进行锁定
  • create_record、update_record、delete_record、execute_method 支持 dry_run 模式——验证但不执行
  • 新增 2 个工具:get_defaults(预览 Odoo 默认值)、get_onchange(预览字段副作用)
  • read_group 支持 时间分组:create_date:month、date:quarter 等
  • 强化屏蔽列表:32 个始终屏蔽的模型(原为 17 个)、29 个始终屏蔽的方法(原为 18 个)、10 个始终屏蔽的写入字段、8 个始终只读的模型
  • 通过 has_group('base.group_system') 进行 服务端管理员身份验证(此前信任认证响应)
  • 凭据包装器可防止通过 repr()/追踪信息泄露密码
  • JSON-RPC 重试仅在发生 OdooSessionExpiredError 时触发(此前每次认证错误都会重试)

完整的 21 项安全修复请参见 CHANGELOG.md。

为什么要开发这个项目

现有的 Odoo MCP 服务普遍存在一些问题:模型列表硬编码,无法涵盖自定义模块;安全性考虑不足;必须安装自定义 Odoo 插件;只支持单一版本。此网关解决了所有这些问题:

  • 双层安全——MCP 限制(YAML)+ Odoo 内置 ACL(ir.model.access + ir.rule)
  • YAML 驱动的配置——模型限制、RBAC、字段级访问控制、速率限制、审计日志
  • 支持自定义模块——通过 ir.model 自动发现模型,添加 YAML 配置即可使用
  • 版本无关——支持 Odoo 17、18、19,并提供特定版本的适配器
  • 无需 Odoo 端代码——pip install + YAML 配置即可完成,无需自定义插件
  • 完整的 MCP 基元——31 个工具 + 6 个资源 + 12 个提示词(大多数服务只实现工具)
  • 插件架构——通过 entry_points 使用可通过 pip 安装的领域扩展包进行扩展

架构

MCP Client (Claude Desktop / Claude Code / HTTP)
    |  User calls login tool with Odoo credentials
    v
MCP Server (FastMCP)
    |
    |-- security_gate()    --> Rate limit + RBAC tool access + audit logging
    |-- restrictions       --> Model/method/field block lists (YAML + hardcoded)
    |-- rbac               --> Field-level filtering + write sanitization
    |
    |-- tools/             --> 31 MCP tools (auth + schema + CRUD + workflow + plugins)
    |-- resources/         --> 6 MCP resources (odoo:// URIs)
    |-- prompts/           --> 12 reusable prompt templates
    |-- plugins/           --> Entry-point plugin system (HR, Sales, Project, Helpdesk)
    |
    |  JSON-RPC / XML-RPC as authenticated user
    v
Odoo 17/18/19 (security enforced per user via ir.model.access + ir.rule)
安全管道

每次工具和资源调用都会经过此管道:

Request --> Rate Limit --> Authentication Check --> RBAC Tool Access
    --> Model Restriction --> Method Restriction --> Field Validation
    --> Handler Execution --> RBAC Field Filtering --> Audit Log --> Response

无法通过 YAML 覆盖的硬编码安全防护措施:

  • 32 个始终禁止访问的模型 — 系统内部信息、身份验证/TOTP、支付令牌、附件、mail.mail、base.automation 等
  • 8 个始终只读的模型 — mail.message、mail.followers、mail.activity、discuss.channel、mail.notification、mail.compose.message、mail.alias、discuss.channel.member(所有人都可以读取,禁止写入)
  • 10 个始终禁止写入的字段 — password、password_crypt、groups_id、totp_secret、signup_token/type/expiration、api_key、share、active
  • 29 个始终禁止调用的方法 — sudo、with_user/env/context、_sql、_write、_create、name_create、load、import_data、export_data 等
  • execute_method 中禁止调用的 28 个 ORM 方法(防止绕过字段级检查)
  • 按用户名实施暴力破解锁定 — 失败 5 次后锁定 5 分钟(时长固定,无法延长)
  • 按来源实施暴力破解锁定 — 15 分钟内失败 30 次,防止轮换用户名攻击
  • 凭据包装类 — 使用防泄露的 __repr__/__str__ 存储密码,关闭时清除
  • 服务端管理员验证 — has_group('base.group_system') 优先于身份验证响应中的 is_admin

快速开始

pip install odoo-mcp-gateway

# Copy and edit config files
cp config/restrictions.yaml.example config/restrictions.yaml
cp config/model_access.yaml.example config/model_access.yaml
cp config/rbac.yaml.example config/rbac.yaml

# Set environment variables
export ODOO_URL=http://localhost:8069
export ODOO_DB=mydb

# Run (stdio mode for Claude Desktop / Claude Code)
python -m odoo_mcp_gateway

# Or HTTP mode for web clients
MCP_TRANSPORT=streamable-http python -m odoo_mcp_gateway
Claude Desktop 配置

添加到 claude_desktop_config.json:

{
  "mcpServers": {
    "odoo": {
      "command": "python",
      "args": ["-m", "odoo_mcp_gateway"],
      "env": {
        "ODOO_URL": "http://localhost:8069",
        "ODOO_DB": "mydb"
      }
    }
  }
}
Claude Code 配置
# Add as MCP server
claude mcp add odoo -- python -m odoo_mcp_gateway
环境变量
变量默认值描述
ODOO_URLhttp://localhost:8069Odoo 服务 URL
ODOO_DB(必填)Odoo 数据库名称
MCP_TRANSPORTstdio传输模式(stdio 或 streamable-http)
MCP_HOST127.0.0.1HTTP 主机(streamable-http 模式)
MCP_PORT8080HTTP 端口(streamable-http 模式)
MCP_LOG_LEVELINFO日志级别
CONFIG_DIR.YAML 配置文件目录
SESSION_TIMEOUT_SECONDS1800会话不活动超时时间
MAX_CONCURRENT_SESSIONS100最大并发会话数
RATE_LIMIT_GLOBAL60每分钟请求数(全局)
RATE_LIMIT_WRITE20每分钟写入操作数

安全

双层安全模型
  1. MCP 网关限制(YAML 配置 + 硬编码安全防护措施)——在调用任何 Odoo 接口之前,阻止访问敏感模型、危险方法和特权字段
  2. Odoo 内置 ACL ——通过 ir.model.access 和 ir.rule 对实际记录执行逐用户访问控制
模型限制等级
等级效果示例
always_blocked任何人都无法访问,包括管理员ir.config_parameter、res.users.apikeys
admin_only仅限管理员用户ir.model、ir.model.fields
admin_write_only所有人都可以读取,写入需要管理员权限res.company、res.currency
硬编码安全防护措施

这些措施无法通过 YAML 配置覆盖:

被屏蔽的模型(32 个):ir.config_parameter、res.users、res.users.apikeys、res.users.log、ir.cron、ir.module.module、ir.model.access、ir.rule、ir.mail_server、ir.ui.view、ir.actions.server、ir.logging、ir.attachment、ir.exports、ir.exports.line、iap.account、auth.totp.wizard、auth.totp.device、payment.token、payment.provider、base.automation、digest.digest、res.config.settings、change.password.wizard、change.password.user、base.module.update、base.module.upgrade、base.module.uninstall、fetchmail.server、bus.bus、mail.mail、mail.template

只读模型(8 个):mail.message、mail.followers、mail.activity、discuss.channel、mail.notification、mail.compose.message、mail.alias、discuss.channel.member(所有人都可以读取,但禁止写入)

禁止写入的字段(10 个):password、password_crypt、groups_id、totp_secret、signup_token、signup_type、signup_expiration、api_key、share、active

被屏蔽的方法(29 个):sudo、with_user、with_company、with_context、with_env、with_prefetch、_auto_init、_sql、_register_hook、_write、_create、_read、_setup_base、_setup_fields、_setup_complete、init、_table_query、_read_group_raw、name_create、load、import_data、export_data、flush_recordset、invalidate_recordset、_search_panel_select_range、_search_panel_select_multi_range、_search_panel_domain_image、_search、_read_progress_bar

其他安全功能
  • 暴力破解防护 — 按用户名锁定(失败 5 次 → 5 分钟),并按来源 IP/连接锁定(失败 30 次 → 15 分钟,防止轮换用户名攻击)。锁定时长固定,后续尝试无法延长锁定时间(可抵御 DoS)。
  • 凭据封装 — 密码/会话 ID 存储在 Credential 类中,该类提供防泄漏的 __repr__/__str__、用于取用凭据的显式 .reveal(),并在关闭时调用 .clear()
  • 服务端管理员验证 — 身份验证后,通过 has_group('base.group_system') 重新验证 is_admin,防止身份验证响应被篡改
  • 私有方法防护 — 以下划线开头的方法(_compute_*、_inverse_* 等)会被屏蔽,除非明确加入白名单,否则所有人(包括管理员)都无法使用
  • 速率限制 — 每个会话使用令牌桶,并分别设置全局和写入预算
  • 基于角色的访问控制(RBAC) — 按用户组控制工具级访问权限、按字段过滤响应,并通过 return_dropped=True 透明报告被丢弃的内容
  • 输入验证 — 验证模型名称、方法名称、字段名称、域筛选器、ORDER BY 子句、带时间运算符的 groupby,以及写入值(大小/深度/类型)
  • IDOR 防护 — 插件工具将数据访问范围限定为已通过身份验证的用户
  • 审计日志 — 为所有允许和拒绝的操作记录结构化 JSON 日志
  • 错误信息脱敏 — 从错误消息中移除内部 URL、SQL 片段、文件路径和堆栈跟踪
  • XXE 防护 — 使用 defusedxml 解析 XML-RPC 响应
  • 域验证 — 验证 Odoo 域筛选器中的运算符、字段名称、值类型、嵌套深度和列表大小
  • 会话过期重试 — 仅在出现 OdooSessionExpiredError 时重试 JSON-RPC,不重试一般身份验证错误(访问被拒时不会重复往返)

身份验证

Odoo 内置三种身份验证方法,无需自定义插件:

方法协议用途
api_keyXML-RPC服务器间通信、CI/CD 流水线
passwordJSON-RPC交互式用户、Claude Desktop
sessionJSON-RPC重用现有浏览器会话(开发)
# Example: login via the MCP tool
> login(method="password", username="admin", credential="admin", database="mydb")

核心 MCP 工具(13 个)

工具描述
login使用 Odoo 进行身份验证(api_key / password / session)
list_models列出可访问的模型及其元数据,并支持关键词筛选
get_model_fields获取模型的字段定义,并支持可选筛选
search_read使用域筛选、字段选择和排序来搜索记录
get_record根据 ID 获取单条记录
search_count统计符合条件的记录数
create_record创建新记录(支持仅用于验证的 dry_run)
update_record更新现有记录(支持仅用于验证的 dry_run)
delete_record根据 ID 删除单条记录(支持 dry_run)
read_group读取聚合分组数据,支持时间运算符(date:month、date:quarter 等)
get_defaults在调用 create_record 前预览 Odoo 默认值
get_onchange预览字段的副作用(并应用 RBAC 筛选)
execute_method调用允许的模型方法(支持 dry_run)

工作流工具(2 个)

工具描述
get_create_requirements在创建记录前获取必填字段和验证规则
get_record_actions获取现有记录可用的工作流操作

MCP 资源(6 个)

URI描述
odoo://models列出所有可访问的模型
odoo://models/{name}包含字段定义的模型详情
odoo://record/{model}/{id}单条记录数据,并应用 RBAC 字段筛选
odoo://schema/{model}包含类型信息和重要性排序的字段架构
odoo://categories模型分类及数量
odoo://workflow/{model}模型的工作流定义,包含阶段和操作

MCP 提示词(12 个)

提示词描述
analyze_model全面分析模型结构
explore_data自然语言数据探索指南
create_workflow引导完成特定模型的工作流
compare_records并排比较记录
generate_report生成分析报告
discover_custom_modules查找并了解自定义模块
debug_access排查访问和权限问题
workflow_guide模型工作流执行分步指南
record_creation_guide在字段验证的引导下创建记录
bulk_operations安全执行批量操作指南
field_mapping映射不同 Odoo 版本(v17/v18/v19)之间的字段
data_migration不同模型或版本之间的数据迁移指南

内置领域插件

HR 插件
工具描述
check_in记录考勤签到
check_out记录考勤签退
get_my_attendance查看考勤记录(支持按月份筛选)
get_my_leaves查看请假申请(支持按状态筛选)
request_leave提交请假申请
get_my_profile查看员工个人资料
Sales 插件
工具描述
get_my_quotations列出报价单/订单(支持按状态筛选)
get_order_details获取订单完整详情及明细项
confirm_order确认草稿/已发送的报价单
get_sales_summary汇总销售统计数据(支持按时间段筛选)
Project 插件
工具描述
get_my_tasks列出分配的任务(支持按状态/项目筛选)
get_project_summary项目统计:按阶段统计任务数及逾期任务
update_task_stage将任务移至其他阶段
Helpdesk 插件
工具描述
get_my_tickets列出分配的工单(支持按状态/优先级筛选)
create_ticket创建新的服务台工单
update_ticket_stage将工单移至其他阶段

自定义模块支持

无需编写 Python 代码即可添加自定义 Odoo 模块。编辑 model_access.yaml:

custom_models:
  full_crud:
    - custom.delivery.route
    - custom.warehouse.zone
  read_only:
    - custom.delivery.log

allowed_methods:
  custom.delivery.route:
    - action_dispatch
    - action_complete
    - action_cancel

之后,所有 CRUD 工具(search_read、create_record、update_record、delete_record)和 execute_method 都可以在自定义模型上运行,并强制执行完整的安全策略。

插件系统

通过可使用 pip 安装的插件扩展网关:

from odoo_mcp_gateway.plugins.base import OdooPlugin

class ManufacturingPlugin(OdooPlugin):
    @property
    def name(self) -> str:
        return "manufacturing"

    @property
    def required_odoo_modules(self) -> list[str]:
        return ["mrp"]

    @property
    def required_models(self) -> list[str]:
        return ["mrp.production", "mrp.bom"]

    def register(self, server, context):
        @server.tool()
        async def get_production_orders(...):
            ...

通过 pyproject.toml 入口点注册:

[project.entry-points."odoo_mcp_gateway.plugins"]
manufacturing = "my_package:ManufacturingPlugin"

配置文件

文件用途
config/restrictions.yaml模型/方法/字段阻止列表(3 个层级)
config/model_access.yaml按模型设置访问策略、允许的方法和敏感字段
config/rbac.yaml基于角色的工具访问权限,以及按组进行的字段过滤
config/gateway.yaml服务、连接和身份验证设置

所有文件都提供 .example 模板,并附有详尽的内联文档。复制并自定义:

cp config/restrictions.yaml.example config/restrictions.yaml
cp config/model_access.yaml.example config/model_access.yaml
cp config/rbac.yaml.example config/rbac.yaml
示例:限制模型
# restrictions.yaml
restrictions:
  always_blocked:
    - my.secret.model
  admin_only:
    - hr.salary.rule
  admin_write_only:
    - res.company
  blocked_write_fields:
    - password_crypt
    - api_key
    - totp_secret
示例:按组进行 RBAC
# rbac.yaml
rbac:
  tool_group_requirements:
    delete_record:
      - base.group_system
    execute_method:
      - base.group_erp_manager
  sensitive_fields:
    hr.employee:
      salary:
        required_group: hr.group_hr_manager

Docker

cp .env.example .env   # Edit with your Odoo settings
docker compose up

服务:

  • MCP 网关 — 端口 8080(streamable-http 模式)
  • Odoo 18 — 仅限内部访问(默认不向主机公开端口)
  • PostgreSQL — 仅限内部访问

网关在精简版 Python 镜像中以非 root 用户运行。

CLI 工具

# Test Odoo connectivity
odoo-mcp-tools test-connection --url http://localhost:8069

# Validate all YAML config files
odoo-mcp-tools validate-config --config-dir config

# List configured model access policies
odoo-mcp-tools list-models --config-dir config

开发

git clone https://github.com/parth-unjiya/odoo-mcp-gateway.git
cd odoo-mcp-gateway
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=odoo_mcp_gateway --cov-report=term-missing

# Lint
ruff check src/ tests/

# Type check (strict mode)
mypy src/
源码布局
src/odoo_mcp_gateway/
├── __main__.py                  # Entry point (stdio + HTTP)
├── server.py                    # FastMCP server setup, tool registration
├── config.py                    # Pydantic settings (env + .env)
├── client/
│   ├── base.py                  # OdooClientBase ABC, AuthResult
│   ├── jsonrpc.py               # JSON-RPC client (session auth)
│   ├── xmlrpc.py                # XML-RPC client (API key auth, defusedxml)
│   └── exceptions.py            # OdooError hierarchy (7 types)
├── core/
│   ├── auth/manager.py          # 3 auth strategies
│   ├── connection/manager.py    # Circuit breaker + retry
│   ├── version/                 # Odoo 17/18/19 detection + adapters
│   ├── workflow/
│   │   ├── definitions.py      # WorkflowDef, StateDef, TransitionDef dataclasses
│   │   ├── registry.py         # Workflow registration and lookup
│   │   └── stock_workflows/    # Built-in workflows (sale, purchase, HR, etc.)
│   ├── security/
│   │   ├── restrictions.py      # 3-tier model/method restrictions + hardcoded guardrails
│   │   ├── rbac.py              # Tool access + field filtering
│   │   ├── middleware.py        # Security pipeline + security_gate()
│   │   ├── rate_limit.py        # Token bucket rate limiter
│   │   ├── audit.py             # Structured audit logging
│   │   ├── sanitizer.py         # Error message sanitization
│   │   └── config_loader.py     # YAML config → Pydantic models
│   └── discovery/
│       ├── model_registry.py    # ir.model auto-discovery
│       ├── field_inspector.py   # fields_get with TTL cache
│       └── suggestions.py       # Category search + related models
├── tools/
│   ├── auth.py                  # login tool
│   ├── schema.py                # list_models, get_model_fields
│   ├── crud.py                  # search_read, create/update/delete, execute_method
│   └── workflow.py              # get_create_requirements, get_record_actions
├── resources/handlers.py        # 6 MCP resources (odoo:// URIs)
├── prompts/handlers.py          # 12 MCP prompt templates
├── plugins/
│   ├── base.py, registry.py     # Plugin ABC + entry_point discovery
│   └── core/                    # Built-in plugins (HR, Sales, Project, Helpdesk)
├── cli/tools.py                 # CLI: test-connection, validate-config
└── utils/                       # Domain builder, formatting, token budget

测试

1,476 项测试通过,代码覆盖率为 93%;mypy strict 检查干净,ruff 检查干净:

tests/unit/
├── client/          # JSON-RPC, XML-RPC, auth manager, XXE protection
├── security/        # Restrictions, RBAC, audit, rate limit, sanitizer, security_gate
├── discovery/       # Model registry, field inspector, suggestions
├── tools/           # All 13 MCP tools + input validation + dry_run
├── plugins/         # Plugin system + 4 domain plugins + IDOR protection
└── cli/             # CLI utility tools
# Run all tests
pytest tests/ -v

# Run specific area
pytest tests/unit/security/ -v
pytest tests/unit/tools/ -v
pytest tests/unit/plugins/ -v

# Coverage report
pytest tests/ --cov=odoo_mcp_gateway --cov-report=html

错误处理

所有 Odoo 错误分为 7 种类型:

错误原因
OdooConnectionError无法连接到 Odoo 服务
OdooAuthError凭据无效
OdooAccessErrorir.model.access 拒绝访问
OdooValidationError字段验证失败
OdooUserError业务逻辑错误
OdooMissingError找不到记录
OdooVersionError不支持的 Odoo 版本

所有错误消息在传递给 MCP 客户端之前都会经过净化处理,自动移除内部 URL、SQL 片段、文件路径和堆栈跟踪。

已知限制

  • XML-RPC 凭据处理:使用 API 密钥身份验证(XML-RPC)时,按照协议要求,每次 RPC 调用都会发送凭据。请在生产环境中使用 HTTPS。(注意:密码存储在 Credential 包装器中,可防止通过 repr()/回溯泄露。)
  • HTTP 模式的会话隔离:streamable-http 传输目前存在已知的会话隔离限制——_current_session_key ContextVar 在登录工具内部设置,但后续来自不同请求上下文的工具调用可能会回退到第一个可用会话。在 v0.3.0 引入按请求中间件之前,HTTP 模式仅限单租户部署(每个服务进程仅供一位用户使用)。stdio 模式在设计上采用单会话,不受影响。

贡献

  1. Fork 此仓库
  2. 创建功能分支(git checkout -b feature/my-feature)
  3. 编写测试并完成更改
  4. 确保所有检查均通过:pytest && ruff check src/ tests/ && mypy src/
  5. 提交 pull request

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。