mcp-odoo: a self-hosted MCP server that puts Odoo 16+ behind an agent, with writes behind a gate
Odoo MCP for AI agents — gated writes, multi-instance. Hosted product: https://erpipe.com
At a glance
- What is it?
- The Python project erpipe-org/mcp-odoo exposes a 41-tool MCP surface over XML-RPC or Odoo's JSON-2 API, with an opt-in field ACL and a gated write workflow. It is the self-hosted counterpart to the author's hosted ERPipe gateway, and the split between the two is the first thing to understand.
- Who is it for?
- Adopt the self-hosted server if you run Odoo 16 or newer and want an agent reading and writing through your own credentials on your own machine, and you are willing to own the process, the config file and the audit file. Do not adopt it if you need ChatGPT on a stable remote URL, a human-in-the-loop inbox, or a dashboard audit trail; the README points those users at the hosted ERPipe gateway instead.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap mcp-odoo fills: Odoo's built-in AI is Enterprise-only
Odoo ships AI features in Enterprise editions only. The README states the project's position plainly: it gives Community and Enterprise 16 and above the same access for no licence cost, with whatever LLM the user already runs (it names Claude, GPT, Gemini, DeepSeek and Ollama). That framing matters because it defines the audience. This is not aimed at a company that already bought the Enterprise AI stack. It is aimed at teams on Community, or on older Enterprise versions, who want an agent to read their ERP data without building a bespoke XML-RPC client per question.
The second audience is narrower and easier to miss: partners and agencies operating many client databases. The README describes cross-instance queries as read-only fan-out across many client DBs with merged, attributed, partial-failure-tolerant results, and it explicitly says there is no warehouse and no sync. That is a different product from a single-tenant assistant. If you manage ten Odoo instances for ten clients, the interesting feature is not the record reader, it is that one server process can address all of them by name.
Two transports, chosen by Odoo version, not by configuration
The project speaks XML-RPC for Odoo 16 through 18 and External JSON-2 for Odoo 19 and later. The README frames this as being JSON-2 ready years before a planned Odoo 22 removal of XML-RPC. So the transport is a function of the target version rather than a setting you flip, which is a sensible default and also a constraint: if you are testing against a 19 instance while your production data sits on 17, you are exercising a different code path than the one that will run in production.
Above the transport sits the MCP surface: 41 tools and 11 prompts in this repository, against 43 tools and 7 prompts in the hosted product. The README's own comparison table makes the trade explicit. The local server has the larger prompt pack, including six end-to-end business workflows (invoice approval, PO match, onboarding, expense review, month-end close, pre-migration data quality) and those workflows route writes through the gate. The hosted product has more tools but fewer prompts, and adds workspace multi-instance handling plus governance.
Two mechanisms are worth calling out because they change what the agent can do rather than just how many endpoints exist. Background tasks: submit_async_task runs long read operations on a bounded worker pool, and the agent polls get_async_task while continuing to reason. The README names addon scans, knowledge indexing and AR/AP aging as the workloads this is for. Local-first knowledge search: index_knowledge and search_knowledge give BM25 relevance ranking over a bounded record slice, accent-insensitive and in-process, with no embeddings service and no data leaving the machine. BM25 over a bounded slice is a deliberate scope limit, not a general document search.
Field-level ACL is the part most Odoo integrations skip
The README claims this is the first open-source Odoo MCP with field-level ACL, and describes it as opt-in, per-instance and per-model, with allow and deny lists enforced on every read path: records, aggregates, the knowledge index, and resources. That last list is the substance of the claim. An access control layer that filters record reads but not aggregate results leaks the same numbers through a sum. The README says aggregates and the knowledge index are covered, which is the correct scope if the claim holds, and the implementation detail lives in docs/field-acl.md.
Note the word opt-in. Nothing in the supplied material says a default deny list ships with the server. If you enable the server and do not configure the ACL, the described behaviour is that no field filtering is applied. That is a reasonable design for a tool aimed at engineers who already control the Odoo user's permissions, since Odoo's own record rules and field groups still apply underneath. It is a poor fit for anyone who assumed the MCP layer adds a second wall by default.
Getting it running: uvx, a setup flag and a config file
The README gives the install as uvx odoo-mcp --setup and calls it a five-minute install with zero Odoo-side setup: no App Store module, no permission setup, no admin access required. The server runs over stdio or local HTTP, and the README also mentions Docker as a supported path without giving a compose file in the supplied text.
Configuration keys named in the material are ODOO_MCP_PLUGINS for loading third-party tool packages, ODOO_MCP_TOOLS_INCLUDE and ODOO_MCP_TOOLS_EXCLUDE for trimming the exposed tool surface per deployment, and ODOO_MCP_RATE_LIMIT_MODE with values warn or block for an opt-in sliding-window budget per instance and per tool. The rate limit state is surfaced in health_check, which is how you confirm it is active rather than assuming it.
Multi-instance support is described as a config file or environment variables on your machine, with an optional instance parameter on the tools. The README's table contrasts this with the hosted product, where you select an instance through a dashboard and pass an explicit instance key per tool. Locally, the instance parameter is optional, which means single-instance deployments never have to name it and multi-instance deployments have a default they need to be aware of. Audit is an optional JSONL file. Writes are described as an env gate plus approval tokens, with optional MCP elicitation, against the hosted product's default-off writes, HITL inbox, journal and field policy.
The write gate is weaker than the hosted product's, by design
This is the sharpest trade-off in the README and it is stated rather than hidden. The hosted gateway defaults writes to off and adds a human-in-the-loop inbox, a journal and a field policy. The self-hosted server uses an environment gate plus approval tokens, optionally with MCP elicitation. Those are not the same control. An env gate is a switch the operator sets; approval tokens are a mechanism the agent must satisfy; elicitation depends on the client supporting it. None of them is a default-off posture unless the operator makes it one.
So the honest reading is that the local server trusts the person running it. That is consistent with everything else in the design: your credentials, your machine, your config file, an optional audit file. If your threat model includes an agent that might write to the wrong record in a production database, the README's own comparison table is telling you which column to look at.
A second limitation is the knowledge index. BM25 over a bounded record slice is cheap and private, and it will not answer questions that require reasoning across the whole database. The README says bounded, and the bound is the point. Do not read search_knowledge as a substitute for Odoo's own reporting or for a warehouse.
Plugins, prompts and skills: three extension paths with different costs
Tool plugins let you ship your own tools as pip packages registered through odoo_mcp.tools entry points, opt-in via ODOO_MCP_PLUGINS, described as fail-isolated and requiring no fork. Fail-isolated is the claim to check in docs/plugins.md, because a plugin that raises during registration can otherwise take the whole server down at startup.
The prompt pack is a different kind of extension: 11 prompts in this repository, six of them full business workflows that route writes through the gate. Prompts are cheaper to change than tools and easier to get wrong, since a workflow prompt that assumes a field exists will fail at call time rather than at install time.
The third path is the Agent Skills pack, installed with npx skills add erpipe-org/mcp-odoo, described as four business-workflow skills (data-quality gate, migration copilot, month-end close, agency fleet review). The README points at a separate 21-skill dev suite, odoo-ai-skills, for people developing on Odoo with shell access. That is a distinct repository with a distinct purpose, and the README does not fold the two together.
Where the self-hosted server is the wrong tool
If your primary client is ChatGPT, this repository is the wrong choice and the README says so directly. Its comparison table lists ChatGPT as the hosted product's primary client and lists Claude Code, Cursor and local agents for this repository. The reason is mechanical: ChatGPT needs a stable remote URL, and the local server runs as a process over stdio or local HTTP. You can put a process behind a tunnel, and the README does not describe doing that. It describes a hosted gateway at https://mcp.erpipe.com/mcp with workspace OAuth for exactly this case.
The second wrong-tool case is governance. If you need a dashboard audit trail, per-field policy enforced centrally, or a human approval inbox, those are hosted-product features in the README's own table. The local equivalent is an optional JSONL file and whatever approval token scheme you configure.
The third case is scale of tenancy. Cross-instance fan-out is read-only and partial-failure-tolerant, which is appropriate for a partner reviewing client databases. It is not a data integration layer. The README says no warehouse, no sync, and that boundary is deliberate.
A real alternative worth naming is writing your own Odoo XML-RPC or JSON-2 client and exposing it as MCP tools yourself. The difference in approach is that you would own the transport versioning (16 to 18 versus 19+), the schema discovery, the domain builder, the addon scanner and the upgrade-log diagnostics, all of which this project ships as tools. The counter-argument is real too: a hand-rolled client exposes exactly the three tools your team needs, with no 41-tool surface for an agent to wander through, and no dependency on a project whose README is partly a funnel toward a commercial hosted product.
Licence, maintenance and what to verify before you commit
The repository is MIT-licensed, which permits commercial use, modification and redistribution with the licence and copyright notice retained. That covers the Python server. The README is explicit that ERPipe is a separate hosted product from the same maintainer, and that the TypeScript open core lives in a different repository, erpipe-org/erpipe. The MIT grant on this repository does not automatically extend to those, and the README does not state their terms. Anyone planning to build a product on top should read the licences of each component rather than assuming one covers all three. This is a description of what the material says, not legal advice.
On maintenance, the material gives a last push date of 2026-08-25 and no releases were retrieved, so there is no published version history to reason about here. The project was formerly tuanle96/mcp-odoo and has moved organisation, which is worth knowing if you have an old clone or an old PyPI pin. The package on PyPI is odoo-mcp, and the install path the README gives is uvx odoo-mcp --setup, so the distribution name and the repository name differ.
Upgrade cost is driven by Odoo's own release cadence rather than by this project's. The README states that XML-RPC is used for 16 to 18 and that Odoo 22 is expected to remove it, with JSON-2 support already present. In practice that means an Odoo major upgrade is also a transport migration, and the project ships migration helpers and a pre-migration data quality workflow prompt for that reason. Verify your own version's path before an upgrade window, not during one.
Editorial conclusion
Adopt the self-hosted server if you run Odoo 16 or newer and want an agent reading and writing through your own credentials on your own machine, and you are willing to own the process, the config file and the audit file. Do not adopt it if you need ChatGPT on a stable remote URL, a human-in-the-loop inbox, or a dashboard audit trail; the README points those users at the hosted ERPipe gateway instead. Before trusting it, verify two things in your own environment: which transport your Odoo version negotiates, since the project states XML-RPC for 16 to 18 and External JSON-2 for 19 and later, and whether the write gate is actually engaged, because the README describes it as an env gate plus approval tokens rather than a default-off setting.
Community notes