Security-first MCP gateway for Odoo 17/18/19
odoo-mcp-gateway
Security-first, version-agnostic MCP gateway for Odoo 17/18/19. Works with stock and custom modules via YAML configuration. Zero Odoo-side code required.
Why This Exists
Existing Odoo MCP servers share common problems: hardcoded model lists that miss custom modules, security as an afterthought, mandatory custom Odoo addons, and single-version targets. This gateway solves all of them:
- Two-layer security — MCP restrictions (YAML) + Odoo's built-in ACLs (ir.model.access + ir.rule)
- YAML-driven configuration — model restrictions, RBAC, field-level access, rate limiting, audit logging
- Custom module support — auto-discovers models via
ir.model, add YAML config and it works - Version-agnostic — Odoo 17, 18, 19 with version-specific adapters
- Zero Odoo-side code —
pip install+ YAML config = done. No custom addon required - Full MCP primitives — 27 Tools + 5 Resources + 7 Prompts (most servers only implement Tools)
- Plugin architecture — extend with pip-installable domain packs via entry_points
Architecture
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/ --> 27 MCP tools (auth + schema + CRUD + plugins)
|-- resources/ --> 5 MCP resources (odoo:// URIs)
|-- prompts/ --> 7 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)
Security Pipeline
Every tool and resource call passes through this pipeline:
Request --> Rate Limit --> Authentication Check --> RBAC Tool Access
--> Model Restriction --> Method Restriction --> Field Validation
--> Handler Execution --> RBAC Field Filtering --> Audit Log --> Response
Hardcoded safety guardrails that cannot be overridden by YAML:
- 18 always-blocked models (ir.config_parameter, ir.cron, ir.module.module, ir.rule, ir.mail_server, etc.)
- 18 always-blocked methods (sudo, with_user, with_env, _sql, _write, _create, etc.)
- 28 ORM methods blocked in execute_method (prevents bypassing field-level checks)
Quick Start
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 Configuration
Add to claude_desktop_config.json:
{
"mcpServers": {
"odoo": {
"command": "python",
"args": ["-m", "odoo_mcp_gateway"],
"env": {
"ODOO_URL": "http://localhost:8069",
"ODOO_DB": "mydb"
}
}
}
}
Claude Code Configuration
# Add as MCP server
claude mcp add odoo -- python -m odoo_mcp_gateway
Environment Variables
| Variable | Default | Description |
|---|---|---|
ODOO_URL |
http://localhost:8069 |
Odoo server URL |
ODOO_DB |
(required) | Odoo database name |
MCP_TRANSPORT |
stdio |
Transport mode (stdio or streamable-http) |
MCP_HOST |
127.0.0.1 |
HTTP host (streamable-http mode) |
MCP_PORT |
8080 |
HTTP port (streamable-http mode) |
MCP_LOG_LEVEL |
INFO |
Logging level |
Security
Two-Layer Security Model
- MCP gateway restrictions (YAML config + hardcoded guardrails) — blocks sensitive models, dangerous methods, privileged fields before any Odoo call is made
- Odoo's built-in ACLs — enforces per-user access on actual records via
ir.model.accessandir.rule
Model Restriction Tiers
| Tier | Effect | Example |
|---|---|---|
always_blocked |
Nobody can access, including admins | ir.config_parameter, res.users.apikeys |
admin_only |
Only admin users | ir.model, ir.model.fields |
admin_write_only |
Read OK for all, write needs admin | res.company, res.currency |
Hardcoded Safety Guardrails
These cannot be overridden by YAML conf
Tools (1)
loginAuthenticate with the Odoo serverEnvironment Variables
ODOO_URLOdoo server URLODOO_DBrequiredOdoo database nameMCP_TRANSPORTTransport mode (stdio or streamable-http)MCP_HOSTHTTP host (streamable-http mode)MCP_PORTHTTP port (streamable-http mode)MCP_LOG_LEVELLogging levelConfiguration
{"mcpServers": {"odoo": {"command": "python", "args": ["-m", "odoo_mcp_gateway"], "env": {"ODOO_URL": "http://localhost:8069", "ODOO_DB": "mydb"}}}}