A flexible MCP server for Odoo that supports dynamic database, user, and password configuration via environment variables. Enables interaction with Odoo CRM, sales, and contact management through MCP tools.
The Odoo MCP server demonstrates moderate definition quality with proper schemas and descriptions for most tools, but has notable gaps in error handling guidance, output schema documentation, and some parameter descriptions lack actionable constraints. All 10 tools have input schemas visible in Pydantic models and descriptions present. Naming is verb-first and generally clear (odoo_get_*, odoo_search_*, odoo_create_*, odoo_update_*, odoo_delete_*). However, descriptions are somewhat generic and often lack context about when to use each tool vs alternatives. Output schemas are not documented, responses are returned as JSON strings with fmt() helper, but the structure of what fields each tool returns is not explicitly declared to the LLM. Error handling is minimal, most errors will be raw exceptions rather than actionable recovery guidance. The 'values' parameters in create/update tools accept JSON as strings, which is error-prone and lacks validation hints.
Create a new record in any Odoo model with specified field values.
Delete or archive a record from any Odoo model.
Get field definitions and metadata for any Odoo model.
Get current Odoo server info: URL, database name, authenticated user, and server version.
List all available databases on the connected Odoo server.
Quickly create or update a contact (res.partner) with common fields.
Quickly create a CRM lead or opportunity with common fields.
JSON string parameters ('values', 'domain', 'order_lines') lack validation and error guidance. LLMs cannot easily construct valid JSON, and malformed JSON yields cryptic XML-RPC errors instead of actionable feedback.
No documented output schemas. Tools return JSON strings via fmt(data), but the LLM does not know which fields to expect. E.g., what does odoo_search_records return? Field names? IDs? Metadata? This forces agents to parse unstructured responses.
Error handling is not implemented. Raw Python exceptions will be returned to the LLM with stack traces instead of recovery guidance. E.g., 'Authentication failed' should tell the agent to check environment variables, not dump an XML-RPC exception.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | 2026-07-28+ | v2 |
Quickly create a sales order with a customer and optional order lines.
Search records in any Odoo model with optional domain filters, field selection, and pagination.
Update an existing record in any Odoo model.
Destructive operations (odoo_delete_record, odoo_update_record, odoo_create_record) lack confirmation or dry-run patterns. An agent mistake could delete records irreversibly.
Tool descriptions are generic and lack context for tool selection. 'Create a new record in any Odoo model' does not explain when to use odoo_quick_contact vs odoo_create_record. LLMs cannot disambiguate.
odoo_search_records 'domain' parameter description references JSON format ([["name","ilike","John"]]) but does not explain Odoo domain syntax or valid operators. LLMs will struggle to construct correct domains without guidance.
odoo_quick_order 'order_lines' parameter accepts JSON as a string without validation. If JSON is malformed, the LLM gets an unhelpful XML-RPC error. Validation should parse JSON early and return clear error messages.
No pagination documentation. odoo_search_records accepts limit/offset but does not state max result count, total count in response, or cursor behavior. LLMs cannot know if results are truncated.
Credentials are read from environment variables, which is correct server-side injection. However, the tool descriptions do not document the required env vars. If connection fails, the LLM has no recovery path.