1. Description Générale
mcp-powershell-http.ps1 est un serveur HTTP autonome écrit en PowerShell, conçu pour exécuter des scripts PowerShell à distance en toute sécurité. Il fonctionne comme une « passerelle » entre un client externe (par exemple, un assistant IA) et l’environnement PowerShell local, en utilisant le protocole JSON-RPC 2.0 pour la communication.
Caractéristiques Principales :
- Sécurité : Chaque script est exécuté dans une instance PowerShell (
runspace) entièrement isolée, ce qui empêche toute interférence avec l’environnement principal du serveur. - Configuration Flexible : Les paramètres du serveur (port, hôte, délais d’attente) peuvent être configurés via des arguments de ligne de commande et un fichier JSON externe.
- Stabilité : Une gestion complète des erreurs à tous les niveaux (HTTP, JSON, exécution de script) assure le fonctionnement fiable du serveur.
- Protocole MCP : Implémente le protocole standard MCP pour l’interaction, y compris les méthodes
initialize,tools/listettools/call. - Contrôle des Ressources : Des délais d’attente intégrés et des limites sur la taille de la sortie empêchent l’abus de ressources.
2. Exécution et Configuration
Prérequis :
- PowerShell 7.0 ou supérieur.
Paramètres de Ligne de Commande :
| Paramètre | Type | Description | Par défaut |
|---|---|---|---|
-Port | [int] | Le port sur lequel le serveur écoutera les requêtes HTTP. | 8090 |
-ServerHost | [string] | L’hôte (adresse IP ou nom de domaine) auquel le serveur sera lié. | localhost |
-ConfigFile | [string] | Le chemin vers un fichier de configuration au format JSON. Les paramètres de ce fichier remplacent les valeurs par défaut et les arguments de la ligne de commande. | $null |
Exemple d’Utilisation :
.\mcp-powershell-http.ps1 -Port 8090 -ServerHost 0.0.0.0 -ConfigFile "C:\config\settings.json"
Fichier de Configuration (settings.json) :
Le serveur peut charger sa configuration à partir d’un fichier JSON. C’est l’approche recommandée pour les environnements de production.
Exemple de settings.json du dépôt :
{
"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. Architecture et Fonctions
Le script est logiquement divisé en plusieurs régions (#region) pour simplifier la navigation.
Région : Utility Functions (Fonctions Utilitaires)
Write-Log- Objectif : Affiche des messages formatés et colorés dans la console avec un horodatage. C’est la fonction principale pour la journalisation (logging).
- Paramètres :
$Message[string](obligatoire) : Le texte du message.$Level[string](optionnel) : Le niveau de journalisation (DEBUG,INFO,WARNING,ERROR). Affecte la couleur de la sortie.
Test-MCPRequest- Objectif : Valide si la requête entrante respecte les exigences de base du protocole JSON-RPC 2.0 (présence des champs
jsonrpc: "2.0"etmethod). - Paramètres :
$Request[hashtable](obligatoire) : La requête, désérialisée depuis JSON.
- Retourne :
$truesi la requête est valide, sinon$false.
- Objectif : Valide si la requête entrante respecte les exigences de base du protocole JSON-RPC 2.0 (présence des champs
New-MCPResponse- Objectif : Une fonction « factory » pour créer des objets de réponse JSON-RPC standardisés.
- Paramètres :
$Id[object]: L’identifiant de la requête.$Result[object]: L’objet contenant un résultat réussi.$Error[hashtable]: L’objet contenant les informations sur l’erreur.
- Retourne : Une
[hashtable]avec la structure complète de la réponse.
Test-ScriptSafety- Objectif : Vérifie si le script contient des commandes potentiellement dangereuses listées dans la variable globale
$script:RestrictedCommands. - Note : Dans la version fournie, cette fonction est désactivée par défaut (
return $true). Pour une utilisation en production, elle doit être activée et configurée. - Paramètres :
$Script[string](obligatoire) : Le texte du script PowerShell à vérifier.
- Retourne :
$truesi le script est sûr, sinon$false.
- Objectif : Vérifie si le script contient des commandes potentiellement dangereuses listées dans la variable globale
Région : Core Logic (Logique Principale)
Invoke-PowerShellScript- Objectif : La fonction principale responsable de l’exécution sécurisée d’un script PowerShell.
- Processus :
- Crée une nouvelle instance PowerShell entièrement isolée (
[powershell]::Create()). - (Optionnel) Définit le répertoire de travail dans cette instance.
- Ajoute le texte du script et ses paramètres à l’instance.
- Exécute le script de manière asynchrone avec un délai d’attente.
- Collecte les flux de sortie (
Output), d’erreur (Error) et d’avertissement (Warning). - Limite la taille de la sortie (par défaut 10 000 caractères) pour éviter les transferts de données volumineux.
- Nettoie les ressources (
Dispose()) à la fin de l’exécution.
- Crée une nouvelle instance PowerShell entièrement isolée (
- Paramètres :
$Script[string](obligatoire) : Le code à exécuter.$Parameters[hashtable]: Les paramètres à passer au script.$TimeoutSeconds[int]: Le temps d’exécution maximum en secondes.$WorkingDirectory[string]: Le répertoire de travail pour le script.
- Retourne : Une
[hashtable]avec les résultats :success(bool),output(string),errors(array),warnings(array),executionTime(double).
Région : MCP Protocol Methods (Méthodes du Protocole MCP)
Invoke-MCPMethod- Objectif : Un répartiteur (dispatcher) qui gère les appels aux méthodes du protocole MCP.
- Processus : Utilise une instruction
switchsur le nom de la méthode ($Method) pour invoquer la logique appropriée. - Méthodes supportées :
"initialize": Renvoie des informations sur le serveur."tools/list": Renvoie une liste des outils disponibles (dans ce cas, uniquement"run-script")."tools/call": Gère l’invocation d’un outil. Il extrait les paramètres et appelleInvoke-PowerShellScriptpour l’exécution.
- Paramètres :
$Method[string]: Le nom de la méthode à appeler.$Params[hashtable]: Les paramètres de la méthode.$Id[object]: L’identifiant de la requête.
- Retourne : Une
[hashtable]représentant la réponse MCP complète, prête à être envoyée.
Région : HTTP Server (Serveur HTTP)
Invoke-RequestHandler- Objectif : Gère le cycle de vie complet d’une seule requête HTTP.
- Processus :
- Configure les en-têtes CORS.
- Gère les requêtes
OPTIONS(CORS preflight). - Vérifie que la méthode de la requête est
POST. - Lit et valide le corps de la requête.
- Analyse (parse) le JSON et le convertit en table de hachage.
- Appelle
Test-MCPRequestpour validation. - Transmet la requête à
Invoke-MCPMethodpour traitement. - Sérialise la réponse en JSON et l’envoie au client.
- Gère toutes les erreurs possibles tout au long de ce processus.
- Paramètres :
$Context[System.Net.HttpListenerContext]: Le contexte de la requête HTTP fourni par l’écouteur .NET.
Start-MCPServer- Objectif : La fonction principale qui initialise et démarre l’écouteur HTTP.
- Processus :
- Crée et configure un objet
System.Net.HttpListener. - Démarre l’écouteur avec
listener.Start(). - Entre dans une boucle infinie
while ($listener.IsListening)pour attendre les connexions entrantes. - Pour chaque connexion, appelle
Invoke-RequestHandler. - Arrête correctement le serveur lorsque le processus est terminé.
- Crée et configure un objet
4. Flux d’Exécution d’une Requête
- Un client envoie une requête
POSTavecContent-Type: application/jsonà l’URL du serveur. Start-MCPServeraccepte la requête et la transmet àInvoke-RequestHandler.Invoke-RequestHandlervalide les en-têtes HTTP, la méthode, et analyse le corps JSON.- La requête MCP valide est transmise à
Invoke-MCPMethod. Invoke-MCPMethoddétermine que la méthodetools/calla été invoquée avec l’outilrun-script.- Les paramètres (script, délai d’attente, etc.) sont passés à
Invoke-PowerShellScript. Invoke-PowerShellScriptexécute le script dans un environnement isolé.- Le résultat de l’exécution remonte la chaîne d’appels, est formaté en une réponse JSON-RPC standard et est renvoyé au client par
Invoke-RequestHandler.
5. Extension des Fonctionnalités
Pour ajouter un nouvel « outil » (en plus de run-script), un développeur doit :
- Ajouter une description du nouvel outil dans le bloc
"tools/list"de la fonctionInvoke-MCPMethod. - Ajouter une nouvelle branche
casepour cet outil dans l’instructionswitch ($toolName)à l’intérieur du bloc"tools/call"deInvoke-MCPMethod. - Implémenter la logique pour le nouvel outil.