# odoo [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/oconsole/odoo-mcp-server  
**GitHub Stars:** 3  
**npm Downloads (last month):** 212  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/odoo

## Description
Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.

## Tools
Capabilities this server exposes over MCP:

- **odoo_search_read** — Query records with domain filters, field selection, pagination
- **odoo_search_count** — Count matching records without fetching data
- **odoo_export** — Bulk export up to 2000 records per call for spreadsheets
- **odoo_create** — Create new records
- **odoo_update** — Update existing records by ID
- **odoo_delete** — Delete records by ID
- **odoo_execute** — Run any model method (action_confirm, action_post, etc.)
- **odoo_list_models** — Discover available models with keyword filter
- **odoo_get_fields** — Inspect field definitions for any model
- **odoo_doctor** — Health diagnostics (version, modules, users, crons, errors)
- **odoo_connection_info** — Show current connection details
- **odoo_model_info** — Get comprehensive model metadata in one call — fields, views, actions, defaults, sort order
- **odoo_set_default** — Set, update, or clear a field's default value (handles ir.default + JSON encoding)
- **odoo_get_view** — Get the fully rendered (merged) form/tree/search view XML
- **odoo_modify_action** — Change a window action's domain, context, sort order, limit, or view modes

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "odoo": {
    "command": "uvx",
    "args": ["fastmcp"]
  }
}
```

## Documentation & README

# Odoo MCP Server

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that connects AI agents to Odoo ERP instances. Works with Claude Code, Cursor, Windsurf, and any MCP-compatible client.

Supports **Odoo 17-18** (JSON-RPC) and **Odoo 19+** (JSON-2 API) — auto-detects the best protocol.

![Odoo MCP Server Overview](https://raw.githubusercontent.com/oconsole/odoo-mcp-server/HEAD/odoo-mcp.gif)

## Quick Start

```bash
# Run directly (uv handles dependencies automatically)
ODOO_URL=https://my.odoo.com ODOO_DB=mydb ODOO_USER=admin ODOO_PASSWORD=secret \
  uv run odoo_mcp_server.py
