Description
The MCP PowerShell Server is a server that implements the Model Context Protocol (MCP) for executing PowerShell scripts. The server operates in STDIO mode and provides tools for the secure execution of PowerShell commands through a standardized interface.
Architecture
Main Components
- JSON Converter – A function to convert JSON into PowerShell hashtables.
- Logging – A system for writing events to a file.
- MCP Handler – The core logic for processing MCP requests.
- PowerShell Executor – Isolated execution of scripts.
- STDIO Interface – Communication via standard streams.
File Structure
mcp-powershell-stdio.ps1
├── ConvertFrom-JsonToHashtable # JSON conversion function
├── Write-Log # Logging function
├── Test-MCPRequest # MCP request validation
├── New-MCPResponse # Creation of MCP responses
├── Invoke-PowerShellScript # Execution of PowerShell scripts
├── Invoke-MCPMethod # Processing of MCP methods
├── Send-MCPResponse # Sending responses
├── Start-MCPServer # Main server loop
└── Initialization and startup
Functions
ConvertFrom-JsonToHashtable
function ConvertFrom-JsonToHashtable {
param([string]$Json)
}
Purpose: This function converts a JSON string into PowerShell hashtables for compatibility with PowerShell 5.x.
Parameters:
Json(string) – The JSON string to be converted.
Returns: A hashtable with the converted data.
Features:
- Recursive conversion of nested objects.
- Handling of arrays and collections.
- Compatibility with PowerShell 5.x.
Write-Log
function Write-Log {
param(
[Parameter(Mandatory=$true)]
[string]$Message,
[Parameter(Mandatory=$false)]
[ValidateSet("INFO", "WARNING", "ERROR", "DEBUG")]
[string]$Level = "INFO"
)
}
Purpose: This function writes logs to a file, as stdout is used for MCP communication.
Parameters:
Message(string) – The message to write to the log.Level(string) – The logging level (INFO, WARNING, ERROR, DEBUG).
Features:
- Writes to the file
$env:TEMP\mcp-powershell-server.log. - Timestamps in
yyyy-MM-dd HH:mm:ssformat. - UTF-8 encoding.
Test-MCPRequest
function Test-MCPRequest {
param(
[Parameter(Mandatory=$true)]
[hashtable]$Request
)
}
Purpose: This function validates an MCP request for compliance with the protocol.
Parameters:
Request(hashtable) – The MCP request to validate.
Returns: Boolean – The result of the validation.
Checks:
- Presence of the
jsonrpcfield with the value “2.0”. - Presence of the mandatory
methodfield.
New-MCPResponse
function New-MCPResponse {
param(
[Parameter(Mandatory=$false)]
[object]$Id = $null,
[Parameter(Mandatory=$false)]
[object]$Result = $null,
[Parameter(Mandatory=$false)]
[hashtable]$Error = $null
)
}
Purpose: This function creates a standardized MCP response.
Parameters:
Id(object) – The request identifier.Result(object) – The result of the operation.Error(hashtable) – Information about the error.
Returns: A Hashtable with the MCP response.
Invoke-PowerShellScript
function Invoke-PowerShellScript {
param(
[Parameter(Mandatory=$true)]
[string]$Script,
[Parameter(Mandatory=$false)]
[hashtable]$Parameters = @{},
[Parameter(Mandatory=$false)]
[int]$TimeoutSeconds = 300,
[Parameter(Mandatory=$false)]
[string]$WorkingDirectory = $PWD
)
}
Purpose: This function executes a PowerShell script in an isolated process.
Parameters:
Script(string) – The PowerShell script to execute.Parameters(hashtable) – Parameters for the script.TimeoutSeconds(int) – Execution timeout (default 300 sec).WorkingDirectory(string) – The working directory.
Returns: A Hashtable with the execution results:
success(bool) – The execution status.output(string) – The command’s output.errors(array) – An array of errors.warnings(array) – An array of warnings.
Features:
- Isolation via a separate PowerShell process.
- Timeout support.
- Collection of all output streams (output, error, warning).
- Automatic resource cleanup.
MCP Methods
initialize
Purpose: Initializes the MCP server and exchanges information about capabilities.
Response:
{
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "PowerShell Script Runner",
"version": "1.0.0",
"description": "Executes PowerShell scripts via MCP"
}
}
tools/list
Purpose: Gets the list of available tools.
Response: An array of tools with descriptions of their input parameter schemas.
tools/call
Purpose: Calls a specific tool with parameters.
Parameters:
name(string) – The name of the tool.arguments(object) – Arguments for the tool.
Tools
run-script
Purpose: Executes a PowerShell script with specified parameters.
Input Parameter Schema:
{
"type": "object",
"properties": {
"script": {
"type": "string",
"description": "PowerShell script to execute"
},
"parameters": {
"type": "object",
"description": "Parameters for the script (optional)",
"additionalProperties": true
},
"workingDirectory": {
"type": "string",
"description": "Working directory for execution (optional)",
"default": "<current directory>"
},
"timeoutSeconds": {
"type": "integer",
"description": "Execution timeout in seconds (optional)",
"default": 300,
"minimum": 1,
"maximum": 3600
}
},
"required": ["script"]
}
Response: A structure with the execution results, including:
- Formatted command output.
- Errors (if any).
- Warnings (if any).
- Execution metadata.
Configuration
Encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
The server is configured to work with UTF-8 encoding for correct handling of JSON data.
Logging
- Log File:
$env:TEMP\mcp-powershell-server.log - Encoding: UTF-8
- Levels: INFO, WARNING, ERROR, DEBUG
- Format:
[yyyy-MM-dd HH:mm:ss] [LEVEL] Message
Security
- Script isolation via separate PowerShell processes.
- Timeouts to prevent hanging.
- Validation of all incoming requests.
- Logging of all operations.
Usage
Starting the Server
.\mcp-powershell-stdio.ps1
The server starts in STDIO mode and waits for MCP commands via standard input.
Example MCP Requests
Initialization
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "test-client",
"version": "1.0.0"
}
}
}
List Tools
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
Script Execution
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-Process | Select-Object -First 5 Name, CPU",
"timeoutSeconds": 60
}
}
}
Error Handling
MCP Error Codes
-32700: JSON Parse error-32600: Invalid MCP Request-32601: Method or tool not found-32602: Invalid params-32603: Internal server error
Error Logging
All errors are logged to a file with detailed information:
- Timestamp
- Error level
- Detailed description
- Stack trace (if necessary)
Limitations
- Execution Timeout: Maximum of 3600 seconds (1 hour).
- Process Isolation: Each script runs in a separate process.
- Encoding: UTF-8 only.
- Compatibility: PowerShell 5.x and higher.
Performance
- Minimal overhead for process creation.
- Efficient JSON serialization.
- Automatic resource cleanup.
- Optimized logging.
Scalability
The server is designed to handle one request at a time in synchronous mode. For parallel processing, multiple instances of the server must be run.
Documentation Version: 1.0.0
Creation Date: September 15, 2025