Saltar a contenido

Referencia de herramientas

Novedades en v1.6.0

Siguen siendo 28 herramientas (25 con el perfil standard).

  • odoo_version agrega un bloque plugin: la versión de odoo-tools que respondió y, en Claude Code, su copia instalada. Ver odoo_version.
  • odoo_execute en Odoo 10 a 12: una clave de un objeto pasado por posición a un método de negocio que no es campo del modelo ni clave de contexto permitida se rechaza (regla context). Ver odoo_execute.

Novedades en v1.5.1

Sin cambios en la lista de herramientas: siguen siendo 28 (25 con el perfil standard). La política revisa como contexto un objeto que odoo_execute pasa por posición, porque Odoo 10 a 12 lo toman como contexto (ver el límite conocido 10). Las herramientas solo corren en Claude Code; en Cowork y Claude chat, /odoo-tools:odoo-doctor te dice dónde usarlas.

Novedades en v1.5.0

  • Política de permisos: siguen siendo 28 herramientas, pero el perfil por defecto standard lista 25: odoo_unlink, odoo_add_field y odoo_add_automation necesitan otro perfil. Una herramienta oculta que se llama por su nombre explica por qué. Ver Política de permisos.
  • Read-only mode ya no lista las 9 herramientas de escritura.
  • odoo_report queda obsoleta: devuelve un error sin llamar a Odoo y se retira en la 2.0.0. Usa odoo_record_documents.
  • odoo_version devuelve un bloque policy; odoo_access_check agrega policy; odoo_list_models agrega hidden_by_policy; odoo_online_profile reporta en unavailable una sección que la política retiene.
  • Los campos con aspecto de credencial se retiran de las lecturas y el resultado los nombra en policy_withheld_fields.
  • Las herramientas de escritura declaran destructiveHint en sus anotaciones.
  • odoo_connections ya no devuelve el user:pass@ de la URL.
  • odoo_add_automation en Odoo 10 llena el campo de disparador kind de base.action.rule.

Novedades en v1.4.1

Sin cambios en las herramientas: la v1.4.1 es una versión de documentación y diagnóstico. Las herramientas solo están disponibles en Claude Code (ver Dónde funciona).

Novedades en v1.4.0

  • 28 herramientas (antes 22): seis para Odoo Online, útiles en cualquier Odoo 10-19. Ver Odoo Online.
  • odoo_execute acepta ids de primer nivel, así la misma llamada funciona en JSON-2 y en los transportes clásicos.
  • odoo_read_group usa formatted_read_group desde saas~18.4 y conserva sus argumentos y su salida clásica.
  • odoo_version inicia sesión antes de responder y agrega transport_notice en Odoo 19+.

El servidor MCP expone 28 herramientas (19 de lectura y 9 de escritura). Cuántas se listan depende del perfil de permisos: 25 con standard (el valor por defecto), 19 con readonly o con Read-only mode, y 28 con builder y full (ver Herramientas que lista cada perfil). Todas las operaciones sobre modelos pasan por la capa de compatibilidad: puedes usar nombres modernos de modelos y campos, y el servidor los resuelve a lo que exista en la versión destino. Los campos no disponibles se descartan con una advertencia dropped_fields en lugar de fallar toda la llamada. Las herramientas funcionan igual por JSON-2, JSON-RPC y XML-RPC, salvo donde se indica.

Fuera del perfil full, los campos con aspecto de credencial (contraseñas, tokens, llaves) se retiran de lo que devuelven las lecturas y el resultado los nombra en policy_withheld_fields.

Herramientas de escritura

Nueve herramientas modifican datos o pueden tener efectos: odoo_create, odoo_write, odoo_unlink, odoo_execute, odoo_translate_set, odoo_add_field, odoo_add_automation, odoo_import_preview y odoo_import. Están marcadas abajo con ESCRIBE. Con Read-only mode (ODOO_READONLY=1) el servidor no las lista y las rechaza todas antes de tocar Odoo. Fuera de ese modo, la política de permisos decide cada llamada encima de los derechos del usuario de Odoo (perfil standard por defecto: sin borrados, sin cambios estilo Studio, sin correos de salida salvo notas internas, sin secretos). El núcleo público no aplica flujos de aprobación (eso vive en una capa de gobernanza privada). Usa un usuario de mínimo privilegio y revisa cada escritura. Sus anotaciones MCP declaran destructiveHint: false en odoo_create, odoo_add_field y odoo_import_preview, true en las demás.

En Odoo 10 a 12, antes de escribir sobre account.move o account.invoice lee la advertencia de Compatibilidad: son modelos distintos (asientos vs. facturas) y nombrar el equivocado puede escribir sobre registros con otra semántica. Nombra explícitamente el modelo correcto.

Resumen

Herramienta Tipo Qué hace
odoo_search lectura Busca y devuelve ids
odoo_search_count lectura Cuenta registros
odoo_read lectura Lee registros por id
odoo_search_read lectura Busca y lee en una llamada
odoo_read_group lectura Agrupa y agrega en el servidor (GROUP BY)
odoo_export_records_json lectura Exporta a JSON
odoo_export_records_csv lectura Exporta a CSV
odoo_version lectura Versión/edición/despliegue/transporte
odoo_connections lectura Sesiones activas
odoo_list_models lectura Lista modelos
odoo_fields_get lectura Campos de un modelo (cacheado)
odoo_module_info lectura Estado de un módulo
odoo_telemetry_preview lectura Muestra el payload de telemetría opt-in (nunca lo envía)
odoo_translate_get lectura Lee una traducción
odoo_report lectura (obsoleta) Devuelve un error sin llamar a Odoo; usa odoo_record_documents. Se retira en la 2.0.0
odoo_online_profile lectura Serie y línea, despliegue, transporte, API keys y su caducidad, límites de Odoo Online
odoo_api_catalog lectura Métodos de un modelo con sus nombres de parámetros
odoo_access_check lectura Qué puede leer, escribir, crear y borrar el usuario, y si puede exportar
odoo_record_documents lectura Adjuntos de un registro y el PDF guardado de una factura
odoo_create escribe Crea un registro
odoo_write escribe Actualiza registros
odoo_unlink escribe Elimina registros (perfiles builder y full)
odoo_execute escribe Llama a cualquier método del modelo
odoo_translate_set escribe Fija una traducción
odoo_add_field escribe Agrega un campo personalizado (Studio-style; perfiles builder y full)
odoo_add_automation escribe Crea una automatización (Studio-style; perfiles builder y full)
odoo_import_preview escribe Prueba una importación con el importador de Odoo, sin guardar
odoo_import escribe Importa filas en una sola llamada atómica

Lectura y consulta

Busca un modelo y devuelve los ids que coinciden.

Parámetro Requerido Tipo Notas
model sí string nombre moderno o histórico
domain no array dominio de búsqueda de Odoo
limit / offset / order no - paginación y orden
odoo_search { "model": "sale.order", "domain": [["state","=","sale"]], "limit": 5 }

odoo_search_count

Cuenta los registros que coinciden con un dominio (sin traer datos).

odoo_search_count { "model": "account.move", "domain": [["state","=","posted"]] }

odoo_read

Lee registros por id, opcionalmente limitando los campos.

Parámetro Requerido Tipo
model sí string
ids sí array de enteros
fields no array de strings
odoo_read { "model": "res.partner", "ids": [7, 9], "fields": ["name","email"] }

odoo_search_read

Busca y lee en una sola llamada: la herramienta de consulta principal.

Parámetro Requerido Tipo
model sí string
domain, fields, limit, offset, order no -
odoo_search_read {
  "model": "account.move",
  "domain": [["state","=","posted"]],
  "fields": ["name","amount_total","invoice_date"],
  "limit": 10, "order": "invoice_date desc"
}

odoo_read_group

