Skip to content

[19.0][MIG] ai_oca_mcp - #102

Open
OmniaGit wants to merge 8 commits into
OCA:19.0from
OmniaGit:19.0-mig-ai_oca_mcp
Open

[19.0][MIG] ai_oca_mcp#102
OmniaGit wants to merge 8 commits into
OCA:19.0from
OmniaGit:19.0-mig-ai_oca_mcp

Conversation

@OmniaGit

Copy link
Copy Markdown

Migration of ai_oca_mcp to 19.0.

Depends on #101 ([19.0][MIG] ai_tool) — until that one is merged this PR also carries the ai_tool commits; they disappear on rebase.

The module is not on 18.0 yet, so the history replayed here is the one from #76: this builds directly on @angelmoya's 16.0 → 18.0 work rather than redoing it, and their commits are preserved as authored.

Three changes beyond the version bump.

_sql_constraintsmodels.Constraint

In 19.0 the ORM logs "Model attribute '_sql_constraints' is no longer supported, please define models.Constraint on the model" (odoo/orm/model_classes.py) and does not create the constraint. The unique keys on mcp.server and mcp.server.key are now declared as models.Constraint("unique (…)", …).

expire_key() cache invalidation

_get_mcp_server_by_key is an ormcache, and expire_key() invalidated it through self._get_mcp_server_by_key.clear_cache(self). In 19.0 the decorator only sets lookup.__cache__, so that attribute no longer exists and the call raises AttributeError — which rolls the transaction back, meaning the key is not revoked at all, and the controller path that expires a key past its expiration_date answers 500 instead of rejecting the request.

The replacement is self.env.registry.clear_cache(). Same scope as before, in both directions: the old clear_cache ignored its arguments and called model.pool._clear_cache(), and the new one defaults to the default cache bucket, which is where this ormcache lives.

readonly=False on the route

This one is not specific to 19.0 and is worth a look on #76 as well.

Since 18.0, a route declared with auth="none" is served with a read-only cursor unless it says otherwise:

default_mode = submethod.original_routing.get('readonly', default_auth == 'none')

The MCP endpoint is auth="none" and writes — it logs every call to mcp.server.log, and expires keys. So on 18.0 and 19.0 every request runs, fails on the first INSERT, and is replayed from the top by service_model.retrying with a read/write cursor:

ERROR odoo.sql_db: bad query: INSERT INTO "mcp_server_log" …
ERROR: cannot execute INSERT in a read-only transaction
WARNING odoo.http: cannot execute INSERT in a read-only transaction, retrying with a read/write cursor

It works — the retry is why the test suite is green either way — but every MCP call is executed twice and every call leaves two ERROR lines in the log. Declaring the route readonly=False fixes it; the module's own tests go from 131 to 119 queries.

Testing

Odoo 19.0-20260803, ai_tool and ai_oca_mcp installed together: 15 tests, 0 failed, 0 errors, and no read-only retries left in the log.

Not included, on purpose

This is a migration. The protocol version answered at initialize is still the hardcoded 2025-03-26 and ping still falls through to "Method not found" — both worth addressing, both in separate PRs.

@etobella @angelmoya, in the context of #73.

@OCA-git-bot OCA-git-bot added mod:ai_oca_mcp Module ai_oca_mcp mod:ai_tool Module ai_tool series:19.0 labels Aug 13, 2026
This was referenced Aug 13, 2026
@OmniaGit
OmniaGit force-pushed the 19.0-mig-ai_oca_mcp branch from 2a7f496 to b8d6e06 Compare September 4, 2026 07:19
@oca-cla-bot

oca-cla-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

The following commit authors need to sign the Contributor License Agreement:

CLA not signed

@OCA-git-bot OCA-git-bot removed the mod:ai_tool Module ai_tool label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants