Odoo MCP

Servidor MCP nativo de flujos de trabajo para operaciones seguras y gobernadas de back-office en Odoo Enterprise.

Documentación

Odoo MCP

odoo-mcp es un servidor MCP nativo del flujo de trabajo para Odoo Enterprise. Expone descubrimiento de capacidades de solo lectura, informes de balanza de comprobación, informes de cuentas por cobrar y por pagar vencidas, visibilidad de libro de caja, detección de líneas bancarias no conciliadas y conciliación bancaria solo propuesta.

La versión inicial de contabilidad también admite flujos de trabajo acotados de facturas, facturas de proveedor, notas de crédito, registro de pagos y asientos manuales. Las herramientas de mutación son solo vista previa de forma predeterminada y requieren ejecución explícita más idempotencia.

El adaptador contable interno proporciona primitivas de lectura acotadas, tipadas y con ámbito de empresa para los flujos de trabajo de informes. Aplica listas permitidas fijas de modelos/acciones, elimina campos denegados, normaliza fechas, decimales, relaciones y páginas de cursor, y traduce fallos de autenticación, permisos y transporte de Odoo en errores seguros. No expone CRUD genérico ni una superficie de configuración de Odoo.

Los destinos de conexión admitidos son Odoo.sh y Odoo Enterprise autoalojado:

  • Odoo 18 a través de JSON-RPC externo
  • Odoo 19 a través de JSON-2

Otras versiones de Odoo, Odoo Online, edición Community y bifurcaciones personalizadas no son compatibles. Este paquete no es un módulo de Odoo y no expone CRUD genérico de modelos.

Instalación

El producto y los comandos se denominan odoo-mcp; la distribución de PyPI es odoo-erp-mcp porque el nombre de distribución odoo-mcp pertenece a otro proyecto.

pipx install odoo-erp-mcp
odoo-mcp --help

El paquete también expone odoo-erp-mcp como lanzador de compatibilidad para clientes de MCP Registry. Inicia el mismo servidor que odoo-mcp.

Desarrollo local

Requiere Python 3.11 o superior y uv.

Copy-Item .env.example .env.local
# Replace the placeholders in .env.local, then:
uv sync --locked --all-extras
uv run odoo-mcp --profile local --config config/config.example.yaml

El desarrollo local utiliza stdio. La configuración del entorno de proceso tiene prioridad sobre .env.local. Nunca confirmes .env.local.

Perfiles remotos

Dedicado remoto y alojado compartido utilizan el mismo servidor, registro, flujo de trabajo y adaptador de Odoo que el desarrollo local, expuestos a través de HTTP Streamable:

uv run odoo-mcp --profile dedicated --host 127.0.0.1 --port 8000
uv run odoo-mcp --profile shared --host 127.0.0.1 --port 8000

Dedicado remoto lee su única conexión de Odoo del entorno de proceso; nunca carga .env.local. Cada solicitud /mcp debe llevar un JWT de portador HS256 emitido por la implementación. El servidor valida su firma, emisor fijo, audiencia fija, caducidad, hora de emisión, sujeto e ID de cliente antes del enrutamiento MCP; los permisos y las concesiones de empresa permanecen propiedad del servidor. Configura ODOO_MCP_AUTH_ISSUER, ODOO_MCP_AUTH_AUDIENCE y un ODOO_MCP_AUTH_SIGNING_KEY suministrado por el almacén de secretos de al menos 32 caracteres.

Alojado compartido es una aplicación de inscripción abierta ejecutable en la misma imagen. Sirve descubrimiento OAuth, registro dinámico de clientes, autorización, token, revocación, inscripción de navegador, metadatos de recursos protegidos y rutas MCP. La aplicación verifica cada conexión de Odoo, permite al usuario seleccionar entre las empresas que Odoo devolvió, almacena la credencial cifrada y vincula cada token a exactamente un conector activo. Configúralo desde .env.shared.example; sus claves de cifrado de 256 bits versionadas deben provenir de un almacén de secretos controlado por el operador. Configuración faltante, texto cifrado no válido, concesiones inactivas, destinos de Odoo inseguros y enlaces de conectores no autorizados fallan de forma segura. Alojado compartido admite un proceso escribible con un volumen SQLite local duradero o PostgreSQL calificado con tiempo de ejecución agrupado y conexiones de migración directa. TLS, entrada pública, monitoreo y despliegue de producción siguen siendo responsabilidades del operador.

Plantillas Docker y systemd reproducibles de Dedicado remoto, requisitos de integración de Alojado compartido y orientación de endurecimiento de red están en docs/deployment.md. No expongas el oyente HTTP de ejemplo directamente a Internet público.

Estado duradero

odoo_mcp.storage.Storage proporciona migraciones SQLite y PostgreSQL ordenadas y repositorios con ámbito de inquilino para registros de auditoría, propuestas, artefactos, reservas de idempotencia, instantáneas de capacidades y conexiones cifradas de Alojado compartido. Las filas de auditoría son solo anexión y encadenadas con hash SHA-256 por inquilino. Las reservas de idempotencia vinculan el inquilino, la empresa, la herramienta, la clave y la carga útil de la solicitud para reproducción de 24 horas, mientras que los resultados en curso y desconocidos permanecen bloqueados para recuperación explícita. Los resultados finales deben conservar una respuesta reproducible y coincidir con la empresa que reserva. El texto de fallo de auditoría se deriva de códigos de error registrados; el texto de error de flujo ascendente de forma libre no se persiste.

Las copias de seguridad de SQLite utilizan una instantánea consistente. La restauración escribe a un nuevo destino y se acepta solo después de que la integridad de la base de datos, las migraciones, las cadenas de auditoría de inquilinos, el estado de idempotencia, los datos de capacidades y las conexiones cifradas se verifiquen. Las claves de cifrado deben respaldarse y restaurarse por separado. PostgreSQL utiliza serialización de migración a nivel de base de datos y conserva los mismos contratos de repositorio, OAuth, auditoría, idempotencia, cifrado y ciclo de vida.

El servidor almacena estado duradero local en .odoo-mcp/state.sqlite3 de forma predeterminada. Usa --storage <path> para seleccionar un archivo SQLite diferente. Los informes contables exitosos persisten atómicamente su artefacto Markdown y un resultado de auditoría compacto; las llamadas de informes fallidas y denegadas persisten una auditoría de fallo segura para secretos cuando se ha resuelto una identidad de aislamiento.

Seguridad de escritura

odoo_mcp.policy.WriteSafetyCoordinator es el límite requerido para flujos de trabajo con capacidad de escritura. Aplica metadatos de riesgo de registro, identidad resuelta, permiso, empresa y puertas de capacidad antes de la preparación del flujo de trabajo. Las llamadas predeterminan a comportamiento solo vista previa. La ejecución requiere dry_run: false explícito y una clave de idempotencia no vacía, luego reserva esa clave y agrega la auditoría de intento antes de la validación de estado fresco y la mutación de Odoo.

Los resultados exitosos, rechazados, conflictivos, reproducidos, con fallo conocido y desconocido permanecen distintos y seguros para reproducción a través del reinicio. Una mutación incierta nunca se reintenta automáticamente; si la persistencia del resultado falla después de una posible mutación, la reserva en curso continúa bloqueando la ejecución duplicada. Las denegaciones de permiso de Odoo que demuestran que no ocurrió ninguna mutación permanecen fallos conocidos estructurados. La auditoría y el texto de respuesta suprimen detalles de excepción sin procesar.

La confirmación humana pertenece al host del cliente MCP. El servidor no emite tokens de aprobación, proporciona una interfaz de aprobación ni convierte automáticamente una vista previa en ejecución. Las llamadas de conciliación predeterminan a vista previa. Una llamada explícita dry_run: false con una clave de idempotencia almacena una propuesta propiedad del servidor y artefacto Markdown, pero nunca finaliza la conciliación ni cambia una línea de extracto bancario en Odoo.

Configuración

La configuración de Odoo local y dedicado está documentada en .env.example; la configuración del operador de Alojado compartido está documentada en .env.shared.example. No configures una versión de Odoo: el adaptador la detecta y falla explícitamente para respuestas no compatibles o malformadas. config/config.example.yaml es el ejemplo seguro de mapa de permisos MCP y habilita las herramientas de lectura actuales. Una herramienta está autorizada solo cuando está listada bajo su permiso definido por registro; las entradas desconocidas o no coincidentes impiden el inicio.

Usa un usuario técnico de Odoo no productivo dedicado con solo el acceso de empresa y módulo requerido. Los IDs de empresa son un límite de autorización MCP adicional y nunca expanden los permisos de Odoo del usuario técnico.

Flujos de trabajo contables

  • get_trial_balance devuelve saldos de apertura publicados, movimiento de débito y crédito de período inclusivo, saldos de cierre, totales y un artefacto Markdown.
  • get_profit_and_loss clasifica líneas publicadas por los tipos de cuenta de ingresos y gastos de Odoo para un período inclusivo. Los ingresos usan crédito menos débito, los gastos usan débito menos crédito y la ganancia neta es ingresos menos gastos.
  • get_balance_sheet clasifica líneas publicadas por los tipos de cuenta de activo, pasivo y patrimonio de Odoo a través de una fecha inclusiva. Informa ganancias no cerradas por separado dentro del patrimonio total y verifica la ecuación contable a precisión de moneda de empresa.
  • get_aged_receivables y get_aged_payables reconstruyen residuales publicados a partir de una fecha, incluyendo conciliaciones parciales posteriores, y los agrupan en cubos de no vencido, 1–30, 31–60, 61–90 y 90+ días.
  • get_cashbook devuelve líneas de asiento publicadas de diarios de efectivo y bancos con saldo de apertura, débito y crédito de período y saldo de cierre.
  • flag_unmatched_statement_lines identifica líneas de extracto no conciliadas sin una coincidencia elegible única en o por encima del umbral solicitado.
  • reconcile_bank_statement_lines puntúa candidatos exactos uno a uno por monto, socio, referencia normalizada y proximidad de fecha. Empates y reutilización de candidatos permanecen resultados no coincidentes explícitos. La herramienta puede persistir una propuesta localmente; no realiza conciliación de Odoo.
  • list_open_invoices y list_open_bills reconstruyen residuales de moneda de registro y de empresa a partir de una fecha, incluyendo conciliaciones parciales posteriores.
  • create_customer_invoice y create_supplier_bill proporcionan vistas previas no mutantes, solo de entrada de forma predeterminada. La ejecución explícita crea un borrador no publicado y lee los resultados contables efectivos de Odoo.
  • create_credit_note crea una reversión de borrador completo vinculada. Antes de publicar, validate_invoice informa bloqueadores de saldo, moneda, cuenta, total e impuestos determinables localmente mientras difiere explícitamente las verificaciones de publicación solo de Odoo.
  • register_payment delega el descubrimiento y la ejecución de rutas al asistente estándar de registro de pagos de Odoo. La vista previa puede crear registros de asistente efímeros acotados pero nunca ejecuta un pago ni altera registros contables. Métodos no manuales o no identificados informan su posible efecto externo como desconocido. La ejecución requiere una clave de idempotencia y una ruta de asistente revalidada recientemente.
  • list_journal_entries devuelve asientos manuales filtrados publicados y en borrador con detalles de línea acotados y cursores de continuación opacos. create_journal_entry crea solo un borrador equilibrado, mientras que la herramienta separada post_journal_entry revalida y publica un borrador existente después de la ejecución explícita.

Los resultados de informes están ordenados determinísticamente y paginados por cursor con un límite predeterminado de 100 y máximo de 500. Los datos vacíos son un informe vacío exitoso; denegación de flujo ascendente, tiempo de espera, datos malformados o recuperación parcial es un fallo estructurado en lugar de un resultado vacío. Los artefactos Markdown paginados etiquetan el rango de filas, el estado de continuación y los totales de todo el informe explícitamente.

Los filtros analíticos de pérdidas y ganancias y balance general aplican la distribución porcentual de Odoo a IDs de cuenta analítica exactos. Estos informes no infieren grupos personalizados de plan de cuentas, reglas de cierre de año fiscal, consolidación, eliminaciones o diseños de informes específicos de localización. Las clasificaciones de cuenta no compatibles fallan explícitamente en lugar de adivinarse.

Verificación

Un comando ejecuta verificaciones de formato, análisis estático, pruebas, compilaciones de paquetes e inspección de artefactos en directorios temporales:

uv run python scripts/verify.py

Las pruebas automatizadas usan respuestas sintéticas de Odoo. No establecen compatibilidad de versión de Odoo en vivo, permisos reales, módulos instalados o redes de implementación.

Los procedimientos de copia de seguridad de almacenamiento, restauración, verificación de integridad, monitoreo, actualización, reversión e incidentes están documentados en docs/operations.md. Consulta SECURITY.md para el límite de seguridad y el informe de vulnerabilidades, y SUPPORT.md para configuraciones compatibles y solicitudes de soporte.

docs/demo.md proporciona una demostración contable acotada que mantiene cada llamada con capacidad de escritura en modo vista previa a menos que el operador autorice por separado la ejecución en un entorno de Odoo no productivo.