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.
Metadata
Release files for odoo-mcp-uvx 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| odoo_mcp_uvx-1.0.1.tar.gz | 69.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| odoo_mcp_uvx-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 140.6 kB
Release files / odoo_mcp_uvx-1.0.1.tar.gz
| Download URL | odoo_mcp_uvx-1.0.1.tar.gz |
|---|---|
| Size | 69.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ce50a09ade419e55bdfb0f7e01e24b1a76ed2ddc2167df70cd633d018e246a5f
|
|
BLAKE2b-256 checksum How to use checksums |
fcb2b922e0cbebb8d9b32b87cd633b8137d684a8a09c000962251d2fe47484c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / odoo_mcp_uvx-1.0.1-py3-none-any.whl
| Download URL | odoo_mcp_uvx-1.0.1-py3-none-any.whl |
|---|---|
| Size | 71.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c50f04a9b3f94e03f127f2cc7f22e8682cda9fbfb5f930df95188982f7e4319b
|
|
BLAKE2b-256 checksum How to use checksums |
0f25ff8f2b6f9d5e9828f95738586b1016cad277effd1b7388a26cacfcb5876a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|