Skip to main content
Glama
twtrubiks

odoo19-mcp-server

by twtrubiks

Odoo 19 MCP Server (JSON-2 API)

odoo19-mcp-server MCP server

License: Apache-2.0 Python GitHub stars GitHub last commit Awesome MCP Servers

Odoo 19 MCP Server,使用 JSON-2 API 連線。

本專案基於 Odoo 19 JSON-2 API 完整使用指南 開發。

執行畫面

技術棧

  • Python: 3.13

  • FastMCP: >=3.0.0,<4.0.0

  • odoo-client-lib: 2.0.1 (JSON-2 API)

Related MCP server: odxproxy-mcpserver

架構

flowchart TB
    subgraph Client["MCP Client"]
        CC[Claude Code]
        GC[Gemini CLI]
        MI[MCP Inspector]
    end

    subgraph Server["MCP Server (FastMCP)"]
        R[Resources<br/>odoo://models<br/>odoo://user<br/>odoo://company]
        T[Tools<br/>search_records<br/>create_record<br/>update_record]
        DI[Dependency Injection<br/>get_shared_client]
    end

    subgraph RPC["OdooJsonRpcClient"]
        OL[odoolib<br/>json2/json2s protocol]
    end

    subgraph Odoo["Odoo Server"]
        EP["/jsonrpc endpoint"]
    end

    Client -->|MCP Protocol<br/>stdio/http/sse| Server
    R --> DI
    T --> DI
    DI --> RPC
    RPC -->|HTTP/HTTPS| Odoo

MCP 核心概念

Resources vs Tools

特性

Resources

Tools

用途

提供上下文資訊

執行操作/動作

觸發

客戶端控制(如 Claude Code)

LLM 自動決定呼叫

參數

無(或 URI 參數)

有(需 LLM 生成)

類比

員工手冊(背景知識)

工具箱(按需使用)

HTTP 類比

GET(讀取)

POST/PUT/DELETE(操作)

Resources - 動態上下文,LLM 一開始就知道的背景資訊:

odoo://user     → "我是誰"
odoo://company  → "我在哪間公司"
odoo://models   → "有哪些模型可用"

Tools - 需要時才呼叫的操作:

search_records(model="res.partner", domain=[...])  → 搜尋
create_record(model="sale.order", values={...})    → 建立

為什麼不用 Default Prompt?

方式

Default Prompt

Resource

資料來源

寫死在程式碼

即時從 Odoo 查詢

更新時機

部署時

每次連線時

換用戶登入

資訊錯誤

自動正確

# ❌ Default Prompt(寫死)
SYSTEM_PROMPT = "當前用戶: Admin"  # 換人登入就錯了

# ✅ Resource(動態)
@mcp.resource("odoo://user")
def get_current_user():
    return client.read("res.users", [uid])  # 即時查詢

結論:Resource 是「動態的上下文」,不是靜態文字。

參考:MCP Resources | MCP Tools

環境變數

變數

說明

預設值

ODOO_URL

Odoo 伺服器 URL

http://localhost:8069

ODOO_DATABASE

資料庫名稱

-

ODOO_API_KEY

API Key 認證

-

READONLY_MODE

唯讀模式(禁止寫入操作)

false

建立 .env 檔案:

cp .env.example .env

安裝

pip install -r requirements.txt

啟動方式

開發模式(MCP Inspector)

fastmcp dev inspector odoo_mcp_server.py

傳輸模式(Transport)

本專案支援三種 MCP 傳輸模式:

模式

說明

適用情境

stdio

標準輸入輸出(預設)

Claude Desktop、Cursor IDE、本機開發

http

HTTP 協定

遠端服務、n8n、Web 應用整合

sse

Server-Sent Events(已棄用)

向下相容舊版 Client

stdio vs HTTP/SSE:算力位置

兩種模式的關鍵差異在於「誰來啟動 MCP Server」以及「算力在哪裡執行」:

stdio 模式(本機算力)

┌─────────────────────────────────────┐
│            你的電腦 💻               │
│                                     │
│  Claude Desktop ──> MCP Server      │
│                     (使用本機算力)   │
└─────────────────────────────────────┘
  • Client(如 Claude Desktop)啟動 MCP Server 作為子進程

  • MCP Server 使用你電腦的 CPU/RAM

  • Server 隨 Client 啟動/關閉

HTTP/SSE 模式(遠端算力)

┌──────────────┐         ┌──────────────────┐
│   你的電腦    │         │     雲端 ☁️       │
│              │         │                  │
│Claude Desktop│ ──網路──>│   MCP Server     │
│  (輕量)      │         │  (使用雲端算力)   │
└──────────────┘         └──────────────────┘
  • MCP Server 獨立運行在雲端/遠端主機

  • 多個 Client 可同時連線同一個 Server

  • 適合團隊共用、n8n 整合、正式環境

啟動不同模式

# stdio 模式(預設)
python odoo_mcp_server.py

# HTTP 模式
python odoo_mcp_server.py --transport http --host 0.0.0.0 --port 8000

# SSE 模式(已棄用,建議使用 HTTP)
python odoo_mcp_server.py --transport sse --host 0.0.0.0 --port 8000

雲端部署(HTTP 模式)

Docker Compose 範例:

services:
  odoo-mcp:
    build: .
    ports:
      - "8000:8000"
    environment:
      - ODOO_URL=http://odoo:8069
      - ODOO_DATABASE=odoo19
      - ODOO_API_KEY=your_api_key_here
    command: ["python", "odoo_mcp_server.py", "--transport", "http", "--host", "0.0.0.0", "--port", "8000"]
    restart: unless-stopped

Client 設定(claude)改用 URL 連線:

claude mcp add --transport http odoo-mcp https://your-cloud-server.com:8000/mcp
{
  "mcpServers": {
    "odoo-mcp": {
      "type": "http",
      "url": "https://your-cloud-server.com:8000/mcp"
    }
  }
}

MCP Resources

URI

說明

odoo://models

列出所有模型

odoo://model/{model_name}

取得模型欄位定義

odoo://record/{model_name}/{record_id}

取得單筆記錄

odoo://user

當前登入用戶資訊

odoo://company

當前用戶所屬公司資訊

MCP Tools

Tool

說明

唯讀

list_models

列出/搜尋可用模型

Yes

get_fields

取得模型欄位定義

Yes

search_records

搜尋記錄

Yes

count_records

計數記錄

Yes

read_records

讀取指定 ID 記錄

Yes

create_record

建立記錄

No

update_record

更新記錄

No

delete_record

刪除記錄(需二次確認)

No

execute_method

執行模型方法

Depends

Claude Code MCP 設定

設定檔位於 ~/.claude.json

本機執行

claude mcp add odoo-mcp-server -- python odoo_mcp_server.py
{
  "mcpServers": {
    "odoo-mcp-server": {
      "command": "/bin/python",
      "args": [
        "odoo_mcp_server.py"
      ]
    }
  }
}

Docker(host.docker.internal)

適用於 Odoo 執行在本機的情況:

claude mcp add odoo-mcp-server -- docker run -i --rm --add-host=host.docker.internal:host-gateway -e ODOO_URL=http://host.docker.internal:8069 -e ODOO_DATABASE=odoo19 -e ODOO_API_KEY=your_api_key_here odoo-mcp-server
{
  "mcpServers": {
    "odoo-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--add-host=host.docker.internal:host-gateway",
        "-e",
        "ODOO_URL=http://host.docker.internal:8069",
        "-e",
        "ODOO_DATABASE=odoo19",
        "-e",
        "ODOO_API_KEY=your_api_key_here",
        "odoo-mcp-server"
      ]
    }
  }
}

Docker(host network)

使用主機網路模式:

claude mcp add odoo-mcp-server -- docker run -i --rm --network host -e ODOO_URL=http://localhost:8069 -e ODOO_DATABASE=odoo19 -e ODOO_API_KEY=your_api_key_here odoo-mcp-server
{
  "mcpServers": {
    "odoo-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--network",
        "host",
        "-e",
        "ODOO_URL=http://localhost:8069",
        "-e",
        "ODOO_DATABASE=odoo19",
        "-e",
        "ODOO_API_KEY=your_api_key_here",
        "odoo-mcp-server"
      ]
    }
  }
}

Docker(遠端 Odoo)

claude mcp add odoo-mcp-server -- docker run -i --rm -e ODOO_URL=https://example.com/ -e ODOO_DATABASE=odoo19 -e ODOO_API_KEY=your_api_key_here odoo-mcp-server
{
  "mcpServers": {
    "odoo-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "ODOO_URL=https://example.com/",
        "-e",
        "ODOO_DATABASE=odoo19",
        "-e",
        "ODOO_API_KEY=your_api_key_here",
        "odoo-mcp-server"
      ]
    }
  }
}

Docker 建置

docker build -t odoo-mcp-server .

Gemini MCP 設定

gemini mcp add --scope user odoo-mcp docker -- run -i --rm --add-host=host.docker.internal:host-gateway -e ODOO_URL=http://host.docker.internal:8069 -e ODOO_DATABASE=odoo19 -e ODOO_API_KEY=your_api_key_here odoo-mcp-server
{
  "mcpServers": {
    "odoo-mcp": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--add-host=host.docker.internal:host-gateway",
        "-e",
        "ODOO_URL=http://host.docker.internal:8069",
        "-e",
        "ODOO_DATABASE=odoo19",
        "-e",
        "ODOO_API_KEY=your_api_key_here",
        "odoo-mcp-server"
      ]
    }
  }
}

安全機制

唯讀模式

設定 READONLY_MODE=true 啟用唯讀模式,適用於生產環境查詢:

  • 寫入工具(create_recordupdate_recorddelete_recordexecute_method)透過 FastMCP tags 直接隱藏,LLM 不會看到這些工具

刪除二次確認

delete_record 內建 confirm 機制,LLM 必須先以 confirm=False 呼叫取得確認提示,經使用者同意後才能以 confirm=True 執行刪除。

健康檢查

HTTP/SSE transport 模式下提供 /health 端點:

curl http://localhost:8000/health
# {"status": "healthy", "service": "odoo-mcp-server", "version": "1.0.0"}

適用於 Docker healthcheck、Kubernetes probe、load balancer 探活。stdio 模式下不影響。

License

Apache 2.0

Available Tools

9 tools
count_recordsA
Read-onlyIdempotent

Count records in an Odoo model matching the domain.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
domainNoOdoo search domain (list of conditions). Examples: - Simple: [["active", "=", True]] - Multiple (AND): [["is_company", "=", True], ["country_id", "=", 1]] - OR condition: ["|", ["type", "=", "contact"], ["type", "=", "invoice"]] - any (Odoo 19+): [["order_line", "any", [["product_uom_qty", ">", 5]]]] - Operators: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, any

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint and idempotentHint. Description adds no further behavioral context beyond the count operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence is direct and front-loaded, but could include minimal context like returning the count as an integer.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only counting tool with full annotations and output schema, the description is completely adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema covers 100% of parameters with descriptions. Description adds no additional parameter meaning beyond what schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states it counts records in an Odoo model with a domain filter, distinguishing it from siblings like search_records or read_records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description does not explicitly mention when to use this tool versus alternatives; usage is implied but not guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_recordB

Create new record(s) in an Odoo model.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
valuesYesDictionary of field values, or list of dicts for batch creation

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, and the description does not disclose behavioral traits such as idempotency, error handling, authorization requirements, or side effects beyond creation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence, front-loaded with the key action. It is not verbose, but could benefit from mentioning batch creation capability briefly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a creation tool with no annotations, the description is minimal. It does not mention required permissions, success response, or batch behavior, despite having an output schema that could cover returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the description adds no additional meaning beyond what the schema already provides for both parameters (model and values). Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly specifies the action 'create' and the resource 'record(s) in an Odoo model', which is distinct from sibling tools like update_record or delete_record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., update_record for modifications) or when not to use it. The description is silent on prerequisites or context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_recordA
DestructiveIdempotent

Delete records from an Odoo model. IRREVERSIBLE operation.

IMPORTANT: You MUST first call with confirm=False to show the user what will be deleted. Only set confirm=True AFTER the user explicitly approves the deletion. NEVER set confirm=True on the first call.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
idsYesList of record IDs to delete
confirmNoSafety flag. Always call with False first, then True only after user approval.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond annotations by emphasizing the irreversibility and the required two-step confirmation process. It adds critical behavioral context that annotations alone (destructiveHint, idempotentHint) do not fully convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, with the action stated first, followed by a clear warning and step-by-step instructions. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema and annotations covering destructiveness and idempotence, the description is complete. It provides all necessary safety protocol for a deletion operation, leaving no gaps in understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully describes the three parameters with 100% coverage. The description reinforces the confirm parameter's usage but does not add new meaning beyond what the schema provides, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the action is deleting records from an Odoo model, using a specific verb and resource. The distinction from sibling tools like create_record and update_record is evident.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to first call with confirm=False to preview deletion, then only set confirm=True after user approval. This provides clear when-to-use guidance and prevents misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_methodC

Execute any method on an Odoo model.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
methodYesMethod name to execute
argsNoPositional arguments for the method
kwargsNoKeyword arguments for the method

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It only states 'Execute any method' but omits critical behavioral traits such as potential destructive side effects, required permissions, or whether the method is idempotent. This is a major omission for such a powerful tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, but it is too brief for the tool's complexity. Conciseness is good, but it sacrifices necessary detail, making it borderline under-specified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema, the description does not mention return values. More critically, it lacks warnings about executing arbitrary methods, which is a safety concern. The tool's complexity demands far more context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for model, method, args, and kwargs. The description adds no additional meaning beyond the schema, earning a baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Execute') and resource ('any method on an Odoo model'). It distinguishes from siblings like 'create_record' or 'delete_record' which are specific CRUD operations, making it unique.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when or when not to use this tool. It does not compare to alternatives like 'create_record' or 'update_record' or mention prerequisites or typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_fieldsA
Read-onlyIdempotent

Get field information for an Odoo model using ORM fields_get().

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
field_filterNoOptional filter for field name (e.g., 'name' to find name-related fields)
fieldsNoSpecific field names to retrieve (None = all fields)
attributesNoField attributes to return (None = default attributes including type, string, help, required, readonly, store, selection, comodel_name, inverse_name, domain)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds that the tool uses the ORM's fields_get() method, but does not disclose additional behavioral traits like potential performance impact on large models or that it might return a large volume of data. Given the good annotation coverage, this is adequate but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that immediately communicates purpose and method. It contains no filler or redundant information, making it optimally concise and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only metadata retrieval tool with 4 parameters, full schema documentation, and an output schema, the description is mostly complete. It lacks mention of error cases (e.g., invalid model name) but these are partially covered by the schema descriptions. Overall, it is sufficient for an AI agent to understand basic functionality.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with all four parameters described in the input schema. The description does not add any parameter-specific semantics beyond what the schema provides. The mention of using ORM fields_get() is a general context, not parameter detail. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get field information'), the resource ('for an Odoo model'), and the method ('using ORM fields_get()'). It accurately distinguishes this tool from siblings like 'read_records' (which retrieve data rows) and 'list_models' (which list models) by specifying it returns field metadata.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, such as 'execute_method' for calling fields_get generically, or 'list_models' for getting available models. There are no usage conditions, exclusions, or prerequisites mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_modelsA
Read-onlyIdempotent

List all available Odoo models.

