Skip to content

[MCP Bug]: Business Central MCP omits a editable custom API field #11674

Description

@MatthewMcCarthy7

Describe the issue

MCP appears to treat a field as read-only based on the table definition, even when the API page explicitly marks the field as editable. Direct API calls through Business Central work correctly and persist the value, but MCP omits the field from its Create/Modify schemas and rejects it as an unknown property. I've attached a full reproduction project and documentation.

Microsoft support told me to reach out to create this ticket this way. TrackingID#2609110010002781

Expected behavior

The MCP should respect the page editability property over the table editability, just like when you call it through the API and on Business Central Pages.

Steps to reproduce

Reproduction objects

The following three AL objects are included:

File Object Purpose
MCPWritableDemo.Table.al Table 83707SWL-API MCP Writable Demo Stores isolated test records
MCPWritableDemoAPI.Page.al Page 83767SWL-API MCP Writable Demo API Exposes the records through a custom API
MCPDemo.PermissionSet.al Permission Set 83700SWL-API MCP Demo Grants access to the table and API page

Table definition

Table 83707 contains two fields used for the comparison:

field(3; "Quantity To Post"; Decimal)
{
    Caption = 'Quantity To Post';
}
field(4; "New Bin Code"; Code[20])
{
    Caption = 'New Bin Code';
    Editable = false;
}

Quantity To Post is editable by default. New Bin Code is explicitly read-only at the table level.

API definition

Page 83767 uses this route metadata:

APIPublisher  = plumblineConsultingLLC
APIGroup      = mcpRepro
APIVersion    = v1.0
EntityName    = mcpWritableFieldDemo
EntitySetName = mcpWritableFieldDemos

The relevant API controls are:

field(quantityToPost; Rec."Quantity To Post")
{
}
field(newBinCode; Rec."New Bin Code")
{
  Editable = true;
}

This intentionally creates conflicting settings: the source table field is read-only while the API page field explicitly requests editability.

The complete API contract is:

Property Editable Purpose
id No ImmutableSystemId OData key
code Yes Record identifier
description Yes Editable text field
quantityToPost Yes Editable control field
newBinCode Yes through API Table hasEditable = false; API page has Editable = true; direct API write succeeds
lastModifiedDateTime No Read-only system timestamp

Deployment

  1. Publish the extension to a Business Central sandbox.
  2. Assign permission set SWL-API MCP Demo to the MCP user.
  3. Confirm the API entity appears in the environment's $metadata document.
  4. Restart or reconnect the Business Central MCP server to force action discovery.

MCP actions discovered

MCP discovered all expected CRUD actions:

Create_McpWritableFieldDemo_PAG83767
Delete_McpWritableFieldDemo_PAG83767
List_McpWritableFieldDemos_PAG83767
Modify_McpWritableFieldDemo_PAG83767

Generated schemas

The List action exposes all six API properties, including newBinCode:

id, code, description, quantityToPost, newBinCode, lastModifiedDateTime

The generated Create schema contains:

code, description, quantityToPost

The generated Modify schema contains:

id, If-Match, code, description, quantityToPost

MCP omits newBinCode from both write schemas even though the Business Central API accepts and persists the property.

Direct Business Central API control

The following request was sent directly to the custom Business Central API endpoint for Page 83767:

POST <api-base>/api/plumblineConsultingLLC/mcpRepro/v1.0/companies(<company-id>)/mcpWritableFieldDemos
Content-Type: application/json

{
  "code": "Test00001-090926",
  "description": "Test00001-090926",
  "quantityToPost": 7,
  "newBinCode": "1-F1"
}

Business Central returned 201 Created, including the persisted value in its response:

{
  "code": "TEST00001-090926",
  "description": "Test00001-090926",
  "quantityToPost": 7,
  "newBinCode": "1-F1"
}

This confirms that newBinCode is writable through the published Business Central API. The table-level Editable = false does not prevent the API page's explicit Editable = true override from accepting the value.

Test procedure and results

Compare the same Create operation through MCP

Invoke Create_McpWritableFieldDemo_PAG83767 with all four business properties:

{
  "code": "MCP-COMPARE-0909",
  "description": "Direct API versus MCP create",
  "quantityToPost": 7,
  "newBinCode": "1-F1"
}

MCP rejects the request before it reaches Business Central:

The tool Create_McpWritableFieldDemo_PAG83767 threw an McpBadRequestException exception.
Message: Unknown property newBinCode for operation Create_McpWritableFieldDemo_PAG83767.
Use 'bc_actions_describe' to see the valid properties for this action.

A List query for code MCP-COMPARE-0909 returned no record, confirming that MCP created no partial data.

Create

Invoke Create_McpWritableFieldDemo_PAG83767:

{
  "code": "MCP-20260909-02",
  "description": "Table versus page editability test",
  "quantityToPost": 45
}

Result: the record was created successfully. The response included newBinCode with an empty value.

Modify an editable field

Invoke Modify_McpWritableFieldDemo_PAG83767 with the record ID and current @odata.etag:

{
  "id": "<record-id>",
  "If-Match": "<current-etag>",
  "quantityToPost": 20
}

Result: the update succeeded, quantityToPost became 20, and Business Central returned a new etag.

Modify the conflicting-editability field

Invoke the same Modify action with the current ID and etag:

{
  "id": "<record-id>",
  "If-Match": "<current-etag>",
  "newBinCode": "1-H1"
}

Result: MCP rejected the request before it reached Business Central:

The tool Modify_McpWritableFieldDemo_PAG83767 threw an McpBadRequestException exception.
Message: Unknown property newBinCode for operation Modify_McpWritableFieldDemo_PAG83767.
Use 'bc_actions_describe' to see the valid properties for this action.

Verify and clean up

Readback after the rejected request confirmed:

{
  "quantityToPost": 20,
  "newBinCode": ""
}

The rejected request caused no data mutation. The disposable record was deleted through Delete_McpWritableFieldDemo_PAG83767, and a final List query confirmed that it no longer existed.

Observed behavior

  • After correcting permissions, Create, List, Modify of quantityToPost, and Delete all succeeded, confirming that the MCP user has the required CRUD permissions.
  • Direct Business Central OData accepts and persists newBinCode on Create, returning 201 Created.
  • MCP exposes newBinCode through the List action.
  • MCP excludes newBinCode from Create and Modify despite the direct API proving that the property is writable.
  • MCP rejects the same Create property as Unknown property before the request reaches Business Central.
  • Editable properties remain available and can be updated successfully.
  • Supplying the omitted newBinCode property causes MCP request validation to return Unknown property.
  • A rejected request does not modify the Business Central record.
  • Removing table-level Editable = false causes MCP to expose and successfully write newBinCode through both Create and Modify.

MCP.zip

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Team: IntegrationsGitHub request for Integrations area

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions