Skip to main content
Glama

Panda Odoo MCP Server

Developed by

This module was developed by Paolo Nugnes and TechLab.

TechLab is a company specialized in custom software development and enterprise system integration. Visit our website www.techlab.it for more information about our services.

Overview

The Odoo MCP Server is a standardized interface for interacting with Odoo instances through the MCP (Model Context Protocol). It provides support for:

  • Communication Protocols:

    • stdio: Direct communication via stdin/stdout

    • streamable_http: HTTP communication with streaming response support

  • Resource Management:

    • Odoo records (single and list)

    • Binary fields

    • Real-time updates

  • Tools:

    • Search and read records

    • Create and update records

    • Delete records

    • Call custom methods

  • Security:

    • Authentication and session management

    • Rate limiting

    • CORS for streamable_http connections

System Requirements

Hardware Requirements

  • CPU: 2+ cores

  • RAM: 4GB minimum (8GB recommended)

  • Disk Space: 1GB minimum

Software Requirements

  • Python 3.9+

  • Odoo 15.0+

    • Required modules: base, web, bus

    • Database configured with admin user

  • Docker (optional)

Network Requirements

  • Port 8069 (Odoo)

  • Port 8080 (streamable_http, optional)

  • Port 5432 (PostgreSQL, if local)

Security Requirements

  • SSL certificate for HTTPS (production)

  • Configured firewall

  • VPN access (optional)

Installation

Direct Installation

# Clone the repository git clone https://github.com/pandeussilvae/mcp-odoo-panda.git cd mcp-odoo-panda # Install dependencies pip install . # To install with caching support pip install .[caching] # To install with development tools pip install .[dev] # Copy the example configuration file cp odoo_mcp/config/config.example.json odoo_mcp/config/config.json # Edit config.json with your settings # nano odoo_mcp/config/config.json

Docker Installation

# Clone the repository git clone https://github.com/pandeussilvae/mcp-odoo-panda.git cd mcp-odoo-panda # Start with Docker Compose docker-compose up -d

Configuration

The server can be configured through a JSON file. Several configuration templates are available:

  • config.example.json: Main template to copy and modify

  • config.dev.json: Development environment template (optional)

  • config.prod.json: Production environment template (optional)

To get started:

# Copy the example configuration file cp odoo_mcp/config/config.example.json odoo_mcp/config/config.json # Edit config.json with your settings # nano odoo_mcp/config/config.json

Selecting the Connection Type

The Odoo MCP server supports several connection types, configurable via the connection_type field in config.json. Supported values:

  • stdio: Default, direct communication via stdin/stdout

  • streamable_http: HTTP with streaming/chunked responses (real-time data flows)

  • http: Classic HTTP POST (stateless, single request/response)

Example configuration:

{ "connection_type": "streamable_http", // or "http" or "stdio" "http": { "host": "0.0.0.0", "port": 8080 } }
  • Use streamable_http for real-time streaming over HTTP (endpoint: POST /mcp)

  • Use http for classic REST requests (endpoint: POST /mcp)

  • Use stdio for direct communication (default)

Example of complete configuration:

{ "mcpServers": { "mcp-odoo-panda": { "command": "/usr/bin/python3", "args": [ "--directory", "/path/to/mcp-odoo-panda", "mcp/server.py", "--config", "/path/to/mcp-odoo-panda/odoo_mcp/config/config.json" ] } }, "odoo_url": "http://localhost:8069", "database": "my_database", "username": "admin", "api_key": "admin", "protocol": "xmlrpc", "connection_type": "streamable_http", "requests_per_minute": 120, "rate_limit_max_wait_seconds": 5, "pool_size": 5, "timeout": 30, "session_timeout_minutes": 60, "http": { "host": "0.0.0.0", "port": 8080, "streamable": true }, "logging": { "level": "INFO", "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s", "handlers": [ { "type": "StreamHandler", "level": "INFO" }, { "type": "FileHandler", "filename": "server.log", "level": "DEBUG" } ] } }

Configuration

You can configure the server via environment variables in your .env file or directly in docker-compose.yml.

Note: Environment variables (from .env or the container environment) always take precedence over values in config.json.

Main variables:

  • ODOO_URL, ODOO_DB, ODOO_USER, ODOO_PASSWORD (Odoo connection)

  • PROTOCOL, CONNECTION_TYPE, LOGGING_LEVEL (MCP server)

  • REQUESTS_PER_MINUTE, SSE_QUEUE_MAXSIZE, ALLOWED_ORIGINS (advanced)

Example .env:

ODOO_URL=http://host.docker.internal:8069 ODOO_DB=odoo ODOO_USER=admin ODOO_PASSWORD=admin PROTOCOL=xmlrpc CONNECTION_TYPE=streamable_http LOGGING_LEVEL=INFO

Starting the Server

The server can be started in two modes: stdio (default) and streamable_http. The configuration file is optional and, if not specified, the server will automatically look for the file in odoo_mcp/config/config.json.

stdio Mode (default)

# Start the server in stdio mode without specifying the configuration file python -m odoo_mcp.server # Start the server in stdio mode with a specific configuration file python -m odoo_mcp.server /path/to/config.json

streamable_http Mode

# Start the server in streamable_http mode without specifying the configuration file python -m odoo_mcp.server streamable_http # Start the server in streamable_http mode with a specific configuration file python -m odoo_mcp.server streamable_http /path/to/config.json

HTTP Modes

The Odoo MCP server supports two HTTP modes:

  1. HTTP Streaming Chunked (streamable_http):

    • Endpoint: POST /mcp

    • Keeps the connection open and streams data

    • Ideal for real-time data flows

    • Required headers:

      Content-Type: application/json Connection: keep-alive
  2. Classic HTTP POST (http):

    • Endpoint: POST /mcp

    • Handles a single request/response (stateless)

    • Standard REST behavior

    • Required headers:

      Content-Type: application/json
  3. Server-Sent Events (SSE):

    • Endpoint: GET /sse

    • Server-push event support

    • Required headers:

      Accept: text/event-stream

To configure the HTTP mode, set connection_type in config.json:

{ "connection_type": "streamable_http", // or "http" "http": { "host": "0.0.0.0", "port": 8080 } }

Example Calls

  1. HTTP Streaming Chunked:

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -H "Connection: keep-alive" \ -d '{"jsonrpc": "2.0", "method": "initialize", "id": 1}'
  1. Classic HTTP POST:

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "method": "initialize", "id": 1}'
  1. Server-Sent Events:

curl -N http://localhost:8080/sse \ -H "Accept: text/event-stream"

Server Verification

stdio Mode

# Test a request without specifying the configuration file echo '{"method": "get_resource", "params": {"uri": "odoo://res.partner/1"}}' | python -m odoo_mcp.server # Test a request with a specific configuration file echo '{"method": "get_resource", "params": {"uri": "odoo://res.partner/1"}}' | python -m odoo_mcp.server /path/to/config.json

streamable_http Mode

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -H "Connection: keep-alive" \ -d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}'

http Mode (Classic HTTP POST)

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}'

Server-Sent Events (SSE)

curl -N http://localhost:8080/sse \ -H "Accept: text/event-stream"

Usage

stdio Connection

import asyncio from mcp import Client async def main(): client = Client(connection_type="stdio") await client.initialize() # Example: Read a record resource = await client.get_resource("odoo://res.partner/1") print(resource.data) if __name__ == "__main__": asyncio.run(main())

streamable_http Connection

import asyncio from mcp import Client async def main(): client = Client(connection_type="streamable_http") await client.initialize() # Example: Read a record resource = await client.get_resource("odoo://res.partner/1") print(resource.data) if __name__ == "__main__": asyncio.run(main())

Connecting Claude Desktop to the Odoo MCP server (stdio)

To connect Claude Desktop to the Odoo MCP server using the stdio protocol:

  1. Make sure the Odoo MCP server is installed and working.

  2. Open Claude Desktop settings (Claude menu → Settings → Developer → Edit Config).

  3. Add the following configuration to the mcpServers section of your claude_desktop_config.json file:

{ "mcpServers": { "odoo-mcp": { "command": "python", "args": [ "-m", "odoo_mcp.server", "C:/absolute/path/to/your/config.json" ] } } }

Replace C:/absolute/path/to/your/config.json with the actual path to your configuration file.

  1. Save and restart Claude Desktop. You should see the MCP tools available.

Note: Claude Desktop only communicates via stdio. Do not use streamable_http for connecting with Claude Desktop.

Documentation

Complete documentation is available in the docs/ directory:

  • mcp_protocol.md: MCP protocol documentation

  • odoo_server.md: Odoo server documentation

  • server_usage.md: Server usage guide

Contributing

  1. Fork the repository

  2. Create your feature branch (git checkout -b feature/amazing-feature)

  3. Commit your changes (git commit -m 'Add amazing feature')

  4. Push to the branch (git push origin feature/amazing-feature)

  5. Open a Pull Request

License

This project is released under the MIT License. See the LICENSE file for details.

Update

Update from Source

# Update the repository git pull origin main # Reinstall the package pip install --upgrade . # Restart the server systemctl restart odoo-mcp-server

Update with Docker

# Update images docker-compose pull # Restart containers docker-compose up -d

Uninstallation

Uninstall from Source

# Uninstall the package pip uninstall odoo-mcp-server # Remove configuration files rm -rf ~/.odoo-mcp-server

Uninstall with Docker

# Stop and remove containers docker-compose down # Remove images docker-compose rm -f

Advanced Configuration

Environment Configuration

Development

{ "protocol": "xmlrpc", "connection_type": "stdio", "odoo_url": "http://localhost:8069", "database": "dev_db", "username": "admin", "api_key": "admin", "logging": { "level": "DEBUG", "handlers": [ { "type": "FileHandler", "filename": "logs/dev.log", "level": "DEBUG" } ] } }

