Skip to content

angelmoya/mcp-odoorpc

Repository files navigation

Odoo MCP Server

An MCP server implementation that integrates with Odoo ERP systems, enabling AI assistants to interact with Odoo data and functionality through the Model Context Protocol.

This project is a fork and modification of the original mcp-odoo by Lê Anh Tuấn, adapted to use the odoorpc library and allow protocol selection.

Features

  • Comprehensive Odoo Integration: Full access to Odoo models, records, and methods
  • ODOO RPC Communication: Secure connection to Odoo instances via odoorpc, supporting JSON-RPC and XML-RPC protocols (and their SSL variants).
  • Flexible Protocol Selection: Specify jsonrpc, xmlrpc, jsonrpc+ssl, or xmlrpc+ssl in the configuration.
  • Flexible Configuration: Support for config files and environment variables
  • Resource Pattern System: URI-based access to Odoo data structures
  • Error Handling: Clear error messages for common Odoo API issues
  • Stateless Operations: Clean request/response cycle for reliable integration

Tools

  • execute

    • Execute a custom method on an Odoo model
    • Inputs:
      • model (string): The model name (e.g., 'res.partner')
      • method (string): Method name to execute
      • args (optional array): Positional arguments
      • kwargs (optional object): Keyword arguments
    • Returns: Dictionary with the method result and success indicator
  • search_employee

    • Search for employees by name
    • Inputs:
      • name (string): The name (or part of the name) to search for
      • limit (optional number): The maximum number of results to return (default 20)
    • Returns: Object containing success indicator, list of matching employee names and IDs, and any error message
  • search_holidays

    • Searches for holidays within a specified date range
    • Inputs:
      • start_date (string): Start date in YYYY-MM-DD format
      • end_date (string): End date in YYYY-MM-DD format
      • employee_id (optional number): Optional employee ID to filter holidays
    • Returns: Object containing success indicator, list of holidays found, and any error message

Resources

  • odoo://models

    • Lists all available models in the Odoo system
    • Returns: JSON array of model information
  • odoo://model/{model_name}

    • Get information about a specific model including fields
    • Example: odoo://model/res.partner
    • Returns: JSON object with model metadata and field definitions
  • odoo://record/{model_name}/{record_id}

    • Get a specific record by ID
    • Example: odoo://record/res.partner/1
    • Returns: JSON object with record data
  • odoo://search/{model_name}/{domain}

    • Search for records that match a domain
    • Example: odoo://search/res.partner/[["is_company","=",true]]
    • Returns: JSON array of matching records (limited to 10 by default)

Configuration

Odoo Connection Setup

The Odoo connection parameters for the OdooClient (and thus the MCP Server) are determined through a combination of a JSON configuration file and environment variables.

1. Configuration File:

The system attempts to load connection details from a JSON configuration file. The path to this file is determined as follows:

  • Highest precedence: If the ODOO_CONFIG_FILE_PATH_FROM_CLI environment variable is set, its value is used as the path.
  • Fallback: The get_odoo_client function accepts a config_file_param argument. If not provided when calling get_odoo_client, it defaults to looking for config/odoo_config.json (this path is relative to the project root, e.g., mcp-odoorpc/config/odoo_config.json). The odoo_config.json.example file in the repository root shows the expected structure.

Example odoo_config.json:

{
  "host": "your-odoo-instance-hostname",
  "port": 8069,
  "db": "your-database-name",
  "username": "your-username",
  "password": "your-password-or-api-key",
  "protocol": "jsonrpc"
}

Supported protocols for the "protocol" field are: "jsonrpc", "jsonrpc+ssl", "xmlrpc", and "xmlrpc+ssl".

2. Environment Variables:

Individual Odoo connection parameters can also be set using environment variables. These environment variables take precedence over any values found in the loaded configuration file.

  • ODOO_HOST: Odoo server hostname or IP address.
  • ODOO_PORT: Odoo server port (must be an integer).
  • ODOO_DB: Database name.
  • ODOO_USERNAME: Login username.
  • ODOO_PASSWORD: Login password or API key.
  • ODOO_PROTOCOL: Connection protocol (e.g., jsonrpc). If not set and not in the config file, jsonrpc is the default used by OdooClient.

The OdooClient initialization logic (within get_odoo_client) first determines the configuration file path, loads the file if it exists and is valid, and then overrides these settings with any corresponding specific environment variables (ODOO_HOST, ODOO_PORT, etc.) that are set.

Usage with Claude Desktop

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "odoo": {
      "command": "python",
      "args": [
        "-m",
        "odoo_mcp_rpc"
      ],
      "env": {
        "ODOO_URL": "https://your-odoo-instance.com",
        "ODOO_DB": "your-database-name",
        "ODOO_USERNAME": "your-username",
        "ODOO_PASSWORD": "your-password-or-api-key",
        "ODOO_PROTOCOL": "jsonrpc"
      }
    }
  }
}

Docker

{
  "mcpServers": {
    "odoo": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "ODOO_URL",
        "-e",
        "ODOO_DB",
        "-e",
        "ODOO_USERNAME",
        "-e",
        "ODOO_PASSWORD",
        "-e",
        "ODOO_PROTOCOL",
        "mcp/odoorpc"
      ],
      "env": {
        "ODOO_URL": "https://your-odoo-instance.com",
        "ODOO_DB": "your-database-name",
        "ODOO_USERNAME": "your-username",
        "ODOO_PASSWORD": "your-password-or-api-key",
        "ODOO_PROTOCOL": "jsonrpc"
      }
    }
  }
}

Using OdooClient Directly

The OdooClient class, located in odoorpc_mcp.odoo_client, provides a direct Python interface for interacting with an Odoo instance. While this client is a core component of the MCP Odoo Server, it can also be used independently in other Python scripts or applications that need to communicate with Odoo.

Initialization:

The get_odoo_client helper function is the recommended way to obtain an initialized OdooClient instance. This function automatically handles loading connection parameters from the configuration file and environment variables, as described in the "Configuration" section.

from odoorpc_mcp.odoo_client import get_odoo_client

# The client will be initialized based on the effective configuration
# (config file + environment variables).
# You can optionally specify a direct path to a config file:
# client = get_odoo_client(config_file_param="custom_config/my_odoo_settings.json")
client = get_odoo_client()

if client:
    print(f"Successfully connected to Odoo. UID: {client.uid}")
    # You can now use the client instance to interact with Odoo.
    # For example, to get the Odoo version (requires odoorpc instance access):
    # print(f"Odoo version: {client.odoo.version}")
else:
    print("Failed to initialize Odoo client. Please check your configuration and Odoo server accessibility.")

Key Methods of OdooClient:

The OdooClient instance provides several methods to interact with Odoo:

  • client.get_models(): Retrieves a list of all available models in the connected Odoo instance, along with their descriptive names.

    • Returns: A dictionary like {"model_names": ["res.partner", ...], "models_details": {"res.partner": {"name": "Partner"}, ...}}.
  • client.get_model_info(model_name): Fetches detailed information about a specific model (e.g., 'res.partner').

    • model_name (str): The technical name of the model.
    • Returns: A dictionary containing model metadata.
  • client.get_model_fields(model_name, attributes=None): Gets the definitions of fields for a given model.

    • model_name (str): The technical name of the model.
    • attributes (list, optional): A list of field attributes to retrieve (e.g., ['string', 'type', 'help', 'relation']). Defaults to a common set of attributes if None.
    • Returns: A dictionary where keys are field names and values are dictionaries of their attributes.
  • client.search_read(model_name, domain, fields=None, offset=0, limit=None, order=None): Performs a search on a model using an Odoo domain and reads the specified fields from the matching records.

    • model_name (str): The model to search on.
    • domain (list): An Odoo search domain, e.g., [('is_company', '=', True), ('customer_rank', '>', 0)].
    • fields (list, optional): List of field names to read. Reads a default set if None (behavior might vary by Odoo version or model).
    • offset (int, optional): Number of records to skip.
    • limit (int, optional): Maximum number of records to return.
    • order (str, optional): Order specification string (e.g., 'name ASC').
    • Returns: A list of dictionaries, where each dictionary represents a record.
  • client.read_records(model_name, ids, fields=None): Reads specific records by their Odoo IDs.

    • model_name (str): The model of the records.
    • ids (list): A list of integer record IDs.
    • fields (list, optional): List of field names to read.
    • Returns: A list of dictionaries representing the records.
  • client.execute(model_name, method_name, *pos_args, **kw_args): Executes an arbitrary method on the specified Odoo model.

    • model_name (str): The model on which to execute the method.
    • method_name (str): The name of the method to call.
    • *pos_args: Positional arguments to be passed to the Odoo method. For example, if an Odoo method is def do_something(self, records, name): ..., you would call it as client.execute('your.model', 'do_something', list_of_record_ids, 'some_name').
    • **kw_args: Keyword arguments to be passed to the Odoo method.
    • Returns: The result from the Odoo method execution.

