MCP Server for connecting Claude/Cursor to multiple Odoo instances
Project description
odoo-mcp-multi
MCP Server for connecting MCP clients (Antigravity, Claude Desktop, Cursor, VS Code) to multiple Odoo instances.
Features
- Multi-profile management: Store credentials for multiple environments (prod, staging, dev)
- Secure storage: Credentials stored in
~/.config/odoo-mcp/with 600 permissions - Multi-protocol: JSON-RPC (8.0+), JSON2 (19.0+), XML-RPC (legacy) with automatic detection
- 7 MCP tools:
search_read,write,create,execute_kw,list_models,list_fields,get_version - Full CLI: Profile and MCP server management
Installation
# Using pip
pip install .
# Using uv
uv pip install .
# Development mode
pip install -e .
After installation, the odoo-mcp command will be available in your PATH.
Quick Start
# 1. Add a profile
odoo-mcp add-profile
# 2. Verify connection
odoo-mcp test -p prod
# 3. Start MCP server
odoo-mcp run -p prod
CLI Commands
odoo-mcp add-profile
Interactive wizard to add an Odoo instance's credentials.
odoo-mcp add-profile
Options:
| Option | Description |
|---|---|
--name TEXT |
Profile identifier (e.g., prod, staging) |
--url TEXT |
Instance URL (e.g., https://odoo.example.com) |
--database TEXT |
Database name |
--user TEXT |
Odoo user |
--password TEXT |
Password (hidden on typing) |
--default |
Set as default profile |
--test / --no-test |
Test connection before saving (default: --test) |
Non-interactive example:
odoo-mcp add-profile \
--name prod \
--url https://erp.mycompany.com \
--database production \
--user admin \
--password secret \
--default
odoo-mcp list-profiles
Displays all configured profiles.
odoo-mcp list-profiles
Options:
| Option | Description |
|---|---|
--json |
JSON output format |
Sample output:
Configured Profiles:
------------------------------------------------------------
prod (default)
URL: https://erp.mycompany.com
Database: production
User: admin
staging
URL: https://staging.mycompany.com
Database: staging_db
User: admin
odoo-mcp edit-profile
Modifies an existing profile. Only the specified fields will be updated.
odoo-mcp edit-profile NAME [OPTIONS]
Arguments:
| Argument | Description |
|---|---|
NAME |
Name of the profile to edit (required) |
Options:
| Option | Description |
|---|---|
--url TEXT |
New URL |
--database TEXT |
New database name |
--user TEXT |
New username |
--password |
Interactively prompt for new password |
--test |
Test connection after editing |
Examples:
# Change only the URL
odoo-mcp edit-profile prod --url https://new-url.com
# Change username and password
odoo-mcp edit-profile staging --user new_admin --password
# Change database and test connection
odoo-mcp edit-profile dev --database new_db --test
odoo-mcp remove-profile
Removes a profile by name.
odoo-mcp remove-profile NAME
Options:
| Option | Description |
|---|---|
-f, --force |
Skip confirmation |
Example:
odoo-mcp remove-profile staging -f
odoo-mcp set-default
Sets the default profile.
odoo-mcp set-default NAME
Example:
odoo-mcp set-default prod
odoo-mcp test
Tests the connection to an Odoo instance.
odoo-mcp test [-p PROFILE]
Options:
| Option | Description |
|---|---|
-p, --profile TEXT |
Profile to use (default: default profile) |
Example:
odoo-mcp test -p prod
# ✓ Connection successful! Authenticated as UID 2
# Server version: 16.0
# Protocol: auto
odoo-mcp run
Starts the MCP server.
odoo-mcp run [-p PROFILE]
Options:
| Option | Description |
|---|---|
-p, --profile TEXT |
Profile to use (default: default profile) |
Example:
odoo-mcp run -p prod
# Starting MCP server with profile 'prod'...
# URL: https://erp.mycompany.com
# Database: production
# User: admin
MCP Clients Configuration
Multi-Profile Configuration
The MCP server handles multi-instance connections dynamically. You only need to declare a single server in your AI editor. When the AI uses a tool, it can pass a profile argument to target a specific instance.
Recommended Setup
Declare a single server without forcing a profile parameter on startup:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run"]
}
}
}
Then you can tell the AI: "In the 'prod' profile, look for the CRM leads".
The AI will use the list_available_profiles tool to see your configured profiles and pass "profile": "prod" automatically.
If the AI doesn't pass a profile, the server will fallback to the profile marked as default in your local configuration.
Forced Default Setup
If you want the fallback profile to be completely explicit regardless of local odoo-mcp set-default, use the -p argument:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run", "-p", "prod"]
}
}
}
Antigravity
Edit ~/.gemini/antigravity/mcp_config.json:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run"]
}
}
}
Note: Restart Antigravity after modifying the configuration.
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run"]
}
}
}
Cursor
Edit .cursor/mcp.json in your project or globally:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run"]
}
}
}
VS Code (with MCP extension)
Edit .vscode/mcp.json or the global configuration:
{
"mcpServers": {
"odoo": {
"command": "odoo-mcp",
"args": ["run"]
}
}
}
Available MCP Tools
Once the server is running, these tools are available for Claude/Cursor. All tools accept an optional profile parameter to target a specific Odoo instance dynamically.
list_available_profiles
Lists all locally configured Odoo profiles. The AI can use this to discover available environments before making requests.
No parameters.
search_read
Searches and reads records from a model.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name (e.g., res.partner) |
domain |
string | Search domain (e.g., [('name', 'ilike', 'John')]) |
fields |
string | Comma-separated fields (e.g., name,email,phone) |
limit |
int | Maximum records (default: 100) |
offset |
int | Records to skip (default: 0) |
order |
string | Sorting (e.g., name asc, id desc) |
profile |
string | (Optional) Target Odoo profile name |
write
Updates existing records.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
ids |
string | IDs as JSON or comma-separated (e.g., [1,2,3] or 1,2,3) |
values |
string | Values as JSON (e.g., {"name": "New Name"}) |
profile |
string | (Optional) Target Odoo profile name |
create
Creates a new record.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
values |
string | Values as JSON (e.g., {"name": "Alice", "email": "alice@example.com"}) |
profile |
string | (Optional) Target Odoo profile name |
export_records
Exports records from a model using native export_data. Returns a clean array of dictionaries, ideal for bulk operations.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
domain |
string | Search domain (e.g., [('name', 'ilike', 'John')]) |
fields |
string | Comma-separated fields. Use id for External ID, and rel/id for relations (e.g., id,name,country_id/id) |
profile |
string | (Optional) Target Odoo profile name |
import_records
Imports and updates records via native load. If the id field contains an External ID, the record is updated. Returns detailed line-by-line messages on format errors.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
fields |
string | Comma-separated field names matching the keys (e.g., id,name) |
rows |
string | JSON array of dictionaries containing the data. |
profile |
string | (Optional) Target Odoo profile name |
execute_kw
Executes any method of an Odoo model.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
method |
string | Method name (e.g., action_confirm, send) |
args |
string | Positional arguments as JSON (e.g., [[42]]) |
kwargs |
string | Keyword arguments as JSON (e.g., {"force_send": true}) |
profile |
string | (Optional) Target Odoo profile name |
list_models
Lists the models available in the instance.
| Parameter | Type | Description |
|---|---|---|
search |
string | Optional filter by model name |
profile |
string | (Optional) Target Odoo profile name |
list_fields
Lists the fields of a model.
| Parameter | Type | Description |
|---|---|---|
model |
string | Model name |
profile |
string | (Optional) Target Odoo profile name |
get_version
Gets version information from the Odoo server.
| Parameter | Type | Description |
|---|---|---|
profile |
string | (Optional) Target Odoo profile name |
Usage Examples in Claude
"List all contacts containing 'John' in their name"
search_read(model="res.partner", domain="[('name', 'ilike', 'John')]", fields="name,email,phone")
"Create a new contact named Alice with email alice@example.com"
create(model="res.partner", values='{"name": "Alice", "email": "alice@example.com"}')
"Confirm the sales order with ID 42"
execute_kw(model="sale.order", method="action_confirm", args="[[42]]")
"What fields does the invoice model have?"
list_fields(model="account.move")
"Export the name and external ID of all active partners"
export_records(model="res.partner", domain="[('active', '=', True)]", fields="id,name")
"Update the phone number of the partner with external ID 'base.res_partner_1' and create a new partner"
import_records(model="res.partner", fields="id,name,phone", rows='[{"id": "base.res_partner_1", "name": "Existing Partner", "phone": "12345"}, {"name": "New Partner", "phone": "67890"}]')
Security
- Credentials are stored in
~/.config/odoo-mcp/profiles.json - File permissions are set to
600(owner read/write only) - Passwords are handled with
SecretStrto prevent accidental logging
Development
# Install with development dependencies
pip install -e ".[dev]"
# Run linting
ruff check odoo_mcp_multi/
# Format code
ruff format odoo_mcp_multi/
License
MIT
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_multi-0.2.4.tar.gz.
File metadata
- Download URL: odoo_mcp_multi-0.2.4.tar.gz
- Upload date:
- Size: 20.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64317eb6ad010cc3bfadcb3e4a2a5addc740a286926a9a591326d6a7fc0d879b
|
|
| MD5 |
6e0a286c252a14aaedbcff829425fa57
|
|
| BLAKE2b-256 |
2468f891b26598b9ffae5a1ac53b0785b732482113ebcc18703de4a8e2827725
|
File details
Details for the file odoo_mcp_multi-0.2.4-py3-none-any.whl.
File metadata
- Download URL: odoo_mcp_multi-0.2.4-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4d23f80e55f3e2df686765cf5d855dfee674437d72a6ef295c1bfd03edef79e
|
|
| MD5 |
fed95f86a1e88eadc91627160b00e0b0
|
|
| BLAKE2b-256 |
ed2b484b2f5ae5be59a7cf90353166b010bce2a98fa795490f7a929618135805
|