Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 13 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Analyze MSBuild binary logs (`.binlog`) with **GitHub Copilot Chat** and **MCP t
@binlog /perf
```

The [BinlogInsights.Mcp](https://www.nuget.org/packages/BinlogInsights.Mcp) server (28 analysis tools) is auto-installed on first use.
The [AITools.BinlogMcp](https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/AITools.BinlogMcp) server (28 analysis tools) is auto-installed on first use.

## What You Get

Expand All @@ -32,7 +32,7 @@ The [BinlogInsights.Mcp](https://www.nuget.org/packages/BinlogInsights.Mcp) serv
| **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 BinlogInsights MCP tools — works with any agent |
| **Build Analysis Mode** | Chat mode pre-configured with 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 |
| **Problems Panel** | Build diagnostics as native VS Code errors/warnings with per-project CodeLens and "Ask @binlog" CodeActions |
Expand All @@ -52,53 +52,36 @@ The [BinlogInsights.Mcp](https://www.nuget.org/packages/BinlogInsights.Mcp) serv

## Troubleshooting: MCP Server Installation

The extension auto-installs [BinlogInsights.Mcp](https://www.nuget.org/packages/BinlogInsights.Mcp) via `dotnet tool install -g`. In corporate environments with restricted NuGet feeds, this may fail. Here are the workarounds:
The extension auto-installs [AITools.BinlogMcp](https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/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 NuGet source
### 1. Install with explicit feed source

```bash
dotnet tool install -g BinlogInsights.Mcp --add-source https://api.nuget.org/v3/index.json
dotnet tool install -g AITools.BinlogMcp --prerelease --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json
```

### 2. Manual download fallback

If all `dotnet tool install` attempts fail (e.g., nuget.org is blocked):

1. Download the `.nupkg` directly from [nuget.org](https://www.nuget.org/packages/BinlogInsights.Mcp)
2. Install from the local file:

```bash
# Download (replace {version} with latest, e.g. 0.2.0)
Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/BinlogInsights.Mcp/{version}" -OutFile "BinlogInsights.Mcp.nupkg"

# Install from local file
dotnet tool install -g BinlogInsights.Mcp --add-source .
```

### 3. Diagnose NuGet issues
### 2. Diagnose NuGet issues

```bash
dotnet nuget list source
```

Common problems:
- **nuget.org not listed or disabled** — the tool is published on nuget.org
- **Authenticated feed requires credentials** — may block fallthrough to nuget.org
- **Package source mapping** excludes nuget.org for this package
- **dotnet-eng feed not configured** — the tool is published on the dotnet-eng Azure DevOps feed
- **Authenticated feed requires credentials** — may block access to the feed
- **Package source mapping** excludes the dotnet-eng feed for this package

### 4. Verify installation
### 3. Verify installation

```bash
dotnet tool list -g | Select-String BinlogInsights
binlog-insights-mcp --help
dotnet tool list -g | Select-String AITools.BinlogMcp
binlog-mcp --help
```

> For the full troubleshooting guide, see [BinlogInsights repo setup instructions](https://github.com/SergeyTeplyakov/BinlogInsights/blob/main/samples/repo-setup/.github/skills/build-tool-setup/SKILL.md).

## Related Projects

- [MSBuild Structured Log Viewer](https://github.com/KirillOsenkov/MSBuildStructuredLog) — WPF viewer with secrets redaction
- [BinlogInsights](https://github.com/SergeyTeplyakov/BinlogInsights) — CLI + MCP server for binlog analysis
- [AITools.BinlogMcp](https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/AITools.BinlogMcp) — MCP server for binlog analysis
- [MSBuild Binary Log docs](https://learn.microsoft.com/en-us/visualstudio/msbuild/obtaining-build-logs-with-msbuild#save-a-binary-log)

## License
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@
"binlogAnalyzer.mcpServerPath": {
"type": "string",
"default": "",
"description": "Custom path to the MCP server dotnet tool (BinlogInsights.Mcp or baronfel.binlog.mcp). Leave empty to use the globally installed tool."
"description": "Custom path to the MCP server dotnet tool (AITools.BinlogMcp). Leave empty to use the globally installed tool."
},
"binlogAnalyzer.mcpServerArgs": {
"type": "string",
"default": "--binlog ${binlog}",
"markdownDescription": "Argument template for the MCP server. Use `${binlog}` as a placeholder for each binlog path. Repeated for each loaded binlog. Examples:\n- BinlogInsights: `--binlog ${binlog}` (default)\n- baronfel: `--binlog ${binlog}`\n- Custom: `--file ${binlog}`"
"markdownDescription": "Argument template for the MCP server. Use `${binlog}` as a placeholder for each binlog path. Repeated for each loaded binlog. Examples:\n- AITools.BinlogMcp: `--binlog ${binlog}` (default)\n- Custom: `--file ${binlog}`"
},
"binlogAnalyzer.autoLoad": {
"type": "boolean",
Expand Down Expand Up @@ -520,14 +520,14 @@
{
"slug": "build-analysis",
"name": "Build Analysis",
"description": "Pre-configured for MSBuild binlog investigation with BinlogInsights MCP tools.",
"description": "Pre-configured for MSBuild binlog investigation with AITools.BinlogMcp MCP tools.",
"toolsReferences": [
{
"type": "tool",
"id": "binlog_insights_mcp"
}
],
"systemPrompt": "You are an MSBuild build analysis assistant with BinlogInsights MCP tools available. Begin investigations with binlog_lm_overview (or binlog_overview) unless the question is narrowly scoped, then drill in with the most specific tool. For performance: rank with binlog_expensive_targets / binlog_expensive_tasks / binlog_expensive_projects / binlog_expensive_analyzers. For errors: binlog_lm_errors (or binlog_errors) then binlog_lm_search (or binlog_search). For deeper context the @binlog chat participant exposes the same tools plus prepared playbooks (try /perf, /incremental, /summary, /errors, /buildcheck). All tools take a binlog_file path parameter — ask the user if you don't know it. Reference real file paths, line numbers and error codes from tool output; don't invent numbers."
"systemPrompt": "You are an MSBuild build analysis assistant with AITools.BinlogMcp MCP tools available. Begin investigations with binlog_lm_overview (or binlog_overview) unless the question is narrowly scoped, then drill in with the most specific tool. For performance: rank with binlog_expensive_targets / binlog_expensive_tasks / binlog_expensive_projects / binlog_expensive_analyzers. For errors: binlog_lm_errors (or binlog_errors) then binlog_lm_search (or binlog_search). For deeper context the @binlog chat participant exposes the same tools plus prepared playbooks (try /perf, /incremental, /summary, /errors, /buildcheck). All tools take a binlog_file path parameter — ask the user if you don't know it. Reference real file paths, line numbers and error codes from tool output; don't invent numbers."
}
],
"menus": {
Expand Down
2 changes: 1 addition & 1 deletion resources/playbooks/core.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
You are an MSBuild build analysis assistant embedded in VS Code. The user has loaded one or more `.binlog` files (binary build logs) and you have BinlogInsights MCP tools available to inspect them.
You are an MSBuild build analysis assistant embedded in VS Code. The user has loaded one or more `.binlog` files (binary build logs) and you have AITools.BinlogMcp MCP tools available to inspect them.

Workflow contract:
- Act on the user's request immediately. Do not ask the user for permission, do not ask "would you like me to…", do not echo the request back. Just call the right tool.
Expand Down
20 changes: 17 additions & 3 deletions src/binlogDocumentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,21 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
// Build overview
try {
const overviewResult = await this.call('binlog_overview', {}, binlogPath);
const ov = JSON.parse(overviewResult.text);
// Handle both JSON (BinlogInsights) and text (AITools.BinlogMcp) formats
let ov: any;
try {
ov = JSON.parse(overviewResult.text);
} catch {
// AITools.BinlogMcp returns human-readable text — parse it
const text = overviewResult.text;
ov = {
succeeded: /SUCCEEDED/i.test(text),
msBuildVersion: text.match(/MSBuild:\s*(.+)/)?.[1]?.trim() || '',
errorCount: parseInt(text.match(/Errors:\s*(\d+)/)?.[1] || '0'),
warningCount: parseInt(text.match(/Warnings:\s*(\d+)/)?.[1] || '0'),
duration: text.match(/Duration:\s*(.+)/)?.[1]?.trim() || '',
};
}
const status = ov.succeeded ? '✅ BUILD SUCCEEDED' : '❌ BUILD FAILED';
const dur = ov.duration || '';
// Parse "HH:MM:SS.xxx" duration to a readable format
Expand Down Expand Up @@ -152,8 +166,8 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
// Handle both formats: array (BinlogInsights) and object (baronfel)
let projectFiles: string[] = [];
if (Array.isArray(projData)) {
// BinlogInsights: [{ fullPath, isLegacy }, ...]
projectFiles = projData.map((p: any) => p.fullPath || '').filter(Boolean);
// Array format: [{ fullPath/projectFile, ... }, ...]
projectFiles = projData.map((p: any) => p.fullPath || p.projectFile || '').filter(Boolean);
} else {
// baronfel: { "id": { projectFile, entryTargets }, ... }
projectFiles = Object.values(projData as Record<string, any>)
Expand Down
Loading
Loading