MCP server for Odoo integration with ChatGPT, reached through an OpenAI Secure MCP Tunnel. Enables secure access to private Odoo instances without requiring public addresses.
Strong foundation with 10 well-named tools following verb_noun convention (odoo_list, odoo_get, odoo_search, odoo_read, odoo_execute). All tools have descriptions (avg ~120 chars, within 10-1024 range). Input schemas are complete with types and descriptions for all parameters. Key strengths: domain-specific parameter annotations (Model, Server, Domain, Ids), smart defaults (limit=50 for search_read to prevent unbounded reads), and clear error handling via run() wrapper. Gaps: output schemas not formally documented; no tool annotations (readOnlyHint/destructiveHint); descriptions could be more prescriptive about when to use each tool vs alternatives; odoo_execute lacks guidance on method discovery.
Who this server is connected as: user, company, timezone and language. Read this before working with dates -- Odoo stores datetimes in UTC.
Execute any public method on an Odoo model. Use this for methods not covered by the other tools.
Get field definitions for an Odoo model. Useful for understanding model structure.
List the models available on this server, with their technical and display names. Transient wizard models and anything out of scope are left out. Reading ir.model needs the Access Rights group, so a least-privilege account cannot call this.
List all configured Odoo servers.
Read specific records by their IDs from an Odoo model. IDs that do not exist are dropped silently rather than raising.
odoo_execute lacks method discovery guidance. Description says 'Use this for methods not covered by the other tools' but provides no way for LLM to learn what methods exist on a model. This forces trial-and-error or requires external Odoo documentation.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk stratification. odoo_execute is marked WRITE but lacks destructiveHint; read tools lack readOnlyHint. This prevents agents from reasoning about safety and retry semantics.
Output schemas not formally documented. Tools return JSON strings via dumps() but LLM has no schema to parse results. E.g., odoo_search_read returns records but structure is implicit, forcing LLM to infer field names.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | 2026-07-28+ | v2 |
Group records and aggregate over them -- counts, sums, averages per group. Far cheaper than reading every record and tallying them yourself.
Count records matching a search domain in an Odoo model.
Search and read records from an Odoo model. Returns records matching the search domain with the specified fields.
Get Odoo server version information.
Domain parameter description uses example syntax but does not explain when to use search_count vs search_read vs read_group. LLM must guess which tool fits the query intent.
fields_not_applied() and read_back() helper functions in tools.py suggest write operations exist but are not exposed as tools. Incomplete tool surface for a domain that likely needs create/update/delete.