Atlas / MCP servers / rosenvladimirov / Odoo Claude

Odoo ClaudeBLOCK

mcp/rosenvladimirov/odoo-claude

Self-hosted MCP server connecting Claude to Odoo 15→19 — 197+ tools, multi-tenant, Bulgaria l10n

Verdict
BLOCK
Grade
F
Trust score
58 /100
Exposed tools
127 86r · 23w · 18d
Transport
stdio · streamable-http
License
AGPL-3.0
Stars
51
01

Overview

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

Production-grade Model Context Protocol (MCP) server suite for Odoo ERP

Odoo MCP server for Claude Code and Claude.ai — turn any self-hosted Odoo instance (15 → 19) into an AI assistant via the Model Context Protocol. 197+ tools, multi-tenant, Bulgaria localization (НАП, ДДС, ЕИК) included.

Connect Claude, Claude Code, and any MCP-compatible client to Odoo, GitHub, filesystem, Portainer, Teams, and more — through a unified, authenticated gateway.

[](LICENSE) [](https://www.odoo.com) [](https://modelcontextprotocol.io) [](https://www.docker.com) [](https://github.com/rosenvladimirov)

Quick Start · Why this vs alternatives? · Use Cases · Architecture · MCP Servers · Companion Modules · Deployment

Two tracks. You are on branch 3.0 — the preview track for integrators, current v3.3.8. The stable track is branch `2.0`, current v2.31.0. All releases: Releases · details in Two Tracks.

🇧🇬 Български README

See Claude editing a live Odoo sale order — real CRUD, real auto-recalculation

▶ Watch the full 4-minute demo: [Running Odoo 18 Entirely Through AI — Claude Code + MCP Server

Read from source at commit be0f97c36427OBSERVED · 2026-10-08
Advertisement
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
claude mcp add claude-terminal-gateway --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env API_KEY=${API_KEY} --env API_KEYS_FILE=${API_KEYS_FILE} --env AUTH_CACHE_TTL=${AUTH_CACHE_TTL} -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "claude-terminal-gateway": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
        "API_KEY": "${API_KEY}",
        "API_KEYS_FILE": "${API_KEYS_FILE}",
        "AUTH_CACHE_TTL": "${AUTH_CACHE_TTL}"
      }
    }
  }
}
03

Exposed tools (127)

86 read · 23 write · 18 destructive. Blast radius: 18 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
backup_historyreadADMIN: list backup/restore ops. Read-only.
backup_listreadADMIN: list backups (optionally per target). Read-only.
cf_dns_createwriteCreate DNS record. ttl=1 means Auto.
cf_dns_deletedestructiveDelete a DNS record.
cf_dns_listreadList DNS records in a zone.
cf_dns_updatewritePatch a DNS record. Pass any of: type, name, content, proxied, ttl.
cf_tunnel_config_getreadGet the current ingress/config of a tunnel.
cf_tunnel_config_putwriteReplace the full ingress config. Last entry must be {
cf_tunnel_listreadList cloudflared tunnels in an account.
cf_tunnel_route_addwriteAdd (or replace) one ingress rule + create CNAME record.
cf_tunnel_route_removedestructiveRemove ingress rule by hostname + delete its CNAME record.
cf_zones_listreadList zones (optional filter by name).
contabo_account_inforeadReturn the authenticated customer
contabo_instances_listreadList VPS instances on the account (name, IP, status, plan).
contabo_object_storage_getreadGet one Object Storage instance in full detail.
contabo_object_storage_statsreadGet usage stats (GB used, object count, etc) for an Object Storage instance.
contabo_object_storages_listreadList Object Storage instances (subscriptions) on the account.
ee_clonereadClone Odoo Enterprise repository with GitHub token authentication.
ee_dependsreadShow full dependency tree of an EE module (CE + EE deps).
ee_deploywriteDeploy EE from buffer to target (rsync). Buffered mode only.
ee_license_statusreadRead Enterprise license status from an Odoo instance (expiration, code, reason).
ee_linkwriteCreate symlink for specific EE modules in the Odoo addons path (selective install).
ee_modulesreadList all Enterprise modules with category, license, depends. Filter by category, country, or keyword.
ee_oca_conflictsreadDetect conflicts between Enterprise and OCA modules: name collisions, model overlaps.
ee_oca_recommendreadFor a module that exists in both EE and OCA — compare and recommend which to use.
ee_searchreadSearch Enterprise modules by name, summary, or dependency.
ee_token_checkreadValidate GitHub token — check access to odoo/enterprise private repo.
ee_unlinkdestructiveRemove symlinks for EE modules from addons path.
ee_updatewriteGit pull Enterprise repository.
google_auth_statusreadCheck Google authentication status.
google_calendar_create_eventwriteCreate a new calendar event.
google_calendar_delete_eventdestructiveDelete a calendar event.
google_calendar_eventsreadList upcoming calendar events. Supports time range and text search.
google_calendar_listreadList all available Google calendars.
google_calendar_update_eventwriteUpdate an existing calendar event. Only provided fields are changed.
google_gmail_labelsreadList all Gmail labels (folders).
google_gmail_readreadRead a specific Gmail message by ID. Returns full body, headers, and labels.
google_gmail_sendwriteSend an email or reply to an existing message.
identify_totp_disablewriteDisable TOTP two-factor for YOUR current identified profile (removes the stored secret).
identify_totp_statusreadReport whether YOUR current profile has TOTP two-factor enrolled.
mcp_drop_elevationdestructiveEnd the current elevation window early. Logs to audit.
mcp_elevation_statusreadReturn whether the server is currently elevated, and remaining TTL.
memory_deletedestructiveDelete a memory file from personal or shared storage.
memory_readreadRead a memory file by filename. Searches personal first, then shared.
migrate_historyreadADMIN: list past migration assessments. Read-only.
module_deploy_historywriteADMIN: list past deploy/rollback ops (optionally per target).
oca_changelogreadGenerate CHANGELOG from newsfragments using oca-towncrier.
oca_clone_reporeadClone a specific OCA repository by name.
oca_deploywriteDeploy OCA repos from buffer to target (rsync). Only in buffered mode.
oca_fix_websitereadFix website URL in addon manifests using oca-fix-manifest-website.
oca_gen_iconreadGenerate default OCA icon for addon(s) using oca-gen-addon-icon.
oca_gen_readmereadGenerate README for an OCA addon using oca-gen-addon-readme.
oca_gen_requirementsreadGenerate requirements.txt from addon external_dependencies using oca-gen-external-dependencies.
oca_gen_tablereadGenerate addons table in repo README.md using oca-gen-addons-table.
oca_linkwriteCreate symlink for OCA addon module in the Odoo addons path.
oca_migratereadMigrate OCA repos to a new Odoo version branch using oca-migrate-branch.
oca_searchreadSearch for a module across all cloned OCA repos by name or keyword.
oca_statusreadShow git status of all OCA repos (branch, clean, behind, modules count).
oca_updatewriteGit pull all OCA repos in the working directory (recursive).
odoo_connectionsreadList all configured Odoo connections.
odoo_createwriteCreate one or more records. Returns list of new IDs.
odoo_disconnectdestructiveRemove an Odoo connection.
odoo_fields_getreadGet field definitions for an Odoo model. Returns field names, types, labels, and attributes.
odoo_fp_remove_actiondestructiveRemove a tax action map entry from a fiscal position (l10n_bg_tax_admin).
odoo_list_modelsreadList available Odoo models (ir.model). Optionally filter by name pattern.
odoo_readreadRead specific records by IDs.
odoo_reportreadGenerate a PDF report for records. Returns base64-encoded PDF.
odoo_searchreadSearch for record IDs matching a domain filter.
odoo_search_countreadCount records matching a domain.
odoo_search_readreadSearch and read records in one call. Most common operation.
odoo_unlinkdestructiveDelete records by IDs.
odoo_versionreadGet Odoo server version info.
odoo_web_exportreadExport records to structured data via web session (Odoo export_data).
odoo_web_logoutdestructiveDestroy web session and logout.
odoo_web_reportreadDownload PDF report via web session. Returns base64-encoded PDF.
odoo_writewriteUpdate existing records.
provision_list_api_keysreadADMIN ONLY: List active provisioning API keys (without hashes).
provision_revoke_api_keydestructiveADMIN ONLY: Revoke an issued API key by key_id.
public_access_barcodereadGenerate barcode image via /report/barcode/{type}/{value}.
public_access_downloadreadDownload attachment/binary content by ID via /web/content/{id}. Public route.
public_access_export_csvreadExport Odoo list data as CSV via web session.
public_access_export_xlsxreadExport Odoo list data as XLSX file via web session. Returns base64.
public_access_imagereadDownload image field from record via /web/image/{model}/{id}/{field}.
public_access_portal_homereadGet portal home page content via web session (/my/home).
public_access_portal_invoicesreadGet list of portal invoices (/my/invoices). Returns HTML page content.
public_access_portal_ordersreadGet list of portal sale orders (/my/orders). Returns HTML page content.
public_access_portal_purchasesreadGet list of portal purchase orders (/my/purchase).
public_access_portal_ticketsreadGet list of portal helpdesk tickets (/my/tickets).
public_access_report_htmlreadRender report as HTML via web session.
public_access_report_pdfreadDownload PDF report via web session. Route: /report/pdf/{report_name}/{doc_ids}.
public_access_report_xlsxreadDownload XLSX report via OCA reporting-engine (/report/xlsx/{name}/{ids}).
public_access_shopreadGet website shop product listing (/shop). Returns HTML.
public_access_sitemapreadDownload sitemap.xml from Odoo website.
s3_bucket_createwriteCreate a new bucket on the configured S3 endpoint.
s3_bucket_deletedestructiveDelete an S3 bucket. Set force=true to delete all objects first.
s3_bucket_statsreadReturn object_count + total_bytes + oldest/newest object key for a bucket.
s3_buckets_listreadList all S3 buckets for the configured account on the target endpoint.
s3_object_deletedestructiveDelete a single object from a bucket.
s3_object_getreadDownload an object (text). Binary or >max_bytes objects return metadata only.
s3_objects_delete_prefixdestructiveDelete all objects under a prefix in one bucket. Returns count.
s3_objects_listreadList objects in a bucket (prefix-filtered, page size-capped).
secrets_revokedestructiveADMIN: mark a secret revoked (audit).
session_handoff_cancelreadCancel an offer you created (offerer only).
session_link_revokedestructiveRevoke a session link by id (owner or admin).
supervisor_historyreadADMIN: list past supervisor ops (optionally per target).
supervisor_rebuildreadMake every farm layer a PURE symlink farm from /opt.
supervisor_runwriteOrchestrate the canonical host ``supervisor.py`` (github / OCA / EE /
supervisor_statusreadDrift report for one odoo container
supervisor_targetsreadList SSH-capable hosts (connections.json entries with an ssh block).
telegram_agent_get_scenarioreadGet the full scenario for an enrolled chat.
telegram_agent_listreadList enrolled chats with their mode/persona/skills.
telegram_agent_set_scenariowriteReplace the scenario for an enrolled chat.
telegram_agent_unenrollwriteStop agentic handling for a chat.
telegram_auth_statusreadCheck Telegram authentication status.
telegram_configurewriteSet Telegram API credentials (api_id and api_hash from my.telegram.org).
telegram_get_dialogsreadList recent Telegram chats (users, groups, channels).
telegram_get_messagesreadRead messages from a Telegram chat. Chat can be @username, phone, or numeric ID.
telegram_search_contactsreadSearch Telegram contacts by name or username.
telegram_send_messagewriteSend a Telegram message. Chat can be @username, phone, or numeric ID.
telegram_sub_listreadList a principal
telegram_sub_removedestructiveRemove a chat from a principal
tenant_currentreadReturn the currently active tenant (or null) and its tool count.
tg_listen_status_howtoreadReturn the commands to inspect listener/session state.
user_connection_activatereadActivate one of your personal connections as the working connection.
user_connection_deletedestructiveDelete a personal connection.
user_connection_listreadList your personal connections.
who_am_ireadShow current user identity and active connection.
04

Trust audit

BLOCKgrade F · trust 58/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

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

What the source does

Filesystem
declared (18 observation(s))
Network
declared (18 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
k3s/base/secrets.example.yaml:45
#     --from-file=id_ed25519=$HOME/.ssh/id_ed25519 \
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
k3s/base/secrets.example.yaml:46
#     --from-file=id_ed25519.pub=$HOME/.ssh/id_ed25519.pub \
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
k3s/base/secrets.example.yaml:47
#     --from-file=known_hosts=$HOME/.ssh/known_hosts
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
k3s/base/secrets.example.yaml:54
id_ed25519: ""
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
k3s/base/secrets.example.yaml:55
id_ed25519.pub: ""
Why it matters. touches a credential store
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
docker-compose.yml:95
- NODE_TLS_REJECT_UNAUTHORIZED=0
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
odoo-rpc-mcp/server.py:1672
verify=False, timeout=30,
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
odoo-rpc-mcp/server.py:1703
verify=False, timeout=timeout,
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
odoo-rpc-mcp/server.py:1750
verify=False, timeout=120,
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
odoo-rpc-mcp/server.py:1762
verify=False, timeout=120,
Why it matters. certificate verification is disabled
Fix. leave verification on
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
odoo-rpc-mcp/admin_ui.py:3122
mod = __import__(mod_name)
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
tools/tg_wakeloop.sh:28
PAYLOAD="$(python3 -c "import json,urllib.parse; print(urllib.parse.quote(json.dumps({'token':'${TOKEN}'})))")"
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:63
# Portainer server URL (e.g. http://192.168.1.100:9000)
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
install.ps1:66
$PUrl = Read-Host "  Portainer URL (e.g. http://192.168.1.100:9000)"
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
install.sh:68
read -p "  Portainer URL (e.g. http://192.168.1.100:9000): " P_URL
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
tools/odoo_module_analyzer.py:385
print("\nПрекъснато.")
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
tools/odoo_module_analyzer.py:393
print(f"\nГотово. Memory файловете са в: {memory_dir}")
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
odoo-rpc-mcp/tests/test_security_phase1.py:496
("sk-ant-api03-AbCdEfGhIjKlMnOpQrSt", True),
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
cf_dns_delete, cf_tunnel_route_remove, ee_unlink, google_calendar_delete_event, mcp_drop_elevation, memory_delete, odoo_disconnect, odoo_fp_remove_action, odoo_unlink, odoo_web_logout, provision_revok
Why it matters. 18 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
docs/.nojekyll
.nojekyll
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
odoo-rpc-mcp/tests/test_oauth_hardening_336.py:47
exec(compile(match.group(0), fn, "exec"), ns)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
odoo-rpc-mcp/tests/test_oauth_hardening_336.py:50
ns["_SECRET_CONN_KEYS"] = eval(f"({keys.group(1)})")  # noqa: S307 - our own literal
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
odoo-rpc-mcp/tests/test_oauth_refresh_339.py:63
exec(compile(match.group(0), fn, "exec"), ns)  # noqa: S102 - our own source
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
k3s/overlays/direct/kustomization.yaml:15
- ../../base
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
k3s/overlays/direct/kustomization.yaml:47
- proxy_services.json=../../../proxy_services.json

Gates applied: no_behavioural_pass.

Audited 2026-10-08 · audit v0.4.1 · source sha be0f97c36427full audit observations/trust-audit/mcp-server/rosenvladimirov__odoo-claude.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-08be0f97c36427BLOCKF58first audit
06

Questions

What is the Odoo Claude MCP server?

Self-hosted MCP server connecting Claude to Odoo 15→19 — 197+ tools, multi-tenant, Bulgaria l10n

What tools does Odoo Claude expose?

127 in total: 86 read-only, 23 that write, and 18 that can delete or overwrite (cf_dns_delete, cf_tunnel_route_remove, ee_unlink, google_calendar_delete_event, mcp_drop_elevation). Every one is listed on this page with its risk.

Is Odoo Claude safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (58/100) and found 10 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 18 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does Odoo Claude need?

It reads ANTHROPIC_API_KEY, API_KEY, API_KEYS_FILE, AUTH_CACHE_TTL, BRIDGE_TOKEN, CENTRIFUGO_API_KEY, CENTRIFUGO_TOKEN_HMAC_SECRET, CF_API_TOKEN, CONTABO_API_PASSWORD, CONTABO_AUTH_URL, CONTABO_CLIENT_SECRET and GITHUB_PERSONAL_ACCESS_TOKEN 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 Claude run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as claude-terminal-gateway at 3.0.0.

How current is this page?

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

Advertisement