Skip to content
| Marketplace
Sign in
Visual Studio Code>Debuggers>DevLogs MCPNew to Visual Studio Code? Get it now.
DevLogs MCP

DevLogs MCP

FreeTools

|
10 installs
| (0) | Free
Expose VS Code logs (Output channels, Extension Host, Webview) to Claude and other MCP-compatible AI assistants — no more copy-pasting from DevTools.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

DevLogs MCP

Give your AI assistant direct access to VS Code logs — no more copy-pasting from DevTools.

Disclaimer: This is an early prototype, not a polished product. The API and features may change based on feedback and use cases. The documentation was mostly written by a LLM, so may not be accurate. Contributions are welcome!

DevLogs MCP is a VS Code extension that captures logs from Output channels, the Extension Host, and Webview panels, then exposes them as tools via the Model Context Protocol (MCP). Your AI assistant can query your logs directly during a conversation.


How it works

Your VS Code workspace
  ├── Output channels  ──┐
  ├── Extension Host   ──┼──▶  DevLogs MCP buffer  ──▶  Local MCP server (HTTP/SSE :3939)
  └── Webview panels   ──┘                                       │
                                                                  ▼
                                              Claude Desktop · GitHub Copilot · claude.ai

Installation

Install from the VS Code Marketplace, or clone and press F5 to run in development:

git clone https://codeberg.org/FreeTools/mcpdevlogs.git
cd mcpdevlogs
npm install
npm run compile
# Press F5 in VS Code

The MCP server starts automatically on port 3939. The status bar item toggles the server: ⊘ MCP off starts it, and ⊕ MCP :3939 stops it.


Tested environments

This extension has been tested on WSL with the Claude plugin and with the GitHub Copilot plugin for VS Code.

As of today, other setups have not been tested, so some instructions may be wrong or incomplete. If you get stuck, ask your LLM to help you set up the extension and, if needed, give it access to the source code so it can inspect the implementation directly.

We plan to test native Windows and native Linux setups soon.


Connecting your AI assistant

Claude Desktop

Claude Desktop has native MCP support and is the simplest integration.

1. Open the config file

OS Path
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json

2. Add the server

{
  "mcpServers": {
    "devlogs-mcp": {
      "url": "http://127.0.0.1:3939/sse"
    }
  }
}

Tip: use the DevLogs MCP: Show Claude Config command if you need this snippet. The status bar item starts and stops the server.

3. Restart Claude Desktop

The tools (get_logs, get_log_summary, etc.) will appear in Claude's tool list. Try: "Are there any errors in my VS Code logs?"


GitHub Copilot (VS Code)

GitHub Copilot in VS Code supports MCP servers via the agent mode configuration introduced in VS Code 1.99.

1. Open your workspace .vscode/mcp.json

Ctrl+Shift+P → MCP: Open Workspace Folder MCP Configuration

2. Register the MCP server

{
  "servers": {
    "devlogs-mcp": {
      "type": "sse",
      "url": "http://127.0.0.1:3939/sse"
    }
  }
}

WSL2: Replace 127.0.0.1 with the WSL VM IP. In the Extension Development Host window, use DevLogs MCP: Show Claude Config if you need the address; the status bar item starts and stops the server.

Note: VS Code uses .vscode/mcp.json for workspace MCP servers. settings.json does not support github.copilot.chat.mcp.servers.

3. Use it in Copilot Chat

Open the Copilot Chat panel (Ctrl+Alt+I), switch to Agent mode (the @ icon → Agent), then ask:

"@devlogs-mcp What errors appeared in the last minute?"

Copilot will call get_logs or get_log_summary automatically when your question implies log access.

Note: MCP support in GitHub Copilot requires VS Code ≥ 1.99 and the GitHub Copilot Chat extension ≥ 0.26. If you don't see Agent mode, update both.


Claude Code (VS Code extension)

The Claude Code extension supports MCP servers directly — no Claude Desktop required.

1. Create or edit .mcp.json in your workspace root:

{
  "mcpServers": {
    "devlogs-mcp": {
      "type": "sse",
      "url": "http://127.0.0.1:3939/sse"
    }
  }
}

This is the Claude Code workspace-root format. For GitHub Copilot in VS Code, use .vscode/mcp.json with a top-level servers object as shown above.

2. Authenticate once

The first time Claude Code connects it will open a browser window and ask you to click Authenticate. Because the server is local, the auth flow completes immediately — no credentials are entered. This uses the OAuth 2.0 flow built into the server (dynamic client registration + automatic token issuance).

3. Use it in chat

The tools appear automatically. Ask Claude Code: "Are there any errors in my VS Code logs?"

Note: Requires Claude Code extension ≥ 2.1 and a workspace with .mcp.json present.


Claude (claude.ai — browser)

The claude.ai web interface supports MCP via the Claude Desktop connector — the browser tab delegates tool calls to your locally running Claude Desktop app, which in turn calls our server.

Prerequisites: Claude Desktop must be running and already configured with DevLogs MCP (see the Claude Desktop section above).

Steps:

  1. Open claude.ai in your browser.
  2. Start a new conversation.
  3. Click the Tools (🔧) icon in the message bar.
  4. If the DevLogs MCP server appears in the list, enable it — Claude will now call it during the conversation.

Note: This requires a Claude Pro or Team plan. The connector is only active while Claude Desktop is open on the same machine.


MCP Tools reference

Tool Description
get_logs Query logs by source, channel, level, filter (substring or regex), and time range
get_log_tail Get the N most recent log entries across all sources
get_log_summary AI-friendly digest: total count, errors/warnings, active channels
clear_logs Reset the in-memory log buffer
list_channels List all channels that have produced entries
get_screen_screenshot Capture the full screen (or a specific display) as a PNG image
get_screenshot_info Check whether screen capture is available and which OS tool will be used

How screen capture works

get_screen_screenshot uses the OS native tool on each platform — no Electron API, no Playwright, no extra runtime needed:

OS Tool used
macOS screencapture (built-in)
Linux (native) scrot, gnome-screenshot, or ImageMagick import (first found)
Linux (WSL) powershell.exe on the Windows host — captures the real Windows desktop
Windows PowerShell + .NET System.Windows.Forms

On macOS 10.15+ the process needs the Screen Recording permission. VS Code will have this if you have ever shared your screen from it — otherwise macOS will prompt on first use.

On Linux (native) without a display server (headless CI), get_screenshot_info will tell you the capture is unavailable before you attempt it.

On WSL, the extension detects WSL automatically (via WSL_DISTRO_NAME or /proc/version) and captures via powershell.exe rather than a Linux tool. This is necessary because VS Code renders on the Windows desktop — Linux tools like scrot can only see the WSL-side X display (if any), not the VS Code window. The capture is DPI-aware, so 4K monitors at 150% scaling return physical pixels (e.g. 3840×2160) rather than logical ones.

Example prompts

  • "Show me the last 20 errors from my project output channel"
  • "Summarise what changed in the logs since I last asked"
  • "Are there any unhandled promise rejections in the webview?"
  • "What warnings appeared in the Extension Host in the last 5 minutes?"
  • "Take a screenshot — I want you to see what the player looks like right now"
  • "My project stalled — grab a screenshot and check the logs"

Capturing logs from your own VS Code extension

When you develop a VS Code extension you work with two windows at once:

  • Main window — where you write and edit code. DevLogs MCP is not running here (it has not been launched yet, or you have stopped it with DevLogs MCP: Stop Server). If you are using the Claude Code extension, verify it is authenticated and connected: type /mcp in the Claude chat panel and confirm devlogs-mcp appears as connected. If it does not appear or shows as disconnected:
    1. Make sure the Extension Development Host is already open (press F5 first — the MCP server must be running before Claude can connect).
    2. For VS Code/Copilot, check that .vscode/mcp.json exists in your workspace with the correct URL. In the Extension Development Host window, use DevLogs MCP: Show Claude Config to open the ready-to-use snippet.
    3. On first connection Claude will open a browser window for OAuth — click Authenticate to complete it. After that the connection is cached and subsequent sessions connect automatically.
  • Extension Development Host — the second VS Code window that opens when you press F5 (or Run Extension). DevLogs MCP starts here, the MCP server is active when the status bar shows ⊕ MCP :3939, and clicking the status bar toggles the server on and off.

Because these are separate processes, console.log calls and output channels from other extensions running in the Extension Development Host are not captured automatically unless they forward logs via HTTP. You need to forward them explicitly via HTTP POST to the MCP server running in the Extension Development Host.

Before pressing F5, make sure DevLogs MCP is stopped in the main window — otherwise both windows will try to bind port 3939 and the second one will fail. Run DevLogs MCP: Stop Server in the main window first, or set devlogsMcp.autoStart to false in your user settings.

There are two separate log sources to handle: extension host code (TypeScript/Node.js) and webview panels (browser-side JavaScript). Both route logs to DevLogs MCP via HTTP POST to port 3939.

DevLogs MCP ≥ 0.2.0 binds the HTTP server to 0.0.0.0 so the webview renderer on the Windows host can reach it when running under WSL2.


1 — Extension host logs

Call the /webview-log endpoint directly from your extension host code using Node.js fetch (available from Node 18 / VS Code 1.82+):

// devbridge.ts  — copy this file into your extension
import { execSync } from 'child_process';
import * as vscode from 'vscode';

let _endpoint: string | null = null;

export function getEndpoint(): string | null { return _endpoint; }

/** Call once in activate(). Resolves and caches the devlogs-mcp endpoint. */
export function resolveEndpoint(): void {
  const port = vscode.workspace.getConfiguration('devlogsMcp').get<number>('port', 3939);
  let host = '127.0.0.1';
  // WSL2: webview renderer runs on Windows and can't reach 127.0.0.1 in WSL.
  // Use the VM's routable IP instead (the server binds to 0.0.0.0).
  const isWsl = !!process.env['WSL_DISTRO_NAME'] ||
    (() => { try { return require('fs').readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft'); } catch { return false; } })();
  if (isWsl) {
    try {
      const ip = execSync('hostname -I', { timeout: 2000 }).toString().trim().split(' ')[0];
      if (ip) { host = ip; }
    } catch { /* keep 127.0.0.1 */ }
  }
  _endpoint = `http://${host}:${port}/webview-log`;
}

export function log(level: 'log'|'info'|'warn'|'error', channel: string, message: string): void {
  if (!_endpoint) { return; }
  void fetch(_endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ level, channel, message, timestamp: new Date().toISOString() }),
  }).catch(() => {});
}

In your activate function:

import * as devbridge from './devbridge';

export async function activate(context: vscode.ExtensionContext) {
  devbridge.resolveEndpoint();   // sync; caches on first call
  // …
}

Then anywhere in your extension host code:

devbridge.log('info',  'my-extension', 'Server started on port 8080');
devbridge.log('error', 'my-extension', `Failed to parse manifest: ${err.message}`);

These appear in DevLogs under source webview, channel my-extension.


2 — Webview panel logs

Browser-side console.* calls inside a webview are isolated from the Extension Host. Inject a small bridge script at the top of <head> that intercepts them and POSTs to the same /webview-log endpoint.

Step 1 — Resolve the endpoint in the extension host

Same resolveEndpoint() call as above. The resolved URL is then embedded into the webview HTML at build time.

Step 2 — Inject the bridge script

function buildWebviewHtml(endpoint: string | null, nonce: string): string {
  const bridge = endpoint ? bridgeScript(endpoint, nonce) : '';
  return `<!DOCTYPE html>
<html>
<head>
  ${bridge}
  <meta http-equiv="Content-Security-Policy"
    content="default-src 'none';
             connect-src *;
             script-src 'nonce-${nonce}';" />
</head>
<body>...</body>
</html>`;
}

function bridgeScript(endpoint: string, nonce: string): string {
  const ep = JSON.stringify(endpoint);
  // IMPORTANT: no \n or \t inside string literals — this HTML is often a
  // backtick template literal and backslash escapes become real whitespace.
  return `<script nonce="${nonce}">(function(){` +
    `var ep=${ep};` +
    `function send(l,a){try{` +
    `  var m=Array.prototype.slice.call(a).map(function(x){return typeof x==='string'?x:JSON.stringify(x);}).join(' ');` +
    `  fetch(ep,{method:'POST',headers:{'Content-Type':'application/json'},` +
    `    body:JSON.stringify({level:l,channel:'my-webview',message:m,timestamp:new Date().toISOString()})` +
    `  }).catch(function(){});` +
    `}catch(e){}}` +
    `['log','info','warn','error','debug'].forEach(function(l){` +
    `  var o=console[l].bind(console);` +
    `  console[l]=function(){send(l,arguments);o.apply(console,arguments);};` +
    `});` +
    `window.addEventListener('error',function(e){` +
    `  send('error',[e.message+' ('+e.filename+':'+e.lineno+')']);` +
    `});` +
    `window.addEventListener('unhandledrejection',function(e){` +
    `  send('error',['Unhandled rejection: '+(e.reason&&e.reason.message?e.reason.message:String(e.reason))]);` +
    `});` +
    `})();</script>`;
}

Step 3 — Build the webview HTML with the resolved endpoint

resolveEndpoint() runs synchronously in activate(), so by the time you create a webview panel the endpoint is already cached:

const endpoint = devbridge.getEndpoint();
panel.webview.html = buildWebviewHtml(endpoint, generateNonce());

If you create the panel in activate() itself (before resolveEndpoint() has run), call resolveEndpoint() first:

devbridge.resolveEndpoint();
const endpoint = devbridge.getEndpoint();
panel.webview.html = buildWebviewHtml(endpoint, generateNonce());

CSP notes

  • connect-src * (or connect-src http://YOUR_WSL_IP:3939) must be present — the bridge uses fetch.
  • The bridge <script> tag must carry the same nonce as the CSP script-src 'nonce-...' directive. Without the nonce the browser will block the script silently.
  • If your CSP uses 'unsafe-inline' instead of a nonce, omit the nonce attribute from the bridge tag.

WSL2 note

On WSL2, vscode.env.asExternalUri returns http://127.0.0.1:PORT. That URL points to the Windows loopback from the webview's perspective — not the WSL server. The hostname -I substitution in resolveEndpoint() above replaces it with the WSL VM's routable IP (e.g. 172.x.x.x), which the Windows-side renderer can reach because DevLogs MCP binds to 0.0.0.0.


Settings

Setting Default Description
devlogsMcp.port 3939 HTTP/SSE port
devlogsMcp.maxLogEntries 2000 Ring-buffer size
devlogsMcp.captureOutputChannels true Intercept VS Code Output panel channels
devlogsMcp.captureExtensionHost true Intercept Extension Host console.*
devlogsMcp.autoStart true Start MCP server on VS Code launch

Commands

Command Description
DevLogs MCP: Start Server Start the MCP server manually
DevLogs MCP: Stop Server Stop the MCP server
DevLogs MCP: Show Claude Desktop Config Open the config snippet panel
DevLogs MCP: Clear Log Buffer Discard all buffered log entries

Security

The MCP server binds to 0.0.0.0 (all network interfaces) rather than 127.0.0.1. This is required for WSL2 users — the webview renderer runs on Windows and cannot reach a WSL-only loopback address.

What this means in practice: the server is reachable from other machines on the same local network, not just your own machine. The OAuth layer provides a first line of defence — any client must complete an OAuth flow before it can call any tool. However, because the auth flow is automatic (no real credentials), a sophisticated attacker on the same network who knows your port could obtain a token and query your logs.

If this concerns you:

  • Set devlogsMcp.port to a non-default value so the port is not trivially guessable.
  • Use your OS firewall to block inbound connections on port 3939 from external interfaces (ufw deny 3939 on Ubuntu, Windows Defender Firewall on Windows).
  • If you are not on WSL, you can patch mcpServer.ts to bind to 127.0.0.1 — this restricts access to your machine only but breaks the webview bridge on WSL2.

This extension is a local development tool. It should not be run on a shared or public-facing machine.


Troubleshooting

Claude Code shows "SDK auth failed" or "Error POSTing to endpoint" Make sure you are running extension version ≥ 0.2.0 — earlier builds did not include the OAuth server. After updating, reload the VS Code window (Ctrl+Shift+P → Developer: Reload Window) and click Reconnect in the MCP servers panel.

Status bar shows ⊕ MCP error Port 3939 is already in use. Change devlogsMcp.port in settings to another value (e.g. 3940) and update your AI config to match.

Copilot doesn't call the tools Make sure you are in Agent mode in Copilot Chat, not the default inline chat. Agent mode is required for MCP tool calls.

Claude Desktop doesn't show the tools Verify the config JSON is valid (no trailing commas), then fully quit and relaunch Claude Desktop — a simple window close is not enough on macOS.

Webview logs are missing Confirm you called both getInjectionScript() in the HTML and registerWebviewPanel() in your extension code, and that enableScripts: true is set on the webview options.

get_screen_screenshot fails on macOS Go to System Settings → Privacy & Security → Screen Recording and enable it for VS Code (or your terminal if running the extension in development).

get_screen_screenshot fails on Linux (native) Run get_screenshot_info first. If it says no tool is available, install scrot: sudo apt install scrot. On a headless machine the capture is not possible by design.

get_screen_screenshot fails on WSL The extension expects powershell.exe to be on the WSL PATH. On a standard WSL2 install it is at /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe and is symlinked into PATH automatically. If get_screenshot_info reports it unavailable, check that /mnt/c/Windows/System32/WindowsPowerShell/v1.0/ is in your $PATH, or that Windows PowerShell is installed on the host.


Contributing

See https://codeberg.org/FreeTools/mcpdevlogs/src/branch/main/docs/CONTRIBUTING.md. Issues and PRs welcome — this extension is designed to be useful for any VS Code extension developer.


Licence

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft