Skip to content
> 💻 🧠 Codice 1001 > > Server MCP in PowerShell > Guida dettagliata all’uso di MCP PowerShell Server. (how-to-use.md)

Guida dettagliata all’uso di MCP PowerShell Server. (how-to-use.md)

Installazione e configurazione

Prerequisiti

  1. PowerShell 7.0+ # Verifica della versione di PowerShell $PSVersionTable.PSVersion # Installazione di PowerShell 7 (se necessario) # Scarica da https://github.com/PowerShell/PowerShell
  2. Diritti di accesso
    • Per le porte < 1024 sono necessari i diritti di amministratore.
    • Permessi per l’esecuzione di script PowerShell.
  3. Impostazione della policy di esecuzione # Verifica della policy corrente Get-ExecutionPolicy # Impostazione della policy per consentire l'esecuzione di script Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Configurazione iniziale

  1. Navigazione nella directory dei server # Spostarsi nella directory principale del modulo cd C:\powershell\modules\mcp-powershell-server # Spostarsi nella directory dei server cd src\servers
  2. Verifica dei file
    powershell # Assicurarsi che tutti i file necessari siano presenti Get-ChildItem *.ps1 | Select-Object Name

Scelta della modalità operativa: HTTP vs. STDIO

Prima di addentrarci nei dettagli, è importante capire quale delle due modalità operative del server è adatta a te. La scelta dipende da come e da dove intendi inviare i comandi.

  • Modalità HTTP (mcp-powershell-http.ps1): Funziona come un servizio web. Accetta comandi tramite la rete (HTTP) e può essere accessibile da altri computer o da applicazioni web. È un metodo versatile per le integrazioni di rete.
  • Modalità STDIO (mcp-powershell-stdio.ps1): Funziona come un’applicazione da console, gestita da un altro processo. Riceve i comandi tramite il flusso di input standard (Standard Input) e restituisce il risultato tramite il flusso di output standard (Standard Output). Questo metodo è ideale per l’integrazione locale, ad esempio con gemini-cli.

Quando usare la modalità HTTP?

Scegli HTTP se hai bisogno di accessibilità di rete:

  • Gestione remota: L’applicazione client (ad es. uno script Python) si trova su un computer diverso.
  • Integrazione web: Vuoi chiamare PowerShell da un pannello web, inviando richieste con JavaScript.
  • Architettura a microservizi: Diversi servizi nella tua rete devono scambiarsi comandi.
  • Test semplici: Vuoi inviare comandi usando strumenti come curl o Postman.

Scenario chiave: Il client e il server si trovano in rete e comunicano tramite protocolli web standard.

Quando usare la modalità STDIO?

Scegli STDIO per un’integrazione locale e più sicura:

  • Integrazione con Gemini CLI: Questo è lo scenario principale e più comune. gemini-cli avvia mcp-powershell-stdio.ps1 come processo figlio e comunica direttamente con esso.
  • Script wrapper locali: La tua applicazione in un altro linguaggio (ad es. Node.js) avvia il server PowerShell come processo figlio e lo gestisce.
  • Sicurezza migliorata: Questa modalità non apre porte di rete, eliminando un’intera classe di minacce di rete.

Scenario chiave: Il client e il server sono in esecuzione sulla stessa macchina, e il client gestisce il ciclo di vita del server.

Ora che hai deciso la modalità, procedi alla sezione corrispondente qui sotto per istruzioni dettagliate sull’avvio e l’utilizzo.

Modalità STDIO

La modalità STDIO è pensata per l’integrazione con client MCP, come gemini-cli.

Avvio del server STDIO

# Avvio diretto del server (dalla cartella src/servers)
.\mcp-powershell-stdio.ps1

# O dalla directory principale del progetto
.\src\servers\mcp-powershell-stdio.ps1

Caratteristiche della modalità STDIO

  • Protocollo: JSON-RPC tramite i flussi di input/output standard.
  • Logging: Nel file %TEMP%\mcp-powershell-server.log.
  • Codifica: UTF-8 per il corretto funzionamento con caratteri di varie lingue.
  • Compatibilità: Funziona con qualsiasi client MCP.

Test della modalità STDIO

# Avvio del server di test per la verifica (dalla cartella src/servers)
.\test-mcp.ps1

# O dalla directory principale del progetto
.\src\servers\test-mcp.ps1

