Panda Odoo
An MCP server for integrating with the Odoo ERP system.
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 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.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/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_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:
-
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
- Endpoint:
-
Classic HTTP POST (
http
):- Endpoint:
POST /mcp
- Handles a single request/response (stateless)
- Standard REST behavior
- Required headers:
Content-Type: application/json
- Endpoint:
-
Server-Sent Events (SSE):
- Endpoint:
GET /sse
- Server-push event support
- Required headers:
Accept: text/event-stream
- Endpoint:
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.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:
- 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
mcpServers
section of yourclaude_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.
- 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-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
-
Connection Management:
async with Client() as client: await client.initialize() # Operations
-
Cache 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 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
-
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
-
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
-
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
- Increase the
-
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 inconfig.json
includes aStreamHandler
, logs are written to the console (stderr). - If a
FileHandler
is 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.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:
- 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 -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
Related Servers
Obsidian Nexus
Connects directly to your local Obsidian vault for seamless note management and data organization.
Coze Workflow
An MCP server to execute Coze workflows locally via a Python script.
Vault MCP
An Obsidian plugin that embeds an MCP server to interact with your notes using AI.
MCPComputerUse
A native C# MCP server for Windows automation using direct Windows API integration. It runs as a self-contained executable with no additional runtime required.
Browser
Interact with and control your web browser via a browser extension.
PDF Reader
Read text, metadata, and page count from PDF files securely within the project context.
Esa MCP Server
A MCP server for the document sharing service esa.io.
Job Tracker AI
An AI-powered chat server for tracking job interview processes, integrated with Supabase.
MCP Documentation Service
A service for reading, writing, and managing markdown documentation with frontmatter metadata.
Readwise Reader
An MCP server for the Readwise Reader API to access and manage your articles and highlights.