Skip to content
💻 🧠 Code 1001 > ⚡ PowerShell Philosophy > MCP PowerShell Server > Developer Documentation: MCP PowerShell HTTP Server. (mcp-powershell-server-http.py)

Developer Documentation: MCP PowerShell HTTP Server. (mcp-powershell-server-http.py)

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, and tools/call methods.
  • 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:

ParameterTypeDescriptionDefault
-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
  1. 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.
  2. Test-MCPRequest
    • Purpose: Validates if the incoming request meets the basic requirements of the JSON-RPC 2.0 protocol (presence of jsonrpc: "2.0" and method fields).
    • Parameters:
      • $Request [hashtable] (mandatory): The request, deserialized from JSON.
    • Returns: $true if the request is valid, otherwise $false.
  3. 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.
  4. Test-ScriptSafety
    • Purpose: Checks the script for potentially dangerous commands listed in the global $script:RestrictedCommands variable.
    • 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: $true if the script is safe, otherwise $false.
Region: Core Logic
  1. Invoke-PowerShellScript
    • Purpose: The core function responsible for securely executing a PowerShell script.
    • Process:
      1. Creates a new, fully isolated PowerShell instance ([powershell]::Create()).
      2. (Optional) Sets the working directory within this instance.
      3. Adds the script text and its parameters to the instance.
      4. Executes the script asynchronously with a timeout.
      5. Collects the output (Output), error (Error), and warning (Warning) streams.
      6. Limits the output size (default 10,000 characters) to prevent large data transfers.
      7. Cleans up resources (Dispose()) upon completion.
    • 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
  1. Invoke-MCPMethod
    • Purpose: A dispatcher that handles MCP protocol method calls.
    • Process: Uses a switch statement 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 calls Invoke-PowerShellScript for 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
  1. Invoke-RequestHandler
    • Purpose: Handles the entire lifecycle of a single HTTP request.
    • Process:
      1. Sets up CORS headers.
      2. Handles OPTIONS requests (CORS preflight).
      3. Verifies that the request method is POST.
      4. Reads and validates the request body.
      5. Parses the JSON and converts it into a hashtable.
      6. Calls Test-MCPRequest for validation.
      7. Passes the request to Invoke-MCPMethod for processing.
      8. Serializes the response back into JSON and sends it to the client.
      9. Handles all possible errors along the way.
    • Parameters:
      • $Context [System.Net.HttpListenerContext]: The HTTP request context from the .NET listener.
  2. Start-MCPServer
    • Purpose: The main function that initializes and starts the HTTP listener.
    • Process:
      1. Creates and configures a System.Net.HttpListener object.
      2. Starts the listener with listener.Start().
      3. Enters an infinite loop while ($listener.IsListening) to wait for incoming connections.
      4. For each connection, it calls Invoke-RequestHandler.
      5. Properly stops the server when the process is terminated.

4. Request Execution Flow

  1. A client sends a POST request with Content-Type: application/json to the server’s URL.
  2. Start-MCPServer accepts the request and passes it to Invoke-RequestHandler.
  3. Invoke-RequestHandler validates the HTTP headers, method, and parses the JSON body.
  4. The valid MCP request is passed to Invoke-MCPMethod.
  5. Invoke-MCPMethod determines that the tools/call method was invoked with the run-script tool.
  6. The parameters (script, timeout, etc.) are passed to Invoke-PowerShellScript.
  7. Invoke-PowerShellScript executes the script in an isolated environment.
  8. 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:

  1. Add a description of the new tool to the "tools/list" block in the Invoke-MCPMethod function.
  2. Add a new case branch for this tool in the switch ($toolName) statement inside the "tools/call" block of Invoke-MCPMethod.
  3. Implement the logic for the new tool.

Leave a Reply

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