# Self-Hosted Odoo AI Assistant: Private Architecture With a Local Model

> Source: https://netray.co/erp-help/private-ai-layer-odoo-self-hosted-on-prem-architecture
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

Self-hosted Odoo already exposes its data through an authenticated external API that enforces access rights and record rules, so a private assistant can call it as the signed-in user. Add a retrieval index over attachments and a local open-weight model, and nothing leaves your servers. Direct PostgreSQL access is for aggregates only, because it bypasses record rules.

## Kind

advanced

## System

small-erp

## Erp

Odoo (self-hosted)

## Module

ORM and external API / AI architecture

## Query

self-hosted Odoo AI assistant without cloud

## Alternate Queries

- how to add a local LLM to Odoo on-premise
- Odoo AI integration private server
- Odoo Community ChatGPT alternative on-prem
- Odoo external API AI agent read-only

## Applies To

Odoo Community and Enterprise self-hosted on your own servers. Odoo.sh and Odoo Online are cloud-hosted and outside this pattern.

## Steps

### Reference build for a private AI layer on self-hosted Odoo

**Items:**

- Confirm the Odoo version and edition, the PostgreSQL version, whether you run multi-company, and where the filestore lives.
- Create a dedicated Odoo user group for the assistant's service identity and, for per-user answers, have each person issue themselves an API key from their account preferences so calls run as that person.
- Use the external API (XML-RPC or JSON-RPC, and the newer JSON API in recent versions) for read calls such as search_read on sale orders, stock quants, manufacturing orders and purchase orders. The ORM then applies access rights and record rules.
- For heavy analytics, add a PostgreSQL streaming replica and a read-only role exposing curated views. Use it only for aggregates the whole team may see.
- Index attachments: ir.attachment holds file metadata in the database and the files in the filestore. Tag chunks with res_model and res_id so retrieval can be scoped to records the user can open.
- Expose approved read actions through an MCP or REST tool server rather than raw model-built domains.
- Serve an open-weight model with vLLM or Ollama on a local GPU server and deny it outbound internet.
- Log every question, tool call, domain filter and result count; review it during the pilot.

## Sections

### Odoo's data model and API for read access

**Body:**

Odoo is a model-based ORM on PostgreSQL. Business objects are models such as res.partner, product.product, sale.order and sale.order.line, purchase.order, stock.quant and stock.move, mrp.production and mrp.bom, and account.move. The external API authenticates a user and then calls ORM methods like search_read with a domain and a list of fields.

Because the call runs through the ORM as that user, groups in ir.model.access and record rules in ir.rule apply, including multi-company restrictions through the allowed companies on the session. That is the cleanest way to make an assistant respect existing permissions.

Recent versions add a newer JSON API and plan to retire the older RPC endpoints, so check your version's documentation before building on one of them.

**Code:**

import xmlrpc.client
url, db = 'https://odoo.internal', 'prod'
common = xmlrpc.client.ServerProxy(url + '/xmlrpc/2/common')
uid = common.authenticate(db, 'user@example.com', 'USER_API_KEY', {})
models = xmlrpc.client.ServerProxy(url + '/xmlrpc/2/object')
rows = models.execute_kw(db, uid, 'USER_API_KEY', 'mrp.production', 'search_read',
  [[['state', 'in', ['confirmed', 'progress']]]],
  {'fields': ['name', 'product_id', 'product_qty', 'date_start'], 'limit': 20})

### Reference architecture and air-gapped option

**Body:**

Run the assistant services next to Odoo: a tool server that wraps API calls, a vector index for attachments and knowledge articles, the model server on a GPU host and an audit store. For aggregate analytics, a PostgreSQL replica with a read-only role keeps load off the production database.

Direct SQL is tempting but bypasses record rules and company limits, and Odoo's table names follow the model names with dots replaced by underscores. Use SQL only for data every permitted user may see, and never for per-user answers.

For an air-gapped deployment, the Odoo instance, replica, model and index all live in the enclave and model files are brought in on controlled media.

### Permissions and write-back

**Body:**

The simplest correct design is to authenticate as the person asking. Each call then returns only what Odoo would show them, in their companies, under their groups. Avoid a single powerful service account that the assistant filters itself.

Attachment retrieval needs the same care: check read access on the parent record through the API before including a chunk in a prompt.

For write-back, use the API to create drafts such as a quotation or a purchase order in draft state and let the user confirm in Odoo. Keep the confirm step human.

### Sizing, rollout and limits

**Body:**

Odoo sites range from a dozen to several hundred users. A single GPU serves most of them, and the main costs are attachment indexing and tuning tool descriptions for custom modules and Studio fields.

Phase 1: read-only questions on sales, stock, manufacturing and purchasing. Phase 2: drafts and summaries. Phase 3: approved actions such as creating draft records.

Limits: Odoo Enterprise includes AI features in recent versions, and if those meet your policy they may be enough; custom modules need their own tool definitions; and API pagination limits must be respected on large tables.

## Pitfalls

- Using direct PostgreSQL access for per-user answers, which bypasses record rules and company limits.
- Sharing one admin API key across the assistant so every user sees everything.
- Calling search_read without limits or field lists on very large tables.
- Ignoring multi-company context, so answers mix entities.
- Indexing attachments without checking read access on the parent record.
- Building on a deprecated RPC endpoint without checking your version's roadmap.

## Ai Angle

ERPray can call Odoo's API as the signed-in user, for instance listing manufacturing orders blocked on components, with the domain filter shown. Netray sets up the tool server, attachment index and local model, and Odoo partners remain the experts on your custom modules.

## Faq

### Can Odoo run a local LLM without any cloud?

**Answer:** Yes, if you self-host. The assistant calls Odoo's external API, retrieves attachments from a local index and uses an open-weight model on your own GPU. Nothing needs to leave your network, and the same design works air-gapped.

### Why not just query PostgreSQL?

**Answer:** Direct SQL bypasses access rights and record rules, so it can show users data Odoo would hide. Use it only for aggregates all permitted users may see. For per-user answers call the API as that user.

### Does it work with Odoo Community?

**Answer:** Yes. The external API is available in Community and Enterprise self-hosted. Some enterprise-only apps add models you may want to expose, and tool definitions should reflect the modules you actually run.

### Is Odoo's built-in AI enough?

**Answer:** Possibly. If the built-in features satisfy your data policy and cover your questions, use them. A private layer helps when data must stay on site or you want one assistant across Odoo data and other document sources.

## Search terms

Odoo AI on-premise, self-hosted Odoo AI, Odoo local LLM, Odoo external API AI agent, Odoo ChatGPT alternative, Odoo record rules AI, private AI Odoo Community, Odoo manufacturing AI assistant

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
