Provides a standardized interface for interacting with Odoo instances, enabling operations such as searching, reading, creating, updating, and deleting records, managing binary fields, and calling custom methods.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Panda Odoo MCP Serverlist all sales orders from the last 7 days"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.jsonDocker 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 -dConfiguration
The server can be configured through a JSON file. Several configuration templates are available:
config.example.json: Main template to copy and modifyconfig.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.jsonSelecting 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/stdoutstreamable_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_httpfor real-time streaming over HTTP (endpoint:POST /mcp)Use
httpfor classic REST requests (endpoint:POST /mcp)Use
stdiofor 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=INFOStarting 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.jsonstreamable_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.jsonHTTP Modes
The Odoo MCP server supports two HTTP modes:
HTTP Streaming Chunked (
streamable_http):Endpoint:
POST /mcpKeeps the connection open and streams data
Ideal for real-time data flows
Required headers:
Content-Type: application/json Connection: keep-alive
Classic HTTP POST (
http):Endpoint:
POST /mcpHandles a single request/response (stateless)
Standard REST behavior
Required headers:
Content-Type: application/json
Server-Sent Events (SSE):
Endpoint:
GET /sseServer-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
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}'Classic HTTP POST:
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "initialize", "id": 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.jsonstreamable_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:
Make sure the Odoo MCP server is installed and working.
Open Claude Desktop settings (Claude menu → Settings → Developer → Edit Config).
Add the following configuration to the
mcpServerssection of yourclaude_desktop_config.jsonfile:
{
"mcpServers": {
"odoo-mcp": {
"command": "python",
"args": [
"-m",
"odoo_mcp.server",
"C:/absolute/path/to/your/config.json"
]
}
}
}Replace
C:/absolute/path/to/your/config.jsonwith the actual path to your configuration file.
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 documentationodoo_server.md: Odoo server documentationserver_usage.md: Server usage guide
Contributing
Fork the repository
Create your feature branch (
git checkout -b feature/amazing-feature)Commit your changes (
git commit -m 'Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)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-serverUpdate with Docker
# Update images
docker-compose pull
# Restart containers
docker-compose up -dUninstallation
Uninstall from Source
# Uninstall the package
pip uninstall odoo-mcp-server
# Remove configuration files
rm -rf ~/.odoo-mcp-serverUninstall with Docker
# Stop and remove containers
docker-compose down
# Remove images
docker-compose rm -fAdvanced 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.jsonAdvanced 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 handlingBest Practices
Connection Management:
async with Client() as client: await client.initialize() # OperationsCache Management:
# Cache configuration cache_config = { 'enabled': True, 'ttl': 300, 'max_size': 1000 }Session Management:
# Create session session = await client.create_session() # Validate session if await client.validate_session(session_id): # Operations
Troubleshooting
Common Issues
Connection Error:
ERROR: Could not connect to Odoo serverSolution:
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
Authentication Error:
ERROR: Authentication failedSolution:
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
Protocol Error:
ERROR: Protocol errorSolution:
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
Rate Limiting Error:
ERROR: Rate limit exceededSolution:
Increase the
requests_per_minutevalue in the configuration fileImplement a retry mechanism with backoff
Optimize requests to reduce the number of calls
Cache Error:
ERROR: Cache errorSolution:
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
loggingsection inconfig.jsonincludes aStreamHandler, logs are written to the console (stderr).If a
FileHandleris present, logs are also written to a file at the path specified byfilename.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.login the directory where you start the server.You can change the log file path by editing the
filenamefield (e.g.,"filename": "logs/dev.log"or an absolute path).
Support
For technical support:
Check the documentation
Open an issue
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 -dThis will:
Build the image from the Dockerfile.
Start the MCP server on port 8080 (default).
Persist logs in the
./logsdirectory.
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=INFOCustom Configuration File
You can mount your own config file:
volumes:
- ./odoo_mcp/config/config.json:/app/odoo_mcp/config/config.jsonAccessing the Server
HTTP streaming:
POST http://localhost:8080/mcpSSE:
GET http://localhost:8080/sse
Stopping the Server
docker-compose down