Tool to manage containers, new environments, update of add-ins, dependecies and fonts.
Requirements
Telemetry & Privacy
This extension sends anonymous usage and error telemetry via VS Code's standard @vscode/extension-telemetry module (Azure Application Insights) so we can prioritise which features to develop and diagnose errors. Nothing is sent unless both of these allow it — turning either one off disables telemetry:
- VS Code's global
telemetry.telemetryLevel setting, and
- the extension setting
ev-tools.enableTelemetry (default true).
Your Windows user id is included. Every event carries ev.user = DOMAIN\username, so usage and errors can be attributed per user/team. A one-time notice discloses this the first time telemetry is active.
What we never send: project or folder names, repository URLs/organisations, Jira keys, file paths, command-line strings, language-model tool inputs, or raw error messages. Error stack traces have file-system paths redacted to [PATH].
Microsoft Learn MCP server. This extension also provides the Microsoft Learn MCP server to Copilot agent mode (see Microsoft Learn MCP Server). When the model uses it, your search queries — which may include context from the AL code you are working on — are sent unauthenticated to Microsoft under the Microsoft Learn Terms of Use. That traffic goes from VS Code straight to Microsoft: it is not routed through EV, it is not covered by ev-tools.enableTelemetry, and EV collects no telemetry about it. Disable the server if you do not want this.
Events collected
| Event |
Kind |
Properties (besides ev.user) |
command.executed |
usage |
commandId (the static command id, never arguments) |
lm.tool.invoked |
usage |
toolName (the static tool name, never inputs) |
project.created |
usage |
projectType, createContainer, repositoryMode |
powershell.command.failed |
error |
exitCode |
process.command.failed |
error |
errorName, exitCode (no stack — the command line is unsafe) |
xliff.failed |
error |
errorName, stack (path-redacted), stage |
project.creation.failed |
error |
errorName, stack (path-redacted), projectType, failedStep |
VS Code also adds anonymous common properties automatically (e.g. common.extname, common.extversion, common.vscodemachineid, common.os). With the extension installed you can run code --telemetry to dump it.
Note: powershell.command.failed undercounts. Legacy PowerShell commands run via fire-and-forget sendText have no exit code and cannot be observed, so a low failure count must not be read as "few PowerShell failures."
Commands
Git Util
Git Cleanup Local Branches: Cleanup local branches to match remote branches.
Git Fetch (Prune) And Checkout: Cleanup local branches to match remote branches & checkout a specific branch.
BC/Docker Util
Add Container Test Users: Adds default test users (Essential, Basic, etc)
Add Fonts to Container: Copies fonts from ./fonts to the container
Add New User to container: Creates a new user to the BC environment
Backup App.json: Backups the current app.json into vscode's context. Enables the user to restore app.json later.
Backup Container Database: Backups the container to a database (.bak-file)
Build & Generate Xliff Files: Builds the solution using AL-language extension and then generates Xliff-files using comments. Read XLIFF Functionality for more information.
Edit NST Settings in Container: Opens a gridview for changing NST settings.
Edit Web Client Settings in Container: Opens a gridview for changing web client settings.
Get Container Information: Prints the container information in terminal.
Install NST Server Add-ins in Container: Installs control add-ins in the container (.NET client add-ins).
Install or Update BCContainerHelper PowerShell Module: Installs or updates the bccontainerhelper powershell module
Install Test Toolkit in Container: Installs the Test Toolkit
Open Client: Opens the webclient of the current workspace container.
Open Container Event Log: Opens the Event Viewer pointing to the container.
Open remote Git repository in browser: Opens the git repository in the users browser.
Open Terminal in Container: Opens powershell instance inside the container.
Open Terminal With EV PowerShell Module: Imports the EV PowerShell module into the terminal.
Remove Container: Removes the container
Restart Server Instance in Container: Restarts the service tier in the container
Restore App.json: Restores the app.json to the state at the point the command Backup App.json was run.
Restore Container Database: Reads the backupfolder and allows the user to select a backup to restore the database to.
Select Global Settings:
Select License File to update: Picks a new license for the container to run with.
Show Container Backup Folder: Shows the folder containing backups (created through Backup Container Database).
Show Container List: Show a list of containers present on the current machine.
Start Container: Starts the container of the current workspace.
Stop Container: Stops the container of the current workspace.
Update Container Dependencies: Updates dependencies from the ./dependencies-folder to the container.
Update Development License: Updates the license with a developer license from your Azure Storage account.
New Development Environment
All of these end up with a New Container View.
Clone development Environment from BitBucket: Clones a repository from bitbucket and opens the request page (if azure-pipeline.yaml is available in the repository).
Create Container from settings: Creates a container from the current workspace settings. Requires workspace settings to be available.
Create New Business Central Project: Creates a new Business Central project from a template repository. See Project Creation for more information.
Create New Development Environment: Pre-populates Request page with values from the database settings.
New Business Centrail Container: Creates a BC container from the request page.
Azure Storage
Install All Dependency from azure blob storage: Searches and installs all the dependencies from app.json from Azure Blob Storage.
Select App to install from Azure Blob Storage: Gives the user a list of the apps in Azure Blob Storage. The user can then search & pick a dependency to install.
Upload App to Azure Blob Storage: Opens a filepicker to which the user can pick a file an upload to Azure Blob Storage
EV Compiler Settings
After picking one of these commands, the user will be presented with a picker to choose the EV Compiler Setting to use.
Add new app to Fixeddependencies on EVCompilerSettings: Utilizes the Azure Storage-feature to pick an app to install and add to dependencies of the EV Compiler Settings.
Debug without publishing with compiler settings: Updates app.json with the compiler settings picked and runs Debug without publishing.
Download Symbols From Compiler Settings: Updates app.json with the compiler settings picked and runs Download Symbols.
Init Compiler Settings: Initialises the EVCompilerSettings.json from the current workspace.
Package with compiler settings: Updates app.json with the compiler settings picked and runs Package.
Publish and open in the designer with compiler settings: Updates app.json with the compiler settings picked and runs Publish and open in the designer.
Publish with debugging with compiler settings: Updates app.json with the compiler settings picked and runs Publish with debugging.
Publish without debugging with compiler settings: Updates app.json with the compiler settings picked and runs Publish without debugging.
Rapid Application Publish with debugging with compiler settings: Updates app.json with the compiler settings picked and runs Rapid Application Publish with debugging.
Rapid Application Publish without debugging with compiler settings: Updates app.json with the compiler settings picked and runs Rapid Application Publish without debugging.
Show Compiler Settings: Shows the Compiler Settings-view
Update App.json from compiler settings: Updates the app.json from the compiler settings picked.
BC Quality
Update BC Quality Knowledge: Downloads the latest BC Quality knowledge base straight away, instead of waiting for the daily check, and reports which commit is installed.
Misc
Clear Bitbucket Credentials: Removes bitbucket credentials from storage - useful for changing user.
Functionality
The extension includes some functionality which may require more context or a usecase.
Below are some of the functionalities
Project Creation
The Create New Business Central Project command creates a new Business Central project from a template repository. This feature streamlines project setup by cloning a template, configuring it according to your specifications, and optionally syncing it to a remote repository.
Configuration Settings:
ev-tools.templateRepository: URL of the template repository (supports both HTTPS and SSH formats)
ev-tools.templateBranch: Branch to use from the template repository (default: develop)
ev-tools.autoOpenNewProject: Automatically open the newly created project (default: false)
Project Creation Process:
- Template Selection: The extension clones or updates the configured template repository
- Project Configuration: Fill in the webview form with:
- Project Name: Name of your Business Central app
- Project Type: Choose between
PTE (Per-Tenant Extension) or AppSource
- Folder Name: Directory name for the new project
- Object Suffix: Optional suffix for AL objects (automatically applied to PTE projects)
- Application Version: Target Business Central version
- Runtime Version: AL runtime version
- Create Tests: Option to include or exclude the test folder
- Remote Repository: Optional Git repository URL (HTTPS or SSH)
- Commit and Sync: Automatically commit and push to the remote repository
What Happens During Creation:
- Copies the template repository to your new project folder (preserving hidden files like
.git)
- Configures
app.json with your project name, generated UUID, and version settings
- Updates
launch.json with appropriate settings
- Configures code analyzers based on project type (removes
AppSourceCop for PTE, PerTenantExtensionCop for AppSource)
- Sets up
CRS.ObjectNameSuffix in VS Code settings if an object suffix is specified
- Configures
AppSourceCop.json with mandatory suffix for AppSource projects
- Renames the
.code-workspace file to match your folder name
- Removes the test folder and updates workspace configuration if tests are disabled
- Initializes a new Git repository with optional remote and initial commit
Template Repository Requirements:
The template repository should contain a standard Business Central project structure with:
app/app.json - Main app manifest
test/app.json - Test app manifest (if using tests)
*.code-workspace - VS Code workspace file
.vscode/settings.json - VS Code settings
.vscode/launch.json - Debug configurations
XLIFF functionality
Generates translations based on the comments in the scope.
In the following example, the caption is English, with a comment specifying the danish translation and in some cases a spanish translation.
Each of the translations follows the pattern of <captionml_language_code>="(.*?)", where the captionml_language_code is the one from Dynamics NAV (e.g. DAN, ENU, ESP).
More information on the available scopes to use this can be found on Microsoft Docs - Caption Property.

