Skip to main content
Glama

Odoo MCP Server Advanced

by AlanOgic
CLAUDE.md10.5 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **Odoo MCP Server Advanced** - An MCP (Model Context Protocol) server providing AI assistants with full access to Odoo ERP systems through just two universal tools. **Core Philosophy**: Radical simplicity - two tools (`execute_method` and `batch_execute`) provide complete Odoo API access rather than dozens of specialized tools. ## Architecture ### Two-Layer Design **1. MCP Server Layer** (`src/odoo_mcp/server.py`) - Built on FastMCP 2.12+ (MCP 2025 spec) - 2 universal tools: `execute_method`, `batch_execute` - 10+ MCP resources for discovery (models, schemas, workflows) - 3 user-facing prompts - Smart limits: DEFAULT_LIMIT=100, MAX_LIMIT=1000 records **2. Odoo Client Layer** (`src/odoo_mcp/odoo_client.py`) - Supports JSON-2 API (Odoo 19+) and JSON-RPC (legacy) - Bearer token authentication with automatic refresh - Singleton pattern via `get_odoo_client()` - HTTP proxy support, configurable SSL verification ### Key Design Decisions **Why only 2 tools?** - `execute_method`: Call ANY Odoo method on ANY model - `batch_execute`: Execute multiple operations atomically - Specialized tools were removed in v1.0 (redundant/broken) - Focus on documentation (COOKBOOK.md) over tool proliferation **Smart Limits System**: - Prevents accidentally returning GBs of data (e.g., all mail.message records) - Auto-applies DEFAULT_LIMIT=100 if user doesn't specify - Caps at MAX_LIMIT=1000 (user can override with pagination) - Warns for unlimited queries (limit=0 or limit=false) ## Development Commands ### Setup & Running ```bash # Install with dev dependencies pip install -e ".[dev]" # Run STDIO transport (Claude Desktop) python run_server.py # Enhanced logging to ./logs/ python -m odoo_mcp # Standard entry point uvx --from . odoo-mcp # Zero-install runner # Run SSE transport (web browsers) python run_server_sse.py # Port 8009 # Run HTTP transport (API integrations) python run_server_http.py # Port 8008 ``` ### Code Quality ```bash # Format code black . isort . # Lint ruff check . # Type checking mypy src/ # Run all checks before committing black . && isort . && ruff check . && mypy src/ ``` ### Building & Publishing ```bash # Build package python -m build # Publish to PyPI twine upload dist/* # Build Docker images docker build -t mcp/odoo:latest -f Dockerfile . docker build -t mcp/odoo:sse -f Dockerfile.sse . docker build -t mcp/odoo:http -f Dockerfile.http . ``` ## Configuration ### Environment Variables **Required:** ```bash ODOO_URL=https://your-instance.odoo.com ODOO_DB=your-database ODOO_USERNAME=your-username ODOO_PASSWORD=your-password-or-api-key ``` **Optional:** ```bash ODOO_API_VERSION=json-2 # "json-2" (Odoo 19+) or "json-rpc" (legacy) ODOO_API_KEY=your_api_key # For JSON-2 API (replaces password) ODOO_TIMEOUT=30 # Connection timeout (default: 30s) ODOO_VERIFY_SSL=true # SSL verification (default: true) HTTP_PROXY=http://proxy.com # HTTP proxy for Odoo connection ``` ### Configuration Files 1. `.env` - Environment variables (preferred) 2. `./odoo_config.json` - JSON config file 3. `~/.config/odoo/config.json` - User config ## Package Structure ``` mcp-odoo-adv/ ├── src/odoo_mcp/ │ ├── __init__.py # Package initialization │ ├── __main__.py # CLI entry point (odoo-mcp command) │ ├── server.py # MCP server (800+ lines) │ │ ├── Tools: execute_method, batch_execute │ │ ├── Resources: discovery resources │ │ ├── Prompts: user-facing templates │ │ └── Smart Limits: Automatic data size protection │ └── odoo_client.py # Odoo API client (500+ lines) │ ├── JSON-2 API support (Bearer token) │ ├── JSON-RPC fallback (legacy) │ └── Session management ├── run_server.py # STDIO runner (enhanced logging) ├── run_server_sse.py # SSE runner (port 8009) ├── run_server_http.py # HTTP runner (port 8008) ├── pyproject.toml # Package config (setuptools, Python 3.10+) ├── fastmcp.json # MCP metadata ├── README.md # User documentation ├── COOKBOOK.md # 40+ usage examples for your personal knowledge ├── USER_GUIDE.md # Setup guide ├── CHANGELOG.md # Version history └── DOCS/ ├── CLAUDE.md # Detailed technical reference (850+ lines) ├── TRANSPORTS.md # Transport details └── LICENSE # MIT license ``` ## Common Development Tasks ### Adding a New MCP Resource 1. Add resource decorator in `src/odoo_mcp/server.py`: ```python @mcp.resource( "odoo://your-resource/{param}", description="Resource description", annotations={"audience": ["assistant"], "priority": 0.8} ) def get_your_resource(param: str) -> str: """Docstring""" odoo_client = get_odoo_client() # Implementation return json.dumps(result, indent=2) ``` 2. Document in README.md and DOCS/CLAUDE.md 3. Add example to COOKBOOK.md if user-facing ### Modifying Smart Limits Edit constants in `src/odoo_mcp/server.py:800-802`: ```python DEFAULT_LIMIT = 100 # Auto-applied if not specified MAX_LIMIT = 1000 # Hard cap on user requests ``` Logic is in `execute_method` tool (lines 800-930). ### Supporting a New Odoo API Version 1. Update `src/odoo_mcp/odoo_client.py:_execute()` method 2. Add authentication logic in `__init__()` or `_connect()` 3. Update environment variable handling in `get_odoo_client()` 4. Document in README.md under "Advanced Usage" ### Adding a New Transport 1. Create `run_server_[transport].py` based on existing patterns 2. Create corresponding `Dockerfile.[transport]` 3. Update DOCS/TRANSPORTS.md with usage 4. Add to README.md Quick Start section ## Testing & Debugging ### Manual Testing ```bash # Test with real Odoo instance (requires .env configuration) python test_transports_real.py # Test smart limits system python test_limits.py ``` ### Debugging Tips **View logs:** ```bash # Real-time log monitoring tail -f logs/mcp_server_*.log # Search for errors grep -i error logs/mcp_server_*.log # View authentication details python -m odoo_mcp 2>&1 | grep -i auth ``` **Common Issues:** 1. **Authentication failures**: Check ODOO_URL includes `https://`, verify credentials 2. **Connection timeouts**: Increase ODOO_TIMEOUT environment variable 3. **SSL errors**: Set ODOO_VERIFY_SSL=false (not recommended for production) 4. **Smart limits blocking queries**: Override with explicit limit in kwargs_json ## Critical Implementation Details ### Domain Normalization (server.py:806-905) `execute_method` automatically normalizes search domains to handle multiple input formats: ```python # Supported formats: [["field", "=", "value"]] # Odoo native {"conditions": [{...}]} # Object format '[["field", "=", "value"]]' # JSON string ["field", "=", "value"] # Single condition (auto-wrapped) ``` Process: unwraps nested domains → converts objects → parses JSON → validates → preserves logic operators ### Smart Limits Logic (server.py:800-930) Applied to `search`, `search_read`, `search_count` methods: 1. Check if user provided `limit` in kwargs 2. If not: apply DEFAULT_LIMIT=100 3. If yes but > MAX_LIMIT: cap at 1000, log warning 4. If limit=0 or false: allow but log warning about massive datasets 5. Log if result ≥ MAX_LIMIT ### Authentication Flow **JSON-2 API (Odoo 19+)**: - Bearer token in Authorization header - Database name in X-Odoo-Database header - Automatic token refresh via session cookies **JSON-RPC (legacy)**: - Initial authenticate call to get UID - UID + password sent with every request - Deprecated in Odoo 20 (fall 2026) ## Important Patterns ### Reading Odoo API Results Always check `success` field before accessing `result`: ```python response = execute_method(model="res.partner", method="search_read", ...) if not response['success']: print(f"Error: {response['error']}") else: records = response['result'] # Process records ``` ### Efficient Querying ```python # ✅ Good: Specify fields + filter + limit execute_method( model="mail.message", method="search_read", args_json='[[["model", "=", "crm.lead"], ["date", ">=", "2025-01-01"]]]', kwargs_json='{"fields": ["date", "subject", "author_id"], "limit": 100}' ) # ❌ Bad: No filters or field selection (returns ALL fields for ALL records) execute_method(model="mail.message", method="search_read") ``` ### Pagination Pattern ```python # Count first count = execute_method(model="your.model", method="search_count", args_json='[[...]]') total = count['result'] # Then paginate for page in range((total // 100) + 1): execute_method( model="your.model", method="search_read", args_json='[[...]]', kwargs_json=f'{{"limit": 100, "offset": {page * 100}}}' ) ``` ## Version Compatibility - **Python**: 3.10+ (configured in pyproject.toml) - **FastMCP**: 2.12+ (MCP 2025-06-18 spec) - **Odoo**: 14+ (JSON-2 API requires 19+) - **MCP Protocol**: 2025-06-18 specification ## References - **Detailed Technical Docs**: `DOCS/CLAUDE.md` (850+ lines with complete API reference) - **Usage Examples**: `COOKBOOK.md` (40+ practical examples) - **Setup Guide**: `USER_GUIDE.md` (step-by-step installation) - **Transport Options**: `DOCS/TRANSPORTS.md` (STDIO, SSE, HTTP details) - **MCP Specification**: https://spec.modelcontextprotocol.io/ - **FastMCP Framework**: https://gofastmcp.com - **Odoo API Docs**: https://www.odoo.com/documentation/ ## Notes for Claude Code - This project emphasizes **simplicity over features** - resist adding specialized tools - **COOKBOOK.md is the main documentation** - add examples there, not new tools - Smart limits are intentionally restrictive - document pagination patterns instead - All Odoo errors are passed through directly - they're excellent and self-explanatory - Use `context7` MCP tool to verify latest Odoo API changes before modifying client code - Never add `Claude Code` attribution to commit messages (per user configuration)

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/AlanOgic/mcp-odoo-adv'

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