Agrega en el servidor (GROUP BY): la base de datos agrupa y suma en lugar de devolver todas las filas. Funciona en Odoo 10 a 19 y devuelve { model, groups }. El nombre del modelo se resuelve; los nombres de fields y groupby se pasan tal cual.

Hasta saas~18.3 usa el read_group clásico. Desde saas~18.4 usa formatted_read_group en todos los transportes (19.0 marca obsoleto el read_group clásico y Odoo Online saas~19.1 a saas~19.4 no lo tiene), y conserva los argumentos y la salida clásica: las claves <groupby>_count / __count, __domain, __context en agrupación lazy, etiquetas de fecha con __range, y orderby. Un campo sin agregador por defecto aparece en dropped_fields: pide campo:sum (u otro operador) explícitamente. Desde Odoo 17.0 cada elemento de fields debe ser campo, campo:agg o nombre:agg(campo); cualquier texto de más se rechaza con un CompatError antes de llamar a Odoo.

Parámetro Requerido Tipo Notas
model sí string nombre moderno o histórico
fields sí array de strings campos de agrupación más agregados, p. ej. "expected_revenue:sum"
groupby sí array de strings p. ej. ["stage_id"] o ["invoice_date:month"]
domain no array dominio de búsqueda de Odoo
limit / offset / orderby no - paginación y orden de los grupos
lazy no boolean default true: agrupa solo por el primer campo de groupby
odoo_read_group { "model": "crm.lead", "fields": ["stage_id","expected_revenue:sum"], "groupby": ["stage_id"] }

odoo_export_records_json

Exporta los registros que coinciden con un dominio como arreglo JSON (solo lectura). Mismos parámetros que odoo_search_read. Devuelve { model, count, records }.

odoo_export_records_json { "model": "product.template", "fields": ["name","list_price"], "limit": 500 }

odoo_export_records_csv

Igual que el anterior pero devuelve texto CSV. Los valores many2one se aplanan a su nombre visible. Devuelve { model, count, columns, csv }.

odoo_export_records_csv { "model": "res.partner", "domain": [["customer_rank",">",0]], "fields": ["name","email","city"] }

Metadatos e introspección

odoo_version

Sin parámetros. Inicia sesión y devuelve version, raw_version, edition, deployment, el transport activo (json2, jsonrpc, xmlrpc o jsonrpc(auto)) y transport_notice: null, o en Odoo 19+ por qué se usan /xmlrpc o /jsonrpc y cómo pasar a JSON-2.

Desde la v1.5.0 agrega policy: el perfil, el archivo, el digest, las herramientas ocultas, las aperturas, las advertencias (W10 cuando el usuario de Odoo es administrador) o el error que bloqueó la política. Con la política bloqueada es la única herramienta disponible, y responde sin contactar a Odoo. Ver Qué reportan las herramientas.

Desde la v1.6.0 agrega plugin: la versión de odoo-tools que respondió y, en Claude Code, su copia instalada, por ejemplo {"name": "odoo-tools", "version": "1.6.0", "copy": "odoo-tools@transgenia-odoo-tools"}. Con dos copias instaladas, dice cuál corre. Está también con la política bloqueada. Una respuesta sin policy viene de una copia anterior a la 1.5.0: la ruta guiada y /odoo-tools:odoo-doctor se detienen ahí (ver Dos copias de odoo-tools).

odoo_version {}

odoo_connections

Sin parámetros. Lista las instancias Odoo con sesión activa en el servidor. Desde la v1.5.0 quita de la URL que reporta el user:pass@ de una autenticación básica delante de Odoo, en todos los perfiles.

odoo_connections {}

odoo_list_models

Lista modelos, opcionalmente filtrados por un fragmento de nombre. Deja fuera los modelos en los que la política de permisos no permite nada y devuelve cuántos son en hidden_by_policy.

Parámetro Requerido Tipo Notas
like no string fragmento (case-insensitive)
limit no integer default 200
odoo_list_models { "like": "sale", "limit": 50 }

odoo_fields_get