```

No virtualenv or `pip install` needed — the script has [inline metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/) that `uv` resolves automatically.

## Configure in Claude Code

Add to your project's `.mcp.json`:

```json
{
  "mcpServers": {
    "odoo": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--python", "3.11", "--script", "/path/to/odoo_mcp_server.py"],
      "env": {
        "ODOO_URL": "https://your-instance.odoo.com",
        "ODOO_DB": "your-database",
        "ODOO_USER": "admin",
        "ODOO_PASSWORD": "your-password"
      }
    }
  }
}
```

Or for Odoo 19+ with API key auth:

```json
{
  "mcpServers": {
    "odoo": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--python", "3.11", "--script", "/path/to/odoo_mcp_server.py"],
      "env": {
        "ODOO_URL": "https://your-instance.odoo.com",
        "ODOO_DB": "your-database",
        "ODOO_USER": "admin",
        "ODOO_API_KEY": "your-api-key"
      }
    }
  }
}
```

## Configure in Cursor / Windsurf

Add to `~/.cursor/mcp.json` or equivalent:

```json
{
  "mcpServers": {
    "odoo": {
      "command": "uv",
      "args": ["run", "--python", "3.11", "--script", "/path/to/odoo_mcp_server.py"],
      "env": {
        "ODOO_URL": "https://your-instance.odoo.com",
        "ODOO_DB": "your-database",
        "ODOO_USER": "admin",
        "ODOO_PASSWORD": "your-password"
      }
    }
  }
}
```

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `ODOO_URL` | Yes | Odoo instance URL |
| `ODOO_DB` | Yes | Database name |
| `ODOO_USER` | Yes | Login username |
| `ODOO_PASSWORD` | One of these | Password (Odoo 17-18) |
| `ODOO_API_KEY` | required | API key (Odoo 19+, preferred) |
| `ODOO_READONLY` | No | Set to `true` to disable all write operations |

### Read-Only Mode

Set `ODOO_READONLY=true` to disable `create`, `update`, `delete`, and `execute` tools. Useful for safe browsing of production instances:

```json
{
  "mcpServers": {
    "odoo": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--python", "3.11", "--script", "/path/to/odoo_mcp_server.py"],
      "env": {
        "ODOO_URL": "https://production.odoo.com",
        "ODOO_DB": "prod",
        "ODOO_USER": "readonly-user",
        "ODOO_PASSWORD": "secret",
        "ODOO_READONLY": "true"
      }
    }
  }
}
```

## Available Tools

### Core CRUD

| Tool | Description |
|---|---|
| `odoo_search_read` | Query records with domain filters, field selection, pagination |
| `odoo_search_count` | Count matching records without fetching data |
| `odoo_export` | Bulk export up to 2000 records per call for spreadsheets |
| `odoo_create` | Create new records |
| `odoo_update` | Update existing records by ID |
| `odoo_delete` | Delete records by ID |
| `odoo_execute` | Run any model method (action_confirm, action_post, etc.) |

### Discovery

| Tool | Description |
|---|---|
| `odoo_list_models` | Discover available models with keyword filter |
| `odoo_get_fields` | Inspect field definitions for any model |
| `odoo_doctor` | Health diagnostics (version, modules, users, crons, errors) |
| `odoo_connection_info` | Show current connection details |

### Model Customization

| Tool | Description |
|---|---|
| `odoo_model_info` | Get comprehensive model metadata in one call — fields, views, actions, defaults, sort order |
| `odoo_set_default` | Set, update, or clear a field's default value (handles ir.default + JSON encoding) |
| `odoo_get_view` | Get the fully rendered (merged) form/tree/search view XML |
| `odoo_modify_action` | Change a window action's domain, context, sort order, limit, or view modes |

## Example Usage

Once configured, ask your AI agent:

- "List all sale orders from this month"
- "Show me the fields on res.partner"
- "Create a new contact named Acme Corp"
- "Run a health check on the Odoo instance"
- "Export all products to a spreadsheet"
- "Confirm sale order 42"

### Model Customization Examples

- "What's the default sort order for sale.order?"
- "Change the default invoice policy on products to 'delivery'"
- "Show me the form view for res.partner"
- "What window actions exist for account.move? Change the default sort to date desc"
- "List all custom fields on res.partner"
- "What fields are required on sale.order?"

## Model Customization Tools — Detailed Reference

### odoo_model_info

Returns everything about a model in one call, eliminating the need for multiple exploratory queries.

```
odoo_model_info(model="sale.order")
```

Returns:
- `default_order` — the model's `_order` attribute (e.g. `"date_order desc, id desc"`)
- `rec_name` — the field used for display name in dropdowns
- `field_count` — total number of fields
- `fields_by_type` — field count grouped by type (`many2one: 12, char: 8, ...`)
- `custom_fields` — user-created fields (x_ prefix or state=manual)
- `relational_fields` — all Many2one, One2many, Many2many with their targets
- `required_fields` — fields that must be filled
- `views` — base views (form, tree, search) with IDs and priorities
- `actions` — window actions with their domain, context, and view modes
- `defaults` — current ir.default values set for this model's fields

### odoo_set_default

Manages field defaults via ir.default with proper JSON encoding. The most common source of agent errors when done manually.

```
# Set global default
odoo_set_default(model="product.template", field_name="invoice_policy", value="delivery")

# Set user-specific default
odoo_set_default(model="sale.order", field_name="warehouse_id", value=2, user_id=5)

# Remove a default
odoo_set_default(model="product.template", field_name="invoice_policy", value=null)
```

The tool:
1. Finds the field_id in ir.model.fields (validates the field exists)
2. JSON-encodes the value automatically
3. Creates or updates the ir.default record
4. Returns before/after values for confirmation

### odoo_get_view

Returns the fully rendered view XML after all inheritance is applied — what the user actually sees, not the raw fragments stored in ir.ui.view.

```
odoo_get_view(model="sale.order", view_type="form")
odoo_get_view(model="res.partner", view_type="tree")
odoo_get_view(model="account.move", view_type="search")
```

Returns:
- `arch` — the complete merged XML
- `view_id` — the base view ID
- `fields_in_view` — list of field names present in the view

### odoo_modify_action

Changes how a model appears in the UI by modifying its window action (ir.actions.act_window).

```
# List actions for a model (read-only)
odoo_modify_action(model="sale.order")

# Change default sort order
odoo_modify_action(action_id=42, order="date_order desc")

# Change default filter and page size
odoo_modify_action(action_id=42, domain="[['state','=','sale']]", limit=200)

# Add default grouping via context
odoo_modify_action(action_id=42, context="{'group_by': 'partner_id'}")
```

The tool returns before/after values so you can verify what changed.

## How It Works

```
AI Agent (Claude, Cursor, etc.)
    ↕ MCP Protocol (stdio)
Odoo MCP Server
    ↕ JSON-RPC / JSON-2 API
Odoo Instance
```

The server authenticates once at startup and maintains a persistent connection. All tools use the same authenticated session.

## Requirements

- Python 3.11+
- [uv](https://docs.astral.sh/uv/) (recommended) or `pip install fastmcp httpx`

## License

MIT

<!-- mcp-name: io.github.oconsole/odoo-simple-mcp -->

