Skip to content

ivnvxd/mcp-server-odoo

v0.7.0 Breaking

This release includes breaking changes for platform teams planning a safe upgrade.

Published 1mo MCP Developer Tools
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

ai erp llm mcp mcp-server mcp-servers
+3 more
model-context-protocol odoo odoo-mcp

Affected surfaces

auth deps crypto_tls

Summary

AI summary

Fixed multiple bugs including schema validation on deletes, XML‑RPC timeouts, keepalive recovery, session persistence, model exclusion in list_models, domain parsing corruption, binary field serialization, default fields handling, resource template reporting, search pagination hints, formatter precision, cache enforcement, error sanitization, error classification, config precedence, auth fallback, and logging redaction.

Changes in this release

Security Medium

Startup warning emitted when binding HTTP transport to non‑loopback host, highlighting lack of built‑in authentication.

Startup warning emitted when binding HTTP transport to non‑loopback host, highlighting lack of built‑in authentication.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Security Medium

Sensitive keys (passwords, API keys, tokens) are redacted in debug‑log payloads.

Sensitive keys (passwords, API keys, tokens) are redacted in debug‑log payloads.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Performance Low

HTTPS transports share a single `ssl.SSLContext` to amortize handshake cost across per‑proxy sockets.

HTTPS transports share a single `ssl.SSLContext` to amortize handshake cost across per‑proxy sockets.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Medium

Socket timeouts now apply to XML-RPC connections, causing hung servers to fail fast.

Socket timeouts now apply to XML-RPC connections, causing hung servers to fail fast.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Half‑open keepalive recovery retries once on fresh connection for idempotent calls only.

Half‑open keepalive recovery retries once on fresh connection for idempotent calls only.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

`streamable-http` sessions persist across HTTP sessions, preventing “Not authenticated” errors after the first call.

`streamable-http` sessions persist across HTTP sessions, preventing “Not authenticated” errors after the first call.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Blocking XML‑RPC/HTTP calls are offloaded to worker threads, keeping the event loop responsive.

Blocking XML‑RPC/HTTP calls are offloaded to worker threads, keeping the event loop responsive.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

`list_models` YOLO mode now correctly excludes system models, avoiding domination by `ir.*`/`base.*` entries.

`list_models` YOLO mode now correctly excludes system models, avoiding domination by `ir.*`/`base.*` entries.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

String domains no longer corrupt values containing substrings like `True` or `False`.

String domains no longer corrupt values containing substrings like `True` or `False`.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Search resource skips binary/html fields and references `search_records` for pagination hints.

Search resource skips binary/html fields and references `search_records` for pagination hints.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Float formatters honor `digits` metadata; unset names render `Record {id}` instead of `False`.

Float formatters honor `digits` metadata; unset names render `Record {id}` instead of `False`.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Memory cache budget is now enforced, preventing unrelated evictions when replacing a key.

Memory cache budget is now enforced, preventing unrelated evictions when replacing a key.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Medium

Error sanitizer trims server tracebacks to the final error message, redacting sensitive details.

Error sanitizer trims server tracebacks to the final error message, redacting sensitive details.

Source: llm_adapter@2026-06-11

Confidence: high

Bugfix Low

`delete_record` falls back to ID label when display name is missing, preventing schema validation failure.

`delete_record` falls back to ID label when display name is missing, preventing schema validation failure.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Low

Binary/datetime fields in `search_records`/`get_record` results now serialize cleanly without errors.

Binary/datetime fields in `search_records`/`get_record` results now serialize cleanly without errors.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Low

`fields=[]` is treated as smart defaults instead of silently fetching all fields.

`fields=[]` is treated as smart defaults instead of silently fetching all fields.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Low

`list_resource_templates` in YOLO mode reports "all models available" rather than `total_models: 0`.

`list_resource_templates` in YOLO mode reports "all models available" rather than `total_models: 0`.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Low

Auth fallback after rejected API key uses session auth for permission checks instead of resending the dead key.

Auth fallback after rejected API key uses session auth for permission checks instead of resending the dead key.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Bugfix Low

`SERVER_VERSION` derives from package version; test now pins it to `pyproject.toml`.

`SERVER_VERSION` derives from package version; test now pins it to `pyproject.toml`.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Refactor Low

Dead code (~550 lines) removed, including unused caches, `RequestOptimizer`, browse resource chain, and error metrics API.

Dead code (~550 lines) removed, including unused caches, `RequestOptimizer`, browse resource chain, and error metrics API.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Refactor Low

`ConnectionPool` simplified to the proxy factory it actually implements.

`ConnectionPool` simplified to the proxy factory it actually implements.

Source: granite4.1:30b@2026-06-11-audit

Confidence: low

Full changelog