Production

{ "protocol": "jsonrpc", "connection_type": "streamable_http", "odoo_url": "https://odoo.example.com", "database": "prod_db", "username": "admin", "api_key": "your-secure-api-key", "http": { "host": "0.0.0.0", "port": 8080, "streamable": true }, "logging": { "level": "INFO", "handlers": [ { "type": "FileHandler", "filename": "logs/prod.log", "level": "INFO" } ] } }

Configuration Backup

# Backup configuration cp odoo_mcp/config/config.json odoo_mcp/config/config.json.backup # Restore configuration cp odoo_mcp/config/config.json.backup odoo_mcp/config/config.json

Advanced Usage

Error Handling

from odoo_mcp.error_handling.exceptions import ( AuthError, NetworkError, ProtocolError ) try: await client.get_resource("odoo://res.partner/1") except AuthError as e: logger.error(f"Authentication error: {e}") # Error handling except NetworkError as e: logger.error(f"Network error: {e}") # Error handling except ProtocolError as e: logger.error(f"Protocol error: {e}") # Error handling

Best Practices

  1. Connection Management:

    async with Client() as client: await client.initialize() # Operations
  2. Cache Management:

    # Cache configuration cache_config = { 'enabled': True, 'ttl': 300, 'max_size': 1000 }
  3. Session Management:

    # Create session session = await client.create_session() # Validate session if await client.validate_session(session_id): # Operations

Troubleshooting

Common Issues

  1. Connection Error:

    ERROR: Could not connect to Odoo server

    Solution:

    • Verify that Odoo is running on port 8069

    • Check that the firewall allows access to port 8069

    • Verify that the Odoo URL in the configuration file is correct

    • Check that the database is accessible

  2. Authentication Error:

    ERROR: Authentication failed

    Solution:

    • Verify that username and api_key in the configuration file are correct

    • Check that the user has the necessary permissions in the Odoo database

    • Verify that the specified database exists

    • Check that the base, web, and bus modules are installed

  3. Protocol Error:

    ERROR: Protocol error

    Solution:

    • Verify that the specified protocol (xmlrpc/jsonrpc) is supported

    • Check that the Odoo version is compatible (15.0+)

    • Verify that the connection type (stdio/streamable_http) is correct

    • Check the logs for specific error details

  4. Rate Limiting Error:

    ERROR: Rate limit exceeded

    Solution:

    • Increase the requests_per_minute value in the configuration file

    • Implement a retry mechanism with backoff

    • Optimize requests to reduce the number of calls

  5. Cache Error:

    ERROR: Cache error

    Solution:

    • Verify that the configured cache type is supported

    • Check that there is sufficient space for the cache

    • Temporarily disable the cache if necessary

Error Logs

Important note: In the current version, the Odoo MCP server can write logs to multiple destinations depending on configuration:

  • If the logging section in config.json includes a StreamHandler, logs are written to the console (stderr).

  • If a FileHandler is present, logs are also written to a file at the path specified by filename.

  • If there is no logging, logs are written only to stderr (console).

Example:

"logging": { "level": "INFO", "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s", "handlers": [ { "type": "StreamHandler", "level": "INFO" }, { "type": "FileHandler", "filename": "server.log", "level": "DEBUG" } ] }
  • In this example, logs go both to the console and to the file server.log in the directory where you start the server.

  • You can change the log file path by editing the filename field (e.g., "filename": "logs/dev.log" or an absolute path).

Support

For technical support:

  1. Check the documentation

  2. Open an issue

  3. Contact support@techlab.it

Running with Docker

You can run the Odoo MCP Server in a Docker container using the provided Dockerfile and docker-compose.yml.

Quick Start

docker-compose up -d

This will:

  • Build the image from the Dockerfile.

  • Start the MCP server on port 8080 (default).

  • Persist logs in the ./logs directory.

Configuration

You can configure the server via environment variables in your .env file or directly in docker-compose.yml.

Main variables:

  • ODOO_URL, ODOO_DB, ODOO_USER, ODOO_PASSWORD (Odoo connection)

  • PROTOCOL, CONNECTION_TYPE, LOGGING_LEVEL (MCP server)

  • REQUESTS_PER_MINUTE, SSE_QUEUE_MAXSIZE, ALLOWED_ORIGINS (advanced)

Example .env:

ODOO_URL=http://host.docker.internal:8069 ODOO_DB=odoo ODOO_USER=admin ODOO_PASSWORD=admin PROTOCOL=xmlrpc CONNECTION_TYPE=streamable_http LOGGING_LEVEL=INFO

Custom Configuration File

You can mount your own config file:

volumes: - ./odoo_mcp/config/config.json:/app/odoo_mcp/config/config.json

Accessing the Server

  • HTTP streaming: POST http://localhost:8080/mcp

  • SSE: GET http://localhost:8080/sse

Stopping the Server

docker-compose down
-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pandeussilvae/mcp-odoo-panda'

If you have feedback or need assistance with the MCP directory API, please join our Discord server