ParametersJSON Schema
NameRequiredDescriptionDefault
name_filterNoOptional filter for model name (e.g., 'sale' to find sale-related models)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint as true, and the description adds no additional behavioral details beyond the simple listing operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no extraneous information, efficiently conveying the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, one parameter, and existing annotations/output schema, the description adequately covers the essentials; minor gap in clarifying 'available models' scope.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains the optional name_filter parameter; the main description adds no further parameter context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'List all available Odoo models' uses a specific verb and resource, clearly distinguishing it from sibling tools that operate on records rather than models.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives, but the context implies its use when discovering available models; lack of exclusions or alternatives mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_recordsA
Read-onlyIdempotent

Read specific records by their IDs.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
idsYesList of record IDs to read
fieldsNoFields to return (None = auto-exclude dangerous fields like binary/image/html)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and idempotentHint=true, so the description adds no new behavioral traits. It does not contradict annotations but also does not elaborate on what the tool returns or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with key action and resource, no unnecessary words. Perfectly concise for a simple read tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, annotations covering safety and idempotence, full schema documentation, and presence of output schema, the description is complete. No additional context needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% description coverage, so the description adds little beyond 'by their IDs', which is already implied by the ids parameter. Baseline 3 applies as description is adequate but not enhancing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Read' and resource 'records', specifying the mechanism 'by their IDs'. This distinguishes it from sibling tools like search_records and count_records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use or when-not-to-use guidance is provided. While the purpose is clear, it does not differentiate from alternatives like search_records or get_fields, leaving the agent to infer contexts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_recordsA
Read-onlyIdempotent

Search for records in an Odoo model.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
domainNoOdoo search domain (list of conditions). Examples: - Simple: [["name", "=", "John"]] - Multiple (AND): [["is_company", "=", True], ["active", "=", True]] - OR condition: ["|", ["name", "ilike", "test"], ["email", "ilike", "test"]] - any (Odoo 19+): [["order_line", "any", [["product_uom_qty", ">", 5]]]] - Operators: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, any
fieldsNoFields to return (None = auto-exclude dangerous fields like binary/image/html)
limitNoMaximum number of records
offsetNoNumber of records to skip
orderNoSort order (e.g., 'name asc', 'create_date desc')

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is clear. The description adds no additional behavioral context (e.g., that results depend on model permissions or that it returns a list). Bar is lowered by good annotations, but the description does not add value beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that efficiently states the tool's core function with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema and annotations, the description is minimally adequate but lacks context about usage scope (e.g., domain filtering) and return behavior. Output schema exists but is not referenced.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter has a description. The tool description does not add any info beyond the schema; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Search') and resource ('records in an Odoo model'), clearly distinguishing it from sibling tools like 'read_records' (read by ID) and 'count_records'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives such as 'read_records' or 'count_records'. The description does not mention context or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_recordA
Idempotent

Update existing records in an Odoo model.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesModel name (e.g., 'res.partner')
idsYesList of record IDs to update
valuesYesDictionary of field values to update

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint: true. Description adds no extra behavioral context (e.g., what happens if record doesn't exist). It is adequate but does not go beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, no wasted words. Efficient, though could be slightly expanded with key usage details without losing conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and input schema fully describes parameters, the brief description is nearly sufficient. Minor lack of info about behavior on invalid IDs or return structure, but overall complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 3 parameters have descriptions in the schema (100% coverage). The description adds no new meaning beyond what is already in the input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Update existing records in an Odoo model' – a specific verb and resource, and implicitly distinguishes from sibling tools like create_record and delete_record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use or not use this tool vs alternatives. It is implied by context (update vs create/delete) but lacks explicit when-not-to-use or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updates
    • Changedcount_records2 fields changed
      • addedInput schema / properties / domain / description
        Added value: +"Odoo search domain (list of conditions). Examples:\n- Simple: [[\"active\", \"=\", True]]\n- Multiple (AND): [[\"is_company\", \"=\", True], [\"country_id\", \"=\", 1]]\n- OR condition: [\"|\", [\"type\", \"=\", \"contact\"], [\"type\", \"=\", \"invoice\"]]\n- any (Odoo 19+): [[\"order_line\", \"any\", [[\"product_uom_qty\", \">\", 5]]]]\n- Operators: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, any"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
    • Changedcreate_record2 fields changed
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
      • addedInput schema / properties / values / description
        Added value: +"Dictionary of field values, or list of dicts for batch creation"
    • Changeddelete_record3 fields changed
      • addedInput schema / properties / confirm / description
        Added value: +"Safety flag. Always call with False first, then True only after user approval."
      • addedInput schema / properties / ids / description
        Added value: +"List of record IDs to delete"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
    • Changedexecute_method4 fields changed
      • addedInput schema / properties / args / description
        Added value: +"Positional arguments for the method"
      • addedInput schema / properties / kwargs / description
        Added value: +"Keyword arguments for the method"
      • addedInput schema / properties / method / description
        Added value: +"Method name to execute"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
    • Changedget_fields4 fields changed
      • addedInput schema / properties / attributes / description
        Added value: +"Field attributes to return (None = default attributes including\n       type, string, help, required, readonly, store, selection,\n       comodel_name, inverse_name, domain)"
      • addedInput schema / properties / field_filter / description
        Added value: +"Optional filter for field name (e.g., 'name' to find name-related fields)"
      • addedInput schema / properties / fields / description
        Added value: +"Specific field names to retrieve (None = all fields)"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
    • Changedlist_models1 field changed
      • addedInput schema / properties / name_filter / description
        Added value: +"Optional filter for model name (e.g., 'sale' to find sale-related models)"
    • Changedread_records3 fields changed
      • addedInput schema / properties / fields / description
        Added value: +"Fields to return (None = auto-exclude dangerous fields like binary/image/html)"
      • addedInput schema / properties / ids / description
        Added value: +"List of record IDs to read"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
    • Changedsearch_records6 fields changed
      • addedInput schema / properties / domain / description
        Added value: +"Odoo search domain (list of conditions). Examples:\n- Simple: [[\"name\", \"=\", \"John\"]]\n- Multiple (AND): [[\"is_company\", \"=\", True], [\"active\", \"=\", True]]\n- OR condition: [\"|\", [\"name\", \"ilike\", \"test\"], [\"email\", \"ilike\", \"test\"]]\n- any (Odoo 19+): [[\"order_line\", \"any\", [[\"product_uom_qty\", \">\", 5]]]]\n- Operators: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, any"
      • addedInput schema / properties / fields / description
        Added value: +"Fields to return (None = auto-exclude dangerous fields like binary/image/html)"
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of records"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
      • addedInput schema / properties / offset / description
        Added value: +"Number of records to skip"
      • addedInput schema / properties / order / description
        Added value: +"Sort order (e.g., 'name asc', 'create_date desc')"
    • Changedupdate_record3 fields changed
      • addedInput schema / properties / ids / description
        Added value: +"List of record IDs to update"
      • addedInput schema / properties / model / description
        Added value: +"Model name (e.g., 'res.partner')"
      • addedInput schema / properties / values / description
        Added value: +"Dictionary of field values to update"
  2. 9 tool updatesv1.0.0
    • First observedcount_records
    • First observedcreate_record
    • First observeddelete_record
    • First observedexecute_method
    • First observedget_fields
    • First observedlist_models
    • First observedread_records
    • First observedsearch_records
    • First observedupdate_record

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a distinct purpose: count, create, delete, execute method, get fields, list models, read, search, update. No two tools overlap in functionality.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., count_records, create_record, list_models), making it predictable and easy to understand.

Tool Count5/5

9 tools is well-scoped for an Odoo server, covering essential operations without being too few or too many.

Completeness5/5

The set includes CRUD operations, search, count, field introspection, model listing, and arbitrary method execution, providing comprehensive coverage for interacting with Odoo models.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that connects AI assistants to Odoo ERP instances via the built-in XML-RPC API without requiring any additional addons. It enables users to search, create, update, and manage Odoo records and models through natural language.
    25 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server to connect Claude with Odoo 18, enabling CRUD operations on Odoo models via natural language.
    2
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A professional MCP server for seamless Odoo ERP integration, supporting HTTP and STDIO transports.
    10 npm
    MIT