MCP Server for Odoo

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

Connect your client

Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs ODOO_URL, ODOO_API_KEY. Replace each <NAME> with your value.

Claude CodeTerminal
claude mcp add for-odoo -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> -- uvx mcp-server-odoo
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "for-odoo": {
      "command": "uvx",
      "args": [
        "mcp-server-odoo"
      ],
      "env": {
        "ODOO_URL": "<ODOO_URL>",
        "ODOO_API_KEY": "<ODOO_API_KEY>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "for-odoo": {
      "command": "uvx",
      "args": [
        "mcp-server-odoo"
      ],
      "env": {
        "ODOO_URL": "<ODOO_URL>",
        "ODOO_API_KEY": "<ODOO_API_KEY>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "for-odoo": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-server-odoo"
      ],
      "env": {
        "ODOO_URL": "<ODOO_URL>",
        "ODOO_API_KEY": "<ODOO_API_KEY>"
      }
    }
  }
}
Codex~/.codex/config.toml
[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 CLITerminal
gemini mcp add --scope user -e ODOO_URL=<ODOO_URL> -e ODOO_API_KEY=<ODOO_API_KEY> for-odoo uvx -- mcp-server-odoo
Local (container)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs ODOO_URL, ODOO_API_KEY. Replace each <NAME> with your value.

Claude CodeTerminal
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
Claude Desktopclaude_desktop_config.json
{
  "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>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "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>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "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>"
      }
    }
  }
}
Codex~/.codex/config.toml
[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 CLITerminal
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-odoo

Settings 12

ODOO_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.

What it does

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.

What it needs

RuntimePython 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.

Limits

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.

Who it suits

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.

Tools 17

search_records
Search any model with a domain filter, chosen fields, sorting and paging
get_record
Fetch one record by ID, with a smart field selection when none is given
get_fields
Describe a model's fields: type, label, required, relation and selection values
get_current_context
Show the connected user, timezone, active and allowed companies
list_models
List the models available to the server (enabled ones in standard mode)
list_resource_templates
List the odoo:// resource URI patterns the server serves
create_record
Create one record in a model
create_records
Create up to 100 records of one model in a single transaction
update_record
Change field values on one record
update_records
Change up to 100 records at once, with shared or per-record values
delete_record
Delete one record
post_message
Post an internal note or follower-notifying comment to a record's chatter
read_attachment
Read an attachment or binary field as text, an image or a download link
list_record_attachments
List the files attached to a record, newest first
upload_attachment
Attach a base64-encoded file to a record
aggregate_records
Group records and compute counts or sums on the database side
call_model_method
Call a public business method such as confirming an order; full YOLO plus opt-in only

Similar servers