Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>MSBuild Binlog Analyzer for VS CodeNew to Visual Studio Code? Get it now.
MSBuild Binlog Analyzer for VS Code

MSBuild Binlog Analyzer for VS Code

Preview

Microsoft

microsoft.com
|
914 installs
| (1) | Free
Analyze MSBuild binary logs with Copilot Chat and MCP tools
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

MSBuild Binlog Analyzer for VS Code

Analyze MSBuild binary logs (.binlog) with GitHub Copilot Chat and MCP tools — right from VS Code.

Preview — This extension is under active development. Feedback welcome — please report issues at dotnet/skills.

Quick Start

  1. Install this extension (requires VS Code with the GitHub Copilot Chat extension and the .NET SDK; VS Code enforces the minimum version from the extension manifest)
  2. Open a .binlog — via Binlog: Load File (Ctrl+Shift+P), Build & Collect Binlog, or from Structured Log Viewer → Open in VS Code
  3. Use @binlog in Copilot Chat:
@binlog why did the build fail?
@binlog what are the slowest targets?
@binlog /perf

The Microsoft.AITools.BinlogMcp server (the MCP binlog analysis tools) is auto-installed on first use.

What You Get

Feature Description
@binlog Chat Ask Copilot about errors, performance, targets, imports, NuGet issues — with slash commands like /errors, /perf, /timeline, /compare, /summary, /incremental, /buildcheck, /search, /targets, /properties, /items, /propertyhistory
Build & Collect Build a project and capture a .binlog in one step — only for a solution/project open in a trusted workspace
Binlog Explorer Sidebar tree with project → target → task hierarchy, errors, warnings, performance
Build Timeline Visual bar charts of target/task durations with click-to-analyze in Copilot
Fix All Issues Copilot fixes all build errors/warnings, rebuilds, and loads before/after for comparison
Auto-fix Diagnostic Right-click any error/warning in the tree → "Auto-fix with Copilot" to fix it directly
Optimize Build Pick optimizations, Copilot applies changes, verify with A/B comparison
Build Analysis Mode Chat mode pre-configured with Microsoft.AITools.BinlogMcp MCP tools — works with any agent
Language Model Tools binlog_lm_overview, binlog_lm_errors, binlog_lm_search, binlog_lm_perf, binlog_lm_compare — available to @workspace, agent mode, and custom chat modes
CI/CD Integration Download binlogs from Azure DevOps Pipelines and GitHub Actions — filter by branch or PR. See CI/CD Integration for how it authenticates and what it stores
Cross-machine binlogs Match a binlog recorded elsewhere (CI, a coworker, another clone) to the solution open in your workspace — Binlog: Map Binlog Paths to This Workspace infers the remote → local root mapping
Problems Panel Build diagnostics as native VS Code errors/warnings with per-project CodeLens and "Ask @binlog" CodeActions
Search Search across all build events — targets, tasks, messages, properties

Binlogs Are Trusted Input

This extension treats a .binlog as trusted input. Loading one is not a sandboxed, read-only peek at an opaque file: a binlog is a complete recording of a build, and the whole point of opening it is to read that recording — project paths, command lines, properties, environment values, diagnostics — display it, resolve it against files on your disk, and send whatever you ask about to GitHub Copilot. There is no meaningful way to analyze a build log while defending against its contents.

So the requirement is on you, not on the file:

Open a binlog only when you trust the build, the machine and the pipeline that produced it — and, for CI, everyone who can edit or queue that pipeline.

The extension makes that decision explicit rather than implicit:

  1. Binlogs inside an open, trusted workspace folder load with no extra prompt. Trusting the folder in VS Code is the decision; the extension is disabled outright in Restricted Mode (untrustedWorkspaces.supported: false) and in virtual workspaces.
  2. Anything else is confirmed every time it is loaded. A file in Downloads, a CI artifact in the download cache, a path carried by a vscode://binlog-analyzer/open?path=… link — nothing in the window vouches for it, so a modal names the files, states the trust requirement, and asks you to confirm. The dialog also offers Add Folder to Workspace…, which turns the repeated confirmation into a durable workspace-trust decision.
  3. Downloading from CI asks you to trust the source, once per GitHub repository or Azure DevOps project, per workspace, before the first artifact is fetched. See CI/CD Integration.

We do not ask you to redact binlogs before opening them. Redaction is not what makes a binlog safe to analyze, and treating it as a prerequisite would imply the extension can cope with a binlog you do not trust. It cannot, and neither can redaction — provenance is the control. What you should still weigh is disclosure: a binlog can contain secrets, environment values, embedded source and PII/EUII, and using Copilot deliberately sends binlog-derived content off-device. That is a privacy decision under your organization's policy and your Copilot plan's data-handling terms, not a defence against a hostile file. See Telemetry for exactly what does and does not leave your machine.

Confining binlog paths to your workspace is about correctness, not security

Several features refuse to act on a path recorded in the binlog when it points outside the folders you have open: path mappings must target a workspace folder, "open this file" resolves inside your workspace, and builds are refused for a target found anywhere else.

For path resolution this is a correctness and convenience feature, not a security measure. A binlog records the paths of the machine that produced it, and nothing in the file says which local directory corresponds to a CI agent's checkout. Resolving those paths anywhere other than the folders you actually opened gives you the wrong file, the wrong diagnostics, and analysis of code you were not looking at. Confining them is what makes the answer meaningful. It is not a barrier against a malicious binlog — the binlog is trusted before it is opened, so there is no such adversary in scope.

Running a build is the exception, and it is a genuine security control. A build executes arbitrary MSBuild code from wherever the target lives, which is a risk regardless of where the binlog came from — see below.

Builds and Workspace Trust

Loading and analyzing a .binlog is read-only — it needs no more than the binlog trust confirmation described above. Building is not: a build executes MSBuild targets, custom tasks, pre/post-build scripts and NuGet build extensions from the location being built, which is arbitrary code execution. The commands that start a build — Build & Collect Binlog, Rebuild with Property Tracking, Fix All Build Issues and Optimize Build — therefore run only when all of the following hold:

  1. A folder is open. There is no "just build in the current directory" fallback; with no workspace folder open there is nothing the extension is willing to build.
  2. The workspace is trusted. In VS Code's Restricted Mode this extension is disabled entirely (untrustedWorkspaces.supported: false), so no build command can run. Use Workspaces: Manage Workspace Trust to trust a folder.
  3. The target is inside an open workspace folder. A solution or project found anywhere else — including one named by a binlog that was produced on another machine — is refused.
  4. You confirm the location. Every build shows a modal naming the exact file and asks you to confirm with I Trust This Location — Build. The same wording appears when picking a solution and in Set Workspace Folder.

Solutions (.sln, .slnx, .slnf) and projects (.csproj, .vbproj, .fsproj, .vcxproj, .sqlproj, .proj, .msbuildproj and similar) are discovered automatically. If your repository builds through something else — a dirs.proj, a custom entry point — choose Select Build File... and pick it; it still has to live inside the open workspace.

Analyzing a binlog from elsewhere is unaffected. If you want to build it too, open your local clone of those sources as the workspace folder and use Binlog: Map Binlog Paths to This Workspace so the binlog's recorded paths resolve to your copy. The build then targets your local file, never the path recorded on the machine that produced the binlog.

Build safety: MSBuild project and solution files can execute arbitrary logic. Use build, fix and optimization features only with trusted source in a trusted workspace, and review Copilot-proposed edits and commands before approving them.

With no folder open — or with a folder open that contains no solution or project — the build actions in the Binlog Explorer's Actions list stay visible but inert: the icon is dimmed, the description reads set workspace folder first, and clicking one explains which of the two problems it is and offers Open Folder… or Set Workspace Folder…. They are shown rather than removed so the capability stays discoverable; an action that only appears once the workspace is already right teaches nobody that it exists. In the Command Palette, where there is no dimmed state to render, the same commands are hidden instead. Opening the folder that merely holds the .binlog is not enough; open the sources.

Build Baseline & Regressions

A build baseline is a saved .binlog snapshot that newly-loaded builds are automatically compared against, so you can spot regressions (slower targets, new errors/warnings, changed properties). If you see "No build baseline is set.", pick one of these:

Set a baseline (any one):

  • Binlog Explorer → right-click a loaded .binlog → Set This Binlog as Baseline (baselines the file you right-clicked).
  • Command Palette (Ctrl+Shift+P) → Binlog: Set This Binlog as Baseline — when invoked without a tree-item context, baselines the currently active binlog.

Once set, the active binlog is compared to the baseline automatically and a Build: status-bar item (bottom-left) reflects the result.

View regressions:

  • Click the Build: status-bar item, or
  • Command Palette → Binlog: Show Build Regressions (focuses the regression results in the Binlog Explorer).

Clear a baseline:

  • Command Palette → Binlog: Clear Build Baseline, or right-click the baseline/regressions node in the explorer → Clear Build Baseline.

Tip: a typical loop is — load a known-good build and Set This Binlog as Baseline, make a change, rebuild via Build & Collect Binlog, then read the regressions that surface automatically.

CI/CD Integration

Binlog: Download Binlog from CI/CD lists recent runs for the repository open in your workspace and downloads the .binlog files from their published artifacts. The provider is inferred from your git remote (Azure DevOps Pipelines or GitHub Actions); you can also pick org/project or owner/repo manually.

The pipeline you investigate must be one you trust

A downloaded binlog is loaded like any other, and the extension treats a binlog as trusted input. Choosing a pipeline is therefore a trust decision, and a broader one than trusting a single file: it covers the pipeline definition, the repository it builds, and everyone who can edit or queue it.

Before the first artifact is fetched from a given repository or project the extension shows a modal naming the provider and the owner/repo or org/project coordinate and asks you to confirm. The answer is remembered against that coordinate, per workspace, so a run publishing several artifacts asks once rather than once per file.

Note the scope this grants, which the dialog also states: the answer covers every workflow in that GitHub repository, or every pipeline in that Azure DevOps project — including pipelines that build other repositories. On GitHub that is the honest boundary anyway, since workflows live in the repository and anyone who can add one can edit another. On Azure DevOps it is genuinely wider than the single pipeline you picked, so confirm only for a project whose pipelines you would all be willing to investigate.

Because downloads land in a private cache outside your workspace, the binlog trust confirmation is then shown when the downloaded file is loaded.

How the extension authenticates

The extension does not implement its own sign-in, and never asks you for a password or a Personal Access Token. It has no credential store of its own and does not read .npmrc, .netrc, git credential, or any PAT you may have configured elsewhere.

  1. Azure DevOps — anonymous first. Run/pipeline listing and the artifact ZIP are requested with no credentials at all, so public projects work with no token and no az CLI. If that fails, the extension shells out to az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 (the well-known Azure DevOps resource ID) and retries the same URL with an Authorization: Bearer header. Listing falls back to az rest / az pipelines the same way.
  2. GitHub Actions — always via gh. There is no anonymous path: listing runs and artifacts uses gh run list / gh api, and the artifact download calls gh auth token and sends the result as an Authorization: Bearer header.

If the relevant CLI is missing or not logged in, the operation fails with an explanatory error. The extension never prompts for a credential to fill the gap — sign in yourself with az login or gh auth login and retry. A response that redirects to a sign-in page is treated as a failure rather than followed.

What is stored, and where

Item Stored? Where Lifetime
Access token / PAT No Held in a local variable for the duration of one HTTPS request Discarded when the download finishes or fails
Your CLI credentials No Owned entirely by az / gh Managed by those tools
Downloaded artifacts and extracted .binlog files Yes os.tmpdir()/binlog-analyzer-ci/, created mode 0700 (owner-only) Pruned on activation: deleted after 7 days, or oldest-first once the cache exceeds 2 GB. Directories younger than 1 hour, and those backing a currently loaded binlog, are never pruned
Recently used AzDO orgs / GitHub repos Yes VS Code workspaceState (names only, no credentials) Last 5, per workspace
Pipelines you confirmed you trust Yes VS Code workspaceState (owner/repo or org/project names only) Until the workspace state is cleared
Path mappings for CI/remote binlogs Yes binlogAnalyzer.ciPathMappings setting (Workspace scope when a folder is open, otherwise User) Until you remove them

The download cache is deliberately owner-only rather than a world-readable temp directory: artifacts and the binlogs inside them carry environment values, command lines and source paths from the build machine. The extension refuses to adopt a binlog-analyzer-ci directory it cannot prove it owns, and re-asserts 0700 on one left behind by an earlier version.

Network boundaries

  • HTTPS only. A redirect that downgrades to http: is rejected — the server chooses the redirect, so you would never see the downgrade.
  • Host allowlist. Redirects are followed only to github.com, githubusercontent.com, actions.githubusercontent.com, pipelines.actions.githubusercontent.com, dev.azure.com, visualstudio.com, core.windows.net (Azure storage backing artifacts) and azureedge.net (Azure CDN) — and their subdomains. Anything else is refused by name.
  • Credentials are not replayed across redirects. The Authorization header is sent on the initial request only, so a redirect to a storage/CDN endpoint cannot harvest your token.
  • Transfer limits. Downloads are capped by binlogAnalyzer.ci.maxArtifactMb (declared and actual size), a per-hop idle timeout, and an absolute wall-clock ceiling for the whole transfer. Extraction is zip-bomb and path-traversal checked, and everything is cancellable.
  • Tokens are never written to the output channel, an error message, telemetry, or disk.

Optional CI watch

binlogAnalyzer.ci.watch (off by default) polls the latest run for your current branch or PR and offers to analyze the binlogs when it fails. It uses exactly the same access path described above, at the interval set by binlogAnalyzer.ci.pollSeconds, backing off while VS Code is idle or unfocused.

Configuration

Setting Default Description
binlogAnalyzer.mcpServerPath "" Custom path to the MCP server executable
binlogAnalyzer.mcpServerArgs "--binlog ${binlog}" Argument template for the MCP server. ${binlog} is replaced with each binlog path
binlogAnalyzer.autoLoad true Auto-load binlog diagnostics on activation
binlogAnalyzer.diagnosticsSeverityFilter "Warning" Min severity for Problems panel
binlogAnalyzer.inlineDecorations true Show build errors as inline decorations in source files
binlogAnalyzer.chat.includeAllTools false Expose all available tools (file editing, terminal, other MCPs) to the @binlog chat participant
binlogAnalyzer.chat.additionalToolPatterns [] Additional tool name patterns to include alongside binlog tools (e.g. ["copilot_codebase", "terminal"])
binlogAnalyzer.tree.topItemsLimit 10 Number of expensive targets/tasks/items to request and show before "Load more"
binlogAnalyzer.mcp.requestTimeoutMs 30000 Base MCP request timeout; large binlogs get an adaptive size-based extension
binlogAnalyzer.buildCheck.timeoutMs 120000 BuildCheck analysis timeout
binlogAnalyzer.diagnostics.autoRunBuildCheck false Automatically run BuildCheck analysis when a binlog is loaded (requires .NET SDK 9.0.100+)
binlogAnalyzer.diagnostics.propertyTrackingLevel 15 MSBuild property-tracking level used when rebuilding with property tracking. 15 = all events
binlogAnalyzer.ci.maxRuns 20 Maximum recent CI runs to fetch
binlogAnalyzer.ci.maxArtifactMb 1536 Maximum size in MiB (1.5 GiB by default) of a CI artifact to download; larger transfers are aborted
binlogAnalyzer.ci.watch false Watch the current branch or PR's latest CI run and offer to analyze binlogs when it fails
binlogAnalyzer.ci.pollSeconds 60 Base polling interval (seconds) for CI watch; the watcher backs off when idle or unfocused
binlogAnalyzer.ciPathMappings [] Path-prefix mappings for CI/remote binlogs, e.g. D:\a\1\s → the local workspace root
binlogAnalyzer.regression.minDeltaMs 200 Minimum target duration increase (ms) to flag as a build regression
binlogAnalyzer.regression.minDeltaPct 15 Minimum target duration increase (%) to flag as a build regression
binlogAnalyzer.regression.failOnNewWarnings false Treat newly added warnings as build regressions

Telemetry

This extension collects usage data and sends it to Microsoft to help improve our products and services. The extension respects the telemetry.telemetryLevel setting — learn more at https://code.visualstudio.com/docs/getstarted/telemetry. To disable telemetry in VS Code, including telemetry from this extension, set:

"telemetry.telemetryLevel": "off"

What is sent. Every extension-defined event and property is enumerated in the bundled telemetry.json using the standard 1DS classification schema (classification, endPoint, purpose); the VS Code telemetry library also adds its standard common properties (including pseudonymized machine and session identifiers). At a glance:

  • Feature insight — extension activation, command invocation, chat participant / slash-command usage, tree navigation, binlog-loaded count.
  • Performance & reliability — MCP tool-install success/failure, build check duration, error counts. Error messages are never sent as raw text: the user's home directory and username are first replaced with ~ and <user>, then the result is hashed with HMAC-SHA256 (16-char hex) — identical to the C# Binlog MCP server's Hash — and only the error kind (exception.type, e.g. TypeError) is sent in clear. Every event also carries binlog.build_version, matching the MCP server's conventions.

What is not sent in telemetry. This paragraph is about the telemetry pipeline described above and nothing else. No .binlog content, no file system paths, no source-code snippets, no Copilot Chat conversation text, and no user identifiers beyond VS Code's pseudonymized machine- and session-id hashes are included in any telemetry event.

This is not a claim that binlog content stays on your machine. When you use the @binlog chat participant, or any other Copilot feature backed by this extension's MCP tools, binlog-derived content — including build errors, target and task names, command lines and file paths — is deliberately sent to GitHub Copilot as part of the model request. That path is a product feature, is separate from telemetry, and is governed by your Copilot plan's data handling terms rather than by the telemetry statements above.

Binlogs can contain secrets (such as tokens, passwords and connection strings), environment-variable values, embedded source or project content, and PII/EUII in user names, paths, command lines and build properties. Sending that to Copilot is a privacy decision — what your organization permits to be processed off-device, under your Copilot plan's data-handling terms — and it is yours to make before you load a binlog and start asking about it.

It is deliberately not framed as a safety prerequisite, and the extension does not ask you to scrub or redact a binlog first. Redaction is not what makes a binlog safe to analyze: provenance is. Load binlogs from builds and pipelines you trust, and load only data you and your organization permit GitHub Copilot to process.

Read the Microsoft privacy statement to learn more.

Development: MCP Contract

The extension vendors the Binlog MCP JSON Schemas under src/contract/schemas/ and commits generated TypeScript declarations in src/contract/.

npm run gen:contract      # regenerate src/contract/*.d.ts from vendored schemas
npm run check:contract    # regenerate and fail if generated files drift

When server schemas change, copy the new *.schema.json files into src/contract/schemas/, run npm run gen:contract, and commit both schemas and generated types.

The binlog_capabilities response is validated against the vendored schema at runtime (src/contractRuntime.ts); a malformed payload falls back to the legacy compatibility path with a specific diagnostic instead of failing later with a type error. src/test/capabilitiesValidation.test.ts asserts the validator's required-field list and enums still match capabilities.schema.json.

Development: Linting

npm run lint              # oxlint src

The linter is oxlint, configured in .oxlintrc.json.

ESLint is deliberately not used. Linting TypeScript with ESLint requires typescript-eslint, which refuses to load against the TypeScript 7 API this project compiles with — it throws typescript-eslint does not support TS 7.0 at import time (upstream tracking issue: typescript-eslint#10940). oxlint parses TypeScript itself and does not depend on the typescript package, so it is the only linter that works on this tree today. If typescript-eslint gains TS 7 support, switching back is a config-only change.

Severity policy: correctness rules fail the build; advisory categories are warnings so pre-existing findings stay visible without blocking CI.

Troubleshooting: MCP Server Installation

The extension auto-installs Microsoft.AITools.BinlogMcp via dotnet tool install -g. In corporate environments with restricted NuGet feeds, this may fail. Here are the workarounds:

1. Install with explicit feed source

dotnet tool install -g Microsoft.AITools.BinlogMcp --prerelease --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json

2. Diagnose NuGet issues

dotnet nuget list source

Common problems:

  • dotnet-public feed not configured — the tool is published on the dotnet-public Azure DevOps feed
  • Authenticated feed requires credentials — may block access to the feed
  • Package source mapping excludes the dotnet-public feed for this package

3. Verify installation

dotnet tool list -g | Select-String Microsoft.AITools.BinlogMcp
binlog-mcp --help

Related Projects

  • MSBuild Structured Log Viewer — WPF viewer with secrets redaction
  • Microsoft.AITools.BinlogMcp — MCP server for binlog analysis
  • MSBuild Binary Log docs

License

See the bundled LICENSE.md for the Microsoft Software License Terms.

Collect diagnostic information

When you hit a problem and want to share details with us, all relevant diagnostic information lives in VS Code's Output panel. Open View → Output and switch the dropdown to one of:

Output channel What it contains
Binlog Analyzer Extension activity: file loads, tree refreshes, command execution.
Binlog Analyzer Telemetry A local mirror of every telemetry event the extension emits (with names + properties), printed before the event is sent. Useful for verifying exactly what would be reported.
MCP: Microsoft.AITools.BinlogMcp The MCP server's stdout/stderr — protocol handshake, tool invocations, any server-side errors.

Before sharing logs publicly

Output channels may contain file paths, project property values, and environment-variable values that MSBuild surfaces into the log. Before posting a log on a GitHub issue or chat:

  1. Search for and redact secrets (tokens, connection strings, passwords).
  2. Search-and-replace your user home directory with ~ (the extension already does this for error strings it sends as telemetry, but the on-disk Output panel still contains the raw values).

Both points are about the output-channel text you are about to publish, not about preparing a binlog for the extension — see Binlogs Are Trusted Input. A .binlog records everything the build touched, so treat attaching one to a public issue as publishing that build in full, and share it only when that is acceptable.

For private reports (security vulnerabilities or anything you'd rather not put on a public issue), follow the process in the bundled SECURITY.md.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft