In This Article
1. Overview
mcp-powershell-http.ps1 is a standalone HTTP server written in PowerShell, designed to securely execute PowerShell scripts remotely. It functions as a “bridge” between an external client (e.g., an AI assistant) and the local PowerShell environment, using the JSON-RPC 2.0 protocol for communication.
Key Features:
- Security: Each script is executed in a fully isolated PowerShell instance (
runspace), preventing any impact on the main server environment. - Flexible Configuration: Server parameters (port, host, timeouts) can be configured via command-line arguments and an external JSON file.
- Stability: Comprehensive error handling at all levels (HTTP, JSON, script execution) ensures the server’s reliable operation.
- MCP Protocol: Implements the standard MCP protocol for interaction, including
initialize,tools/list, andtools/callmethods. - Resource Control: Built-in timeouts and output size limits prevent resource abuse.
2. Running and Configuration
Requirements:
- PowerShell 7.0 or higher.
Command-Line Parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
-Port | [int] | The port on which the server will listen for HTTP requests. | 8090 |
-ServerHost | [string] | The host (IP address or domain name) to bind the server to. | localhost |
-ConfigFile | [string] | The path to a configuration file in JSON format. Parameters from this file override defaults and command-line arguments. | $null |
Example Usage:
.\mcp-powershell-http.ps1 -Port 8090 -ServerHost 0.0.0.0 -ConfigFile "C:\config\settings.json"
Configuration File (settings.json):
The server can load its configuration from a JSON file. This is the recommended approach for production environments.
Example settings.json from the 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. Architecture and Functions
The script is logically divided into several regions (#region) to simplify navigation.
Region: Utility Functions
Write-Log- Purpose: Outputs formatted and color-coded messages to the console with a timestamp. This is the primary function for logging.
- Parameters:
$Message[string](mandatory): The message text.$Level[string](optional): The logging level (DEBUG,INFO,WARNING,ERROR). Affects the output color.
Test-MCPRequest- Purpose: Validates if the incoming request meets the basic requirements of the JSON-RPC 2.0 protocol (presence of
jsonrpc: "2.0"andmethodfields). - Parameters:
$Request[hashtable](mandatory): The request, deserialized from JSON.
- Returns:
$trueif the request is valid, otherwise$false.
- Purpose: Validates if the incoming request meets the basic requirements of the JSON-RPC 2.0 protocol (presence of
New-MCPResponse- Purpose: A factory function for creating standardized JSON-RPC response objects.
- Parameters:
$Id[object]: The request identifier.$Result[object]: The object containing a successful result.$Error[hashtable]: The object containing error information.
- Returns: A
[hashtable]with the complete response structure.
Test-ScriptSafety- Purpose: Checks the script for potentially dangerous commands listed in the global
$script:RestrictedCommandsvariable. - Note: In the provided version, this function is disabled by default (
return $true). For production use, it should be enabled and configured. - Parameters:
$Script[string](mandatory): The PowerShell script text to be checked.
- Returns:
$trueif the script is safe, otherwise$false.
- Purpose: Checks the script for potentially dangerous commands listed in the global
Region: Core Logic
Invoke-PowerShellScript- Purpose: The core function responsible for securely executing a PowerShell script.
- Process:
- Creates a new, fully isolated PowerShell instance (
[powershell]::Create()). - (Optional) Sets the working directory within this instance.
- Adds the script text and its parameters to the instance.
- Executes the script asynchronously with a timeout.
- Collects the output (
Output), error (Error), and warning (Warning) streams. - Limits the output size (default 10,000 characters) to prevent large data transfers.
- Cleans up resources (
Dispose()) upon completion.
- Creates a new, fully isolated PowerShell instance (
- Parameters:
$Script[string](mandatory): The code to execute.$Parameters[hashtable]: Parameters to pass to the script.$TimeoutSeconds[int]: Maximum execution time in seconds.$WorkingDirectory[string]: The working directory for the script.
- Returns: A
[hashtable]with the results:success(bool),output(string),errors(array),warnings(array),executionTime(double).
Region: MCP Protocol Methods
Invoke-MCPMethod- Purpose: A dispatcher that handles MCP protocol method calls.
- Process: Uses a
switchstatement on the method name ($Method) to invoke the appropriate logic. - Supported Methods:
"initialize": Returns information about the server."tools/list": Returns a list of available tools (in this case, only"run-script")."tools/call": Handles a tool invocation. It extracts parameters and callsInvoke-PowerShellScriptfor execution.
- Parameters:
$Method[string]: The name of the method to call.$Params[hashtable]: The method’s parameters.$Id[object]: The request identifier.
- Returns: A
[hashtable]representing the complete MCP response, ready to be sent.
Region: HTTP Server
Invoke-RequestHandler- Purpose: Handles the entire lifecycle of a single HTTP request.
- Process:
- Sets up CORS headers.
- Handles
OPTIONSrequests (CORS preflight). - Verifies that the request method is
POST. - Reads and validates the request body.
- Parses the JSON and converts it into a hashtable.
- Calls
Test-MCPRequestfor validation. - Passes the request to
Invoke-MCPMethodfor processing. - Serializes the response back into JSON and sends it to the client.
- Handles all possible errors along the way.
- Parameters:
$Context[System.Net.HttpListenerContext]: The HTTP request context from the .NET listener.
Start-MCPServer- Purpose: The main function that initializes and starts the HTTP listener.
- Process:
- Creates and configures a
System.Net.HttpListenerobject. - Starts the listener with
listener.Start(). - Enters an infinite loop
while ($listener.IsListening)to wait for incoming connections. - For each connection, it calls
Invoke-RequestHandler. - Properly stops the server when the process is terminated.
- Creates and configures a
4. Request Execution Flow
- A client sends a
POSTrequest withContent-Type: application/jsonto the server’s URL. Start-MCPServeraccepts the request and passes it toInvoke-RequestHandler.Invoke-RequestHandlervalidates the HTTP headers, method, and parses the JSON body.- The valid MCP request is passed to
Invoke-MCPMethod. Invoke-MCPMethoddetermines that thetools/callmethod was invoked with therun-scripttool.- The parameters (script, timeout, etc.) are passed to
Invoke-PowerShellScript. Invoke-PowerShellScriptexecutes the script in an isolated environment.- The execution result is returned up the call chain, formatted into a standard JSON-RPC response, and sent back to the client by
Invoke-RequestHandler.
5. Extending Functionality
To add a new “tool” (besides run-script), a developer needs to:
- Add a description of the new tool to the
"tools/list"block in theInvoke-MCPMethodfunction. - Add a new
casebranch for this tool in theswitch ($toolName)statement inside the"tools/call"block ofInvoke-MCPMethod. - Implement the logic for the new tool.