odoo-hands
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ODOO_DB | Yes | The Odoo database name | |
| ODOO_URL | Yes | The URL of the Odoo instance, e.g. http://localhost:8069 | |
| ODOO_LOGIN | Yes | The Odoo login (username) | |
| ODOO_PASSWORD | Yes | The Odoo password | |
| ODOO_MCP_ALLOW_JS | No | Set to '1' to enable the evaluate_js tool. Defaults to false. | false |
| ODOO_MCP_VIDEO_DIR | No | Directory where session videos (.webm) are saved. When set, disconnect() returns the video path. | |
| ODOO_MCP_TIMEOUT_MS | No | Timeout in milliseconds for slow operations; can be raised for large databases. | |
| ODOO_MCP_ALLOW_REMOTE | No | Set to '1' to allow connections to non-localhost Odoo instances. Defaults to false (localhost only). | false |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| connectA | Open a browser on the Odoo instance and log in. Arguments default to ODOO_URL/ODOO_DB/ODOO_LOGIN/ODOO_PASSWORD from .env. Must be called before any other tool. Refuses non-localhost URLs unless ODOO_MCP_ALLOW_REMOTE=1. |
| disconnectC | Close the browser. |
| where_am_iA | Describe the current screen: menu path, model, record id, view type, record state, dirty/new flags, open dialog, notifications. |
| get_elementsA | List the interactive elements of the current screen (or of the open dialog when scope='auto'/'dialog'): fields (name, label, type, widget, value, required/readonly/invalid), buttons (name, label, kind), notebook tabs, statusbar, x2many lists with their rows, list/kanban rows, search facets, pager. include: subset of ["fields","buttons","tabs","statusbar","lists","rows","facets","pager"]. Output is compact and truncated. |
| open_menuA | Open a menu by label path ("Ventes > Commandes > Devis", separators > or /) or by xmlid ("sale.menu_sale_quotations"). Labels are matched case/accent-insensitively (exact > prefix > contains). Returns the resulting location. |
| open_recordA | Open a record (model + id) in a form, or a model's list/kanban view (view_type="list"/"kanban"). Without res_id and view_type="form", opens a blank new record. Prefer click_button("new") from a list to keep the menu's defaults. |
| set_fieldA | Set a field on the current form (or open dialog), by technical field name. Handles char/text/number, many2one (type + pick the matching suggestion; {"index": 0} picks the first suggestion, {"create": "Name"} quick-creates, {"search_more": "query"} opens the selection dialog), selection (value or label), boolean, date/datetime (ISO "2026-09-18" or "2026-09-18 14:30"), many2many tags (string or list), html. Switches notebook tab automatically when needed. For a cell of an editable list: line=<row index or "editing">, list_field=; the row is then validated (commit=True) and invalid cells are reported. Returns the value read back and the other fields changed by onchange. |
| add_lineA | Add a line to a one2many/many2many list field (e.g. order_line) and fill it: click "Add a line", set each cell in the given order (put the main many2one such as product_id first), validate the row. If required cells are missing the row stays in edition and invalid_cells lists them (fill them with set_field(..., line="editing", list_field=...)). Falls back to the popup form when the list is not editable inline. create: label of the add link when there are several. |
| delete_lineA | Remove a row from a one2many/many2many list field (e.g. order_line) by clicking its trash icon. line: 0-based row index, or "editing" for the row currently in edition. Nothing is saved until save/validate. |
| action_menuA | Pick an entry of the cog / "Actions" dropdown of the current view by label (e.g. "Delete", "Duplicate", "Archive"). A confirmation dialog, if any, is reported (changes.dialog_opened): confirm it with click_button on its button (e.g. "Delete" or "Ok"), or click_button("discard") to cancel. |
| click_buttonB | Click a button by technical name (e.g. action_confirm) or label. Also: "new", "save", "discard", "save_new", a statusbar state, a notebook tab (name or label), a dialog footer button. Waits for the resulting RPCs and reports state change, navigation, opened/closed dialog, notifications and server errors. timeout in ms for long actions. |
| click_rowA | Open a row of the current list/kanban view (0-based index, or text matched against the row content). list_field targets a one2many list inside a form instead. |
| searchA | Type in the search box of the current list/kanban. Without field, Enter takes the first suggestion (usually the name); with field="Product" (label as shown in the suggestions, matched loosely) the matching suggestion is chosen. clear=True removes existing facets first. Returns the active facets. |
| saveA | Save the current form (or the open form dialog). Reports invalid required fields and server errors. timeout in ms. |
| open_urlA | Navigate to a URL path on the connected Odoo host (e.g. "/wms/reception" for a kiosk page, or "/web" to come back to the web client). Plain HTML pages are then driven through get_elements / set_field / click_button too. |
| screenshotA | Take a PNG screenshot of the browser (saved under screenshots/ unless an absolute path is given) and return it. |
| orm_callA | Call a model method server-side through the logged-in web session (e.g. search_read, read, name_search, create for test data). Bypasses the UI: use it to prepare or verify data, not to replace the user flow. Result truncated at 20 kB. |
| evaluate_jsA | Escape hatch: evaluate a JavaScript expression in the Odoo page (async allowed; |
| export_tourB | Turn the actions performed in this session (open_menu, set_field, add_line, click_button, click_row, search, save) into an Odoo web_tour: JS tour file + HttpCase test + manifest asset line. format: all | js | python | json (raw steps). clear=True empties the recording afterwards. Review the generated selectors before committing them. |
| run_tourA | Replay the recorded actions as an Odoo web_tour inside the open browser (auto mode), to validate an export_tour result before adding it to a module. steps_js: a JS array of tour steps to run instead of the recording. Returns success/failure with the failing step description. |
| get_errorsA | Return intercepted errors: server RPC errors (with traceback), JS errors, open error dialogs, error notifications. since: only entries with seq > since. clear: empty the buffer afterwards. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 21 tools
Most tools target distinct actions (navigation, form editing, list manipulation, debugging), but some overlap exists: 'open_menu' vs 'open_record' vs 'open_url' all navigate, and 'action_menu' vs 'click_button' both handle dropdown/button actions. 'get_elements' and 'where_am_i' both describe the current screen, though with different granularity.
The naming is predominantly verb_noun (open_menu, set_field, add_line, delete_line, click_button, click_row, export_tour, run_tour, get_errors), with a few exceptions like 'where_am_i' and 'orm_call' that break the pattern. Overall the convention is clear and predictable.
21 tools is on the higher end but justified for a browser automation server covering navigation, form interaction, list editing, debugging, and tour export/replay. A few tools (evaluate_js, orm_call, export_tour, run_tour) are advanced escape hatches that could be optional, but they serve distinct purposes.
The tool set covers the full lifecycle of UI automation: connect/disconnect, orientation (where_am_i), element discovery (get_elements), navigation (open_menu, open_record, open_url), form filling (set_field, add_line, delete_line), actions (action_menu, click_button, click_row, search, save), verification (screenshot, get_errors), and even test export/replay. No obvious dead ends for the stated purpose of driving an Odoo instance.