Fixed

  • delete_record on records without a display name (e.g. mail.message): the unlink succeeded but the result then failed schema validation (deleted_name received Odoo's False), so clients believed the delete had failed — now falls back to an ID label.
  • Timeouts: Socket timeouts now actually apply to XML-RPC connections — a hung Odoo server fails fast instead of blocking forever.
  • Half-open keepalive recovery (#68): a timeout on a reused keepalive socket (LB dropped the upstream without FIN/RST) transparently retries once on a fresh connection — idempotent calls only: read-only model methods plus login/version/db-list probes (a timed-out write is never re-sent, it could be double-executed by a slow server); timeouts on fresh connections are NOT retried.
  • streamable-http sessions (#70): the Odoo connection and registered handlers now persist across HTTP sessions — previously every tool call after the first failed with "Not authenticated with Odoo" because session teardown disconnected Odoo. stdio still cleans up on exit.
  • Event loop: Blocking XML-RPC/HTTP calls offloaded to worker threads; concurrent tool calls and pings stay responsive during slow operations.
  • YOLO list_models: System-model exclusion was a no-op (tautological domain) — results were dominated by ir.*/base.* models.
  • Domain parsing: String domains no longer corrupt values containing True/False substrings (e.g. 'True North').
  • Binary fields: search_records/get_record results with binary/datetime fields serialize cleanly instead of erroring.
  • fields=[]: Treated as smart defaults instead of silently fetching ALL fields.
  • list_resource_templates: YOLO mode reports "all models available" instead of total_models: 0.
  • Search resource: odoo://{model}/search skips binary/html fields like the record path; pagination hints now reference the search_records tool instead of emitting unroutable query-param URIs.
  • Formatters: Float precision honors digits metadata; unset names render Record {id} instead of False; long values truncated with a marker; x2many "View all" hints carry real record ids.
  • Cache: Memory budget actually enforced (looped eviction); replacing a key no longer evicts an unrelated entry.
  • Error sanitizer: Server tracebacks reduced to the final error message (multi-line business errors kept intact) — no more leaked source lines, SQL constraint names, or row values; no more literal {} placeholders in error messages.
  • Error classification: Builtin PermissionError/ConnectionError no longer misclassified as critical system errors (custom classes shadowed the builtins); access-control infrastructure failures report as connection errors, not "Access denied".
  • Config precedence: ODOO_MCP_TRANSPORT/HOST/PORT/LOG_LEVEL set only in .env now take effect; invalid ODOO_MCP_PORT or ODOO_MCP_SLOW_OPERATION_THRESHOLD_MS no longer crash startup/import with raw tracebacks.
  • Auth fallback: After a rejected API key falls back to password auth, permission checks use session auth instead of resending the dead key (which 401'd every tool call).
  • Logging: Sensitive keys (passwords, API keys, tokens) redacted in debug-log write payloads; database names moved to DEBUG level.
  • Version: SERVER_VERSION derives from the package version; a test pins it to pyproject.toml (v0.5.2 shipped reporting 0.5.1).

Changed

  • TLS: HTTPS transports share one ssl.SSLContext to amortize handshake cost across the per-proxy sockets introduced in 0.6.0.
  • HTTP transport: Loud startup warning when binding a non-loopback host (the transport has no built-in authentication); README security notes added.
  • Dead code removed (~550 lines): never-wired record/permission caches, RequestOptimizer, the browse resource chain, and the unused error metrics/conversion API; ConnectionPool simplified to the proxy factory it actually was.
  • CI: Push trigger limited to main/dev (PRs cover feature branches; kills duplicate runs); Dependabot switched to the uv ecosystem so uv.lock gets update/security PRs; publish workflow verifies the built version against the release tag (manual dispatch requires typed version confirmation); Python 3.13 classifier added; MCP integration job skips Dependabot PRs — repository secrets aren't available to them, so the private-module checkout failed with "Input required and not supplied: token"; Dependabot version-update PRs now target dev directly (manual retargeting desynced Dependabot's base-branch metadata); codecov-action bumped to v7 (supersedes the stuck Dependabot PR).
  • --help: documents ODOO_MCP_ENABLE_METHOD_CALLS.
  • Tests: integration suite hardened — MCP-module detection works on multi-database instances (health probe sends X-Odoo-Database); an env-var leak that wedged spawned transport servers under DEBUG logging fixed; vacuous if records: guards replaced with real fixtures and assertions; MCP test client read_resource returned "" (matched the wrong content type).

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track ivnvxd/mcp-server-odoo

Get notified when new releases ship.

Sign up free

About ivnvxd/mcp-server-odoo

Connect AI assistants to Odoo ERP systems for business data access, record management, and workflow automation.

All releases →

Beta — feedback welcome: [email protected]