Se rendre au contenu
You may also like this products
My Cart

Odoo MCP server


🚀 Odoo MCP Server Integration

Expose a Model Context Protocol (MCP) server directly from your Odoo instance—no external services required.

With this module, tools like Claude or Cursor can securely query and manage your Odoo data using natural language.

Key benefits:

  • No separate backend process
  • Native Odoo integration
  • Real-time interaction via SSE
  • Full ORM access (read/write)

⚙️ Setup

1. Install the Module

Install the module on your Odoo database like any standard addon.

2. Specify the Database

You can pass the database using one of the following methods:

  • URL parameter: ?db=<name>
  • Header: X-Odoo-Database
  • Authorization: Bearer demo_ai:YOUR_API_KEY

3. Connect with Claude / Cursor

Use mcp-remote with:

  • --transport sse-only
  • --allow-http

4. Fix 404 Errors

If you encounter a 404 error:

[options]
server_wide_modules = web,rag_odoo_mcp_server

Restart Odoo after applying changes.

💡 Usage Examples

🔍 Data Retrieval

Natural language queries are translated into MCP tool calls:

  • “Show me all customers from Spain”
    → odoo_search_read(res.partner, country_id.code = ES)
  • “Find products with stock below 10 units”
    → Use product.product or stock.quant
  • “List today's sales orders over $1000”
    → Filter sale.order by amount
  • “Search for unpaid invoices from last month”
    → Filter account.move by payment state

✏️ Data Management

  • “Create a new customer contact for Acme Corporation”
    → odoo_create(res.partner, {...})
  • “Add a new product ‘Premium Widget’ with price $99.99”
    → odoo_create(product.product, {...})
  • “Update the phone number for John Doe”
    → odoo_search_read → odoo_write
  • “Confirm order SO/2024/001”
    → odoo_execute(action_confirm)
  • “Delete the test contact”
    → odoo_unlink(...)

🔌 API Endpoints

MethodEndpointDescription
GET/mcp/sse?db=<database>Open SSE stream
POST/mcp/messages/?session_id=<id>&db=<database>JSON-RPC calls
GET/mcp/health?db=<database>Health check

Authentication (optional):

  • Authorization: Bearer <key>
  • X-API-Key: <key>

🧰 Available MCP Tools

  • list_tables
  • describe_table
  • get_table_row_count
  • run_readonly_query
  • get_odoo_models_info
  • get_table_schema_pg
  • odoo_search_read
  • odoo_create
  • odoo_write
  • odoo_unlink
  • odoo_execute

🧪 Standalone Mode (Read-Only)

Run MCP without Odoo ORM:

pip install -r rag_odoo_mcp_server/requirements-mcp.txt
python -m rag_odoo_mcp_server.mcp_server --host 0.0.0.0 --port 8000

SSE Endpoint:

http://<host>:8000/sse

⚠️ ORM methods (create, write, etc.) are not available in this mode.

🏢 Company Context (Optional)

Note: Now handled via UI configuration. Manual setup is kept for reference.

Priority order:

  1. Per-tool argument
  2. Per-request / session
  3. System default

Examples:

  • Per-tool: company_id=2
  • Request: ?company_id=2 or header
  • Session: SSE URL param
  • Default: Set in module settings

If unset → all companies are visible.

⚡ Nginx Optimization (Important)

For real-time SSE performance, disable buffering:

location /mcp/ {
    proxy_pass http://your_odoo_backend;
    proxy_buffering off;
    proxy_set_header X-Accel-Buffering no;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    chunked_transfer_encoding on;
}

👉 Without this, SSE events may be delayed or blocked.

☁️ Odoo.sh Configuration

No need to specify the database:

{
  "mcpServers": {
    "odoo": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://link.dev.odoo.com/odoo/mcp/sse",
        "--allow-http",
        "--transport",
        "sse-only",
        "--header",
        "Authorization:${MCP_CRM_AUTH}"
      ],
      "env": {
        "MCP_CRM_AUTH": "Bearer tokenkey"
      }
    }
  }
}

⚠️ Troubleshooting

Error: HTTP 400 Unknown or expired session

✅ Option 1 (Recommended for VPS)

  • SSH into your server
  • Set:
workers = 0
  • Restart Odoo

✅ Option 2 (Production Setup – Nginx Sticky Sessions)

Use session-based routing:

map $arg_session_id $mcp_sticky {
    default        $remote_addr;
    ~.+            $arg_session_id;
}

upstream odoo_mcp {
    hash $mcp_sticky consistent;
    server 127.0.0.1:8069;
    server 127.0.0.1:8070;
}

Then configure:

location ~ ^/(odoo/)?mcp/ {
    proxy_pass http://odoo_mcp;
    proxy_http_version 1.1;
    proxy_buffering off;
    proxy_read_timeout 1h;
    proxy_send_timeout 1h;
    chunked_transfer_encoding on;
    add_header X-Accel-Buffering no;
}

⚠️ Important Notes

  • Odoo workers share ports by default → true sticky routing requires custom setup
  • Single-instance deployments benefit most from Option 1
  • Always disable buffering for SSE

Security overview — rag_odoo_mcp_server

Authentication

  • Two modes, chosen in Settings → MCP Server → Authentication:
    • API Token — two tiers: User (read-only) and Admin (read + write). Tokens are 32-byte URL-safe random (secrets.token_urlsafe), stored in ir.config_parameter, never displayed twice. Compared with constant-time secrets.compare_digest to defeat timing attacks.
    • Odoo User Credentials — the LLM operates as a real Odoo user; all ORM access goes through that user's record rules and access rights, just like a logged-in human.
  • The Admin token can be disabled entirely; without one, writes are refused even if the token is valid.

Transport

  • The MCP server runs inside Odoo (no separate process, no extra ports). All traffic uses your existing Odoo HTTP/HTTPS endpoint — put Odoo behind your normal TLS proxy and the MCP traffic is encrypted with it.
  • Auth headers are enforced on every /mcp/messages POST. The SSE GET is just a session bootstrap; no data leaves until the client proves itself on the next POST.
  • Sessions are persisted in a DB table (multi-worker safe on Odoo.sh) and auto-expire via a 10-min GC cron.

Authorization (what the LLM can do)

  • Write tools (odoo_create/odoo_write/odoo_unlink/odoo_execute, lead/campaign creation) are hidden from tools/list and refused on tools/call unless the Admin token (or an Odoo user with write rights) is used.
  • Dashboard-only lockdown: an admin can flip a switch that restricts the LLM to building dashboards and refuses everything else.
  • CRM Manager feature flag gates lead-gen and mailing tools behind a security group; off by default.
  • Raw SQL is read-only: run_readonly_query accepts SELECT only and rejects any query containing INSERT/UPDATE/DELETE/DROP/CREATE/ALTER/TRUNCATE/GRANT/REVOKE.

Data residency & privacy

  • Nothing is sent to RAG Solutions or any third party by the module. Your Odoo data goes only to the MCP client your customer connects (Claude Desktop / Cursor / etc.) — that's their existing AI vendor relationship, not ours.
  • No telemetry, no phone-home, no external API calls. The module's only network surface is the MCP endpoint your customer chooses to expose.

Multi-company & audit

  • company_id can be set as a default or per call; ORM operations run inside with_company() so Odoo's standard multi-company isolation applies.
  • All writes go through the ORM, so Odoo's audit log (mail.message, mail-thread tracking) captures them as if a normal user made them.

What's left to the customer

  • TLS termination, IP allow-listing, and reverse-proxy hardening are the customer's responsibility (same as any Odoo deployment).
  • Token rotation: tokens have no expiry on our side — the admin should rotate them on a schedule. Re-clicking Generate User/Admin Token invalidates the previous one immediately.

Risk summary for your customers

Concern Mitigation
Data leakage to a third party None — module makes no outbound calls; data flows only to the MCP client they choose
Token theft Constant-time comparison, single-display generation, easy rotation, optional require-API-key enforcement
Unauthorized writes Two-tier tokens, dashboard-only lockdown, Odoo-user mode that respects ACLs
Multi-tenant Odoo Works with Odoo's standard multi-company isolation via company_id
SQL injection via the LLM Read-only enforcement on raw SQL; ORM tools go through Odoo's normal sanitization
Audit Standard Odoo audit log applies (writes are normal ORM writes)

The module adds no new data egress path. Whatever risk model your customers already accept for connecting Claude/Cursor to their data applies here — they just gain a controlled, auditable, tokenized way to do it through Odoo.

Documentation

To install this Web App in your iPhone/iPad press and then Add to Home Screen.