Read-only MCP server for standard Odoo (SaaS/Cloud) via XML-RPC — no custom module required
Project description
odoo-mcp-uvx
A read-only MCP server that lets AI assistants (Claude, Cursor, Copilot, etc.) query your Odoo instance via the standard XML-RPC API — no custom Odoo module required. Works with any Odoo SaaS, Community, or Enterprise instance.
Access is determined entirely by the Odoo user account you configure: if your user can read a model in Odoo, the MCP server can read it; if not, Odoo will return an Access Denied error.
Features
- Search and retrieve records from any accessible Odoo model
- Read individual records by ID
- Count records matching filters
- Inspect model field definitions
- List all models the user can access (via
ir.model) - Smart field selection — automatically picks the most relevant fields
- LLM-optimized hierarchical text output
- Multi-language support via
ODOO_LOCALE - No custom Odoo module needed — pure standard XML-RPC
Quick Start
1. Install UV
The server runs on your local machine (where your AI client is). Install UV if you haven't already:
macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Restart your terminal after installation.
2. Add to your MCP client
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"odoo": {
"command": "uvx",
"args": ["odoo-mcp-uvx"],
"env": {
"ODOO_URL": "https://mycompany.odoo.com",
"ODOO_DB": "mycompany-prod-12345",
"ODOO_USER": "ai-team@mycompany.com",
"ODOO_PASSWORD": "your-password-or-api-key"
}
}
}
}
Claude Code
claude mcp add odoo \
--env ODOO_URL=https://mycompany.odoo.com \
--env ODOO_DB=mycompany-prod-12345 \
--env ODOO_USER=ai-team@mycompany.com \
--env ODOO_PASSWORD=your-password \
-- uvx odoo-mcp-uvx
Or add to .mcp.json in your project root:
{
"mcpServers": {
"odoo": {
"command": "uvx",
"args": ["odoo-mcp-uvx"],
"env": {
"ODOO_URL": "https://mycompany.odoo.com",
"ODOO_DB": "mycompany-prod-12345",
"ODOO_USER": "ai-team@mycompany.com",
"ODOO_PASSWORD": "your-password"
}
}
}
}
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"odoo": {
"command": "uvx",
"args": ["odoo-mcp-uvx"],
"env": {
"ODOO_URL": "https://mycompany.odoo.com",
"ODOO_DB": "mycompany-prod-12345",
"ODOO_USER": "ai-team@mycompany.com",
"ODOO_PASSWORD": "your-password"
}
}
}
}
VS Code (GitHub Copilot)
Add to .vscode/mcp.json in your workspace:
{
"servers": {
"odoo": {
"type": "stdio",
"command": "uvx",
"args": ["odoo-mcp-uvx"],
"env": {
"ODOO_URL": "https://mycompany.odoo.com",
"ODOO_DB": "mycompany-prod-12345",
"ODOO_USER": "ai-team@mycompany.com",
"ODOO_PASSWORD": "your-password"
}
}
}
}
Note: VS Code uses
"servers"as the root key, not"mcpServers".
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json.
Zed
Add to ~/.config/zed/settings.json under "context_servers".
Configuration
Environment Variables
| Variable | Required | Description | Example |
|---|---|---|---|
ODOO_URL |
Yes | Odoo instance URL or bare hostname | https://myco.odoo.com or myco.odoo.com |
ODOO_PORT |
No | Port number (used when ODOO_URL is a bare hostname) |
443 |
ODOO_PROTOCOL |
No | Protocol hint when ODOO_URL is a bare hostname |
jsonrpc+ssl, https, http |
ODOO_DB |
Recommended | Database name | myco-prod-28478563 |
ODOO_USER |
Yes* | Odoo username (email) | ai-team@myco.com |
ODOO_PASSWORD |
Yes* | Odoo password or API key | eaqwywMXbpx9fqYDdBxr |
ODOO_API_KEY |
Yes* | API key (alternative to password; requires ODOO_USER) |
0ef5b399e9... |
ODOO_LOCALE |
No | Language for Odoo responses | es_ES, fr_FR |
*Either (ODOO_USER + ODOO_PASSWORD) or (ODOO_USER + ODOO_API_KEY) is required.
Notes:
ODOO_URLcan be a bare hostname likemyco.odoo.com— the server will build a properhttps://URL automatically usingODOO_PORTandODOO_PROTOCOLas hints.- If
ODOO_DBis omitted, the server tries to auto-detect the database. Odoo SaaS instances usually have database listing disabled, so always setODOO_DBfor SaaS. - The server also reads from a
.envfile in the working directory.
Example for Odoo SaaS (using separate host/port/protocol env vars)
ODOO_URL=mycompany.odoo.com
ODOO_PORT=443
ODOO_PROTOCOL=jsonrpc+ssl
ODOO_DB=mycompany-prod-28478563
ODOO_USER=ai-team@mycompany.com
ODOO_PASSWORD=eaqwywMXbpx9fqYDdBxr
Advanced Configuration
| Variable | Default | Description |
|---|---|---|
ODOO_MCP_DEFAULT_LIMIT |
10 |
Default records returned per search |
ODOO_MCP_MAX_LIMIT |
100 |
Maximum record limit per request |
ODOO_MCP_MAX_SMART_FIELDS |
15 |
Max fields returned by smart field selection |
ODOO_MCP_LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARNING, ERROR) |
ODOO_MCP_LOG_JSON |
false |
Structured JSON log output |
ODOO_MCP_LOG_FILE |
— | Path for rotating log file |
ODOO_MCP_TRANSPORT |
stdio |
Transport (stdio or streamable-http) |
ODOO_MCP_HOST |
localhost |
Host for HTTP transport |
ODOO_MCP_PORT |
8000 |
Port for HTTP transport |
Transport Options
stdio (default)
Standard input/output — used by Claude Desktop and most MCP clients.
uvx odoo-mcp-uvx
streamable-http
HTTP transport for remote or API-style access.
uvx odoo-mcp-uvx --transport streamable-http --host 0.0.0.0 --port 8000
The MCP endpoint will be at http://localhost:8000/mcp/.
Available Tools
search_records
Search for records matching a domain filter.
{
"model": "res.partner",
"domain": [["is_company", "=", true], ["country_id.code", "=", "ES"]],
"fields": ["name", "email", "phone"],
"limit": 10
}
get_record
Retrieve a specific record by ID.
{
"model": "res.partner",
"record_id": 42,
"fields": ["name", "email", "street", "city"]
}
count_records
Count records matching a domain.
{
"model": "sale.order",
"domain": [["state", "=", "sale"]]
}
get_fields
Inspect field definitions for a model.
{
"model": "product.product"
}
list_models
List all models the authenticated user can access.
{}
Smart Field Selection
Omitting the fields parameter (or passing null) triggers automatic smart field selection:
- Essential fields (
id,name,display_name,active) are always included - Business-relevant fields (state, amount, email, phone, partner, etc.) are prioritized
- Technical/expensive fields (binary, HTML blobs, computed non-stored) are excluded
- Default cap: 15 fields (adjustable via
ODOO_MCP_MAX_SMART_FIELDS)
To get every field: "fields": ["__all__"].
Resources
Direct URI access to Odoo data:
| URI Pattern | Description |
|---|---|
odoo://{model}/record/{id} |
Retrieve a specific record |
odoo://{model}/search |
Search records (first 10) |
odoo://{model}/count |
Count all records in a model |
odoo://{model}/fields |
Get field definitions |
Examples:
odoo://res.partner/record/1odoo://product.product/searchodoo://res.partner/countodoo://product.product/fields
Usage Examples
Ask your AI assistant:
- "Show me all customers from Spain"
- "Find products with stock below 10 units"
- "List today's confirmed sales orders"
- "How many active employees do we have?"
- "Show contact details for the partner with ID 42"
- "What fields does the sale.order model have?"
How It Works
AI Assistant (Claude, Cursor, Copilot, etc.)
↓ MCP Protocol (stdio or HTTP)
odoo-mcp-uvx
↓ XML-RPC (/xmlrpc/2/common, /xmlrpc/2/object)
Odoo Instance (SaaS / Community / Enterprise)
Authentication uses the standard Odoo XML-RPC authenticate() call. All permission checks are enforced by Odoo itself — if your user cannot read a model, Odoo returns Access Denied.
Security
- Always use HTTPS in production (
https://URL orODOO_PORT=443) - Use a dedicated low-privilege Odoo user for the MCP connection
- The server is read-only; it never creates, updates, or deletes records
- API keys are preferred over passwords (generate one in Odoo under Settings > Users > your user > API Keys tab)
Troubleshooting
"spawn uvx ENOENT" — UV is not installed or not in PATH. Install UV and restart your terminal. On macOS, launch Claude Desktop from Terminal: open -a "Claude".
Authentication failed — Verify ODOO_USER, ODOO_PASSWORD/ODOO_API_KEY, and ODOO_DB. Make sure the user is active in Odoo.
"Access Denied" on a model — The Odoo user does not have read access to that model. Grant access via Odoo Settings > Users & Companies > Groups, or use a user with sufficient rights.
Database auto-selection failed — Odoo SaaS disables database listing. Always set ODOO_DB explicitly.
SSL errors — Add "SSL_CERT_FILE": "/etc/ssl/cert.pem" to your MCP environment config.
Enable debug logging:
{ "env": { "ODOO_MCP_LOG_LEVEL": "DEBUG" } }
Development
git clone https://github.com/niduran-orion/odoo-mcp-uvx.git
cd odoo-mcp-uvx
pip install -e ".[dev]"
# Run the server
python -m mcp_server_odoo
# Check version
python -m mcp_server_odoo --version
# Inspect with MCP Inspector
npx @modelcontextprotocol/inspector uvx odoo-mcp-uvx
License
Mozilla Public License 2.0 — see LICENSE.
Contributing
See CONTRIBUTING.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file odoo_mcp_uvx-1.0.1.tar.gz.
File metadata
- Download URL: odoo_mcp_uvx-1.0.1.tar.gz
- Upload date:
- Size: 69.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce50a09ade419e55bdfb0f7e01e24b1a76ed2ddc2167df70cd633d018e246a5f
|
|
| MD5 |
19477bc47c2ad10d0514ca559831b58b
|
|
| BLAKE2b-256 |
fcb2b922e0cbebb8d9b32b87cd633b8137d684a8a09c000962251d2fe47484c7
|
File details
Details for the file odoo_mcp_uvx-1.0.1-py3-none-any.whl.
File metadata
- Download URL: odoo_mcp_uvx-1.0.1-py3-none-any.whl
- Upload date:
- Size: 71.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c50f04a9b3f94e03f127f2cc7f22e8682cda9fbfb5f930df95188982f7e4319b
|
|
| MD5 |
1ea761bb751c8470c577b4a4a4bfa6c6
|
|
| BLAKE2b-256 |
0f25ff8f2b6f9d5e9828f95738586b1016cad277effd1b7388a26cacfcb5876a
|