Skip to content

[TEST] Stacked branch: ai_tool docs + ai_oca_mcp + ai_tool_read (19.0) - #128

Draft
dreispt wants to merge 33 commits into
OCA:19.0from
dreispt:19.0-test-stack
Draft

dreispt wants to merge 33 commits into
OCA:19.0from
dreispt:19.0-test-stack

Conversation

@dreispt

@dreispt dreispt commented Oct 8, 2026

Copy link
Copy Markdown
Member

Draft — for testing only. Do not merge.

Stacks the following open PRs into a single branch so the full AI/MCP feature set can be exercised on a 19.0 runboat-style install:

The ai_tool fixes from #125 are included transitively (they are cherry-picked inside both migration branches).

Provides ai_tool (with non-admin access fix and valid date output schema), ai_oca_mcp, and ai_tool_read on one branch.

etobella and others added 30 commits October 7, 2026 15:46
Currently translated at 100.0% (43 of 43 strings)

Translation: ai-16.0/ai-16.0-ai_oca_mcp
Translate-URL: https://translation.odoo-community.org/projects/ai-16-0/ai-16-0-ai_oca_mcp/it/
Currently translated at 100.0% (43 of 43 strings)

Translation: ai-16.0/ai-16.0-ai_oca_mcp
Translate-URL: https://translation.odoo-community.org/projects/ai-16-0/ai-16-0-ai_oca_mcp/pt_BR/
Currently translated at 4.6% (2 of 43 strings)

Translation: ai-16.0/ai-16.0-ai_oca_mcp
Translate-URL: https://translation.odoo-community.org/projects/ai-16-0/ai-16-0-ai_oca_mcp/gl/
The MCP endpoint switches to the key's user_id via with_user before
serving tools/list and tools/call. mcp.server and mcp.server.key were
only accessible to base.group_system, so a non-admin key user hit an
AccessError while reading its own key and server.

Grant base.group_user read access to both models and add record rules
limiting internal users to their own keys (and the servers those keys
belong to), while keeping full visibility for administrators.
cover exception in the execute method
it was wrongly set to True we do not notify client if list changed
Rewrite the readme fragments to explain the tool registry (ai.tool
records bound to @aitool-decorated methods with JSON schemas), document
the three tool kinds and their invocation semantics, and fix the glue
module example: it omitted the kind field, which defaults to record and
would fail for the model-level function shown.

Assisted-by: Devin:SWE-2 High
Building and dispatching a tool reads ir.model via model_id, which a
plain internal user (base.group_user) cannot access. Resolve the model
name with sudo() while keeping the actual tool execution under the
caller's own permissions, so non-admin MCP keys can list and call tools.

Add a regression test exercising a non-admin user through
_get_tool_definition and _execute_tool.

(cherry picked from commit 16beaa7)
'date' is not a JSON Schema type, so the declared output schema is not
valid for MCP clients validating against it. Declare the RFC 3339
format instead.

Assisted-by: Devin:SWE-2 High
Port ai_oca_mcp to 19.0, based on the 17.0 migration in OCA#85 and
the 18.0 migration in OCA#76.

- Replace _sql_constraints with models.Constraint.
- Declare the MCP endpoint readonly=False: auth="none" routes default
  to a read-only cursor in 19.0 and this endpoint always writes (log
  records, key expiry).
- res.users groups_id renamed to group_ids in tests.
- Replace per-method ormcache clear_cache() with
  env.registry.clear_cache() in tests.
- Restore the security/security.xml manifest entry lost while rebasing
  the 17.0 migration over the 16.0 fix commit.
- Non-admin key usage additionally requires the ai_tool fixes in the
  preceding commits: the ir.model metadata lookup cherry-picked from
  OCA#119, and an equivalent output-schema fix for _ai_get_date.

Assisted-by: Devin:SWE-2 High
Rewrite the readme fragments to document the actual protocol surface
(JSON-RPC over HTTP POST, tools/list and tools/call, no SSE), the
hashed-key/per-user auth model, key lifecycle and audit logging, the
tool-kind limitation, where real capabilities come from (ai_tool_read
and other extension modules), and the admin vs internal-user access
rules. Update contributors.

Assisted-by: Devin:SWE-2 High
MCP's InitializeResult supports an optional instructions field that
spec-compliant clients pass to the model. Return an auto-generated
capability summary — the server's purpose and the exposed tools with
their descriptions — and append the optional instructions text
configured on mcp.server for extra context.

Assisted-by: Devin:SWE-2 High
ai_tool lets modules expose tools to AI agents, but each one has to be
written for a specific model. This module adds three generic tools,
list_models, get_fields and search_read, so that an agent can read any
model the calling user is allowed to read, with the user's own access
rights (ACLs, record rules and field groups still apply).

Personal or otherwise sensitive data can be kept out of the results with
a new "AI Read Forbidden" flag on ir.model.fields. A flagged field is
never returned nor described, and neither is any field exposing its
value: related fields, _inherits included, and computed fields depending
on it, as the registry reports them. Many2one values are returned as
plain IDs, and display names computed on the fly are left out, as both
come from name_get, which may show another record's forbidden field.

Searches are not restricted, so an agent probing on purpose can still
find records by a forbidden value; the README lists those cases.

search_read returns the stored fields unless a field list is given, pages
its results with limit, offset and has_more, and does not fail as a whole
because of one field or record the user may not read.

Assisted-by: Claude Opus 5.5
Building and dispatching a tool reads ir.model via model_id, which a
plain internal user (base.group_user) cannot access. Resolve the model
name with sudo() while keeping the actual tool execution under the
caller's own permissions, so non-admin MCP keys can list and call tools.

Add a regression test exercising a non-admin user through
_get_tool_definition and _execute_tool.

(cherry picked from commit 16beaa7)
'date' is not a JSON Schema type, so the declared output schema is not
valid for MCP clients validating against it. Declare the RFC 3339
format instead.

Assisted-by: Devin:SWE-2 High
- _ai_jsonify: note that isinstance(date) also covers datetime.
- _ai_get_fields: document that reporting forbidden fields under
  "hidden" is deliberate, unlike group-restricted fields which are not
  disclosed.
- _ai_forbidden_fields: return early when no field is flagged.
- _ai_search_read: an explicit empty fields list now returns ids only;
  previously it fell back to the stored-fields default, same as no
  fields argument at all.

Assisted-by: Devin:SWE-2 High
Port ai_tool_read from OCA#122 to 19.0.

- Manifest version bump.
- user_has_groups() removed: use res.users.has_groups().
- check_access_rights() deprecated since 18.0: use has_access() /
  check_access().
- View xpath targets use <list> instead of <tree>.
- display_name is never stored in 19.0, so it is excluded everywhere;
  adjust test_display_name_hidden.
- Replace setup/ symlink dir with the whool pyproject.toml convention.

Requires the ai_tool fixes from OCA#125, cherry-picked in the
preceding commits (ir.model is not readable by internal users in 19.0).

Assisted-by: Devin:SWE-2 High
Add a USAGE section covering how the registered ai.tool records are
consumed (e.g. via ai_oca_mcp), the list_models / get_fields /
search_read agent workflow, and the search_read arguments with an
example. Drop the "This module" opening from the description.

Assisted-by: Devin:SWE-2 High
@OCA-git-bot OCA-git-bot added mod:ai_oca_mcp Module ai_oca_mcp mod:ai_tool Module ai_tool series:19.0 mod:ai_tool_read Module ai_tool_read labels Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:ai_oca_mcp Module ai_oca_mcp mod:ai_tool_read Module ai_tool_read mod:ai_tool Module ai_tool series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants