Skip to main content
Glama
SShadowS

business-central-mcp

by SShadowS

bc_upload_file

Destructive

Upload a local file into an open Business Central file-upload dialog so the page's Upload/UploadIntoStream AL code runs on your bytes. Invoke the page's upload action first.

Instructions

Upload a local file into a Business Central file-upload dialog, driving the page's AL Upload/UploadIntoStream code on the uploaded stream. This is a TWO-STEP flow: first invoke the page's upload action (bc_execute_action, e.g. "Import Layout" on Custom Report Layouts / page 9650) so BC opens the file-picker dialog (a FileUploadForm, returned in dialogsOpened), then call bc_upload_file with that page's pageContextId. The file is sent as a multipart POST to BC's DynamicFileUploadHandler over the same authenticated session, and the dialog is closed afterwards — exactly what the web client does — which resumes the suspended AL code on your bytes.

The upload targets the page's open FileUploadForm dialog automatically; optionally pass formId (the dialog formId from bc_execute_action's dialogsOpened) to target it explicitly. The call FAILS with a clear error instead of uploading when no FileUploadForm dialog is open — BC would otherwise silently discard the bytes (HTTP 200 with no effect), e.g. when the action failed and opened an error dialog instead, or when the invoked action is a declarative fileuploadaction (wire type fla, such as Extension Management's "Upload Extension..."), which uses a different protocol this tool does not serve.

Provide the file as either path (an absolute path to a local file) or base64 (inline content, with fileName).

The response reports the uploaded fileName, sizeBytes, the target formId, and any dialogsOpened the AL code raised in reaction to the file (e.g. a validation error for a bad file — respond to those with bc_respond_dialog, or re-read the page with bc_read_data to see the imported rows). This tool is for pushing a file TO BC; to retrieve files FROM BC (reports, "Open in Excel"), use bc_run_report / bc_execute_action, which return downloads[].

Example (local path): { "pageContextId": "session:page:9650:ab12", "path": "C:/tmp/layout.docx" } Example (base64): { "pageContextId": "session:page:9650:ab12", "base64": "UEsDBAo...", "fileName": "layout.docx" }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathNoAbsolute path to a local file to upload. Provide exactly one of `path` or `base64`.
base64NoBase64-encoded file content, as an alternative to `path`. Provide exactly one of `path` or `base64`.
formIdNoOverride the target dialog form id. By default the open FileUploadForm dialog on the page is used. Pass the form id from bc_execute_action's dialogsOpened to target a specific upload dialog; it must be a FileUploadForm.
fileNameNoFile name BC should see (e.g. "extension.app"). Required with `base64`; defaults to the basename of `path`.
operationIdNoOptional idempotency key (e.g. a UUID you generate). Retrying with the same operationId and the same arguments returns the first call's stored result instead of running the change again, so a retry after a dropped connection or timeout cannot double-post. Reusing it with different arguments is rejected (OPERATION_ID_REUSED). If the first call's outcome is unknown, the retry returns OPERATION_IN_DOUBT: check the record's state before acting again under a new operationId. Every result of this tool carries replaySafe: true means BC's response proved that re-running the same call (even under a new operationId, after an unknown outcome) cannot apply the change twice -- the write was echoed as an absolute value, or the form it acted on is closed so BC rejects a re-run; false means a re-run may double-apply or nothing proved otherwise, so read the record back before retrying. Replay is time-limited: a completed entry is kept for BC_OPERATION_TTL (default 24h), after which the same operationId runs the call again; check with bc_get_operation before a late retry. A replayed result carries download metadata (fileName, contentType, sizeBytes, savedPath) but not the file bytes.
pageContextIdYesPage context ID of the host page whose upload action you just invoked (e.g. page 9650 after "Import Layout"). The open FileUploadForm dialog on that page is targeted automatically.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
formIdYes
successYes
fileNameYes
sizeBytesYes
replaySafeYes
dialogsOpenedYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv2.0.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as destructive, non-read-only, and not idempotent, but the description adds substantial behavioral context: multipart POST to DynamicFileUploadHandler, authenticated session use, dialog closure, resumption of suspended AL code, failure conditions instead of silent discard, unsupported fla actions, and optional idempotency/replay semantics. These details go well beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but it is front-loaded with the core action and flow before details. Most sentences earn their place given the complexity, though the operationId/idempotency explanation is lengthy and overlaps with the schema's own parameter description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the rich input schema, the annotations, and the presence of an output schema, the description is complete enough for correct invocation. It covers prerequisites, failure modes, response shape, and next actions such as responding to raised dialogs or re-reading the page.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the parameters thoroughly; baseline would be 3. The description adds practical meaning through examples, the relationship between formId and bc_execute_action's dialogsOpened, and the path/base64/fileName usage patterns, though much of this is also present in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: upload a local file into a Business Central file-upload dialog, driving the page's AL Upload/UploadIntoStream code. It clearly distinguishes this tool from its pre-step sibling bc_execute_action and from retrieval siblings bc_run_report/bc_execute_action by explaining that this tool pushes files TO BC.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance, including the required two-step flow: first invoke the page's upload action with bc_execute_action, then call bc_upload_file with that page's pageContextId. It also states when the call fails and why, and routes the agent to alternatives for retrieving files FROM BC.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.