odoo-mcp
by AleemHaider
README.md
# Odoo MCP Multi (own build)
A from-scratch, open MCP server that turns Claude (or any MCP client) into an
operator of the **Odoo ORM** — exactly the 12 tools described in
[`Odoo_MCP_Tools_Guide.md`](./Odoo_MCP_Tools_Guide.md).
It is a thin, ergonomic wrapper around Odoo's **external API (XML-RPC)**:
```
Claude ──(MCP tool)──► server.py ──(XML-RPC /xmlrpc/2/object)──► Odoo (PostgreSQL)
◄──(structured JSON)── ◄──(ORM data)──
```
Everything ultimately routes through one call:
`models.execute_kw(db, uid, key, model, method, args, kwargs)`.
---
## The 12 tools
| Tool | Group | Risk | Purpose |
|---|---|---|---|
| `list_available_profiles` | Discover | — | See configured environments (call FIRST) |
| `get_version` | Discover | — | Odoo server version |
| `list_models` | Discover | — | Find tables (models) |
| `list_fields` | Discover | — | See a model's schema |
| `search_read` | Read | — | **Query data** (returns pagination envelope) |
| `get_financial_report` | Read | — | Native reports (Odoo 17+) |
| `create` | Write | ⚠️ | Create a record |
| `write` | Write | ⚠️ | Update records |
| `unlink` | Write | ⚠️⚠️ | Delete records |
| `execute_kw` | Write | ⚠️⚠️ | **Run ANY model method** |
| `export_records` | Bulk | — | Export (backup/migration) |
| `import_records` | Bulk | ⚠️ | Import/upsert in bulk |
---
## Quick install — one command, no clone (recommended)
Requires [`uv`](https://docs.astral.sh/uv/) (`pip install uv`). This fetches the
code straight from GitHub, installs it in an isolated env, and registers it with
Claude — credentials are passed inline as env vars, so there's no file to edit:
```bash
claude mcp add odoo -s user \
-e ODOO_URL=https://your-instance.odoo.com \
-e ODOO_DB=your-db-name \
-e ODOO_USER=you@company.com \
-e ODOO_PASSWORD=your-api-key \
-- uvx --from git+https://github.com/AleemHaider/odoo-mcp odoo-mcp
```
That's the whole install. Start Claude and ask *"List my Odoo profiles"*.
For multiple Odoo instances, use the `profiles.json` flow below instead.
---
## Setup (manual / multi-profile)
### 1. Install
```bash
pip install -r requirements.txt # installs fastmcp
```
### 2. Configure profiles
Copy the example and fill in your Odoo credentials:
```bash
cp profiles.example.json profiles.json
```
```json
{
"default": "Interhi",
"profiles": {
"Interhi": {
"url": "https://your-instance.odoo.com",
"database": "your-db-name",
"username": "admin",
"password": "your-api-key-or-password"
}
}
}
```
> **Tip:** In Odoo, generate an **API key** (Settings → Users → API Keys) and use
> it as the `password`. Mark production profiles with `"readonly": true` to block
> all mutations from that profile.
**Alternative (single profile via env vars, no file):**
```bash
export ODOO_URL="https://your-instance.odoo.com"
export ODOO_DB="your-db-name"
export ODOO_USER="admin"
export ODOO_PASSWORD="your-api-key"
```
### 3. Run
```bash
python server.py # speaks MCP over stdio
```
---
## Connect it to Claude
### Claude Desktop
Add to `claude_desktop_config.json`
(macOS: `~/Library/Application Support/Claude/`, Windows: `%APPDATA%\Claude\`):
```json
{
"mcpServers": {
"odoo": {
"command": "python",
"args": ["/absolute/path/to/odoo mcp/server.py"]
}
}
}
```
### Claude Code (CLI)
```bash
claude mcp add odoo -- python "/absolute/path/to/odoo mcp/server.py"
```
Restart the client; the 12 tools appear automatically.
---
## Key concepts (how to drive it)
- **Domains** use Odoo **prefix (Polish) notation** — never the words `and`/`or`:
```
["&", ["state","=","posted"], ["move_type","=","out_invoice"]]
["|", ["a","=",1], ["b","=",2]]
```
- **Every read returns a pagination envelope**:
```json
{"records": [...], "total": 128, "limit": 100, "offset": 0,
"has_more": true, "next_offset": 100, "format": "json"}
```
If `has_more` is true, call again with `offset = next_offset`.
- **Output `format`**: `json` (process), `compact` (light array-of-arrays),
`table` (Markdown for users), `html` (paste into Odoo), `csv` (spreadsheet).
- **IDs for methods** always go in a list: `args=[[490749]]`.
- **Relational command tuples**: `[[0,0,{...}]]` (new o2m line),
`[[6,0,[id1,id2]]]` (set m2m).
- **execute_kw is the swiss-army knife** — any Odoo button = a method behind it:
`account.move / action_post / [[490749]]` validates an invoice.
## Safety notes
- Always run `list_available_profiles` first to confirm the environment.
- Read-only introspection via `execute_kw` (search/read/fields_get/read_group…)
is allowed on `readonly` profiles; mutating methods are blocked.
- Errors come back as `{"success": false, "error": "..."}` with the cleaned
Odoo message (e.g. `Invalid leaf`, `Expected singleton`).
---
*Wraps the Odoo external API. Concept & tool set documented in
`Odoo_MCP_Tools_Guide.md`.*
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues