odoo-safe-mcp
Provides a deterministic security firewall between AI agents and Odoo ERP (v14 to v19+), using Odoo's JSON-RPC/XML-RPC API for safe reads and guarded/approval-gated writes. Enforces traffic-light policies: GREEN read methods execute instantly; YELLOW draft creations are audited; RED destructive methods (unlink, action_post, action_confirm, button_validate, write on account.move) pause for human approval; BLACKLIST mutations on sensitive models are blocked.
Sends interactive Approve/Reject buttons to Slack for RED critical Odoo operations, enabling human-in-the-loop authorization before destructive or accounting-sensitive mutations are executed.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@odoo-safe-mcp Show me all unpaid customer invoices from last month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π‘οΈ Odoo Safe MCP β let AI work in Odoo, with a human in control
Connect Claude, Cursor, n8n or your own agents to Odoo 14 β 20 through a deterministic firewall:
reads run instantly, drafts are guarded, and anything critical (write, unlink, confirming orders,
posting invoicesβ¦) waits for a person on your team to approve it from their phone β seeing exactly what
will change. Your Odoo credentials never leave your machine.
Why
Odoo 20 ships its own MCP server, and there are several community ones. They connect AI to your ERP;
none of them answers "who approves what the AI does?". An API key that can read quotes can also
unlink customers or action_post invoices to the tax authority. One hallucination or one
prompt-injected email is enough.
Odoo Safe MCP is the control layer:
π’ Reads |
|
π‘ Guarded drafts |
|
π΄ Critical | Everything else waits for a human on Slack or Teams, who sees the real records, before β after values and amounts β not just the agent's own explanation. |
β Never | Users, groups, access rules, API keys, system parameters, settings, modules, server actionsβ¦ blocked even with a paid licence. |
Related MCP server: OdooSurface MCP
How approvals work (zero-credential)
AI agent ββMCPβββΊ odoo-safe-mcp (your machine, holds the Odoo API key)
β 1. builds a preview from Odoo: records, before β after, amount
β 2. sends the Guard ONLY: operation JSON + SHA-256 + preview (no URL, no user, no key)
βΌ
Guard cloud ββcardβββΊ approver on Slack / Teams / web
β 3. signs the decision (Ed25519) bound to that exact SHA-256, database and licence
βΌ
odoo-safe-mcp verifies the signature with a pinned public key, checks the hash
matches the operation it proposed, executes ONCE with your credentials, reports the audit.A compromised cloud cannot make your machine run anything it did not propose itself. No tunnels: it works the same with Odoo Online, Odoo.sh and on-premise.
Quickstart (3 minutes)
In Odoo, create a user for the AI (e.g.
ai-bot, with an email) with only the business rights it needs, and generate an API key for it (Preferences β Account Security).Run the guided setup β it checks the connection and permissions and writes the Claude Desktop / Cursor config:
uvx odoo-safe-mcp initRestart your AI client and ask "How many open quotations do we have?"
Manual configuration (claude_desktop_config.json or .cursor/mcp.json):
{
"mcpServers": {
"odoo": {
"command": "uvx",
"args": ["odoo-safe-mcp@3.0.0"],
"env": {
"ODOO_URL": "https://your-company.odoo.com",
"ODOO_DB": "your-database",
"ODOO_USERNAME": "ai-bot@your-company.com",
"ODOO_API_KEY": "the_bot_api_key",
"ODOO_SAFE_GUARD_KEY": "optional_pro_licence"
}
}
}
}Diagnose anything with uvx odoo-safe-mcp doctor. On Windows use http://127.0.0.1:<port> rather than
localhost for local instances (about 20Γ faster).
Tools exposed to the agent
Tool | What it does |
| Read records (paginated, long texts trimmed to save tokens) |
| Totals and counts grouped by fields ( |
| Discover models and fields before writing |
| Any ORM method through the firewall, with an optional |
| Check a pending approval and execute it once approved |
Read tools carry readOnlyHint; write tools destructiveHint. Blocks are returned as MCP errors so
agents understand they failed.
Plans
Plan | Price | What you get |
Community | Free (MIT) | Firewalled reads, secret redaction, dry-run simulation ( |
Pro Guard | β¬49 / month | Up to 5 databases, guarded drafts, human approvals on Slack/Teams/web with previews, audit log, kill-switch, AI Defender |
Business | β¬149 / month | Up to 10 databases, Microsoft Teams, your own Slack app (in-Slack buttons). Need more? Contact us |
Get a licence at odoosafemcp.stream.
Security & testing
Every rule is covered by an exhaustive policy matrix (~1,750 model Γ method Γ licence combinations) and a regression test for each vulnerability found during our own red-teaming.
A real testbed starts Odoo 14 β 20 in Docker with a least-privilege bot and runs the integration suite; an end-to-end suite runs the real Guard Worker locally and proves, among other things, that the Guard database never contains Odoo credentials and that signed approval links cannot be forged, reused or swapped.
Report vulnerabilities privately to soporte@odoosafemcp.stream.
Compatibility
Built for Odoo 14 β 20 (Community & Enterprise, Online / Odoo.sh / on-premise), Python 3.10 β 3.14 and
any MCP client (Claude Desktop, Cursor, Windsurf, VS Code, n8n, custom agents). name_get is emulated on
Odoo 17+, and Chatter notes use body_is_html where required.
Odoo | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Live integration suite (real Odoo in Docker) | β | β | β | β | β | β | β |
End-to-end approvals with the real Guard | β | β | β | β | β | β | β |
Last full run: 20 Oct 2026, 0 failures. Odoo 20 needs an API key with the RPC scope; aggregations are
translated to its new read_group API automatically.
License & disclaimer
MIT. Provided "as is", without warranties. Odoo Safe MCP is an auxiliary control layer: it does not replace Odoo's access rights, backups or accounting review, and the person who approves an operation is its authoriser. Liability is capped at the fees paid in the month preceding the event. Read-only operations never transit our cloud; approval previews are encrypted at rest and purged on resolution.
Not affiliated with, sponsored or endorsed by Odoo S.A. "Odoo" is a trademark of Odoo S.A.; "Slack" of Slack Technologies, LLC; "Microsoft Teams" of Microsoft Corporation.
Available Tools
8 toolsodoo_aggregateARead-onlyIdempotent
Aggregate records (read_group): totals and counts grouped by fields. Read-only.
Example: model='sale.order', groupby=['state'], fields=['amount_total:sum'].
Inputs: model (required), groupby (required), limit, domain, +1 more. Returns: result
odoo_approval_statusADestructive
Check a write that is waiting for human approval. If it has been approved, it is executed now (once) and the result is returned. If rejected or expired, nothing is changed in Odoo.
Inputs: intent_id (required). Returns: result
odoo_countCRead-onlyIdempotent
Count Odoo records matching a domain. Read-only.
Inputs: model (required), domain. Returns: result
odoo_describe_modelARead-onlyIdempotent
Describe a model's fields (label, type, relation, required, readonly). Use before writing.
Inputs: model (required). Returns: result
odoo_execute_kwADestructive
Safely execute any Odoo ORM method (execute_kw) through the firewall.
Reads run immediately. Draft creations (sale.order, purchase.order, crm.lead) run under the guarded-draft policy. Critical operations (write, unlink, confirm, post...) wait for a human approval on Slack/Teams and are executed here only after a signed decision.
Args: model: Odoo technical model name (e.g. 'sale.order', 'res.partner', 'account.move'). method: ORM method name (e.g. 'search_read', 'create', 'write', 'action_confirm'). args: Positional arguments (domains, record ids, value dictionaries). kwargs: Keyword arguments (e.g. {'fields': ['name'], 'limit': 10}). justification: One honest sentence on why (shown to the approver, marked as unverified).
Inputs: model (required), method (required), args, kwargs, +1 more. Returns: result
odoo_list_modelsBRead-onlyIdempotent
List installed business models (technical name and label), optionally filtered by text. Read-only.
Inputs: limit, search. Returns: result
odoo_readBRead-onlyIdempotent
Read specific Odoo records by id. Read-only.
Inputs: ids (required), model (required), fields. Returns: result
odoo_searchARead-onlyIdempotent
Search Odoo records and return their fields (search_read). Read-only.
Args: model: Technical model, e.g. 'res.partner', 'sale.order', 'account.move'. domain: Odoo domain, e.g. [["state", "=", "sale"], ["amount_total", ">", 1000]]. fields: Fields to return. Use odoo_describe_model to discover them; omit for all. limit: Max records (default 20, max 200). offset: Records to skip, for pagination. order: Sort, e.g. 'date_order desc'.
Inputs: model (required), limit, order, domain, +2 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelogβ¦
TDQS
Scored across 8 tools
Dedicated read/search/count/aggregate and metadata tools are clearly separated, and execute_kw is framed as the generic write/ORM path. Some overlap remains because execute_kw can also perform reads and approval_status both checks and may execute a pending write, but the descriptions make intended use fairly clear.
All names use the odoo_ prefix and snake_case, with predictable verb/resource ordering in describe_model, list_models, approval_status, and execute_kw. A few names are verb-only (search, read, count, aggregate) rather than full verb_noun, but the set remains readable and consistent.
Eight tools is well within the appropriate range for a general-purpose Odoo server. The split between read helpers, metadata discovery, approval handling, and generic execution is purposeful and each tool earns its place.
The surface covers discovery, querying, aggregation, and writes through execute_kw, including an approval workflow for critical operations. There are minor gaps such as no explicit pending-approval listing and CRUD being indirect via execute_kw, but the core lifecycle is reachable.
Maintenance
Related MCP Connectors
Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.
Read, write and run Odoo actions from any AI app, as each user, with approval rules per colleague.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Connect AI to Odoo ERP 14-20: search, create, update and manage records in natural language.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to interact with Odoo ERP systems through natural language to search records, create entries, update data, and manage business operations. Supports secure authentication and configurable access controls for production environments.Mozilla Public 2.0
- AlicenseAqualityBmaintenanceEnables AI agents to interact with Odoo ERP as the authenticated user, with tools for discovery, planning, and mutations bounded by user permissions.3665 npm2Apache 2.0
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with Odoo ERP via the external API. It supports listing models, describing schemas, searching, aggregating, creating, updating, deleting records, and invoking business methods, with a configurable permission matrix for safety.-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants like Claude, ChatGPT, and Copilot to connect to Odoo ERP, providing tools to search, read, create, and update any Odoo model such as partners, sales orders, invoices, and products.11 npmAGPL 3.0