Devuelve las definiciones de campos de un modelo (cacheado). Acepta nombres históricos o modernos.

Parámetro Requerido Tipo
model sí string
attributes no array de strings
odoo_fields_get { "model": "account.move", "attributes": ["string","type","required"] }

odoo_module_info

Estado de instalación y metadatos de un módulo por su nombre técnico.

odoo_module_info { "name": "web_enterprise" }

odoo_telemetry_preview

Sin parámetros. Muestra el payload exacto de telemetría opt-in que podrías compartir, o opted_in: false si la telemetría está apagada (el default; se activa con ODOO_TELEMETRY=opt-in). Solo lectura: nunca transmite nada. Devuelve { opted_in, payload, note }. Ver Privacidad.

odoo_telemetry_preview {}

odoo_translate_get

Lee el valor de un campo en un idioma específico para un registro.

Parámetro Requerido Tipo Notas
model sí string
id sí integer
field sí string
lang sí string p. ej. es_MX, en_US, zh_CN
odoo_translate_get { "model": "product.template", "id": 42, "field": "name", "lang": "en_US" }

odoo_report (obsoleta)

Obsoleta desde la v1.5.0; se retira en la 2.0.0

odoo_report siempre devuelve un error sin llamar a Odoo. Usaba el método privado ir.actions.report._render_qweb_pdf, que Odoo rechaza por RPC en todas las versiones, así que nunca pudo funcionar. Lo dice incluso antes de que haya una conexión configurada, porque nunca pide una sesión. Para obtener un PDF usa odoo_record_documents, que devuelve los documentos que Odoo ya guardó (por ejemplo el PDF de una factura generado al enviarla o imprimirla).

Conserva sus parámetros (report_name, ids) para que una llamada existente reciba el error con su remedio en lugar de un error de validación.


Escritura

Cada escritura pasa por la política de permisos: primero se decide con los argumentos, antes de iniciar sesión (capa A), y luego cada llamada a Odoo se revisa otra vez con sus valores y rutas al enviarse (capa B), incluidos los registros que cambian sus comandos x2many. Un rechazo nombra el perfil, la regla y qué lo cambia.

odoo_create ESCRIBE

Crea un registro. Devuelve el nuevo id.

Parámetro Requerido Tipo
model sí string
values sí object
odoo_create { "model": "res.partner", "values": { "name": "ACME S.A.", "email": "hola@acme.mx" } }

odoo_write ESCRIBE

Actualiza registros por id.

Parámetro Requerido Tipo
model sí string
ids sí array de enteros
values sí object
odoo_write { "model": "res.partner", "ids": [15], "values": { "phone": "+52 55 0000 0000" } }

Elimina registros por id. Con el perfil por defecto standard no se lista y los borrados se rechazan: archiva en su lugar con odoo_write { ..., "values": { "active": false } } donde el modelo tiene campo active. Se lista con builder (que solo borra en modelos de personalización, salvo que un archivo de política abra unlink) y con full.

odoo_unlink { "model": "res.partner", "ids": [999] }

odoo_execute ESCRIBE

Llama a un método público arbitrario del modelo (escape hatch). Puede cambiar datos, así que Read-only mode lo rechaza. No pasa por la resolución de edición, así que úsalo con criterio.

Bajo la política de permisos, odoo_execute es la operación call, más la clase del método (un unlink por odoo_execute es un borrado). Los métodos que leen datos (search_read, read_group, web_search_read, onchange y otros) se revisan como lecturas, y el resultado de cualquier otro método se redacta. Los métodos de salida (message_post a contactos, message_subscribe, send_mail, etc.) se rechazan salvo que sean una nota interna (message_post con subtype_xmlid "mail.mt_note" y sin partner_ids) o que un archivo de política los liste para ese modelo. Solo se aceptan ciertas claves de contexto, y los valores default_<campo> tienen límites propios: ver Claves de contexto. Como Odoo 10 a 12 toman como contexto un objeto pasado por posición después de los parámetros del método, la política también lo revisa con esas reglas (ver el límite conocido 10): pasa el contexto por nombre, en kwargs. Desde la v1.6.0, en Odoo 10 a 12, una clave de un objeto pasado por posición a un método de negocio que no es campo del modelo ni clave de contexto permitida se rechaza (regla context), y si los campos del modelo no se pueden leer, la llamada se rechaza (regla unverified). Ver Reglas integradas.

Parámetro Requerido Tipo Notas
model sí string
method sí string
ids no array de enteros registros de un método de registro (write, unlink, copy, action_*); omítelo en métodos de modelo como search o create
args no array argumentos posicionales (estilo execute_kw; el primero son los ids de un método de registro)
kwargs no object argumentos con nombre, p. ej. {"fields": ["name"]}

La forma ids + kwargs funciona en todos los transportes, incluido JSON-2 (Odoo 19+), que solo acepta argumentos con nombre. Los args posicionales se nombran en JSON-2 con la tabla del plugin de los métodos que conoce; si la sobrecarga de un modelo usa otros nombres, Odoo la rechaza antes de ejecutar nada y el plugin corrige los nombres o, en auto, envía esa llamada por JSON-RPC/XML-RPC. Los nombres que pasas en kwargs nunca se cambian. Para conocer los nombres de parámetros, usa odoo_api_catalog.

odoo_execute { "model": "account.move", "method": "action_post", "ids": [128] }

odoo_translate_set ESCRIBE

Fija la traducción de un campo para un idioma. En Odoo 16+ usa la API nativa update_field_translations; en versiones anteriores escribe el campo bajo el contexto de idioma. La capa de compatibilidad elige el camino correcto.

Parámetro Requerido Tipo
model sí string
id sí integer
field sí string
lang sí string
value sí string
odoo_translate_set { "model": "product.template", "id": 42, "field": "name", "lang": "en_US", "value": "Wireless mouse" }

odoo_add_field ESCRIBE

Agrega un campo personalizado a un modelo (estilo Odoo Studio, funciona en CE y EE). Crea un registro ir.model.fields manual (state='manual'); el nombre se fuerza al prefijo requerido x_. Necesita el perfil builder o full (con standard no se lista). Ver Personalización low-code.

Parámetro Requerido Tipo Notas
model sí string modelo destino, por ejemplo res.partner
name sí string nombre del campo; se le antepone x_ si falta
label sí string etiqueta visible (field_description)
field_type sí string char, text, html, boolean, integer, float, monetary, date, datetime, many2one, one2many, many2many, selection
relation no string co-modelo para tipos relacionales
relation_field no string campo inverso para one2many
selection no array para selection: lista de pares [valor, etiqueta]
required no boolean default false
help no string texto de ayuda
odoo_add_field { "model": "res.partner", "name": "loyalty_points", "label": "Puntos de lealtad", "field_type": "integer" }

odoo_add_automation ESCRIBE

Crea una acción automatizada (estilo Studio) que ejecuta código de server action en un disparador del modelo. El código Python se valida contra el safe_eval de Odoo antes de enviarse (crítico en Odoo online/SaaS). Se adapta al esquema de base.automation de la versión destino (en Odoo 10, base.action.rule, cuyo campo de disparador se llama kind; desde la v1.5.0 la herramienta lo llena). Necesita el perfil builder o full (con standard no se lista). Ver Personalización low-code.

Parámetro Requerido Tipo Notas
model sí string
name sí string
code sí string Python bajo safe_eval: usa env, model, record(s), datetime...; asigna action = {...} en la última línea para devolver una acción
trigger no string on_create, on_write, on_create_or_write (default), on_unlink
filter_domain no array dominio opcional que condiciona el disparador
odoo_add_automation {
  "model": "crm.lead",
  "name": "Marcar leads calientes",
  "trigger": "on_create_or_write",
  "code": "for rec in records:\n    if rec.probability and rec.probability > 80:\n        rec.write({'priority': '3'})"
}

safe_eval

El código de automatización corre bajo el safe_eval de Odoo: sin import, def, class, return, with ni acceso a nombres/atributos con guion bajo o dunder, y sin asignar atributos (rec.campo = valor compila a STORE_ATTR y se rechaza: usa rec.write({...})). La herramienta rechaza esos constructos antes de enviar. Detalle en Personalización low-code.


Odoo Online (útiles en cualquier Odoo)

Seis herramientas cubren lo que una base de Odoo Online complica: sin Python propio, acceso a la API solo en planes Custom, API keys que caducan (18+), una nueva línea saas~X.Y cada pocos meses, sin renderizado de PDF por RPC, y la importación como vía autorizada para cargas masivas. Funcionan en cualquier Odoo 10-19 y se degradan según la versión. En Odoo Online, dosifica el trabajo masivo: alrededor de 1 llamada por segundo, sin llamadas en paralelo.

odoo_online_profile

Sin parámetros. Una sola lectura con: la serie y la línea (19.0 o saas~19.2), el despliegue y qué tan segura es esa detección (deployment_confidence), el transporte, si JSON-2 y el catálogo /doc-bearer de Odoo están disponibles, el aviso de obsolescencia y cuándo desaparecen /xmlrpc y /jsonrpc, el usuario y sus compañías, 2FA, las API keys del usuario con su caducidad (solo nombres y fechas, nunca el material de la key), las aplicaciones instaladas, los módulos de datos importados, Studio, y los límites de Odoo Online (plan Custom, alrededor de 1 llamada/s, de 5 a 200 correos al día, solo módulos de datos). Lo que una versión no tiene vuelve como null.

Odoo 10-19; API keys desde 14, caducidad desde 18. En 19.0 la lista de módulos necesita un administrador. Desde la v1.5.0, una sección que la política de permisos retiene aparece en unavailable en lugar de hacer fallar la herramienta.

odoo_online_profile {}

odoo_api_catalog

Los métodos públicos de un modelo con sus nombres de parámetros en orden, si cada uno es de modelo (no recibe ids) y si es de solo lectura, para JSON-2 y la forma ids + kwargs de odoo_execute. En Odoo 19.0+ con la API key de un administrador lee el catálogo propio de la base (/doc-bearer, con caché por ETag): los nombres exactos de ese modelo, incluidos métodos propios y de Studio. Si no, devuelve la tabla integrada del plugin: los nombres base desde saas~18.4 (la sobrecarga de un modelo puede renombrar un parámetro) y sin nombres (parameters: null) de la 10.0 a saas~18.3, donde odoo_execute usa args posicionales. source dice de dónde vienen y note por qué. Máximo 100 métodos; los campos están en odoo_fields_get.

Parámetro Requerido Tipo Notas
model sí string nombre técnico, p. ej. res.partner
method no string fragmento del nombre del método (sin distinguir mayúsculas)
odoo_api_catalog { "model": "res.partner", "method": "write" }

odoo_access_check

Qué puede hacer el usuario conectado (el dueño de la credencial configurada) en un modelo: leer, escribir, crear y borrar, y export_allowed (grupo base.group_allow_export, Odoo 16+). Por defecto revisa los permisos de acceso del modelo; con ids en Odoo 18+ cuentan también las reglas de registro de esos registros. Usa has_access en Odoo 18+ y check_access_rights en 10-17. No cambia nada. Desde la v1.5.0 devuelve también policy ({operación: true o false} según la política de permisos) junto a la respuesta de Odoo, con una nota en notes cuando Odoo permite una operación que la política rechaza.

Parámetro Requerido Tipo Notas
model sí string nombre técnico, p. ej. sale.order
operations no array de strings read, write, create, unlink; por defecto las cuatro
ids no array de enteros hasta 1000 ids para una revisión por registro (Odoo 18+)
odoo_access_check { "model": "sale.order", "operations": ["write"], "ids": [42] }

odoo_record_documents

