Skip to content
Agentmart
Submit a tool

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

IndexedApache-2.0Local (stdio)★ 2
Write a review

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.

We use your email only for this newsletter. Privacy

About

Full Odoo access for AI agents via MCP: CRUD, website, translations, attachments, workflows.

No 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.

  • echo
  • find_skill
  • get_available_actions
  • get_defaults
  • get_fields
  • get_filters
  • get_model_actions
  • get_model_interface
  • get_models
  • get_page_arch
  • get_record
  • get_skills
Show 16 more tools
  • get_snippet
  • get_workflows
  • inspect_action
  • inspect_fields
  • inspect_view
  • list_attachments
  • list_pages
  • list_records
  • list_skills
  • list_snippets
  • list_workflows
  • ping
  • read_group
  • search_records
  • translation_audit
  • translation_get

Write 14 · Create, change, send or run things.

  • archive
  • create
  • create_page
  • download_binary
  • execute_action
  • fetch_and_upload
  • post_message
  • restart_mcp
  • schedule_activity
  • set_page_arch
  • set_page_visibility
  • translation_update
Show 2 more tools
  • update
  • upload_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_DB
  • ODOO_URL
  • ODOO_USERNAME

Network hosts it talks to 3

  • api.github.com · found in code
  • github.com · found in code
  • myodoo.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_binary

    Download 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_skill

    Find 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_actions

    Return 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_defaults

    Return 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_fields

    Return 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_filters

    Return 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_actions

    Return 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_interface

    Single-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_models

    List 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_arch

    Return 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_record

    Return 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_skills

    Return 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_snippet

    Fetch 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_workflows

    Return 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_attachments

    Search 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_pages

    List website pages. Returns id, name, url, is_published, view_id, website_id for each page.

  • list_records

    Return 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_skills

    List 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_snippets

    List 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_workflows

    List 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_message

    Post 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_group

    Count 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_activity

    Schedule 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_records

    Find 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_audit

    Audit 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_get

    Read 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
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)