Skip to main content
Glama
business-central-mcp

business-central-mcp

by SShadowS

bc_run_tests

Destructive

Run AL test codeunits in Business Central through Microsoft's AL Test Runner (page 130455 "Command Line Test Tool", the same path BcContainerHelper uses) and return one structured row per test method.

Instructions

Run AL test codeunits in Business Central through Microsoft's AL Test Runner (page 130455 "Command Line Test Tool", the same path BcContainerHelper uses) and return one structured row per test method. Runners 130450/130451 run the full before-test hook, so the Permissions Mock, TestPermissions and test personas apply; a dev-endpoint test hub does not, and restrictive tests can pass there as SUPER.

Select tests with exactly one of codeunits (a BC filter: "50490..50494", "50490|50492") or extensionId (app GUID). Narrow to methods with a name filter ("Persona"). The suite (default "MCP") is rebuilt on every call and stays in BC with the last run's results, so it does not touch BcContainerHelper's "DEFAULT" suite unless you name it.

The tool runs one codeunit per round trip until all are done. Each row has codeunitId, codeunitName, method, status (passed/failed/skipped/notRun), durationMs, output (the failure message) and callStack for failures, the same row shape as bc-dev-mcp's bcdev_test_run. outcome is "passed", "failed", "noTests" (the filter matched nothing) or "aborted" (the run stopped early, e.g. a test opened an unhandled dialog or the session dropped; results holds the codeunits that finished).

Use this to run, check or debug AL tests. It wraps the manual route (bc_open_page 130455, bc_write_data on "Suite Name" / "Test Codeunit Range", bc_execute_action "Run Next Test" until "All tests executed."); use those tools directly to inspect the suite's lines afterwards. Do NOT use it on production data with runner 130451 (isolation disabled): test writes are committed there. Returns TEST_RUNNER_NOT_INSTALLED when the Test Runner app is missing. Not idempotent: every call runs the tests again.

Example: { "codeunits": "50490..50494" } Example: { "extensionId": "6c3f0b8e-4f49-4b49-9a49-0049c0de4949", "methods": "Persona" } Example: { "codeunits": "134000", "testRunnerCodeunitId": 130451, "suiteName": "NOISOL" }

Input Schema

NameRequiredDescriptionDefault
methodsNoOptional test procedure name filter in BC filter syntax, e.g. "TestPostInvoice" or "*Persona*|NoPersona*". Only matching methods run.
testTypeNoOptional TestType filter (1 UnitTest, 2 IntegrationTest, 3 Uncategorized, per the CodeUnit Metadata option).
codeunitsNoTest codeunit ID filter in BC filter syntax: a range "50490..50494", a list "50490|50492", or one ID "50490". Provide exactly one of `codeunits` or `extensionId`.
suiteNameNoTest suite to (re)build and run. Default "MCP". Up to 10 characters. The suite's lines are replaced on every run; pick a different name to keep another suite (e.g. BcContainerHelper's "DEFAULT") untouched.
extensionIdNoApp ID (GUID) of the extension whose test codeunits to run. Provide exactly one of `codeunits` or `extensionId`.
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.
testRunnerCodeunitIdNoTest runner codeunit. Default 130450 ("Test Runner - Isol. Codeunit", rolls back after each codeunit). 130451 runs with isolation disabled, so test writes are committed.
requiredTestIsolationNoOptional RequiredTestIsolation filter (0 None/Codeunit, 1 Disabled, 2 Function, per the CodeUnit Metadata option). Only applies together with testType.

Output Schema

NameRequiredDescriptionDefault
abortedNo
outcomeYes
resultsYes
summaryYes
suiteNameYes
replaySafeYes
failedTestsYes
testRunnerCodeunitIdYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv2.3.0

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations: discloses that the suite is rebuilt every call and persists in BC, that runners 130450/130451 run the before-test hook so Permissions Mock/TestPermissions/personas apply while a dev-endpoint hub does not (restrictive tests can falsely pass as SUPER), the round-trip-per-codeunit execution model, the outcome vocabulary including 'aborted', and the TEST_RUNNER_NOT_INSTALLED error. The isolation-disabled write-commit warning is consistent with destructiveHint=true and the non-idempotency note with idempotentHint=false.

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?

Front-loaded with the core action and scope, then layered warnings and examples; most sentences earn their place. There is some redundancy — filter syntax examples are repeated from the schema, and 'not idempotent' is restated after being implied earlier — which keeps it short of a 5 given the overall length.

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?

For an 8-parameter, destructive, non-idempotent test runner, the description covers selection semantics, suite persistence, execution model, result row shape and outcome values, failure modes, and the manual-route fallback. With an output schema present it did not need to enumerate row fields but did so anyway, leaving no obvious gap for correct invocation.

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 coverage is 100%, so the baseline is 3; the description adds value beyond it by showing concrete BC filter literals ('50490..50494', '50490|50492', '*Persona*') and by explaining the consequence of suiteName — that its lines are replaced on each run and a different name leaves BcContainerHelper's DEFAULT suite untouched. It does not add much on testType/requiredTestIsolation beyond what the schema already states.

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?

States a specific verb+resource: run AL test codeunits in Business Central via the Command Line Test Tool (page 130455) and return one structured row per test method. It distinguishes itself from the sibling manual route by naming bc_open_page/bc_write_data/bc_execute_action as the equivalent workflow, so an agent can tell which tool to pick without opening a schema.

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?

Gives explicit selection rules (exactly one of codeunits or extensionId, methods/name filter to narrow), an explicit when-to-use ('run, check or debug AL tests'), an explicit when-not ('do NOT use it on production data with runner 130451'), and an explicit alternative (drive the page manually to inspect the suite lines).

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