Skip to content

[MCP] Add codeunit APIs as MCP tools in MCP configuration - #10008

Merged
Onat Buyukakkus (onbuyuka) merged 15 commits into
mainfrom
bugs/643238-codeunit-mcp-tools
Aug 20, 2026
Merged

[MCP] Add codeunit APIs as MCP tools in MCP configuration#10008
Onat Buyukakkus (onbuyuka) merged 15 commits into
mainfrom
bugs/643238-codeunit-mcp-tools

Conversation

@onbuyuka

@onbuyuka Onat Buyukakkus (onbuyuka) commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Fixes AB#643238

Summary

Adds Codeunit as a new object type in the MCP configuration UI, at parity with API pages and queries, and sources all API metadata from the Api Web Service table.

  • Unified Select APIs lookup lists API pages, queries and codeunits together. Opening the lookup from a tool row's Object Id field filters to that row's object type; the Select APIs action stays unfiltered.
  • Add APIs by API Group and Add all standard APIs work across pages, queries and codeunits.
  • New public facade CreateCodeunitAPITool; GetAPIToolId object type extended to Codeunit.
  • Permission model: renamed Allow Bound Actions -> Allow Actions (page caption + facade AllowActions, with AllowBoundActions deprecated behind #if not CLEAN29). For codeunit tools Allow Actions is the invoke toggle; Read/Create/Modify/Delete are not applicable.
  • Missing-object / missing-parent warnings, export/import, upgrade and version handling updated for codeunits.
  • API Overview page (812) now lists API pages, queries and codeunits, all sourced from the same Api Web Service table. Because each codeunit procedure has its own endpoint, no single object URL is shown for codeunit rows.

Metadata source: Api Web Service

API metadata for all three object types now comes from the Api Web Service table, replacing the separate Page Metadata, Query Metadata and CodeUnit Metadata lookups in both the MCP configuration and the API Overview page:

  • A single source keyed by Object Type + Object ID, exposing Publisher / Group / Version, Service Name (entity set name), ObjectName, ALNamespace, and the InsertAllowed / ModifyAllowed / DeleteAllowed capability flags.
  • Only published APIs are listed.
  • The table holds one row per API version; consumers aggregate versions per object (the MCP selection applies the highest version when a tool is created).
  • V1 APIs (Microsoft.API.V1) and the Base Application beta customer/vendor queries (5480/5481) remain excluded from the MCP selection.

This removes the previous codeunit-specific handling (namespace matching, regex-derived entity names and fixed microsoft/codeunits/beta values); codeunits now carry their real publisher, group, version and entity name, and page create/modify/delete editability reads the capability flags directly.

API Overview page (812)

The API Overview page now uses Api Web Service as its single source for all object types, so pages and queries are no longer read from Page Metadata / Query Metadata (and codeunits no longer use the interim CodeUnit Metadata namespace match). A shared AddAPIObjects helper enumerates the published web services per object type, and an object published under several versions is listed once with its versions aggregated.

  • The page lists all published API pages, queries and codeunits. It is intentionally comprehensive and does not apply the MCP-specific V1 / 5480-5481 exclusions.
  • The Entity column now shows the entity set name from Api Web Service Service Name (e.g. postedSalesInvoices) - the value that appears in the API URL - instead of the singular EntityName previously read from metadata.

Beta APIs

Microsoft and standard beta pages (publisher microsoft or empty) are excluded from the selection lookup, bulk add, the publisher list and the version picker. Third-party beta pages stay available. Beta queries and codeunits are unaffected.

Test plan

  • Codeunit permission tests (TestCodeunitToolDoesNotAllowRead/Create/Modify/Delete, TestCodeunitToolAllowsActions) plus a CreateMCPCodeunitConfigTool helper.
  • Existing bound-actions tests renamed to AllowActions.
  • Updated the MCP test library LookupAPIObjects wrapper and the GetHighestAPIPageVersion helper (now takes an object id) for the new signatures.
  • API Overview tests updated for the Api Web Service source: TestAPIOverviewIncludesKnownAPIPage now asserts the entity set name (postedSalesInvoices), and TestAPIOverviewListsEveryAPIPage counts distinct published API pages from Api Web Service.

Adds Codeunit as a new object type in the MCP configuration alongside API pages and queries: unified Select APIs lookup, Add by API Group, per-tool 'Allow Actions' permission (renamed from Allow Bound Actions), version handling, missing-object warning, and export/import. First-version behavior matches API codeunits by the 'Microsoft.API.Codeunits' namespace and hardcodes microsoft/codeunits/beta until CodeUnit Metadata exposes the API fields (AB#641822).

Fixes AB#643238

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
@github-actions github-actions Bot added AL: System Application Integration GitHub request for Integration area labels Aug 5, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 5, 2026
…code

The commented restore-when-AB#641822-ships code matched API codeunits by EntityName (the query heuristic). API codeunits are identified by the new codeunit SubType 'API' (analogous to PageType::API), so switch the deferred filters and validation to SubType and drop the spurious Microsoft.API.V1 exclusion. Interim live code still matches by the Microsoft.API.Codeunits namespace.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
Extend API Overview Buffer (table 812) with a Codeunit object type and load API codeunits alongside API pages and queries, matched by the Microsoft.API.Codeunits namespace in the first version (SubType-based once AB#641822 ships). Adds an API Codeunits view. The URL column is blank for codeunit rows because each procedure is its own unbound-action endpoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
Strip all non-alphanumeric characters from the codeunit name when deriving the API entity name in page 812, matching the MCP module. Adds the System.Utilities using and a Regex codeunit variable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
When the Select APIs lookup is opened from a tool row's Object Id field it now filters to that row's object type; the Select APIs action stays unfiltered. Codeunit API entity names are derived by stripping all non-alphanumeric characters via Regex instead of removing spaces only. Update the MCP test library wrapper for the new LookupAPIObjects signature.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
SetPermissions() early-exits for Query/Codeunit rows (no Page Metadata match), which previously left AllowCreate/Modify/DeleteEditable holding the prior Page row's values. Reset all three to false up front so stale editability can't leak across row types if the field-level Object Type guards ever change. Addresses PR review feedback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb90ebfd-967b-4ba4-98ec-57b054806669
@github-actions github-actions Bot added the AL: Apps (W1) Add-on apps for W1 label Aug 13, 2026
Replace Page/Query/CodeUnit Metadata with the Api Web Service table as the source for MCP API page, query and codeunit tools. Assumes the platform exposes ObjectName, ALNamespace, InsertAllowed, ModifyAllowed and DeleteAllowed on Api Web Service. Microsoft/standard beta pages (publisher microsoft or empty) are excluded while third-party beta pages remain available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d333ffa5-b544-46f0-a32e-410452089eaf
@onbuyuka
Onat Buyukakkus (onbuyuka) force-pushed the bugs/643238-codeunit-mcp-tools branch from 2ea0e24 to 02c41b5 Compare August 14, 2026 19:56
@github-actions github-actions Bot removed the AL: Apps (W1) Add-on apps for W1 label Aug 14, 2026
Align the API Overview page (812) with the MCP configuration, which now reads
API object metadata from the "Api Web Service" table. The codeunit rows no
longer rely on the interim "CodeUnit Metadata" namespace match with hard-coded
microsoft/codeunits/beta values and a regex-derived entity name (AB#641822);
instead they use the real publisher, group, version, service (entity) name and
object name from the published web services. A codeunit published under several
versions is listed once, with its versions aggregated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1b34da29-3e61-4831-9999-c4e3cce5f128
Complete the move to the "Api Web Service" table as the single source for the
API Overview page (812), matching the MCP configuration. Pages and queries are
no longer read from "Page Metadata"/"Query Metadata"; all three object types
(pages, queries, codeunits) are now enumerated from the published web services
through a shared AddAPIObjects helper. An object published under several
versions is listed once, with its versions aggregated.

As a result the Entity column now shows the entity set name (Api Web Service
"Service Name", e.g. postedSalesInvoices) that appears in the API URL, instead
of the singular EntityName from Page/Query Metadata. Tests updated accordingly:
- TestAPIOverviewIncludesKnownAPIPage now expects postedSalesInvoices.
- TestAPIOverviewListsEveryAPIPage counts distinct published API pages from
  Api Web Service instead of Page Metadata.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1b34da29-3e61-4831-9999-c4e3cce5f128
Comment thread src/Layers/W1/BaseApp/System/API/APIOverview.Page.al
Comment thread src/System Application/Test/MCP/src/MCPConfigTest.Codeunit.al
@divyanshukapoor

Divyanshu Kapoor (divyanshukapoor) commented Aug 17, 2026

Copy link
Copy Markdown

MCPConfigImplementation.Codeunit.al — line 739 (IsMicrosoftBetaAPI)

Behavior change worth confirming (non-blocking). IsMicrosoftBetaAPI only classifies a beta row as beta when the publisher is microsoft or empty, and ExcludeMicrosoftBeta is passed true only for pages (queries/codeunits pass false). Net effect vs. the old APIVersion <> 'beta' filter: non-Microsoft (partner) beta API pages are now surfaced in the picker, and Microsoft v2.0+beta pages now show only v2.0

@divyanshukapoor

Copy link
Copy Markdown

. MCPConfigToolList.Page.al — line 229 (SetPermissions)

Nit (non-blocking). SetPermissions() always filters Object Type::Page, but it runs for Query/Codeunit rows too. If a Query/Codeunit Object Id coincides with a published API page's Object ID, it reads that page's Insert/Modify/Delete Allowed into the editability flags. Harmless today (those fields' Editable also require Object Type = Page), but fragile — consider an early if Rec."Object Type" <> Rec."Object Type"::Page then exit; after clearing the flags.

@divyanshukapoor

Copy link
Copy Markdown

MCPUpgrade.Codeunit.al — line 36 (IsAPIPage)

Confirm ordering (non-blocking). This upgrade path depends on IsAPIPage(), which queries Api Web Service with Published = true. Please confirm the upgrade runs after web services are registered/published — otherwise IsAPIPage returns false for real API pages and API Version won't be back-filled. Same dependency applies to MCPConfigMissingParent line 38.

@divyanshukapoor

Copy link
Copy Markdown

The facade/caption were renamed Page→"Allow Actions", but the backing table field remains "Allow Bound Actions" and is now reused as the invoke toggle for codeunit tools — whose endpoints this PR explicitly documents as unbound actions (see the APIOverview GetApiUrl comment "one endpoint per procedure (unbound action)"). The persisted field name is now semantically inaccurate for codeunit rows.

@divyanshukapoor

Copy link
Copy Markdown

The new permission tests insert an MCP Configuration Tool directly with a random Object Id, bypassing CreateCodeunitAPITool / ValidateAPICodeunitTool. So the new public facade CreateCodeunitAPITool and its guards (CodeunitNotFoundErr, InvalidCodeunitTypeErr) are untested — the only genuinely new creation logic in the PR has no test asserting it rejects a non-existent codeunit or a non-API codeunit, nor that it stamps the highest codeunit version.
Fix: Add tests: (1) CreateCodeunitAPITool on a real API codeunit succeeds and sets "Allow Bound Actions" + "API Version"; (2) it errors on a missing codeunit and on a non-API codeunit; mirror the existing page/query validation tests.

@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟡\ Medium\ Severity\ —\ Testing}$

The lookup coverage still exercises only the unfiltered path. TestLookupAPIObjects calls the test-library helper with TypeFilter = false, so the new filtered lookup branch used from the Object ID lookup is never verified. A regression that lets a page row pick a query/codeunit (or vice versa) would still leave this suite green. Add a test that drives the lookup with TypeFilter = true and asserts the selected object type matches the current row.

Agent judgement — not directly backed by a BCQuality knowledge article.

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.34.4

@onbuyuka
Onat Buyukakkus (onbuyuka) added this pull request to the merge queue Aug 20, 2026
Merged via the queue into main with commit 6670f6a Aug 20, 2026
348 of 397 checks passed
@onbuyuka
Onat Buyukakkus (onbuyuka) deleted the bugs/643238-codeunit-mcp-tools branch August 20, 2026 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: System Application Integration GitHub request for Integration area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants