Search, read, create, write and unlink cover any model in the database, and `odoo_call_method` reaches the business methods behind the buttons in the Odoo UI. That is real power and real reach: the credentials you configure are an Odoo login, and delete works on every model that account can touch, so give it a user scoped to what you actually want reachable.
A Python server that puts a standard interface in front of an Odoo instance. Records are addressable as resources under `odoo://{model}/{id}` URIs, including binary fields, and the tools map onto Odoo's own ORM verbs rather than inventing a new vocabulary.
- `odoo_search_read` searches a model with an Odoo domain and returns the fields you name
- `odoo_read` fetches specific record ids; `odoo_create` creates a record from a values dictionary
- `odoo_write` updates records in place and `odoo_unlink` deletes them
- `odoo_call_method` calls any method on a model, such as action_confirm, for the operations the CRUD verbs do not cover
- Records, record lists and binary fields are exposed as resources over `odoo://` URIs
- Session management, rate limiting and CORS handling are built in
- Three transports: stdio, classic HTTP POST, and streamable HTTP with chunked responses; SSE is available at GET /sse
Python 3.9+ and Odoo 15.0+ with the base, web and bus modules installed and an admin user configured. Configuration lives in `odoo_mcp/config/config.json`, copied from the example, but environment variables always win: `ODOO_URL`, `ODOO_DB`, `ODOO_USER`, `ODOO_PASSWORD`, plus `PROTOCOL` (xmlrpc or jsonrpc), `CONNECTION_TYPE` and `LOGGING_LEVEL`. The Python package is `mcp-odoo-panda`, version 0.1.1, with the entry point `odoo-mcp-server`; Docker Compose is included and serves HTTP on port 8080. Claude Desktop must use stdio.
