Atlas / MCP servers / tuanle96 / Odoo

OdooSAFE

mcp/tuanle96/odoo

Odoo MCP for AI agents — gated writes, multi-instance. Hosted product: https://erpipe.com

Verdict
SAFE
Grade
B
Trust score
89 /100
Exposed tools
23 18r · 5w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
417
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

ERPipe is the managed Odoo MCP gateway from the maintainer of `erpipe-org/mcp-odoo`, formerly `tuanle96/mcp-odoo`; the Python project remains the self-hosted server.

The free AI layer for Odoo — any edition, any version. Odoo's built-in AI is Enterprise-only. Odoo MCP gives Community and Enterprise 16+ the same power for $0 with the LLM you already use (Claude, GPT, Gemini, DeepSeek, Ollama). Five-minute install. Zero Odoo-side setup. Safe writes, real diagnostics, JSON-2 ready years before the Odoo 22 XML-RPC removal.

🚀 ERPipe hosted — free v1 · live at erpipe.com ·

Read from source at commit b91dff6a1f00OBSERVED · 2026-10-02
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (pypi)
claude mcp add odoo-mcp --env ODOO_PASSWORD=${ODOO_PASSWORD} -- None odoo-mcp==1.3.2
03

Exposed tools (23)

18 read · 5 write · 0 destructive.

ToolRiskDescription
accounting_health_summaryreadQuick accounting posture: open AR/AP item counts plus draft invoices.
aggregate_across_instancesreadGroup/aggregate per instance plus additive grand totals across them.
build_domainreadBuild safe domain arrays for search_records and Odoo ORM calls.
cancel_async_taskwriteCancel a task: pending tasks never start; running ones are discarded.
fit_gap_reportreadNormalize requirements into standard/config/Studio/custom/avoid/unknown buckets.
generate_json2_payloadreadGenerate a JSON-2 endpoint, headers, and named JSON body.
get_async_taskreadReturn task status; includes the result once status is succeeded.
get_model_fieldsread
health_checkreadReturn local process health and hardening flags without opening Odoo.
index_knowledgereadIndex records for free-text relevance search without further RPC calls.
inspect_model_relationshipsreadSummarize relationship fields using provided metadata or bounded fields_get.
knowledge_statsreadList per-model index sizes, total documents, and the configured cap.
list_async_tasksreadList live and recently finished tasks (results omitted; poll by id).
list_instancesreadList configured Odoo instances (name, url, db, transport) — never credentials.
list_modelsread
preview_writewriteBuild a canonical approval token for a later approved write.
read_recordread
scan_addons_sourcereadSummarize manifests, custom models, risky methods, views, and ACL files.
search_across_instanceswriteRun one search across many instances; rows are tagged with `_instance`.
search_employeeread
search_knowledgereadRank indexed records against a free-text query (accent-insensitive).
submit_async_taskwriteSubmit a background task; poll with get_async_task.
validate_writewriteValidate write shape and return an approval payload when safe.
04

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codePASS
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
declared (5 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
none-found

Findings (14)

LOWInventory / provenance · inv.hidden_file · CWE-1104
.importlinter
.importlinter
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_tool_helpers.py:72
tool_helpers.validate_model_name("../../../etc/passwd")
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/benchmarks.md:22
ODOO_URL=http://127.0.0.1:18169 \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/benchmarks.md:166
ODOO_URL=http://127.0.0.1:18169 ODOO_DB=mcp_bench_db \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/benchmarks.md:296
ODOO_URL=http://127.0.0.1:18169 ODOO_DB=mcp_bench_db \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/claude-desktop-connector.md:100
The server listens on `http://127.0.0.1:8000/mcp`. The reverse proxy handles
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/claude-desktop-connector.md:156
proxy_pass         http://127.0.0.1:8000;
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
tests/test_attachment.py:49
assert base64.b64decode(report["data_base64"]) == b"hello pdf!"
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
examples/crewai/requirements.txt
crewai, crewai-tools
Why it matters. 2 requirement(s) not pinned with ==
Fix. pin exact versions
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
examples/langgraph/requirements.txt
langchain, langchain-mcp-adapters, langchain-openai, langgraph
Why it matters. 4 requirement(s) not pinned with ==
Fix. pin exact versions
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
examples/openai-agents/requirements.txt
openai-agents
Why it matters. 1 requirement(s) not pinned with ==
Fix. pin exact versions
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
site/cloud.html:400
<div class="a">Envelope-encrypted at rest. Decrypted only on the request path — never in logs or the platform admin UI. Prefer read-only API keys; writes stay off until you enable them and complete th
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
site/services.html:322
<div class="flow-step" data-n="1"><div><h4>15-minute intro call</h4><p>Scope the models (audit) or addons + target version (pre-flight). You create a <b>read-only user + API key</b> — we send instruct
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
site/services.html:340
<li><b>Read-only credentials</b> recommended and verified at kickoff</li>
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-02 · audit v0.4.1 · source sha b91dff6a1f00full audit observations/trust-audit/mcp-server/tuanle96__odoo.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-02b91dff6a1f00SAFEB89first audit
06

Questions

What is the Odoo MCP server?

Odoo MCP for AI agents — gated writes, multi-instance. Hosted product: https://erpipe.com

What tools does Odoo expose?

23 in total: 18 read-only, 5 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Odoo safe to connect to an agent?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B.

What credentials does Odoo need?

It reads ODOO_API_KEY, ODOO_PASSWORD and OPENAI_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Odoo run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as odoo-mcp.

How current is this page?

The grade is for one exact copy of the source (b91dff6a1f00), read on 2026-10-02. The repository is watched and re-audited when it changes.

Advertisement