Ask Odoo in plain language. Nothing changes without your sign-off.
Good morning.
What can I do for you this time?
Answers come from gemini-3-flash-preview, which runs in the cloud at Google (Vertex AI), not on your premises. Your questions and the Odoo data ODXPilot reads, with sensitive fields masked, are sent there.
- Which customer invoices are still unpaid?
- How many sales orders did we confirm this month?
- Who are our biggest customers this year?
- Which companies are set up in this database?
Built on MCP
ODXPilot is built on an MCP server made for Odoo.
Every Odoo lookup goes through it. Permissions are checked in code before Odoo is reached, and sensitive fields are masked before the AI sees the answer.
The AI
Asks for the data it needs to answer. It has no Odoo key.
MCP server for Odoo
Checks the request against the person's role, refuses what isn't allowed, masks sensitive fields in the answer.
ODXProxy
Carries the lookup to Odoo over v1 or v2.
Your Odoo
Its own access rules still apply.
The AI never calls Odoo directly. The MCP server runs inside your ODXPilot stack and isn't opened to outside AI tools. How it works
What it does today
TodayThe questions your team asks every week, answered from Odoo.
Unpaid invoices, this month's sales, your biggest customers. No report to build, no export to clean up: ask, check how it got there, and take the numbers into Excel.
Gemini · gemini-3-flash-preview
Runs in the cloud at Google (Vertex AI), not on your premises. Your questions and the Odoo data ODXPilot reads, with sensitive fields masked, are sent there.
- Which customer invoices are still unpaid?
- 3 lookups in Odoo
- Where this is kept in Odoo
- Fields of account.move
- Search in account.move
6 customer invoices are unpaid, IDR 184,250,000 in total. Five are overdue. The oldest is INV/2026/0412 to CV Kopi Lereng, due 3 Oct, 39 days overdue.
Invoice Customer Due Amount due (IDR) INV/2026/0412 CV Kopi Lereng 3 Oct 38,500,000 INV/2026/0437 PT Arunika Retail 14 Oct 52,000,000 INV/2026/0451 Toko Sinar Pagi 21 Oct 9,750,000 INV/2026/0463 PT Batu Kali Logistik 30 Oct 41,200,000 INV/2026/0478 CV Kopi Lereng 7 Nov 18,300,000 INV/2026/0490 PT Daun Hijau Farma 20 Nov 24,500,000 - Send me that in Excel
- 1 lookup in Odoo
Here it is: one sheet, with the total at the bottom.
Unpaid invoices November 2026.xlsxExcel · 18 KBDownload
Ask the way you'd ask a colleague
In your own words, Indonesian included. ODXPilot works out where in Odoo the answer lives and reads the fields as they are on your database, custom ones included.
It shows its working
Every lookup it made is listed under the answer. Anything it wasn't allowed to read is marked, with the reason, so you know what the answer is based on.
Excel when you need it
Ask for a spreadsheet and get one: a sheet per query, real dates and numbers, totals. The rows go into the file, not to the AI.
Tasks follow your procedures
Ask it to do something and it lays out the steps from your company's approved procedure, or tells you none fits.
Your procedures
TodayIt follows your procedures, or it stops and asks.
When someone asks ODXPilot to do something, it first looks for your company's approved procedure (SOP) for exactly that operation. If one matches, it lays out the steps as a plan. If none does, it tells you, rather than improvising accounting.
A procedure matches
- Register the payment for the oldest unpaid vendor bill.
- 4 lookups in Odoo
- Your company's procedure for this
- Procedure vendor-payment
- Where this is kept in Odoo
- Search in account.move
Following your approved procedure Register a vendor payment (version
29828a95): the oldest unpaid bill is BILL/2026/0087 from PT Kayu Manis Supplies, IDR 42,800,000, due 28 Oct.- Open the posted bill.
- Register the payment from the bank journal, full amount, today’s date.
- Reconcile it with the bank statement line when it arrives.
No procedure matches
- Cancel the posted vendor bill BILL/2026/0087.
- 1 lookup in Odoo
- Your company's procedure for this
No approved procedure covers cancelling a vendor bill. The closest are: Record a vendor bill · Register a vendor payment.
How would you like to proceed?
Written by your people
Your accountants write the business rules, your developers the technical notes, in ODXDocs. ODXPilot doesn't come with procedures: yours stay yours.
The exact version, every time
Every published version is kept. ODXPilot names the procedure and the version it followed, so you can check what it was told to do.
No match, no guess
Questions don't need a procedure. Tasks do. If none fits that exact operation, ODXPilot says so and asks, instead of improvising.
Where your team writes them: ODXDocs
Procedures are written in plain words in ODXDocs' editor, which your team opens in a browser on its own machine or server when there's something to add or change. No account to manage, and nothing goes live until it has been tested.
Standard operating procedures
Written together by accountants and developers. The automation agent finds them through ODXBrain once they are published, and follows them as written.
| SOP | Status | Applies to | Intents |
|---|---|---|---|
| Register a vendor paymentvendor-payment · 29828a95 | Live | account | 5 |
| Record a vendor bill from a received purchase ordervendor-bill-from-po · c41e07a2 | Live | 17.0+, Enterprise, account, purchase | 3 |
| Withhold PPh 23 on a vendor paymentvendor-payment-pph23 · 7b3f19d0 | Changededited since it was published | account, l10n_id | 4 |
| Reimburse an employee expenseexpense-reimbursement · e90a4c16 | Live | hr_expense | 5 |
| Send a reminder for an overdue customer invoicecustomer-payment-reminder · 5d2b8e47 | New | account | 3 |
| Close the books for the monthmonth-end-close · a17c62f9 | Live | account | 4 |
See what's live
Every procedure in one list, marked live, changed or new against what's published, with the conditions it applies to: Odoo version and edition, apps installed, companies.
- pay an open vendor bill
- register a payment to a supplier
- record an outgoing payment for a vendor bill
- settle what we owe a vendor
- mark a supplier bill as paid by bank transfer
## Business rules (Accountant) - Pay only posted bills. A draft bill is not a debt yet. - Pay from the bank journal the vendor's contract names; when it names none, use the operating account. - If the vendor provides a service subject to PPh 23, follow "Withhold PPh 23 on a vendor payment" instead. ## Technical notes (Developer) - Use account.move.action_register_payment, so the payment is reconciled with the bill. - Ask the user to confirm the amount and journal first.
Ask the way the agent would. Ranks this draft, unsaved edits included, against every other SOP in the folder with ODXBrain’s own embeddings. Nothing is published.
- 1Register a vendor payment0.671
- 2Withhold PPh 23 on a vendor payment0.602
- 3Record a vendor bill from a received purchase order0.566
- 4Reimburse an employee expense0.554
- 5Send a reminder for an overdue customer invoice0.521
Scores are for authors. The agent gets ranked ids and a match signal, never a threshold.
The gate publishing runs: each intent is held out and must find this SOP in the top 3.
Test it before it goes live
Write how people ask for it and what to do. Try it ranks a sample request against all your procedures, so you can spot two that are easy to confuse, or a request with no confident match. The self-test checks that every way of asking still finds this procedure. If any procedure fails, publishing is refused, with no override.
Published versions are all kept, and changes go through git, so you can see who changed what and roll back by publishing an earlier version.
Controls
The AI does the prep work. Your people keep the signature.
ODXPilot is built around the controls a finance team already runs: least access, maker and checker, and a trail. Some are in place today; the rest are designed and next to be built.
In place today
TodayDefault deny
ODXPilot reads only what the role's policy allows. Everything else is refused, and the refusal shows up in the steps.
Rules in code, not in the AI
Permissions are checked by ODXPilot's policy engine before a lookup reaches Odoo. A clever prompt, or text planted in an Odoo record, can't talk its way past it.
Sensitive fields masked
Fields the policy marks as sensitive, such as bank account numbers, are masked before the data reaches the AI.
- What are the balances of our bank journals?
- 2 lookups in Odoo, 1 refused or failed
- Where this is kept in Odoo
- Records from account.journal · refused or failedrole 'reader' may not read 'account.journal'
Your role can’t read bank journals, so I can’t give you their balances. Someone with access to accounting can.
Coming next
Coming nextDrafts, not postings
ODXPilot prepares the work as drafts. Posting, payments and reconciliation each wait for a person.
Maker ≠ checker
Whoever asked for a change can't approve it, checked on the real person, not a shared Odoo user.
Approval by role, per company
The approver must hold the approver role in the company the change belongs to, and sign in again before approving.
A trail on every change
Who asked, who approved, which procedure, logged in ODXPilot and noted on the Odoo record itself.
Plan · Register a vendor payment
PT Contoh AbadiYour approved procedure, version 29828a95
- 1Open the posted bill BILL/2026/0087 from PT Kayu Manis Suppliesread
- 2Register a payment from the bank journal: IDR 42,800,000, todaydraft
- 3Reconcile it with the bank statement line when it arriveslater
Asked by Rina · accountant
Needs approval from a finance manager of PT Contoh Abadi
Roles, as designed
- Auditor
- Reads accounting data, bank numbers masked. No changes.
- Billing clerk
- Drafts customer invoices and vendor bills.
- Accountant
- Also drafts journal entries and prepares reconciliation. Doesn't post payments.
- Finance manager
- Posts, registers payments, approves bank-account changes. Still can't approve their own requests.
Roles are per person and per company: the same person can be finance manager for one subsidiary and accountant for another.
Your data
Where your data goes, plainly.
ODXPilot uses a hosted AI model, so it is not an on-premises product today. It tells your team so in every chat, and keeps masked values and your Excel rows out of what it sends.
The AI runs in the cloud
Claude (Anthropic), Gemini (Google Vertex AI) or OpenAI GPT, one chosen for your deployment. Every chat says which, before the first question.
What is sent
Your question and the Odoo data ODXPilot reads to answer it, with sensitive fields masked.
What isn't
Masked fields, the rows in your Excel exports, and your Odoo API keys, which stay on the server.
Yours alone
Each Odoo database gets its own ODXPilot, ODXProxy and ODXBrain. Nothing is shared between customers.
Running the AI on your own hardware is on the roadmap. ODXBrain, which ODXPilot uses to find data in Odoo, already runs fully offline.
For your IT team
The model plans. Deterministic code decides.
ODXPilot keeps the model's job small and puts every decision that matters in code it can't talk its way around. It is a client of ODXProxy, uses ODXBrain to find Odoo models and procedures, and gets procedures from ODXDocs.
| The model | ODXPilot's code | |
|---|---|---|
| Understands the question | Yes | — |
| Finds where the data lives | Describes what it needs | ODXBrain names the Odoo model; fields are read live from the instance |
| Picks the procedure (SOP) | Chooses among the matches and checks it's the same operation | ODXBrain flags when no approved SOP matches, and the AI is told to stop. Enforced in code once ODXPilot can make changes |
| Decides permissions | Never | Policy engine in odx-mcp, default deny |
| Sees masked fields | Never | Masked before tool results reach the model |
| Changes Odoo | Never on its own | Coming next: drafts, posted only after a person approves |
- Reaches Odoo only through ODXProxy, over v1 or v2 (JSON-2). ODXProxy itself is unchanged; ODXBrain lookups need ODXProxy 0.10 or later.
- Odoo tools run in a separate MCP server (odx-mcp) that hosts the policy engine; the model never calls Odoo directly.
- One stack per Odoo database: ODXPilot + ODXProxy + ODXBrain, packaged as Docker images.
- The AI provider (Claude, Gemini or OpenAI) is set per deployment and fixed at startup; switching means a restart. OpenAI support is new and being verified.
- Tested so far against Odoo 20 Enterprise. No model or field names are hardcoded.
+++ id = "vendor-bill-from-po" title = "Record a vendor bill from a received purchase order" intents = [ "create a bill from a purchase order", "record a supplier invoice against a PO", ] [applies_to] odoo_min = "17.0" edition = "enterprise" modules = ["account", "purchase"] +++ ## Business rules (Accountant) - Only bill what was received. - Bills above IDR 50,000,000 need CFO approval. - The vendor's NPWP must be on the partner. If it is missing, stop and ask Finance. ## Technical notes (Developer) - Compare qty_received with qty_invoiced first. - Create it with purchase.order.action_create_invoice.
Putting AI on Odoo yourself? Start with these.
01
Never give an agent an admin key
Use the narrowest Odoo users that work, so Odoo's own access rules stay a real backstop.
02
Enforce permissions in code
A rule in the prompt can be argued away. A check in front of the API can't.
03
Draft first, post by hand
Posting, paying and reconciling are separate, explicitly approved steps.
Status
Early, and honest about it.
ODXPilot is in incubation: no customers or production deployments yet. What this page marks as today is built and tested against an Odoo 20 Enterprise test database. Everything marked coming next is designed, not built.
Built
Today- The web app: plain-language questions, every lookup shown
- Lookups in one Odoo database through ODXProxy
- Policy engine: default deny per role, masking, live-schema checks
- Excel export
- Procedure gate with ODXDocs: plan as text, or stop and ask
- Claude or Gemini, chosen per deployment. OpenAI GPT is new and being verified
Designed
Coming next- Drafts and an approval step, with plan cards like the preview above
- Sign-in with your identity provider, roles per person and per company
- Segregation of duties, audit log, notes on Odoo records
- Switching between companies in one chat
- Running the AI on your own hardware
FAQ
- How will ODXPilot make changes in Odoo?
- As drafts. Making changes is the next step: ODXPilot prepares the work as drafts, and posting, payments and reconciliation each wait for approval from a person with the right role in that company.
- Will it ever post or pay on its own?
- No. That's the design, not a setting: the AI proposes, and a person with the right role approves before anything is posted or paid.
- Does the AI decide what my team can see?
- No. A policy engine in ODXPilot checks every lookup against the role before it reaches Odoo, and refuses anything not allowed. The AI only sees what's left, with sensitive fields masked.
- Which AI does it use, and what does it see?
- Claude (Anthropic), Gemini on Google Vertex AI or OpenAI GPT (new, being verified), one chosen for your deployment. It receives your question and the Odoo data ODXPilot reads to answer it, with sensitive fields masked. Excel rows go into the file, not to the AI.
- Can it run entirely on our own servers?
- Not yet. The AI runs in the cloud today. Running it on your own hardware is on the roadmap. ODXBrain, which ODXPilot uses to find data in Odoo, already runs fully offline.
- Where do the procedures come from?
- From your own team. Your accountants and developers write them in ODXDocs, test them and publish them. ODXPilot doesn't come with a procedure library.
- What happens when no procedure matches a task?
- ODXPilot stops and asks. It names the closest procedures for you to look at, but never follows one that isn't a confident match.
- Which Odoo versions does it work with?
- So far it's tested on Odoo 20 Enterprise. It isn't tied to one version: what another version needs is your procedures and ODXBrain's coverage for it. Tell us yours when you request a demo.
- Who uses it today? What will it cost?
- ODXPilot is early: there are no customers or production deployments yet, and availability and pricing aren't decided. Request a demo and we'll show you where it stands.