1. Überblick
mcp-powershell-http.ps1 ist ein eigenständiger HTTP-Server, der in PowerShell geschrieben wurde, um PowerShell-Skripte sicher aus der Ferne auszuführen. Er fungiert als „Brücke“ zwischen einem externen Client (z. B. einem KI-Assistenten) und der lokalen PowerShell-Umgebung und verwendet für die Kommunikation das JSON-RPC 2.0-Protokoll.
Hauptmerkmale:
- Sicherheit: Jedes Skript wird in einer vollständig isolierten PowerShell-Instanz (
Runspace) ausgeführt, was Auswirkungen auf die Hauptumgebung des Servers verhindert. - Flexible Konfiguration: Serverparameter (Port, Host, Timeouts) können über Befehlszeilenargumente und eine externe JSON-Datei konfiguriert werden.
- Stabilität: Eine umfassende Fehlerbehandlung auf allen Ebenen (HTTP, JSON, Skriptausführung) gewährleistet den zuverlässigen Betrieb des Servers.
- MCP-Protokoll: Implementiert das Standard-MCP-Protokoll für die Interaktion, einschließlich der Methoden
initialize,tools/listundtools/call. - Ressourcenkontrolle: Integrierte Timeouts und eine Begrenzung der Ausgabegröße verhindern den Missbrauch von Ressourcen.
2. Ausführung und Konfiguration
Voraussetzungen:
- PowerShell 7.0 oder höher.
Befehlszeilenparameter:
| Parameter | Typ | Beschreibung | Standardwert |
|---|---|---|---|
-Port | [int] | Der Port, an dem der Server auf HTTP-Anfragen lauscht. | 8090 |
-ServerHost | [string] | Der Host (IP-Adresse oder Domainname), an den der Server gebunden wird. | localhost |
-ConfigFile | [string] | Der Pfad zu einer Konfigurationsdatei im JSON-Format. Parameter aus dieser Datei überschreiben die Standardwerte und Befehlszeilenargumente. | $null |
Anwendungsbeispiel:
.\mcp-powershell-http.ps1 -Port 8090 -ServerHost 0.0.0.0 -ConfigFile "C:\config\settings.json"
Konfigurationsdatei (settings.json):
Der Server kann seine Konfiguration aus einer JSON-Datei laden. Dies ist der empfohlene Ansatz für Produktionsumgebungen.
Beispiel settings.json aus dem Repository:
{
"Port": 8090,
"Host": "localhost",
"MaxConcurrentRequests": 10,
"TimeoutSeconds": 300,
"LogLevel": "INFO",
"AllowedPaths": [
"C:\\Scripts\\",
"C:\\Users\\%USERNAME%\\Documents\\"
],
"Security": {
"EnableScriptValidation": false,
"BlockDangerousCommands": false,
"RestrictedCommands": [
"Remove-Item -Path C:\\Windows\\*",
"Format-Volume"
]
}
}
3. Architektur und Funktionen
Das Skript ist logisch in mehrere Regionen (#region) unterteilt, um die Navigation zu vereinfachen.
Region: Utility Functions (Hilfsfunktionen)
Write-Log- Zweck: Gibt formatierte und farbige Nachrichten mit einem Zeitstempel in der Konsole aus. Dies ist die Hauptfunktion für die Protokollierung.
- Parameter:
$Message[string](obligatorisch): Der Nachrichtentext.$Level[string](optional): Die Protokollierungsstufe (DEBUG,INFO,WARNING,ERROR). Beeinflusst die Farbe der Ausgabe.
Test-MCPRequest- Zweck: Überprüft, ob die eingehende Anfrage die grundlegenden Anforderungen des JSON-RPC 2.0-Protokolls erfüllt (Vorhandensein der Felder
jsonrpc: "2.0"undmethod). - Parameter:
$Request[hashtable](obligatorisch): Die aus JSON deserialisierte Anfrage.
- Rückgabewert:
$true, wenn die Anfrage gültig ist, andernfalls$false.
- Zweck: Überprüft, ob die eingehende Anfrage die grundlegenden Anforderungen des JSON-RPC 2.0-Protokolls erfüllt (Vorhandensein der Felder
New-MCPResponse- Zweck: Eine Factory-Funktion zur Erstellung standardisierter JSON-RPC-Antwortobjekte.
- Parameter:
$Id[object]: Der Bezeichner der Anfrage.$Result[object]: Das Objekt, das ein erfolgreiches Ergebnis enthält.$Error[hashtable]: Das Objekt, das Fehlerinformationen enthält.
- Rückgabewert: Eine
[hashtable]mit der vollständigen Antwortstruktur.
Test-ScriptSafety- Zweck: Überprüft das Skript auf potenziell gefährliche Befehle, die in der globalen Variablen
$script:RestrictedCommandsaufgeführt sind. - Hinweis: In der bereitgestellten Version ist diese Funktion standardmäßig deaktiviert (
return $true). Für den Produktionseinsatz sollte sie aktiviert und konfiguriert werden. - Parameter:
$Script[string](obligatorisch): Der zu überprüfende PowerShell-Skripttext.
- Rückgabewert:
$true, wenn das Skript sicher ist, andernfalls$false.
- Zweck: Überprüft das Skript auf potenziell gefährliche Befehle, die in der globalen Variablen
Region: Core Logic (Kernlogik)
Invoke-PowerShellScript- Zweck: Die Kernfunktion, die für die sichere Ausführung eines PowerShell-Skripts verantwortlich ist.
- Ablauf:
- Erstellt eine neue, vollständig isolierte PowerShell-Instanz (
[powershell]::Create()). - (Optional) Legt das Arbeitsverzeichnis innerhalb dieser Instanz fest.
- Fügt den Skripttext und seine Parameter zur Instanz hinzu.
- Führt das Skript asynchron mit einem Timeout aus.
- Sammelt die Ausgabe (
Output)-, Fehler (Error)- und Warnungs (Warning)-Streams. - Begrenzt die Ausgabegröße (Standard 10.000 Zeichen), um große Datenübertragungen zu verhindern.
- Gibt die Ressourcen nach Abschluss wieder frei (
Dispose()).
- Erstellt eine neue, vollständig isolierte PowerShell-Instanz (
- Parameter:
$Script[string](obligatorisch): Der auszuführende Code.$Parameters[hashtable]: Parameter, die an das Skript übergeben werden.$TimeoutSeconds[int]: Maximale Ausführungszeit in Sekunden.$WorkingDirectory[string]: Das Arbeitsverzeichnis für das Skript.
- Rückgabewert: Eine
[hashtable]mit den Ergebnissen:success(bool),output(string),errors(array),warnings(array),executionTime(double).
Region: MCP Protocol Methods (MCP-Protokollmethoden)
Invoke-MCPMethod- Zweck: Ein Dispatcher, der die Aufrufe von MCP-Protokollmethoden verarbeitet.
- Ablauf: Verwendet eine
switch-Anweisung auf den Methodennamen ($Method), um die entsprechende Logik aufzurufen. - Unterstützte Methoden:
"initialize": Gibt Informationen über den Server zurück."tools/list": Gibt eine Liste der verfügbaren Tools zurück (in diesem Fall nur"run-script")."tools/call": Verarbeitet einen Tool-Aufruf. Extrahiert die Parameter und ruftInvoke-PowerShellScriptzur Ausführung auf.
- Parameter:
$Method[string]: Der Name der aufzurufenden Methode.$Params[hashtable]: Die Parameter der Methode.$Id[object]: Der Bezeichner der Anfrage.
- Rückgabewert: Eine
[hashtable], die die vollständige, sendebereite MCP-Antwort darstellt.
Region: HTTP Server
Invoke-RequestHandler- Zweck: Verarbeitet den gesamten Lebenszyklus einer einzelnen HTTP-Anfrage.
- Ablauf:
- Richtet CORS-Header ein.
- Behandelt
OPTIONS-Anfragen (CORS-Preflight). - Überprüft, ob die Anfragemethode
POSTist. - Liest und validiert den Anfragetext (Body).
- Parst das JSON und konvertiert es in eine Hashtabelle.
- Ruft
Test-MCPRequestzur Validierung auf. - Übergibt die Anfrage zur Verarbeitung an
Invoke-MCPMethod. - Serialisiert die Antwort zurück in JSON und sendet sie an den Client.
- Behandelt alle möglichen Fehler auf diesem Weg.
- Parameter:
$Context[System.Net.HttpListenerContext]: Der HTTP-Anfragekontext vom .NET-Listener.
Start-MCPServer- Zweck: Die Hauptfunktion, die den HTTP-Listener initialisiert und startet.
- Ablauf:
- Erstellt und konfiguriert ein
System.Net.HttpListener-Objekt. - Startet den Listener mit
listener.Start(). - Tritt in eine Endlosschleife
while ($listener.IsListening)ein, um auf eingehende Verbindungen zu warten. - Ruft für jede Verbindung
Invoke-RequestHandlerauf. - Stoppt den Server ordnungsgemäß, wenn der Prozess beendet wird.
- Erstellt und konfiguriert ein
4. Ablauf einer Anforderungsausführung
- Ein Client sendet eine
POST-Anfrage mitContent-Type: application/jsonan die URL des Servers. Start-MCPServernimmt die Anfrage entgegen und übergibt sie anInvoke-RequestHandler.Invoke-RequestHandlervalidiert die HTTP-Header, die Methode und parst den JSON-Body.- Die gültige MCP-Anfrage wird an
Invoke-MCPMethodübergeben. Invoke-MCPMethodstellt fest, dass die Methodetools/callmit dem Toolrun-scriptaufgerufen wurde.- Die Parameter (Skript, Timeout usw.) werden an
Invoke-PowerShellScriptübergeben. Invoke-PowerShellScriptführt das Skript in einer isolierten Umgebung aus.- Das Ausführungsergebnis wird die Aufrufkette zurückgegeben, in eine Standard-JSON-RPC-Antwort formatiert und von
Invoke-RequestHandleran den Client zurückgesendet.
5. Erweiterung der Funktionalität
Um ein neues „Tool“ (neben run-script) hinzuzufügen, muss ein Entwickler:
- Eine Beschreibung des neuen Tools zum Block
"tools/list"in der FunktionInvoke-MCPMethodhinzufügen. - Einen neuen
case-Zweig für dieses Tool in derswitch ($toolName)-Anweisung innerhalb des"tools/call"-Blocks vonInvoke-MCPMethodhinzufügen. - Die Logik für das neue Tool implementieren.