MCP server · Odoo 16 → 19+

The Odoo MCP that is fluent in every Odoo version.

Turn any Odoo 16+ database into a Model Context Protocol server with credentials you already have. No App Store module. No permission setup. No admin access. Safe writes, real diagnostics, JSON-2 ready years before the Odoo 22 XML-RPC removal.

Read the docs
claude — odoo-mcp · production
Show me all customers from Spain with unpaid invoices.
search_records(model="res.partner", domain=[["country_code","=","ES"]], …)
aggregate_records(model="account.move", groupby=["partner_id"], …)
23 partners · €148,220.00 outstanding — 2 calls, 0.6s, read-only
Audit the custom_billing addon for upgrade risks before we move to Odoo 19.
scan_addons_source(path="./addons/custom_billing")
upgrade_risk_report(target="19.0")
3 blocking · 7 warnings — XML-RPC call sites flagged with JSON-2 payload previews
39
MCP tools
1619
Odoo versions
0
Odoo-side setup steps
854
Tests + real Odoo stacks
MIT
License, since day one
01 /

More than CRUD. A fieldwork kit for Odoo agents.

›_

Read & aggregate, server-side

Search, read, and group records with smart field selection that drops audit, binary, and compute noise. aggregate_records pushes sum/count/avg into Postgres.

Safe writes, by design

Direct create/write/unlink are blocked. Approved writes need live metadata, a same-session token, explicit confirmation, and an env gate.

Multi-instance routing

One server, several named Odoo instances. Optional instance parameter on every tool, instance-bound approval tokens, per-instance schema caches.

Real diagnostics

diagnose_odoo_call, diagnose_access, relationship inspection, fit/gap and business-pack reports — answers why a call failed, not just that it did.

JSON-2 ready, years early

XML-RPC for Odoo 16–18, External JSON-2 for 19+. generate_json2_payload previews the migration body for any legacy call before Odoo 22 removes XML-RPC.

Audit trail & chatter

One JSONL line per write-path event with token digests. chatter_post reaches any mail.thread under the same approval gate as writes.

Addon & upgrade analysis

Scan local addon source, flag upgrade risks per target version, and resolve model renames across releases — built for migration consulting work.

Resilient by default

Read-only calls retry with exponential backoff, schema caches are TTL- and LRU-bounded, and health_check flags N+1 read loops before they hurt.

10 MCP workflow prompts

End-to-end business process workflows — invoice approval chain, PO-to-receipt, customer onboarding, expense claim review, accounting close checklist, plus diagnostic and migration prompts. Write-bearing steps route through the gated workflow automatically; no prompt engineering required.

Field-level ACL (open-source first)

Deny or allowlist individual Odoo fields per model per instance — enforced server-side across search_records, read_record, aggregate_records, and the BM25 knowledge index. Sensitive columns never reach the agent context. Fail-closed: a malformed policy aborts startup rather than running unprotected.

Cross-instance fan-out

Query multiple Odoo databases in one call — AR/AP aging across a whole client portfolio, margin sweeps by region, module/version census. Three tools: search_across_instances, aggregate_across_instances, accounting_health_across_instances. Partial-failure contract, per-source field ACL, bounded concurrency. The only open-source MCP server with this.

Background tasks

submit_async_task runs long addon scans, knowledge indexing, and AR/AP aging on a bounded worker pool — the agent keeps reasoning and polls for results. Writes never run async.

Local-first knowledge search

index_knowledge + search_knowledge: BM25 relevance ranking over your records, accent-insensitive, fully in-process. No embeddings service, no data leaving the machine.

Σ

Accounting pack

receivable_payable_aging buckets open items by days overdue with per-partner totals; accounting_health_summary reports AR/AP counts and draft backlog. Read-only, Odoo 16+.

02 /

Your ERP is not a sandbox.

Most Odoo bridges hand agents direct create / write / unlink — one hallucinated ID away from corrupting production books. Odoo MCP treats every write as a transaction that must earn its execution.

With ODOO_MCP_ELICIT_WRITES=1, the human sees a native MCP confirmation form with a diff summary before anything executes. Every event lands in a JSONL audit log.

Reads stay instant and unrestricted — the gate only exists where the risk does.

preview_write

The agent proposes a change; the server fetches live field metadata and renders a diff.

validate

Values checked against fields_get — wrong types and unknown fields fail before touching Odoo.

approval token

A same-session, instance-bound token is issued. It cannot be replayed across sessions or instances.

execute_approved_write

Runs only with the token, explicit confirmation, and ODOO_MCP_ENABLE_WRITES=1 set in the environment.

odoo-mcp — write gate
Set credit_limit = 999999 on res.partner #42.
write(model="res.partner", id=42, vals={…})
Direct write blocked — approval workflow required.
preview_write → diff built from live fields_get
validate → 1 field OK, types match schema
approval token issued — session + instance bound
execute_approved_write → 1 record updated — ODOO_MCP_ENABLE_WRITES=1
03 /

Why this one, not the other bridges.

Odoo MCPTypical MCP-Odoo bridge
odoo-side setup0 steps — existing credentials on any Odoo 16+Install an App Store module, enable models, grant per-tool permissions
writesToken + live validation + confirm + env gateDirect create/write/unlink, or a "yolo" bypass
transportXML-RPC and External JSON-2 — ready for the Odoo 22 removalXML-RPC only (deprecated since 19, removed in 22)
diagnostics7 diagnostic & analysis tools, migration helpersCRUD only
multi-instanceNamed instances, per-tool routing, isolated tokens & cachesOne global connection per process
cross-instance fan-out3 tools — AR/AP aging, aggregates, search across all DBs; open-source firstNot available
workflow prompts10 MCP prompts encoding full business processes with gated writes & human checkpointsNot available
field-level ACLDeny/allow fields per model per instance — enforced server-side, fail-closed; open-source firstNot available
measured latency (head-to-head, Odoo 19 Docker, XML-RPC)search_records 9.9 ms p50; read_record 9.0 ms; list_models 16.8 ms. aggregate_records 12.8 ms — competitor faster at 9.4 ms. Full methodology →search_records 22.4 ms; read_record 10.9 ms; list_models 19.6 ms; aggregate_records 9.4 ms. Note: v0.6.0 has a ~12 s/call regression in Claude Desktop (issue #68).
testingDocker harness boots real Odoo 16/17/18/19 stacks per releaseMock-based only

Comparing a specific project? See the per-project breakdown in docs/comparison.md.

04 /

Plugs into the agents you already run.

Copy-paste-runnable adapters ship in examples/ — stdio for local clients, Streamable HTTP for everything else.

05 /

Five minutes. Either path.

For humans

Run the wizard

It asks for your Odoo URL, database, and credentials, tests the connection live, and prints ready-to-paste snippets for Claude Code, Cursor, and Claude Desktop.

$ uvx odoo-mcp --setup # or: pip install odoo-mcp # quick smoke check: uvx odoo-mcp --health

Prefer a container? Docker images on GHCR →

For AI agents

Paste one line

Tell Claude Code, Cursor, Codex — any coding agent — to install it for you. Machine-readable instructions ship in the repo.

$ claude mcp add odoo \ --env ODOO_URL=https://mycompany.odoo.com \ --env ODOO_DB=mycompany \ --env ODOO_USERNAME=agent@mycompany.com \ --env ODOO_PASSWORD=your-api-key \ -- uvx odoo-mcp

Agent install guide: llms-install.md →