Skip to main content
Glama

MCP for Claude & ChatGPT

Update records

odoo_write
Destructive

Update fields on one or more existing Odoo records. The model must be on the workspace's write whitelist with can_write=true; sensitive fields cannot be set. Runs in one call, except a write with force_workflow (see that parameter). Hard limit of 200 ids per call: split a longer list into batches. context sets the company scope.

A WRITE REPLACES THE WHOLE VALUE OF EVERY FIELD YOU PASS — it never merges. On long-form fields (description, internal notes, …) that is destructive and unrecoverable: the previous value leaves no trace in the chatter. If the user asked you to ADD to or COMPLETE such a field, pass mode='append' with only the new content; the default mode='replace' is for when they want what is there discarded. To change PART of an html field, use odoo_html (edit / replace_section) instead of rewriting it. Html fields take markdown, converted the Odoo way: - [ ]/- [x] checklists, pipe tables, ##/### sections, --- separators. No inline style, invented classes or invented image URLs.

READ THE ANSWER BEFORE REPORTING: Odoo accepts fields it will not keep (computed, screen-only) and still says success, so the result carries ignored (with the reason), unverified and warnings. Their absence means everything landed. Report what was saved in Odoo, never that the change already shows on the user's screen.

SEND INTERDEPENDENT FIELDS IN ONE CALL: Odoo respects a field you write explicitly alongside the ones that would recompute it, but across two calls the second write recomputes over the first and silently discards it.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "model": "<model>",
      "ids": "<ids>",
      "values": "<values>"
    },
    "name": "odoo_write"
  }
}

Input Schema

NameRequiredDescriptionDefault
idsYesRecord IDs to update (max 200).
modeNo'replace' (default) overwrites every field with what you send. 'append' keeps the current content of the html/text fields and puts yours below it, per record — use it whenever the user asked to add to or complete a description or a note. Other field types are replaced in both modes.replace
modelYesOdoo model technical name.
valuesYesField-value dict applied to every id.
contextNoOptional Odoo context.
force_workflowNoOnly after a `workflow_field` refusal, and only when the user explicitly asked to set that field by hand anyway (a data fix). It skips the refusal. In Tuqui's chat the write then returns a preview and runs only once the user replied to it in a later turn.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedInput schema / properties / confirm
      Removed value: -{
      -  "default": false,
      -  "description": "Set to true to proceed past the preview. Over 50 records it only counts when the user already replied to a preview you showed them: setting it in the same turn as the preview returns the preview again.",
      -  "type": "boolean"
      -}
    • changedInput schema / properties / force_workflow / description
      Previous value: -"Only after a `workflow_field` refusal, and only when the user explicitly asked to set that field by hand anyway (a data fix). It skips the refusal, and the write then returns a preview: in a chat it runs only once the user replied to it in a later turn; over MCP, on a second call after that preview."New value: +"Only after a `workflow_field` refusal, and only when the user explicitly asked to set that field by hand anyway (a data fix). It skips the refusal. In Tuqui's chat the write then returns a preview and runs only once the user replied to it in a later turn."
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, but the description adds substantial context beyond them: the can_write whitelist and sensitive-field refusal, the unrecoverable whole-value replacement on long-form fields with no chatter trace, the inability to merge interdependent fields across calls, and the fact that Odoo reports success for computed/screen-only fields that are actually discarded. It even explains the preview-then-execute flow in chat for force_workflow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the hard limits, then the destructive-semantics warning, then result-reading guidance — a sensible escalation order for a destructive tool. It is long and uses capitalized emphasis headers that partly repeat themselves (replace/append is explained twice), but given the stakes of an unrecoverable write, nearly every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description discloses the shape of the response (`ignored` with reason, `unverified`, `warnings`) and how to interpret absent fields, plus permissions, batching, recompute ordering, and the preview flow. For a 6-parameter destructive mutation with nested values, nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: `context` is described as setting company scope (the schema only says "Optional Odoo context"), and the rewrite-vs-append distinction is grounded in concrete field types and user intent. The remaining duplication of mode/force_workflow semantics, which the schema already documents, keeps this at 4 rather than 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ("Update fields on one or more existing Odoo records") and immediately bounds the scope (existing records, whitelisted model). It also distinguishes itself from siblings by name, pointing to odoo_html for partial html edits, so an agent can route correctly without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use rules for the alternatives: mode='append' when the user asked to add to or complete a long-form field, mode='replace' only when the current value should be discarded, odoo_html when editing part of an html field, and force_workflow only after a workflow_field refusal with explicit user intent. Batching guidance for >200 ids is stated as an operational rule, not left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.