Przejdź do treści
> 💻 🧠 Kod 1001 > ⚡ Filozofia PowerShe > Serwer MCP w PowerShell > Dokumentacja dla deweloperów: Serwer MCP PowerShell HTTP. (mcp-powershell-server-http.py)

Dokumentacja dla deweloperów: Serwer MCP PowerShell HTTP. (mcp-powershell-server-http.py)

1. Przegląd

mcp-powershell-http.ps1 to samodzielny serwer HTTP napisany w PowerShellu, zaprojektowany do bezpiecznego zdalnego wykonywania skryptów PowerShell. Działa jako „most” między klientem zewnętrznym (np. asystentem AI) a lokalnym środowiskiem PowerShell, używając do komunikacji protokołu JSON-RPC 2.0.

Kluczowe cechy:

  • Bezpieczeństwo: Każdy skrypt jest wykonywany w całkowicie izolowanej instancji PowerShell (runspace), co zapobiega wpływowi na główne środowisko serwera.
  • Elastyczna konfiguracja: Parametry serwera (port, host, limity czasowe) można konfigurować za pomocą argumentów wiersza poleceń i zewnętrznego pliku JSON.
  • Stabilność: Kompleksowa obsługa błędów na wszystkich poziomach (HTTP, JSON, wykonanie skryptu) zapewnia niezawodne działanie serwera.
  • Protokół MCP: Implementuje standardowy protokół MCP do interakcji, w tym metody initialize, tools/list i tools/call.
  • Kontrola zasobów: Wbudowane limity czasowe (timeouty) i ograniczenia rozmiaru danych wyjściowych zapobiegają nadużyciom zasobów.

2. Uruchamianie i konfiguracja

Wymagania:

  • PowerShell 7.0 lub nowszy.

Parametry wiersza poleceń:

ParametrTypOpisDomyślnie
-Port[int]Port, na którym serwer będzie nasłuchiwał żądań HTTP.8090
-ServerHost[string]Host (adres IP lub nazwa domeny), do którego serwer ma być przypisany.localhost
-ConfigFile[string]Ścieżka do pliku konfiguracyjnego w formacie JSON. Parametry z tego pliku nadpisują wartości domyślne i argumenty wiersza poleceń.$null

Przykład użycia:

.\mcp-powershell-http.ps1 -Port 8090 -ServerHost 0.0.0.0 -ConfigFile "C:\config\settings.json"

Plik konfiguracyjny (settings.json):

Serwer może wczytywać swoją konfigurację z pliku JSON. Jest to zalecane podejście w środowiskach produkcyjnych.

Przykład settings.json z repozytorium:

{
  "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. Architektura i funkcje

Skrypt jest logicznie podzielony na kilka regionów (#region), aby uprościć nawigację.

Region: Utility Functions (Funkcje pomocnicze)
  1. Write-Log
    • Cel: Wyświetla sformatowane i pokolorowane komunikaty w konsoli ze znacznikiem czasu. Jest to główna funkcja do logowania.
    • Parametry:
      • $Message [string] (obowiązkowy): Treść komunikatu.
      • $Level [string] (opcjonalny): Poziom logowania (DEBUG, INFO, WARNING, ERROR). Wpływa na kolor wyświetlanego tekstu.
  2. Test-MCPRequest
    • Cel: Sprawdza, czy przychodzące żądanie spełnia podstawowe wymagania protokołu JSON-RPC 2.0 (obecność pól jsonrpc: "2.0" i method).
    • Parametry:
      • $Request [hashtable] (obowiązkowy): Żądanie zdeserializowane z formatu JSON.
    • Zwraca: $true, jeśli żądanie jest prawidłowe, w przeciwnym razie $false.
  3. New-MCPResponse
    • Cel: Funkcja fabrykująca (factory function) do tworzenia standardowych obiektów odpowiedzi JSON-RPC.
    • Parametry:
      • $Id [object]: Identyfikator żądania.
      • $Result [object]: Obiekt zawierający pomyślny wynik.
      • $Error [hashtable]: Obiekt zawierający informacje o błędzie.
    • Zwraca: [hashtable] z kompletną strukturą odpowiedzi.
  4. Test-ScriptSafety
    • Cel: Sprawdza skrypt pod kątem obecności potencjalnie niebezpiecznych poleceń wymienionych w zmiennej globalnej $script:RestrictedCommands.
    • Uwaga: W dostarczonej wersji funkcja jest domyślnie wyłączona (return $true). Do użytku produkcyjnego należy ją włączyć i skonfigurować.
    • Parametry:
      • $Script [string] (obowiązkowy): Tekst skryptu PowerShell do sprawdzenia.
    • Zwraca: $true, jeśli skrypt jest bezpieczny, w przeciwnym razie $false.
Region: Core Logic (Logika główna)
  1. Invoke-PowerShellScript
    • Cel: Kluczowa funkcja odpowiedzialna za bezpieczne wykonanie skryptu PowerShell.
    • Proces:
      1. Tworzy nową, całkowicie izolowaną instancję PowerShell ([powershell]::Create()).
      2. (Opcjonalnie) Ustawia katalog roboczy wewnątrz tej instancji.
      3. Dodaje do instancji tekst skryptu i jego parametry.
      4. Uruchamia wykonanie asynchronicznie z limitem czasu (timeout).
      5. Zbiera strumienie wyjścia (Output), błędów (Error) i ostrzeżeń (Warning).
      6. Ogranicza rozmiar danych wyjściowych (domyślnie 10 000 znaków), aby zapobiec przesyłaniu dużych ilości danych.
      7. Czyści zasoby (Dispose()) po zakończeniu.
    • Parametry:
      • $Script [string] (obowiązkowy): Kod do wykonania.
      • $Parameters [hashtable]: Parametry do przekazania do skryptu.
      • $TimeoutSeconds [int]: Maksymalny czas wykonania w sekundach.
      • $WorkingDirectory [string]: Katalog roboczy dla skryptu.
    • Zwraca: [hashtable] z wynikami: success (bool), output (string), errors (array), warnings (array), executionTime (double).
Region: MCP Protocol Methods (Metody protokołu MCP)
  1. Invoke-MCPMethod
    • Cel: Dyspozytor, który obsługuje wywołania metod protokołu MCP.
    • Proces: Używa konstrukcji switch na nazwie metody ($Method), aby wywołać odpowiednią logikę.
    • Obsługiwane metody:
      • "initialize": Zwraca informacje o serwerze.
      • "tools/list": Zwraca listę dostępnych narzędzi (w tym przypadku tylko "run-script").
      • "tools/call": Obsługuje wywołanie narzędzia. Wyodrębnia parametry i wywołuje Invoke-PowerShellScript w celu wykonania.
    • Parametry:
      • $Method [string]: Nazwa wywoływanej metody.
      • $Params [hashtable]: Parametry metody.
      • $Id [object]: Identyfikator żądania.
    • Zwraca: [hashtable] reprezentującą kompletną odpowiedź MCP, gotową do wysłania.
Region: HTTP Server (Serwer HTTP)
  1. Invoke-RequestHandler
    • Cel: Obsługuje pełny cykl życia pojedynczego żądania HTTP.
    • Proces:
      1. Konfiguruje nagłówki CORS.
      2. Obsługuje żądania OPTIONS (CORS preflight).
      3. Sprawdza, czy metoda żądania to POST.
      4. Odczytuje i waliduje ciało żądania.
      5. Parsuje JSON i konwertuje go na tabelę skrótów (hashtable).
      6. Wywołuje Test-MCPRequest w celu walidacji.
      7. Przekazuje żądanie do Invoke-MCPMethod w celu przetworzenia.
      8. Serializuje odpowiedź z powrotem do formatu JSON i wysyła ją do klienta.
      9. Obsługuje wszystkie możliwe błędy na tej drodze.
    • Parametry:
      • $Context [System.Net.HttpListenerContext]: Kontekst żądania HTTP z nasłuchiwacza .NET.
  2. Start-MCPServer
    • Cel: Główna funkcja, która inicjalizuje i uruchamia nasłuchiwacz HTTP.
    • Proces:
      1. Tworzy i konfiguruje obiekt System.Net.HttpListener.
      2. Uruchamia nasłuchiwacz za pomocą listener.Start().
      3. Wchodzi w nieskończoną pętlę while ($listener.IsListening), aby czekać na przychodzące połączenia.
      4. Dla każdego połączenia wywołuje Invoke-RequestHandler.
      5. Prawidłowo zatrzymuje serwer po zakończeniu procesu.

4. Przebieg przetwarzania żądania

  1. Klient wysyła żądanie POST z Content-Type: application/json na adres URL serwera.
  2. Start-MCPServer akceptuje żądanie i przekazuje je do Invoke-RequestHandler.
  3. Invoke-RequestHandler waliduje nagłówki HTTP, metodę i parsuje ciało JSON.
  4. Prawidłowe żądanie MCP jest przekazywane do Invoke-MCPMethod.
  5. Invoke-MCPMethod określa, że wywołano metodę tools/call z narzędziem run-script.
  6. Parametry (skrypt, limit czasu itp.) są przekazywane do Invoke-PowerShellScript.
  7. Invoke-PowerShellScript wykonuje skrypt w izolowanym środowisku.
  8. Wynik wykonania jest zwracany w górę łańcucha wywołań, formatowany do standardowej odpowiedzi JSON-RPC i wysyłany z powrotem do klienta przez Invoke-RequestHandler.

5. Rozszerzanie funkcjonalności

Aby dodać nowe „narzędzie” (oprócz run-script), deweloper musi:

  1. Dodać opis nowego narzędzia w bloku "tools/list" w funkcji Invoke-MCPMethod.
  2. Dodać nową gałąź case dla tego narzędzia w instrukcji switch ($toolName) wewnątrz bloku "tools/call" w Invoke-MCPMethod.
  3. Zaimplementować logikę dla nowego narzędzia.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *