"Can I just ask the AI how much of that part we have on hand?"
We kept hearing some version of that question from Odoo teams. People already use ChatGPT and Claude to write emails and summarize documents. The obvious next step is letting those assistants look things up in the ERP, and maybe even draft a purchase order. The hard part is doing it without giving an AI tool, or some outside service in the middle, free rein over your database.
So we built it as an Odoo app. Here's what it does, how we kept it safe, and a few things we learned along the way.
The problem: useful AI needs real data, and real data needs guardrails
A common early "AI plus ERP" setup looks like this. You run a separate bridge program somewhere, give it an admin API key, and let the AI send requests through it. It works in a demo. In real life it creates three problems:
- Another system to host and babysit. The bridge has to live on a server, stay patched, and stay running.
- A key with too much power. One shared admin credential means every request runs with admin rights, no matter who's asking.
- No clear record. When something changes, it's hard to say who asked for it and what exactly was sent.
We wanted the opposite: nothing extra to host, every request running as the actual person asking, and a log of every call.
What we built: an MCP server that lives inside Odoo
MCP, the Model Context Protocol, is an open standard that lets AI assistants like ChatGPT and Claude call tools in other systems. Our module turns an Odoo database into an MCP server. You install it like any other Odoo app, and the AI connects straight to your Odoo address. There's no bridge process and no third party holding a key to your data.
Signing in uses OAuth 2.1, the same kind of "log in and approve access" flow you see when one app connects to another. In ChatGPT, for example, you add your Odoo connector address, sign in to Odoo, and approve the connection. Desktop tools like Claude and Cursor use the same address.
The module runs on Odoo 17, 18, 19 and 20, with a separate branch for each version.
Reading data
Once connected, the assistant can:
- See which Odoo models it's allowed to read and what fields they have
- Search records and open a single record
- Run grouped totals for quick, ad-hoc reporting
- Run named reports, such as purchases by vendor, on-hand inventory, or sales by product
Drafting changes
Writing is where most teams get nervous, so we were strict about it. There's no general "change any record" tool. Instead, each write is a purpose-built tool that understands the record it touches:
- Create or update a draft purchase order, including where it should be received and a correct expected date
- Create or update a draft sales quotation
- Create a bill of materials, or change a recipe and show exactly which components changed
- Record a counted quantity as a stock adjustment
Write tools are turned off when the module is installed. An administrator has to switch each one on deliberately. If an Odoo app isn't installed, say there's no Manufacturing app, the related tools simply don't show up instead of appearing and then failing.
How access stays under control
We built four separate layers, and each has to say yes:
- A permission group. Only people added to the "MCP: Can Connect" group can connect at all.
- Tool settings. Each tool can be turned on or off, and limited to certain groups or users.
- A list of readable models. The read tools only touch the models an administrator picks.
- Odoo's own security. Every request runs as the signed-in user, so the access rights and record rules you already set still apply.
That last layer is the one that matters most. The AI never gets more access than the person using it already has in Odoo. If a buyer can't see payroll in Odoo, their assistant can't either.
Every call is also written to an activity log in Odoo's settings, so an administrator can see who asked for what and when.
On the security side, the module follows current OAuth practice: tokens are stored only as one-way fingerprints, the stronger PKCE sign-in check is required, and refresh tokens change on every use. If an old token is ever reused, the module treats it as a possible leak and shuts off that whole chain of access.
What we learned building it
Don't invent rules Odoo doesn't have
An early version only let the AI pick vendors that Odoo had marked as suppliers. That sounded sensible. It turned out Odoo only sets that marker when orders are confirmed through the normal screens, so vendors that were imported or created through EDI never got it. Real vendors were being rejected.
The fix was to stop making up our own rules about what's allowed. Odoo decides permissions. What our tools check is identity: a record only matches on an exact identifier or exact name, and if a name could mean more than one record, the AI comes back with the options and a person chooses. Whether it's the right record is the approver's call, shown in a preview before anything is saved.
Follow the spec, but don't break on the future
The MCP and OAuth specs move quickly. In a couple of places we chose not to follow a rule to the letter because doing so would break real clients. For example, we deliberately don't publish an OpenID Connect discovery file, because answering there made one AI client think the server was something it isn't, and the connection failed after sign-in had already worked. We also log and accept unfamiliar protocol versions instead of refusing them, so a future client update doesn't lock everyone out.
Give yourself a way to see what the client is doing
Some AI clients finish a perfectly normal sign-in and then report only "a network error occurred." We added an optional debug setting that writes each request to the server log with the credential hidden. It has already caught two connection problems that error codes alone couldn't explain.
Is this right for your Odoo database?
If your team already uses ChatGPT or Claude and keeps asking the same questions of Odoo, this is a practical way to let the assistant answer them, and to draft routine orders for a person to review, without opening up the whole database. It's also a good example of how we work in general: when stock Odoo doesn't cover a need, we build it as a versioned Odoo module that uses the same records and the same access rights as everything else.
Want to see it running on a real Odoo database, or talk through what you'd want an AI assistant to do in yours? Get in touch with Brapps and we'll walk you through it.