Managed ERP · AI

An AI assistant inside Odoo where every write is guarded, and nothing bills per token

The question about AI in an ERP is never “can it”. It is “who is accountable when it is confidently wrong”. Our answer: the assistant carries the mechanical work, and a named person releases anything with consequences attached.

A hairline diagram of a bounded tool surface.

The question worth asking

Every ERP vendor is shipping an assistant. The demonstrations are all variations on the same scene: someone types “create a quotation for Acme, ten units of the blue one” and it appears.

That demonstration answers a question nobody serious is asking. The real question is the one after it: what happens on the day it is confidently wrong, and what did it touch?

An ERP is not a chat surface. It is the record of what your company owes, is owed, holds and has promised. A model that is right 95 % of the time is a superb research assistant and an unacceptable accounts clerk, and the gap between those two roles is not closed by a better prompt.

Two decisions close it. Neither is about the model.

Named intents, not database access

The lazy integration hands the model generic ORM access — search, read, write, unlink on any model — and relies on instructions to keep it in bounds. Instructions are not a boundary. They are a suggestion with good manners.

Ours exposes named, typed business intents instead. Each one is a specific question with a specific shape: margin by product for a period, stock on hand for a lot with an expiry window, open purchase orders past their promised date. Each has typed parameters, a defined result, and access rules that Odoo enforces exactly as it would for a human user.

Three things follow that generic access cannot give you:

  • The surface is enumerable. You can print the complete list of things the assistant can do. Try producing that list for a generic ORM tool.
  • Record rules still apply. An intent runs as a user, subject to the same multi-company and record-level rules as the interface. Nothing gets a back door.
  • It is auditable in the ordinary way. Intents are data in Odoo, so what the assistant may do is inspected the same way anything else in the system is.

The transport is MCP — the Model Context Protocol — over the OCA ai_tool and ai_oca_mcp foundation, both AGPL-3. Nothing bespoke about the plumbing; the design work is entirely in which intents exist.

One thing about that foundation is worth stating, because it is the sort of detail a supplier normally leaves out. OCA's MCP module is merged for Odoo 16, not 18. The Odoo 18 migration is still an open pull request upstream, so we run it pinned to a specific commit of that PR with a small patch series on top — five patches against the MCP module alone. Four are backports or Odoo 18 fixes: a non-admin API key that got a 403 on every call, an AttributeError where Odoo 18 moved clear_cache, a missing readonly flag that made every tool call execute twice on retry, and a missing body-size cap. The fifth we found ourselves: archiving a server did not revoke its access.

We report those upstream where they are upstream's, and we tell clients which parts of their stack are riding an unmerged branch. A dependency you cannot name a version for is not auditable, and auditability is the entire claim being made on this page.

Guarded writes, by construction

This is the sentence that matters, and it is worth being pedantic about the wording.

Every write the assistant makes is prepared. A person releases it.

Not “it is instructed to check first”, and not “it is permitted to post but told not to”. The write side reaches drafts and staging rows and stops there by construction. Posting, sending and confirming happen when somebody with the authority to be accountable for them presses the button in Odoo’s own interface.

The distinction is the whole argument. A permission is a setting, and settings get changed by tired administrators under deadline pressure. A guarantee built into the tool surface cannot be switched on by accident, cannot be argued into existence by a persuasive prompt, and cannot be reached by a model that has misunderstood its situation.

Read that as a division of labour rather than a limitation, because that is what it is in daily use. What the assistant takes off your staff is the mechanical half — the retyping, the cross-referencing, the reconciling of one list against another, the twenty minutes spent assembling a draft out of four screens. What it leaves with them is the half that actually needs a person: whether this is right, and whether the company is willing to stand behind it.

It also means the failure mode is boring, which is the objective. The worst realistic outcome is a wrong draft, sitting in a list of drafts, in front of somebody who was always going to look at it.

The import case, and who presses the button

Bulk import is where an assistant is genuinely useful and where the risk usually concentrates. Someone has a supplier's price list as a spreadsheet with the columns in the wrong order and three different date formats.

The assistant prepares the import: it maps columns, normalises formats, and stages the result. Then it stops.

The actual import runs through Odoo's own base_import screen — its preview, its column matching, its “Test import” dry run and its Import button — as the person who pressed it. Our contribution is one intent that fills in the staging row and one override so the standard screen can open on it.

Nothing here is novel and that is the point. The import path is Odoo's, so it inherits Odoo's validation, Odoo's error reporting and Odoo's audit trail. A human sees the preview and presses the button. If the mapping is wrong, they see it before anything is written, exactly as they would have if they had done the tedious part themselves.

Why metered tokens are the wrong meter

Now the commercial half, which gets discussed less and changes behaviour more.

Most Odoo AI integrations want provider API keys and bill per token. That is a perfectly honest pricing model with one bad property in this context: it makes curiosity cost money.

An assistant is valuable in proportion to how casually people use it. The finance manager who asks eleven follow-up questions about a margin anomaly finds the anomaly. The one who asks two, because someone mentioned the API bill last month, does not. Metered billing puts a small, visible tax on exactly the behaviour that produces the return, and it does it to the least technical users first.

So our integration can drive an existing subscription — a Claude Code or Codex plan the company already pays for — rather than metered API keys. The marginal cost of a question is zero, the monthly cost is a number known in advance, and nobody rations themselves.

Three deployment shapes, chosen per client:

  • Existing subscription. Fixed monthly, unmetered in practice, best when a team already has the tooling.
  • Provider API keys. Metered, correct when usage is genuinely low or has to be attributed per department.
  • On-premise open-weight model. No external call at all, no per-question cost after the hardware, correct when the data may not leave the building. Separate note on that.

Why the licence is part of the argument

The module is AGPL-3, and not by accident. It inherits ai.tool from OCA's AGPL-3 stack, so it could not be anything else — but here that constraint is an asset rather than a concession.

The entire security claim of this module is “every write is prepared, and a person releases it”. That claim is either verifiable or it is marketing. Under AGPL-3 the client owns the source, and their own auditor can confirm it in an afternoon by reading the tool definitions, instead of taking a vendor's word for it.

An AI safety claim you cannot audit is a brand promise. We would rather ship one you can check.

What it is actually good at

Stripped of the demo theatre, the honest list is narrower than the marketing and more useful than the scepticism:

  • Questions that would otherwise need a report built. “Which customers bought product X last quarter but not this one” is a five-minute answer and a two-week backlog item.
  • Finding the anomaly you already suspect. Margin drift on one product family, a lot that has been sitting too long, a supplier whose lead time has quietly doubled.
  • The tedious half of data entry. Preparing an import, drafting a quotation from an email, normalising a supplier list — always stopping before the commit.
  • Explaining the ERP to the person using it. Genuinely underrated. Most Odoo frustration is not knowing which screen answers a question.

What it is not good at: anything where being wrong is expensive and nobody checks. Which is precisely why the tool surface stops where it does.

Questions

Yes, provided every write ends with a person. Ours creates and amends drafts and stages imports, and the steps that commit — posting a journal entry, confirming a sales order, validating a delivery, sending an email — are released by a member of your team in Odoo's own interface. That guarantee is built into the tool surface rather than granted as a permission, which is what makes it survive a confidently wrong model: a permission can be granted in a hurry by an administrator, while a tool that was never built cannot be talked into existing.

That is the point. Most Odoo AI integrations require provider API keys and bill per token. Ours can be driven by an existing Claude Code or Codex subscription instead, so the marginal cost of a question is zero and nobody in the company is quietly rationing their own curiosity. Where a client prefers metered API keys, or a fully on-premise open-weight model with no external call at all, both are supported.

It depends on the deployment you choose, and you should decide that deliberately. Against a hosted model, the content of the questions and the records they touch reach that provider — the same consideration as any cloud tool, and something PDPA obliges you to have thought about. Against an on-premise open-weight model, nothing leaves. We build both. A separate question applies either way: if the assistant ever decides something about a person rather than drafting a document, Malaysia’s April 2026 guideline on automated decision-making is engaged at any scale, and this assistant is deliberately built so a person releases every write.

Have a version of this problem?

A technical review with the engineer who would do the work. No pitch deck, no discovery invoice.