Backup/restore functionality
Useful for creating a backup of the container databasebase and for restoring it. A usecase could be to perform manual testing. Steps could look as follows:
- Setup the test database
- Run the command
Backup Container Database.
- Perform the test
- Run the command
Restore Container Database, selecting the backup you just made.
Differentiated Licensed depending on the container version
By setting the LicensePath-setting, the user can specify different license depending on the container version. In the example below, version 13, 14, 15, 16, 17, 18, 19 will use a .flf-file, while the default is a .bclicense-file

Azure Storage integration
This feature enables the user to hold dependencies in an Azure Storage-account. The feature is controlled by the setting dependenciesAzureStorage which specifices the storage account.
EV Compiler Settings
EV Compiler Settings is the solution to the problem of having to compile an app to multiple different versions.
EV Compiler Settings makes it possible easily switch between multiple launch.json and app.json files in the same repository. It furthermore enables the user to set variables for their pipeline (If the pipeline is set up for it).
As can be seen below, the file EVCompilerSettings.json is an array consisting of objects. These objects have properties name, launch, app and pipeline.
name is the name of the compilersettings. It is meant for the user to be easily able to differentiate settings and to be defined in their pipeline.
launch is the properties of launch.json to replace when selecting the given EV Compiler Setting.
app is the properties of app.json to replace when selecting the given EV Compiler Setting.
pipeline is the properties to use in the pipeline. This could be which version to use when compiling in the pipeline.
There exists a view of the EV Compiler Settings files, which can be found in Compiler Settings View

Four language-model tools let Copilot inspect the database of the Business Central Docker container referenced by your launch.json (the configuration with type=al, request=launch, environmentType=OnPrem): #bcCompanies, #bcFindTable, #bcDescribeTable and #bcReadTable.
- Read-only: only parameterized
SELECT/COUNT statements with NOLOCK are generated. No free-form SQL is accepted from the model.
- Local Docker containers only. By default the container is the one in your
launch.json (type=al, request=launch, environmentType=OnPrem); you can also name any running container (e.g. "what data is in container DANW?") without touching launch.json. Shared on-prem BC servers and cloud environments are rejected — the target must be a running local Docker container.
- AL table names are mapped to the physical schema (
Company$Table$AppId, table extensions in …$ext) for BC23 and later; single- and multitenant containers are supported.
- Returned column names are the SQL names (
No. → No_). Enum/Option values are raw integers (the tool cannot decode them), booleans are 0/1, blobs are shown as sizes only. Max 200 rows per call (default 20).
- Settings:
ev-tools.bcSql.enabled, ev-tools.bcSql.username (default dev), ev-tools.bcSql.password (default Logon2me), ev-tools.bcSql.port (default 1433). Generated SQL is logged to the EV BC SQL output channel.
Azure KeyVault
You can use Azure KeyVault secret in:
License path settings
"ev-tools.licensePath": [
{
"version": 23,
"path": "{{KeyVaultSecret.MySecret}}"
}
]
Dependencies Azure Storage settings
"ev-tools.dependenciesAzureStorage": [
{
"name": "MyName",
"account": "MyAccount",
"container": "MyContainer",
"sharedKey": "{{KeyVaultSecret.MySecret}}"
}
]
Compilersettings
"fixedDependenciesInstall": [
{
"id": "00000000-0000-0000-0000-000000000000",
"type": "devOps",
"organization": "Organization",
"project": "Project",
"definition": "Definition",
"build": "latest",
"branch": "master",
"accessToken": "{{KeyVaultSecret.MySecret}}"
}
]
Azure KeyVault Setup
"ev-tools.AzureKeyVault": [
{
"name": "MyDefaultKeyVault",
"credentialsType": "Default",
},
{
"name": "MyClientSecretDefaultKeyVault",
"credentialsType": "Client Secret",
"clientId": "00000000-0000-0000-0000-000000000000",
"clientSecret": "MyClientSecret",
"directoryId": "00000000-0000-0000-0000-000000000000"
}
]
If you are using the Default Credentials Type, you must log in with one of the following types:
Azure CLI
rem Install Azure CLI (only if not installed)
winget install -e --id Microsoft.AzureCLI
rem login
az login
PowerShell
#Install latest PowerShell
winget install --id Microsoft.PowerShell --source winget
# In PowerShell:
Install-Module Az.Accounts # if not installed
Import-Module Az.Accounts
Connect-AzAccount
BC Quality
BC Quality is the shared, curated set of Business Central coding rules maintained in
EV-Common/BCQuality on GitHub Enterprise. The extension makes that knowledge available to Copilot
in agent mode, so a review in the editor applies the same rules that pull request review applies.
How it stays current. The knowledge base is downloaded into the extension's global storage and
checked for updates once a day. The check is a single request that asks what commit the tracked
branch points at; the content is downloaded again only when that has moved. In practice a change
merged to main reaches every developer within about a day, with no action on their part.
The tools. All three are available to Copilot in agent mode and can be referenced directly in a
prompt:
#bcQualityReview: starts a review, and the one to reach for when reviewing code. It collects the
AL under review, works out which review skill applies, and — the important part — ranks the whole
knowledge base against that specific code, handing Copilot a shortlist of around 45 candidate
rules instead of whole domains. Ask Copilot to "review my AL changes" and it will reach for this
on its own.
#bcQualityIndex: looks up what the standards say about a topic. With no arguments it lists the
knowledge domains; with a domain it lists that domain's articles. Good for answering a question,
but for reviewing code #bcQualityReview is both cheaper and more accurate.
#bcQualityArticle: reads articles in full, and can pull named sections out of a large skill file
rather than the whole thing. Good and bad AL examples on request.
How ranking works. Articles are scored by term overlap with your AL, weighted so that a keyword
appearing on nearly every article counts for little and a rare, specific one counts for a lot. On top
of that, every article in the custom layer is always included: those are company standards, they
apply whether or not their wording happens to match your code, and many of them key on words too
common to rank well. A checked-in evaluation (npm run eval:bcquality) derives test cases from
BCQuality's own fixture convention and fails the build if any registered domain's rule stops ranking
into the shortlist — a rule that cannot be retrieved is a rule reviews will not apply.
Layers. The knowledge base is organised into three layers: microsoft (platform guardrails),
community (shared community patterns) and custom (Elbek & Vejrup's own standards, which override
the other two where they disagree). ev-tools.bcQuality.enabledLayers selects which to use; a layer
left out is deleted from the local copy, so it cannot influence a review at all.
Following a release tag instead of main. ev-tools.bcQuality.ref defaults to main, so you
see new rules as soon as they are merged. Pull request review runs against a pinned release tag
instead, so main is occasionally slightly ahead of what is enforced there. Set ref to a release
tag (for example v1.5-ev.1) if you would rather match pull request review exactly.
Signing in to GitHub Enterprise is required. Until you do, the tools will say so rather than fail.
Microsoft Learn MCP Server
The extension provides the Microsoft Learn MCP server to GitHub Copilot agent mode, so the model can look up official Microsoft and Business Central documentation instead of guessing. It requires no setup — the server appears as Microsoft Learn (EV) once the extension is active.
It adds three tools:
microsoft_docs_search: search official documentation.
microsoft_docs_fetch: fetch a full documentation page.
microsoft_code_sample_search: search official code samples.
How to turn it off. There are two independent controls:
- Just for you: in Copilot Chat agent mode, open the tools picker and untick
Microsoft Learn (EV) or its individual tools. This choice is personal and is not overwritten by EV's central settings.
- Remove it entirely: set
ev-tools.enableMicrosoftLearnMcp to false. This takes effect immediately, with no window reload. EV can manage this setting centrally, so prefer the option above if you only want to opt out yourself.
Notes:
- Requires MCP to be permitted by your GitHub Copilot organisation policy.
- The Learn endpoint is public, free and unauthenticated. Microsoft applies fair-use rate limits to it.
- You can manage the running server with
MCP: List Servers in the Command Palette — start, stop, restart, and Show Output to see its connection log.
- See Telemetry & Privacy for what leaves your machine.
EV custom agents
The extension ships seven domain-scoped agents for Copilot Chat. Pick one from the agent dropdown above the chat input. Each agent sees only the tools of its own domain and carries that domain's workflow, so it does not have to guess which of the 23 EV tools to use or in what order.
| Agent |
Use it for |
Can it change anything? |
| EV Jira |
An issue by key, searching Jira, attachments, comments, workflow transitions, reassigning, resolving |
Writes to Jira |
| EV Tempo |
Logged hours, timesheets, planned hours and capacity — and logging time |
Writes to Tempo |
| EV BC Code Explorer |
How BC/AL code works, base-application source, where something is implemented, EV AL conventions |
Read-only |
| EV BC Learn |
What Microsoft's documentation actually says, with a link for every claim |
Read-only |
| EV BC Telemetry |
Investigating a customer environment: slow SQL, long-running AL, job queues, locks, web-service failures |
Read-only |
| EV BC Data |
Looking at real data and setup records in a local BC Docker container |
Read-only |
| EV BC Quality |
An AL code review against the EV standards, or what our rules say about a topic |
Read-only |
Views
The extension provides multiple views New Container View, Container list View, Extension Manager and Compiler Settings.
New Container View
The page for creating a new docker container.

Container List View
The list of containers currently installed on the machine.

Extension Manager
The list of extensions installed in the container. Can be founder by going to Container List and thrugh the Action, clicking Extension Management.

Compiler settings
A view to show the different compiler settings. From the bar on top, you can see the different projects's EVCompilerSettings.json (Eg. in App/EVCompilerSettings.json, Test/EVCompilerSettings.json, Debug/EVCompilerSettings etc.).
In the left side, you see the different names of EV Compiler Settings of the selected EVCompilerSettings-file.
Once you have selected a EV Compiler Setting, you can right-click and update your launch.json, app.json or both. You can also copy the setting or edit the setting.

Special Settings which require more context
Clone development Environment from BitBucket uses the settings bitbucketWorkspaceId, bitbucketApiQuerystring to determine the Bitbucket workspace ID and filter string.
Create New Development Environment uses the settings useEnvironmentDatabaseServer, environmentDatabaseServer, environmentDatabaseName, environmentOdbcDriver to determine versions.