Example Usage:

# Assuming 'client' is an initialized OdooClient instance from the previous example.
if client:
    try:
        # Example 1: Get and print the first 5 models
        models_data = client.get_models()
        if not models_data.get("error") and models_data.get("model_names"):
            print("Available Models (first 5):")
            for model_name in models_data["model_names"][:5]:
                details = models_data["models_details"].get(model_name, {})
                print(f"  - {model_name} (Name: {details.get('name', 'N/A')})")
        else:
            print(f"Could not retrieve models: {models_data.get('error', 'Unknown error')}")

        print("\n" + "-"*20 + "\n") # Separator

        # Example 2: Search for 'res.partner' records that are companies
        print("Searching for company partners (limit 3):")
        company_partners = client.search_read(
            model_name="res.partner",
            domain=[("is_company", "=", True)],
            fields=["name", "email", "phone"],
            limit=3
        )

        if company_partners:
            for partner in company_partners:
                print(f"  - Name: {partner.get('name', 'N/A')}, "
                      f"Email: {partner.get('email', 'N/A')}, "
                      f"Phone: {partner.get('phone', 'N/A')}")
        elif company_partners == []: # Explicitly check for empty list vs None or error
            print("  No company partners found matching the criteria.")
        else: # Indicates an issue if search_read returned something unexpected (e.g. None or error dict)
            print("  Could not perform search or an error occurred.")

    except ConnectionError as ce:
        print(f"A connection error occurred: {ce}")
    except Exception as e:
        print(f"An unexpected error occurred during Odoo operations: {e}")

Installation

From PyPI (Recommended)

Note: This package is not yet available on PyPI. Please use the "From Source Code" method below for now.

pip install odoorpc-mcp

From Source Code

  1. Clone the repository:

    git clone https://github.com/angelmoya/mcp-odoorpc.git
    cd mcp-odoorpc
  2. Install the package (use -e for an editable install if you plan to make changes):

    pip install .
    # For an editable install:
    # pip install -e .

Running the Server

# Using the installed package
odoorpc-mcp

# Using the MCP development tools (from project root)
mcp dev src/odoorpc_mcp/server.py

# With additional dependencies
mcp dev src/odoorpc_mcp/server.py --with pandas --with numpy

# Mount local code for development (from project root)
mcp dev src/odoorpc_mcp/server.py --with-editable .

Build

Docker build:

docker build -t mcp/odoorpc:latest -f Dockerfile .

Parameter Formatting Guidelines

When using the MCP tools for Odoo, pay attention to these parameter formatting guidelines:

  1. Domain Parameter:

    • The following domain formats are supported:
      • List format: [["field", "operator", value], ...]
      • Object format: {"conditions": [{"field": "...", "operator": "...", "value": "..."}]}
      • JSON string of either format
    • Examples:
      • List format: [["is_company", "=", true]]
      • Object format: {"conditions": [{"field": "date_order", "operator": ">=", "value": "2025-03-01"}]}
      • Multiple conditions: [["date_order", ">=", "2025-03-01"], ["date_order", "<=", "2025-03-31"]]
  2. Fields Parameter:

    • Should be an array of field names: ["name", "email", "phone"]

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

 
 
 

Contributors