TL;DR:
Problem: In einer Sandbox ausgeführte Linux-Container-Agenten in WSL2 (Claude Code, Gemini CLI) können Windows-MCP-Server (wie den Power BI Modeling MCP) aufgrund von Transportbeschränkungen über Betriebssystemgrenzen hinweg, Blockierungen durch die Hyper-V-Firewall am Port 3000 und Problemen beim JSON-RPC-Stream-Framing nicht nativ ausführen.
Lösung: Ein auf dem Windows-Host ausgeführtes Node.js-Proxy-Skript empfängt HTTP-Anfragen vom Container, wandelt diese in native stdio-Prozesskommunikation des Hosts um, aggregiert fragmentierte JSON-Nutzdaten und verarbeitet asynchrone Benachrichtigungen sicher.
Dieser Beitrag ist eine (teil-)automatisierte Übersetzung des englischen Originals.
Durch die Integration von MCP-Servern (Model Context Protocol) in Entwicklertools erhalten Sprachmodelle direkten, strukturierten Kontext aus lokalen Umgebungen. In Verbindung mit Tools wie dem „Power BI Modeling MCP“ von Microsoft können CLI-Agenten wie Claude Code (claude) und Gemini CLI (gemini) tabellarische Modelle auswerten, DAX-Abfragen ausführen und TMDL-Definitionen in Echtzeit in lokalen Power BI Desktop-Instanzen ändern.
Sicherheitsrichtlinien schreiben jedoch vor, dass KI-CLI-Agenten in Sandbox-Umgebungen (wie Podman- oder Docker-Linux-Containern) ausgeführt werden müssen. Dies führt zu einem gravierenden Konflikt, wenn versucht wird, Windows-native Binärdateien aus einer isolierten Linux-Laufzeitumgebung heraus auszuführen.
Dieser Artikel beschreibt die damit verbundenen architektonischen Hindernisse – einschließlich der Einschränkungen der Windows 11 Hyper-V-Firewall – und stellt ein leichtgewichtiges Node.js-Proxy-Skript bereit, das die Kommunikation zwischen CLI-Agenten in der Sandbox und nativen Windows-Ausführungsdateien überbrückt.
Technische Herausforderungen auf Windows-Hostsystemen
Bei der Ausführung von Agent-CLIs mit aktivierter Container-Sandbox-Funktion treten vier wesentliche Probleme auf:
- Inkompatibilitäten zwischen Betriebssystem und DLLs
Die Power BI Modeling MCP-Server-Binärdatei (.exe) ist auf Windows-Systembibliotheken wie iphlpapi.dll (IP Helper API) angewiesen, um laufende Power BI Desktop-Instanzen zu erkennen. Innerhalb einer Linux-Container-Sandbox sind diese Windows-Bibliotheken nicht vorhanden, was dazu führt, dass Standardausführungsversuche unter Linux sofort fehlschlagen. - Trennung der Transportschicht (stdio vs. HTTP/SSE)
MCP-Server kommunizieren in der Regel über Standard-Ein- und -Ausgabe (stdio). Eine containerisierte Sandbox kann native stdio-Streams nicht direkt an eine auf dem Host-Betriebssystem ausgeführte ausführbare Datei anbinden. Die Kommunikation muss in Netzwerkprotokolle wie HTTP oder SSE umgewandelt werden. - Einschränkungen der Hyper-V-Firewall (Windows 11 22H2+)
Die Hyper-V-Firewall filtert den Datenverkehr, der über virtuelle Netzwerkadapter fließt, die für Container-Laufzeiten und WSL erstellt wurden. Selbst wenn die Standardports der Windows Defender-Firewall offen sind, wird eingehender Datenverkehr vom virtuellen Container-Switch zum Host standardmäßig verworfen, sofern er nicht ausdrücklich zugelassen wird. - Unterschiede beim Stream-Framing und beim JSON-RPC-Protokoll
MCP-Implementierungen unter Windows unterteilen JSON-Nutzdaten häufig in fragmentierte Datenblöcke oder fügen Längen-Header hinzu. Die rohe TCP-Weiterleitung führt zu Parsing-Fehlern wie „Unerwartetes Ende der JSON-Eingabe“. Zudem erwarten standardmäßige JSON-RPC-Benachrichtigungsmethoden (wie „notifications/initialized“) keine Antworten, was dazu führt, dass synchrone Listener eine Zeitüberschreitung verzeichnen.
Die grobe Übersicht für Claude und für Gemini ist unten dargestellt:

Implementierungsanleitung
Schritt 1: Konfigurieren der Windows Hyper-V-Firewall-Regeln
Da der Container-Datenverkehr über einen virtuellen Hyper-V-Switch geleitet wird, führen Sie den folgenden Befehl in PowerShell als Administrator aus, um eingehenden Datenverkehr auf Port 3000 vom Container-Switch zuzulassen:
|
1 2 3 4 5 6 7 |
New-NetFirewallHyperVRule -Name "AllowMCPBridgeInbound" ` -DisplayName "Allow Inbound MCP Proxy Bridge from Sandbox" ` -Direction Inbound ` -VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' ` -Protocol TCP ` -LocalPorts 3000 ` -Action Allow |
Schritt 2: Bereitstellung des Node.js-Bridge-Skripts (bridge.js)
Speichern Sie dieses Proxy-Skript auf Ihrem Windows-Host. Es verarbeitet nicht blockierende Benachrichtigungen, aggregiert fragmentierte stdout-Puffer und stellt die ausführbare Datei über HTTP bereit.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
const { spawn } = require('child_process'); const http = require('http'); const args = process.argv.slice(2); const help = args.includes('--help') || args.includes('-h'); const verbose = args.includes('--verbose') || args.includes('-v'); const exePath = args.find(arg => !arg.startsWith('-')); if (help || !exePath) { console.log(` Power BI MCP Bridge Usage: node bridge.js [path-to-exe] [options] Arguments: path-to-exe Full path to the native Windows MCP executable. Options: -v, --verbose Log raw JSON-RPC payloads and chunk buffering status. -h, --help Display this help message. `); process.exit(0); } const getTimestamp = () => `[${new Date().toLocaleTimeString()}]`; const mcpProcess = spawn(exePath, ['--start']); let currentResponse = null; let responseBuffer = ""; mcpProcess.stderr.on('data', (data) => { console.error(`${getTimestamp()} [EXE LOG/ERROR]: ${data.toString().trim()}`); }); mcpProcess.stdout.on('data', (data) => { if (!currentResponse) return; responseBuffer += data.toString(); const jsonStartIndex = responseBuffer.indexOf('{'); if (jsonStartIndex !== -1) { const payloadCandidate = responseBuffer.substring(jsonStartIndex); try { JSON.parse(payloadCandidate); if (verbose) console.log(`${getTimestamp()} [RESPONSE] Valid JSON assembled. Returning to agent.`); currentResponse.writeHead(200, { 'Content-Type': 'application/json' }); currentResponse.end(payloadCandidate.trim()); currentResponse = null; responseBuffer = ""; } catch (e) { if (verbose) console.log(`${getTimestamp()} [BUFFER] Partial JSON received. Awaiting chunks...`); } } }); const server = http.createServer((req, res) => { if (req.method === 'POST') { let requestBody = ''; req.on('data', chunk => { requestBody += chunk; }); req.on('end', () => { try { const parsedPayload = JSON.parse(requestBody); if (verbose) console.log(`${getTimestamp()} [REQUEST] Method: ${parsedPayload.method}`); if (parsedPayload.method && parsedPayload.method.startsWith('notifications/')) { mcpProcess.stdin.write(requestBody + '\n'); res.writeHead(202); res.end(); return; } currentResponse = res; responseBuffer = ""; mcpProcess.stdin.write(requestBody + '\n'); setTimeout(() => { if (currentResponse === res) { console.log(`${getTimestamp()} [TIMEOUT] Method timed out: ${parsedPayload.method}`); res.writeHead(504); res.end(JSON.stringify({ error: "Execution timeout" })); currentResponse = null; } }, 15000); } catch (err) { res.writeHead(400); res.end(JSON.stringify({ error: "Malformed JSON payload" })); } }); } }); server.listen(3000, '0.0.0.0', () => { console.log(`${getTimestamp()} Bridge listening on http://0.0.0.0:3000/mcp`); console.log(`${getTimestamp()} Target executable: ${exePath}`); }); process.on('SIGINT', () => { mcpProcess.kill(); process.exit(); }); |
Schritt 3: Konfiguration der CLI-Clients
Option A: Konfiguration der Gemini CLI (gemini)
Fügen Sie den Bridge-Eintrag zu Ihrer Datei „settings.json“ hinzu:
|
1 2 3 4 5 6 7 8 |
{ "mcpServers": { "powerbi-modeling-mcp": { "httpUrl": "http://host.containers.internal:3000/mcp", "timeout": 30000 } } } |
Option B: Konfiguration von Claude CLI (claude / Claude Code)
Fügen Sie den Bridge-Eintrag in Ihre Datei .mcp.json oder ~/.claude.json ein:
|
1 2 3 4 5 6 7 8 |
{ "mcpServers": { "powerbi-modeling-mcp": { "type": "http", "url": "http://host.containers.internal:3000/mcp" } } } |
Schritt 4: Überprüfung und Arbeitsablauf
- Starten Sie die Bridge auf dem Windows-Host:
1node bridge.js "C:\Path\To\powerbi-modeling-mcp.exe" --verbose - Rufen Sie die Tool-Erkennung in Ihrem bevorzugten CLI-Client auf:
- Für Gemini CLI: /mcp refresh
- Für Claude CLI: claude mcp list oder /mcp
Fazit
Durch die Kombination gezielter Hyper-V-Firewall-Regeln mit einer Node.js-Proxy-Brücke können in einer Sandbox ausgeführte CLI-Agenten wie Claude CLI und Gemini CLI nahtlos mit Windows-nativen MCP-Servern interagieren. Diese Konfiguration gewährleistet eine vollständige Containerisolierung und gewährt Ihren KI-Agenten gleichzeitig uneingeschränkten Zugriff auf lokale Power BI-Modelle.