Odoo MCP
Self-hosted Python MCP server for Odoo 16-19 with schema tools, diagnostics and gated writes
Search, read, create, update and delete records in an Odoo ERP database over XML-RPC
By Andrey Ivanov (individual) Python Local · stdio CRM and salesFinance and paymentsE-commerce
63 popularity score ★ 413 ↓ 6.5k/mo
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs ODOO_URL, ODOO_API_KEY. Replace each <NAME> with your value.
claude mcp add for-odoo -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> -- uvx mcp-server-odoo{
"mcpServers": {
"for-odoo": {
"command": "uvx",
"args": [
"mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}{
"mcpServers": {
"for-odoo": {
"command": "uvx",
"args": [
"mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}{
"servers": {
"for-odoo": {
"type": "stdio",
"command": "uvx",
"args": [
"mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}[mcp_servers.for-odoo]
command = "uvx"
args = ["mcp-server-odoo"]
[mcp_servers.for-odoo.env]
ODOO_URL = "<ODOO_URL>"
ODOO_API_KEY = "<ODOO_API_KEY>"gemini mcp add --scope user -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> for-odoo uvx -- mcp-server-odooOpens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs ODOO_URL, ODOO_API_KEY. Replace each <NAME> with your value.
claude mcp add for-odoo -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> -- docker run -i --rm -e ODOO_URL -e ODOO_API_KEY ivnvxd/mcp-server-odoo{
"mcpServers": {
"for-odoo": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"ODOO_URL",
"-e",
"ODOO_API_KEY",
"ivnvxd/mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}{
"mcpServers": {
"for-odoo": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"ODOO_URL",
"-e",
"ODOO_API_KEY",
"ivnvxd/mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}{
"servers": {
"for-odoo": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"ODOO_URL",
"-e",
"ODOO_API_KEY",
"ivnvxd/mcp-server-odoo"
],
"env": {
"ODOO_URL": "<ODOO_URL>",
"ODOO_API_KEY": "<ODOO_API_KEY>"
}
}
}
}[mcp_servers.for-odoo]
command = "docker"
args = ["run", "-i", "--rm", "-e", "ODOO_URL", "-e", "ODOO_API_KEY", "ivnvxd/mcp-server-odoo"]
[mcp_servers.for-odoo.env]
ODOO_URL = "<ODOO_URL>"
ODOO_API_KEY = "<ODOO_API_KEY>"gemini mcp add --scope user -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> for-odoo docker -- run -i --rm -e ODOO_URL -e ODOO_API_KEY ivnvxd/mcp-server-odooODOO_URL |
Required: Address of the Odoo instance. |
|---|---|
ODOO_API_KEY |
Required: API key of the Odoo user; or set ODOO_USER and ODOO_PASSWORD instead. |
ODOO_USER |
Optional: Odoo login, used with ODOO_PASSWORD, or with the API key in YOLO mode over XML-RPC. |
ODOO_PASSWORD |
Optional: Password for ODOO_USER when no API key is used. |
ODOO_DB |
Optional: Database name; detected automatically unless database listing is restricted. |
ODOO_YOLO |
Optional: off (default), read or true: use Odoo without the MCP module. |
ODOO_MCP_ENABLE_METHOD_CALLS |
Optional: true adds call_model_method, only together with ODOO_YOLO=true. |
ODOO_ALLOWED_COMPANIES |
Optional: Comma-separated company IDs to scope calls to; the first is active. |
ODOO_LOCALE |
Optional: Language for Odoo responses, such as es_ES. |
ODOO_RPC_TRANSPORT |
Optional: auto, xmlrpc or json2: protocol used in YOLO mode. |
ODOO_MCP_DEFAULT_LIMIT |
Optional: Records per search by default, 25; capped by ODOO_MCP_MAX_LIMIT (100). |
ODOO_MCP_TRANSPORT |
Optional: stdio (default) or streamable-http, with ODOO_MCP_HOST and ODOO_MCP_PORT. |
In a container, a setting goes in with -e NAME=value after docker run.
MCP Server for Odoo is a Python server that runs on your own computer and talks to an Odoo instance over XML-RPC (or Odoo's JSON-2 API on Odoo 19 and later in YOLO mode with an API key). It exposes Odoo's models generically rather than per app: the same tools search, read, count, group and change contacts, products, sale orders, invoices or any other model the connected user can see. Beyond plain CRUD it can describe a model's fields, run grouped totals on the database side, read and upload attachments, and post notes or comments to a record's chatter.
It works in two modes. Standard mode expects the author's companion Odoo module (mcp_server, from the Odoo Apps store) on Odoo 16.0 or later; there an administrator picks which models are exposed and whether each allows read, write, create or delete, and the user must be in the module's MCP User group. YOLO mode skips the module and connects to any Odoo with XML-RPC enabled, either read-only (ODOO_YOLO=read) or with full access (ODOO_YOLO=true); its makers say it is for development, testing and demos only and must never be used in production.
The v0.9.0 source registers 16 tools by default and a 17th, call_model_method, only when both ODOO_YOLO=true and ODOO_MCP_ENABLE_METHOD_CALLS=true are set. Searches return 25 records by default, up to 100 per request (ODOO_MCP_DEFAULT_LIMIT and ODOO_MCP_MAX_LIMIT). In YOLO mode, list_models stops at 500 models and says how many there were in all, a cap the README does not mention (tools.py, MAX_LISTED_MODELS). It runs over stdio by default and can serve streamable HTTP.
| Runtime | Python 3.10+orDocker |
|---|
Python 3.10 or later with uv (for uvx), or Docker. An Odoo instance you can reach and a user's API key, or a username and password (without 2FA). Standard mode needs Odoo 16.0+ with the mcp_server module installed, the models enabled under Settings > MCP Server, and the user in the MCP User group; on Odoo 20 the API key needs the rpc scope. YOLO mode needs only XML-RPC enabled, and ODOO_USER is required there over XML-RPC even with an API key.
YOLO mode bypasses the module's model allowlist and has no rate limiting; its makers say it is for development and demos only. The write tools are registered in every mode; in YOLO read mode their calls are refused. Each batch create or update takes at most 100 records; upload_attachment takes about 2.9 MB of decoded data; read_attachment returns text up to 100,000 characters and images up to 256 KB inline. Per-record different-value batch updates need Odoo 19 or later. The HTTP transport has no client authentication of its own, refuses bodies over 4 MiB and holds at most 10,000 sessions, which never expire unless ODOO_MCP_SESSION_IDLE_TIMEOUT is set. SSE transport is not offered.
Teams on Odoo who want an assistant to look up and maintain ERP records across any app, and who can install the companion module so an administrator controls which models are exposed and with which rights. It is a community project, not one published by Odoo S.A. Without the module, YOLO read mode is a quick way to try it against a test database; full YOLO mode, especially with call_model_method, gives an administrator's reach and belongs only on throwaway data. It suits local use best: the HTTP mode needs a reverse proxy with its own sign-in before it is reachable by others.
search_recordsget_recordget_fieldsget_current_contextlist_modelslist_resource_templatescreate_recordcreate_recordsupdate_recordupdate_recordsdelete_recordpost_messageread_attachmentlist_record_attachmentsupload_attachmentaggregate_recordscall_model_method