Lista los archivos adjuntos de un registro (id, nombre, tipo MIME, tamaño en bytes, fecha de creación) y marca su adjunto principal y, en facturas (Odoo 17+), el PDF guardado de la factura, que una búsqueda simple de adjuntos no muestra. Con attachment_id e include_content: true también devuelve ese archivo en base64, solo si pertenece a ese registro y mide como máximo max_bytes. Es la forma de obtener PDFs: estas herramientas no renderizan reportes (odoo_report está obsoleta). Devuelve documentos que Odoo ya guardó (p. ej. el PDF que se generó al enviar o imprimir la factura). Odoo 10-19. Sus llamadas internas a ir.attachment están ancladas al registro pedido (ver ir.attachment queda anclado a su padre).

Parámetro Requerido Tipo Notas
model sí string p. ej. account.move
res_id sí integer id del registro
attachment_id no integer un adjunto de ese registro (un id del listado)
include_content no boolean default false; devuelve el archivo de attachment_id en base64
max_bytes no integer default 1048576 (1 MiB), máximo 5242880 (5 MiB)
limit no integer adjuntos listados, los más nuevos primero; default 50, máximo 500
odoo_record_documents { "model": "account.move", "res_id": 128 }

odoo_import_preview ESCRIBE

Prueba una importación con el importador propio de Odoo (base_import, Odoo 16-19): devuelve los errores y avisos por fila que Odoo reportaría y would_import, el número de registros que crearía o actualizaría. No importa nada: Odoo revierte la ejecución, pero aun así puede consumir números de secuencia y disparar efectos fuera de la base (p. ej. webhooks de acciones automatizadas). Por eso Read-only mode la rechaza. Necesita JSON-RPC o JSON-2 (no XML-RPC).

Parámetro Requerido Tipo Notas
model sí string p. ej. res.partner
fields sí array de strings nombres de columna de load(), p. ej. ["name", "email", "country_id"]; campo/id recibe un id externo, id lleva el id externo del propio registro (máximo 100)
rows sí array de arrays de strings una lista de cadenas por registro, en el orden de fields (celdas CSV: fechas AAAA-MM-DD, números con . decimal, many2one por nombre o con campo/id); máximo 500 filas
odoo_import_preview {
  "model": "res.partner",
  "fields": ["name", "email"],
  "rows": [["ACME S.A.", "hola@acme.mx"], ["Beta S.A.", "info@beta.mx"]]
}

odoo_import ESCRIBE

Importa filas en un modelo con load() de Odoo, en una sola llamada atómica: se guardan todas las filas o ninguna, y los errores dicen por qué. Devuelve los ids creados o actualizados, cuántos son y los mensajes de Odoo. Una columna id lleva identificadores externos: una fila cuyo id externo ya existe actualiza ese registro en lugar de crear uno. Mismos fields y rows que odoo_import_preview, máximo 500 filas por llamada. Odoo 12-19, por JSON-RPC o JSON-2.

Las importaciones necesitan create y write en el modelo bajo la política de permisos, y cada columna se revisa como una ruta (una columna hacia un one2many crea y escribe líneas en su comodelo). Las importaciones a res.partner que tocan el correo de contactos existentes siguen la regla de identidad: ver Identidad.

odoo_import { "model": "res.partner", "fields": ["name", "email"], "rows": [["ACME S.A.", "hola@acme.mx"]] }

Importaciones: confirma antes y nunca por XML-RPC

Ninguna de las dos herramientas corre sola: la prueba previa no importa, y el agente te pregunta antes de odoo_import. El XML-RPC de Odoo no puede devolver los valores vacíos que trae el resultado de una importación, así que una sesión en XML-RPC (Odoo 10-11, o ODOO_TRANSPORT_PREF=xmlrpc) las rechaza antes de enviar nada, en lugar de arriesgarse a reportar como error una importación que sí se guardó.


Para entender cómo se resuelven los nombres entre versiones, ver Compatibilidad entre versiones.