Odoo Surface MCP
Full Odoo access for AI agents via MCP: CRUD, website, translations, attachments, workflows.
Connector by solutionsunity · GitHub account verified by the MCP Registry
Install
Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.
npx agentmarket install connector/solutionsunity-odoo-surface-mcp
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.
- Tools
- 28 read · 14 write · 1 delete · 1 not yet classified
- Secrets
- 1 (API keys, tokens or passwords)
- Install scripts
- None found
- Runs as
- Node.js package
Tools by what they do 44
Read from the source code; the running server may list different tools.
Read 28 · Look things up without changing anything.
echofind_skillget_available_actionsget_defaultsget_fieldsget_filtersget_model_actionsget_model_interfaceget_modelsget_page_archget_recordget_skills
Show 16 more tools
get_snippetget_workflowsinspect_actioninspect_fieldsinspect_viewlist_attachmentslist_pageslist_recordslist_skillslist_snippetslist_workflowspingread_groupsearch_recordstranslation_audittranslation_get
Write 14 · Create, change, send or run things.
archivecreatecreate_pagedownload_binaryexecute_actionfetch_and_uploadpost_messagerestart_mcpschedule_activityset_page_archset_page_visibilitytranslation_update
Show 2 more tools
updateupload_binary
Delete 1 · Delete, drop, revoke or wipe things.
clear_cache
Not yet classified 1 · We could not tell from the name and description.
dump_cache
Secrets and settings it asks for
Secrets: values you paste in that let it act as you.
ODOO_PASSWORD
Other settings (environment variables or headers).
ODOO_DBODOO_URLODOO_USERNAME
Network hosts it talks to 3
api.github.com· found in codegithub.com· found in codemyodoo.com· found in code
Files it touches
/tmp/smoke_binary_DOES_NOT_EXIST.bin/tmp/smoke_binary_dst.bin/tmp/smoke_binary_src.bin/tmp/smoke-compat-logo.png- Any path the agent passes to its tools
Tools (44)
Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].
archive💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Archive (deactivate) a record by setting active=False. Only works on models that have an active field (most standard models do). Returns {success: true} or {error}.
clear_cache[DEBUG] Clear all cache entries. Next call rebuilds from Odoo.
create💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Create a new record. values: dict of field/value pairs (form-view fields only). Defaults are merged with provided values automatically. Pass action_id to include the action's context (e.g. default_partner_id). Pass context dict directly for wizard models. Returns {id, display_name} or {error}.
create_page💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Create a website page as the website editor's "New → Page" does: a view from the default page template plus the page, with a URL made unique from the name. The page is created unpublished (publish with set_page_visibility). add_menu: also add it to the main menu. website_id: target website (default: the current one). Returns {page_id, view_id, url, menu_id?} — fill it with get_page_arch / set_page_arch.
download_binaryDownload a binary field value from an Odoo record to a local absolute path on the MCP server filesystem. The binary is decoded and written to disk — no base64 passes through the AI context. Use this as the source step in a cross-instance binary migration: call download_binary on source MCP, then upload_binary on target MCP using the same path. Returns {success, dest_path, size_bytes} or {error}.
dump_cache[DEBUG] Show cache stats and all live keys.
echo[DEBUG] Reflect payload back. Tests MCP tool-call roundtrip.
execute_action💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Execute a button or server action on a record. action: button name (method) or label as shown in get_model_actions — e.g. "action_confirm", "Confirm", "Privacy Lookup". View buttons (type=object) call the method directly; server actions use ir.actions.server.run. A button hidden on the record in its current state is refused, as in the form. Returns the Odoo action result, {success: true}, or {error}.
fetch_and_upload💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Load a file from a URL or local absolute path and store it as an Odoo ir.attachment. The MCP server handles the transfer — no binary passes through the AI context. Pass attachment_id to replace an existing attachment in-place (same ID, no arch update needed). Omit attachment_id to create a new attachment. is_image: process the file as an image (validated and optimised; Odoo rejects other files) — false for JS/CSS/HTML/JSON/fonts. Returns {id, src} usable in any context (arch_db, chatter, record field); src is /…
find_skillFind skills matching a situation. Filters by model, field_type, and/or operation against each skill's applies_to. Returns full skill records (with body) for all matches; empty array if none.
get_available_actionsReturn the buttons and actions that are actually visible for a specific record right now, based on its current field values. Mirrors what the Odoo web client shows when a user opens the form view: invisible conditions are evaluated with the web client's own evaluator against the record. Returns {visible_buttons[], server_actions[], reports[], can_create, can_write, can_delete}.
get_defaultsReturn the default field values Odoo would pre-fill when clicking New. Pass action_id to include the action's context (e.g. default_partner_id). Pass context dict directly for wizard models.
get_fieldsReturn metadata for all fields visible in a model's form or list view. view_type: "form" (default) or "list". Returns [{name, string, type, required, readonly, relation?, selection?}].
get_filtersReturn saved filters and favourites available for a model's list view. These appear in the Filters and Favourites dropdown in the Odoo UI.
get_model_actionsReturn all actions available on a model: server actions (Action menu), report actions (Print menu), and form-view buttons (type=object/action) with their invisible condition (Python expression, or a domain on Odoo 15/16). Also returns CRUD access flags for the current user.
Show 29 more tools
get_model_interfaceSingle-call planning helper: returns form-view field metadata AND all model actions (server actions, reports, view buttons) AND CRUD access flags. Use this before creating or editing records to understand the full model interface without separate get_fields + get_model_actions round trips.
get_modelsList primary models the user can navigate to via menus (get_models()), or list relational models reachable from a base model via its form-view fields (get_models({ base: "sale.order" })).
get_page_archReturn the raw arch_db XML of a website page's view. Pass page_id from list_pages. Returns {view_id, arch_db}. The AI is responsible for reading and editing this XML.
get_recordReturn form-view field values for a single record. Pass fields to fetch a specific subset instead of all form-view fields. Pass context to control read behaviour — e.g. {lang: "fr_FR"} returns field values in that language for all translate=True fields on the record.
get_skillsReturn one or more skills in full: frontmatter + markdown body + used_in back-references. Pass a single name or multiple names in the array. Missing names return {name, error} in the same array (partial success).
get_snippetFetch the ready-to-inject HTML for a website building-block snippet. Pass the snippet key (e.g. "website.s_text_image"). Returns {key, name, html} or {error}.
get_workflowsReturn one or more workflows in full: frontmatter + markdown body. Pass a single name or multiple names in the array. With expand_skills=true, each workflow also includes the full body of every skill it composes. Missing names return {name, error} in the same array (partial success).
inspect_action[DEBUG] get_model_actions' result plus the raw attributes of every form button (context, groups, class, … as the server sends them).
inspect_fields[DEBUG] Return all fields on a model — including technical fields not filtered by view visibility.
inspect_view[DEBUG] Return the compiled arch XML for a model's view. view_type: form (default), list, kanban, search.
list_attachmentsSearch ir.attachment records for any model. Returns metadata only — never binary data. Use to find existing files before uploading duplicates. src is ready to use as an image/file URL.
list_pagesList website pages. Returns id, name, url, is_published, view_id, website_id for each page.
list_recordsReturn a paginated list of records — as the list view or the Export dialog would show them. domain: Odoo domain, e.g. [["state","=","draft"]]; ANDed with the action's domain when action_id is given. fields: field names to return (any readable field; relational ones as [id, display_name]); default: the list view's columns. Pass context to control read behaviour — e.g. {lang: "fr_FR"} returns translated field values, {active_test: false} includes archived records. order: e.g. "date desc, id"; ordering by a many2one follows the related model's own order (e.g. order_id on sale.order = date_order d…
list_skillsList all atomic skills (canonical recipes for ONE thing). Returns name, summary, hint, applies_to, and used_in (workflows that compose this skill). No body — call get_skill for full text.
list_snippetsList available website building-block snippets. Optional "search" filters by any substring of the key or name (case-insensitive). Returns {available_modules: [], snippets: [{key, name, module}]}. Use get_snippet(key) to fetch the ready-to-inject HTML.
list_workflowsList all multi-step workflows. Returns name, summary, applies_to, and the skills each workflow composes. No body — call get_workflow for full text.
ping[DEBUG] Check MCP↔Odoo connectivity. Returns version and latency.
post_messagePost a plain-text message or internal note on a record (requires mail.thread). HTML in body is shown as text, as when typed in the chatter. message_type: "comment" (sent to followers) or "note" (internal log note, not emailed). Returns {message_id} or {error}.
read_groupCount and aggregate records per group — as the list view grouped by a field shows them. groupby: field names, dates with a granularity ("create_date:month"; day|week|month|quarter|year); empty for one total. aggregates: "field:agg" specs (sum, avg, min, max, count_distinct, …). domain filters the records first. Returns [{<groupby>: value, __count, <aggregate>: value}] — many2one values as [id, name], date groups as [range start, label].
restart_mcp[DEBUG] Exit the MCP server process. The MCP client detects the disconnect and relaunches the server automatically (standard stdio MCP restart pattern).
schedule_activitySchedule an activity on a record. activity_type: name of the activity type (e.g. "To-Do", "Email", "Phone Call"). deadline: ISO date string YYYY-MM-DD. summary: short title. note: longer description (optional). assigned_user_id: who to assign (default: current user). Returns {activity_id, activity_type, deadline} or {error}.
search_recordsFind records by name — "which record is called X" — with the model's own name matching (display name, plus per-model keys such as reference, email or code). domain / action_id narrow the search. For filtering by field values use list_records. Pass context for search-time behaviour — e.g. {active_test: false} finds archived records, {lang: "fr_FR"} matches and returns display_name in that language. Returns [{id, display_name}] up to limit.
set_page_arch💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Write arch_db XML to an ir.ui.view. Use view_id from get_page_arch. The caller is fully responsible for valid, well-formed XML.
set_page_visibility💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Publish or unpublish a website page.
translation_auditAudit translation coverage and integrity for translatable field(s) across one or more records. For each record×field it reports total source terms and, per target language, how many are translated and which source terms are still missing. It also returns two integrity flags: suspect_source (when base_lang is English, source terms written in Arabic script — the signature of the "translation stored as source" defect that destroys the English body) and nonempty_base (terms whose base-language value is non-empty). Use it to verify a bilingual push in one call and to catch source corruption early. …
translation_getRead all language translations for a translatable field on a record. Works on any field with translate=True (char fields: returns one entry per language) or callable translate (html / arch_db: returns one entry per translatable term per language). record_id and field_name each accept a single value OR an array (batch read in one call). langs: optional list of language codes to filter (e.g. ["fr_FR", "ar_001"]); omit to return all installed languages. Single record_id AND single field_name → {translations: [{lang, source, value}], translation_type, translation_show_source}. Any array argument →…
translation_update💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Write translations for translatable field(s). Two forms: (1) Single/same-map — pass record_id (a number or an array of ids), field_name and translations; the same translations map is applied to every id. (2) Batch — pass updates: [{record_id, field_name, translations}, ...] to write different content per record and per field in one call (e.g. name + html_content for many records). For char fields (translate=True): translations = {"fr_FR": "Bonjour", "ar_001": "مرحبا"}. For html / arch_db fields (callable transl…
update💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Update fields on an existing record. values: {field: value, ...}. Writes both form-view fields and model fields not exposed in the form view. One2many / many2many fields accept Odoo Command tuples directly: [[0,0,{vals}]] create+link, [[1,id,{vals}]] update line, [[2,id]] delete line, [[6,0,[ids]]] replace set. Pass context to control write behaviour — e.g. {lang: "fr_FR"} writes the value for that language on translate=True fields (without it, the user's language, as in the form), {mail_notrack: true} suppress…
upload_binary💡 Before multi-step work, check find_skill / list_workflows for canonical recipes. Upload a local file into an Odoo record's binary field. Reads the file at source_path (absolute path on the MCP server filesystem), encodes it, and writes it to the specified field via the ORM — no base64 in AI context. Use this as the target step in a cross-instance binary migration: call download_binary on source MCP first, then upload_binary on target MCP using the same path. Returns {success, model, record_id, field, size_bytes} or {error}.
Signals
- Stars
- 2
- Forks
- 0
- Open issues
- 2
- Last commit
- Oct 3, 2026 (25 days ago)
- Last release
- Oct 3, 2026 (25 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- Registry name
io.github.solutionsunity/odoo-surface-mcp- Version
- 0.6.1
- Auth
- API key
- Packages
- npm @suco/odoo-surface-mcp
- License
- Apache-2.0
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
Cite this page
Odoo Surface MCP. Agent Mart. https://agentmart.dev/connectors/solutionsunity-odoo-surface-mcp (last updated 2026-10-24)