← back to work
work
built for multiskills it · open source

Python Odoo MCP server.

A multi-tenant REST API that lets n8n, webhooks, and automation platforms talk to Odoo with encrypted API keys, scope-based permissions, and connection pooling.

  • roleSolo builder.
  • clientBuilt for Multiskills IT. Productized as an open source project.
  • datesoct 2025
  • statuslive, maintaining

the problem

Odoo's XML-RPC interface works, but wiring it into automation platforms is a mess. Every workflow needs credentials, every credential is sensitive, and most teams either hard-code passwords into n8n nodes or give the automation platform full admin access. There was no clean way to hand an automation platform limited, auditable access to a specific Odoo model with specific permissions. Multiskills IT needed that layer to safely wire Odoo into the automation stack without exposing the CRM to every workflow that touched it.

the approach

Built a FastAPI REST server that sits in front of Odoo and exposes nine operations (search, read, search_read, search_count, fields_get, default_get, create, write, unlink) as HTTP endpoints. Added a scope-based permission system with R/W/D granularity per model, so a workflow could be given 'res.partner:RW,sale.order:R,*:R' and nothing more. Wrapped credentials in Fernet-encrypted API keys so no plaintext credentials ever live in n8n or automation configs. Built a connection pool with scope-aware caching: connections for different scopes stay isolated even for the same user, and each connection has a TTL so stale sessions clear themselves out. Shipped with Docker Compose for one-command deployment and a full pytest suite reaching 75%+ coverage. Open-sourced under MIT.

the outcome

In active production use at Multiskills IT as the bridge between n8n and Odoo. Published on GitHub at christopher-igweze/python-odoo-mcp with Codecov integration, GitHub Actions CI across Python 3.9, 3.10, and 3.11, and contributor documentation. 142 tests passing at 75%+ coverage. The scope-based permission layer does its job: workflows get exactly the access they need, nothing more.

the lessons

Most 'MCP' servers in the wild are actually HTTP REST APIs designed for automation platforms, not the true MCP protocol for AI assistants. Being clear about that distinction in the README was as important as the code, because it prevents the wrong users from pulling it into the wrong context. Also: connection pooling with scope hashing is the kind of thing that sounds over-engineered until you run it in production and realize a user with two different scopes should never share a connection object.

stack

  • Python 3.9+ ·
  • FastAPI ·
  • Pydantic ·
  • cryptography (Fernet) ·
  • XML-RPC ·
  • Docker ·
  • Docker Compose ·
  • pytest

screenshots

coming soon