Esempio di test manuale:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run-script","arguments":{"script":"Get-Date"}}}

Modalità HTTP

La modalità HTTP è pensata per le integrazioni web e le API REST.

Avvio del server HTTP

# Avvio base (localhost:8090) dalla cartella src/servers
.\mcp-powershell-http.ps1

# Avvio su una porta diversa
.\mcp-powershell-http.ps1 -Port 9090

# Avvio su tutte le interfacce di rete
.\mcp-powershell-http.ps1 -ServerHost "0.0.0.0" -Port 8080

# Avvio con un file di configurazione
.\mcp-powershell-http.ps1 -ConfigFile "config.json"

# O dalla directory principale del progetto
.\src\servers\mcp-powershell-http.ps1 -Port 8090

Endpoint dell’API HTTP

Tutte le richieste vengono inviate come POST all’URL principale del server.

URL: http://localhost:8090/
Metodo: POST
Content-Type: application/json

Test della modalità HTTP

# Test con Invoke-RestMethod
$body = @{
    jsonrpc = "2.0"
    id = 1
    method = "tools/list"
} | ConvertTo-Json

Invoke-RestMethod -Uri "http://localhost:8090/" -Method POST -Body $body -ContentType "application/json"
# Test con curl
curl -X POST http://localhost:8090/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Integrazione con Gemini CLI

Configurazione automatica

# Avvio con configurazione automatica di Gemini CLI
.\start-mcp-with-gemini.ps1 -ApiKey "la-tua-chiave-api-gemini"

# Con parametri aggiuntivi
.\start-mcp-with-gemini.ps1 -ApiKey "la-tua-chiave" -ServerPort 9090 -Wait 15

Configurazione manuale

  1. Creazione della configurazione MCP # Creazione della directory di configurazione $configDir = "$env:USERPROFILE\.config\gemini" New-Item -Path $configDir -ItemType Directory -Force # Creazione del file di configurazione MCP $config = @{ mcpServers = @{ powershell = @{ command = "pwsh" args = @("-File", "C:\percorso\a\mcp-powershell-stdio.ps1") env = @{} } } } | ConvertTo-Json -Depth 5 $config | Set-Content "$configDir\mcp_servers.json" -Encoding UTF8
    1. Utilizzo con gemini-cli
    # Modalità interattiva gemini --mcp-config "percorso/a/mcp_servers.json" -i # Richiesta singola gemini --mcp-config "percorso/a/mcp_servers.json" -m gemini-2.5-pro -p "Esegui il comando Get-Process | Select-Object -First 5"

Esempi di utilizzo

Comandi PowerShell di base

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "run-script",
    "arguments": {
      "script": "Get-ComputerInfo | Select-Object WindowsProductName, TotalPhysicalMemory"
    }
  }
}

Lavorare con i file

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "run-script",
    "arguments": {
      "script": "Get-ChildItem C:\\ -Directory | Select-Object Name, CreationTime | Format-Table",
      "workingDirectory": "C:\\",
      "timeoutSeconds": 30
    }
  }
}

Script con parametri

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "run-script",
    "arguments": {
      "script": "param($ProcessName) Get-Process -Name $ProcessName -ErrorAction SilentlyContinue",
      "parameters": {
        "ProcessName": "notepad"
      }
    }
  }
}

Monitoraggio del sistema

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "run-script",
    "arguments": {
      "script": "$cpu = Get-Counter '\\Processor(_Total)\\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; $memory = Get-Counter '\\Memory\\Available MBytes' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; Write-Output \"CPU: $([math]::Round($cpu, 2))%, Available Memory: $memory MB\""
    }
  }
}```

## Configurazione

### File config.json

json
{
“Port”: 8090,
“Host”: “localhost”,
“MaxConcurrentRequests”: 10,
“TimeoutSeconds”: 300,
“LogLevel”: “INFO”,
“AllowedPaths”: [
“C:\Scripts\”,
“C:\Tools\”,
“C:\Temp\”
],
“Security”: {
“EnableScriptValidation”: true,
“BlockDangerousCommands”: true,
“RestrictedCommands”: [
“Remove-Item”,
“Format-Volume”,
“Stop-Computer”,
“Restart-Computer”,
“New-ItemProperty -Path ‘HKLM:‘”, “Remove-ItemProperty -Path ‘HKLM:‘”
],
“AllowedModules”: [
“Microsoft.PowerShell.*”,
“PackageManagement”,
“PowerShellGet”
]
},
“Logging”: {
“LogFile”: “%TEMP%\mcp-powershell-server.log”,
“MaxLogSize”: “10MB”,
“LogRotation”: true
}
}

### Variabili d'ambiente

powershell

Configurazione tramite variabili d’ambiente

$env:MCP_PS_PORT = “8090”
$env:MCP_PS_HOST = “localhost”
$env:MCP_PS_TIMEOUT = “300”
$env:MCP_PS_LOG_LEVEL = “INFO”

## Sicurezza

### Raccomandazioni di sicurezza

1.  **Restrizione dei comandi**
    ```json
    "RestrictedCommands": [
      "Remove-Item",
      "Format-Volume",
      "Stop-Computer",
      "Restart-Computer",
      "Invoke-Expression",
      "iex",
      "& *"
    ]
    ```
2.  **Restrizione dei percorsi**
    ```json
    "AllowedPaths": [
      "C:\\Scripts\\",
      "C:\\Tools\\",
      "C:\\Temp\\"
    ]
    ```
3.  **Restrizioni di rete**
    ```powershell
    # Limitare l'accesso solo al localhost
    .\start-mcp-server.ps1 -ServerHost "127.0.0.1"
    ```
4.  **Timeout**
    ```json
    "TimeoutSeconds": 60  // Limitare il tempo di esecuzione
    ```

### Auditing e monitoraggio

powershell

Monitoraggio dei log in tempo reale

Get-Content “$env:TEMP\mcp-powershell-server.log” -Wait -Tail 10

Analisi dei comandi eseguiti

Select-String -Path “$env:TEMP\mcp-powershell-server.log” -Pattern “Esecuzione dello script PowerShell”

## Estensione delle funzionalità

### Aggiunta di nuovi strumenti MCP

1.  **Struttura dello strumento**
    ```powershell
    # Nella funzione Invoke-MCPMethod, aggiungi un nuovo case
    "my-custom-tool" {
        # Validazione dei parametri
        if (-not $arguments.ContainsKey("required_param")) {
            return New-MCPResponse -Id $Id -Error @{
                code = -32602
                message = "Parametro obbligatorio 'required_param' mancante"
            }
        }

        # Logica di esecuzione
        $result = Invoke-MyCustomFunction -Param $arguments.required_param

        # Restituzione del risultato
        return New-MCPResponse -Id $Id -Result @{
            content = @(
                @{
                    type = "text"
                    text = "Risultato: $result"
                }
            )
        }
    }
    ```
2.  **Registrazione in tools/list**
    ```powershell
    # Aggiungi la descrizione dello strumento al metodo tools/list
    @{
        name = "my-custom-tool"
        description = "Descrizione del mio strumento personalizzato"
        inputSchema = @{
            type = "object"
            properties = @{
                required_param = @{
                    type = "string"
                    description = "Parametro obbligatorio"
                }
            }
            required = @("required_param")
        }
    }
    ```

### Esempio di strumento personalizzato

powershell

Aggiunta di uno strumento per lavorare con il registro di sistema

“registry-query” {
if (-not $arguments.ContainsKey(“path”)) {
return New-MCPResponse -Id $Id -Error @{
code = -32602
message = “Parametro obbligatorio ‘path’ mancante”
}
}

try {
    $regPath = $arguments.path
    $regKey = Get-ItemProperty -Path $regPath -ErrorAction Stop
    $result = $regKey | Format-List | Out-String

    return New-MCPResponse -Id $Id -Result @{
        content = @(
            @{
                type = "text"
                text = "Valori del registro in ${regPath}:`n$result"
            }
        )
    }
}
catch {
    return New-MCPResponse -Id $Id -Error @{
        code = -32603
        message = "Query sul registro fallita: $($_.Exception.Message)"
    }
}

}

## Risoluzione dei problemi

### Comandi di diagnostica

powershell

Verifica della versione di PowerShell

$PSVersionTable.PSVersion

Verifica della disponibilità della porta

Test-NetConnection -ComputerName localhost -Port 8090

Verifica dei log

Get-Content “$env:TEMP\mcp-powershell-server.log” -Tail 50

Verifica dei processi PowerShell

Get-Process -Name pwsh*

### Problemi comuni

1.  **"La porta è già in uso"**
    ```powershell
    # Trovare il processo che utilizza la porta
    Get-NetTCPConnection -LocalPort 8090 | Get-Process

    # O usare una porta diversa
    .\start-mcp-server.ps1 -Port 9090
    ```
2.  **"Accesso negato"**
    ```powershell
    # Eseguire con diritti di amministratore per le porte < 1024
    Start-Process pwsh -Verb RunAs -ArgumentList "-File", "start-mcp-server.ps1"
    ```
3.  **"Problemi di codifica"**
    ```powershell
    # Verifica della codifica della console
    [Console]::OutputEncoding
    [Console]::InputEncoding

    # Impostazione forzata a UTF-8
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    [Console]::InputEncoding = [System.Text.Encoding]::UTF8
    ```
4.  **"Lo script non viene eseguito"**
    ```powershell
    # Verifica della policy di esecuzione
    Get-ExecutionPolicy -List

    # Permesso temporaneo
    powershell.exe -ExecutionPolicy Bypass -File "script.ps1"
    ```

### Debugging

powershell

Abilitazione del logging dettagliato

$DebugPreference = “Continue”

Tracciamento dell’esecuzione degli script

Set-PSDebug -Trace 1

Disattivazione del tracciamento

Set-PSDebug -Off

## Riferimento API

### Metodi MCP

#### initialize

Inizializza il server MCP.

**Richiesta (Request):**

json
{
“jsonrpc”: “2.0”,
“id”: 1,
“method”: “initialize”,
“params”: {
“protocolVersion”: “2024-11-05”
}
}“`

Risposta (Response):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "PowerShell Script Runner",
      "version": "1.0.0",
      "description": "Esegue script PowerShell tramite MCP"
    }
  }
}

tools/list

Ottiene l’elenco degli strumenti disponibili.

Richiesta (Request):

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}```

**Risposta (Response):**

json
{
“jsonrpc”: “2.0”,
“id”: 2,
“result”: {
“tools”: [
{
“name”: “run-script”,
“description”: “Esegue uno script PowerShell con i parametri specificati”,
“inputSchema”: {
“type”: “object”,
“properties”: {
“script”: {
“type”: “string”,
“description”: “Codice PowerShell da eseguire”
},
“parameters”: {
“type”: “object”,
“description”: “Parametri per lo script (opzionale)”
},
“workingDirectory”: {
“type”: “string”,
“description”: “Directory di lavoro per l’esecuzione”
},
“timeoutSeconds”: {
“type”: “integer”,
“description”: “Timeout di esecuzione in secondi”,
“default”: 300,
“minimum”: 1,
“maximum”: 3600
}
},
“required”: [“script”]
}
}
]
}
}

#### tools/call

Esegue uno strumento.

**Richiesta (Request):**

json
{
“jsonrpc”: “2.0”,
“id”: 3,
“method”: “tools/call”,
“params”: {
“name”: “run-script”,
“arguments”: {
“script”: “Get-Date”,
“timeoutSeconds”: 30
}
}
}

**Risposta (Response):**

json
{
“jsonrpc”: “2.0”,
“id”: 3,
“result”: {
“content”: [
{
“type”: “text”,
“text”: “Output del comando:\n\nMartedì 25 settembre 2025 14:30:45\n“
}
],
“isError”: false,
“_meta”: {
“executionTime”: “2025-09-25 14:30:45”,
“success”: true,
“errorCount”: 0,
“warningCount”: 0
}
}
}
“`

Codici di errore

CodiceDescrizione
-32700Parse error – Errore di parsing JSON
-32600Invalid Request – Richiesta non valida
-32601Method not found – Metodo non trovato
-32602Invalid params – Parametri non validi
-32603Internal error – Errore interno del server

Livelli di logging

LivelloDescrizione
DEBUGInformazioni di debug dettagliate
INFOInformazioni generali sul funzionamento
WARNINGAvvisi su potenziali problemi
ERRORErrori che richiedono attenzione

Conclusione

MCP PowerShell Server offre un modo potente e sicuro per integrare PowerShell con assistenti AI e altre applicazioni tramite il protocollo standardizzato MCP. Segui le raccomandazioni di sicurezza e utilizza il logging for monitorare il funzionamento del server.

Leave a Reply

Your email address will not be published. Required fields are marked *