In Questo Articolo
1. Обзор
mcp-powershell-http.ps1 — это автономный HTTP-сервер, написанный на PowerShell, предназначенный для безопасного удаленного выполнения PowerShell-скриптов. Он функционирует как «мост» между внешним клиентом (например, AI-ассистентом) и локальной средой PowerShell, используя для взаимодействия протокол JSON-RPC 2.0.
Ключевые особенности:
- Безопасность: Выполнение каждого скрипта происходит в полностью изолированном экземпляре PowerShell (
runspace), что предотвращает влияние на основную среду сервера. - Гибкая конфигурация: Параметры сервера (порт, хост, таймауты) можно настраивать через аргументы командной строки и внешний JSON-файл.
- Стабильность: Комплексная обработка ошибок на всех уровнях (HTTP, JSON, выполнение скрипта) обеспечивает надежную работу сервера.
- Протокол MCP: Реализует стандартный протокол MCP для взаимодействия, включая методы
initialize,tools/listиtools/call. - Контроль ресурсов: Встроенные таймауты и ограничение размера вывода предотвращают злоупотребление ресурсами.
2. Запуск и Конфигурация
Требования:
- PowerShell 7.0 или выше.
Параметры командной строки:
| Параметр | Тип | Описание | По умолчанию |
|---|---|---|---|
-Port | [int] | Порт, на котором сервер будет прослушивать HTTP-запросы. | 8090 |
-ServerHost | [string] | Хост (IP-адрес или доменное имя) для привязки сервера. | localhost |
-ConfigFile | [string] | Путь к файлу конфигурации в формате JSON. Параметры из этого файла переопределяют значения по умолчанию и параметры командной строки. | $null |
Пример запуска:
.\mcp-powershell-http.ps1 -Port 8090 -ServerHost 0.0.0.0 -ConfigFile "C:\config\settings.json"
Файл конфигурации (settings.json):
Сервер может загружать конфигурацию из JSON-файла. Это рекомендуемый способ для производственных сред.
Пример settings.json из репозитория:
{
"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. Архитектура и Функции
Скрипт логически разделен на несколько регионов (#region), что упрощает навигацию.
Регион: Utility Functions (Вспомогательные функции)
Write-Log- Назначение: Выводит форматированные и окрашенные сообщения в консоль с временной меткой. Основная функция для логирования.
- Параметры:
$Message[string](обязательный): Текст сообщения.$Level[string](необязательный): Уровень логирования (DEBUG,INFO,WARNING,ERROR). Влияет на цвет вывода.
Test-MCPRequest- Назначение: Проверяет, соответствует ли входящий запрос базовым требованиям протокола JSON-RPC 2.0 (наличие полей
jsonrpc: "2.0"иmethod). - Параметры:
$Request[hashtable](обязательный): Запрос, десериализованный из JSON.
- Возвращает:
$true, если запрос валиден, иначе$false.
- Назначение: Проверяет, соответствует ли входящий запрос базовым требованиям протокола JSON-RPC 2.0 (наличие полей
New-MCPResponse- Назначение: Фабричная функция для создания стандартизированных объектов ответа JSON-RPC.
- Параметры:
$Id[object]: Идентификатор запроса.$Result[object]: Объект с успешным результатом.$Error[hashtable]: Объект с информацией об ошибке.
- Возвращает:
[hashtable]с готовой структурой ответа.
Test-ScriptSafety- Назначение: Проверяет скрипт на наличие потенциально опасных команд, перечисленных в глобальной переменной
$script:RestrictedCommands. - Примечание: В представленной версии функция по умолчанию отключена (
return $true). Для производственного использования ее следует активировать и настроить. - Параметры:
$Script[string](обязательный): Текст PowerShell-скрипта для проверки.
- Возвращает:
$true, если скрипт безопасен, иначе$false.
- Назначение: Проверяет скрипт на наличие потенциально опасных команд, перечисленных в глобальной переменной
Регион: Core Logic (Основная логика выполнения)
Invoke-PowerShellScript- Назначение: Ключевая функция, отвечающая за безопасное выполнение PowerShell-скрипта.
- Процесс:
- Создает новый, полностью изолированный экземпляр PowerShell (
[powershell]::Create()). - (Опционально) Устанавливает рабочую директорию внутри этого экземпляра.
- Добавляет в экземпляр текст скрипта и его параметры.
- Запускает выполнение асинхронно с таймаутом.
- Собирает потоки вывода (
Output), ошибок (Error) и предупреждений (Warning). - Ограничивает размер вывода (по умолчанию 10 000 символов), чтобы предотвратить передачу больших объемов данных.
- Очищает ресурсы (
Dispose()) после завершения.
- Создает новый, полностью изолированный экземпляр PowerShell (
- Параметры:
$Script[string](обязательный): Код для выполнения.$Parameters[hashtable]: Параметры для передачи в скрипт.$TimeoutSeconds[int]: Максимальное время выполнения в секундах.$WorkingDirectory[string]: Рабочая директория для скрипта.
- Возвращает:
[hashtable]с результатами:success(bool),output(string),errors(array),warnings(array),executionTime(double).
Регион: MCP Protocol Methods (Методы протокола MCP)
Invoke-MCPMethod- Назначение: Диспетчер, который обрабатывает вызовы методов протокола MCP.
- Процесс: Использует конструкцию
switchпо имени метода ($Method) для вызова соответствующей логики. - Поддерживаемые методы:
"initialize": Возвращает информацию о сервере."tools/list": Возвращает список доступных инструментов (в данном случае, только"run-script")."tools/call": Обрабатывает вызов инструмента. Извлекает параметры и вызываетInvoke-PowerShellScriptдля выполнения.
- Параметры:
$Method[string]: Имя вызываемого метода.$Params[hashtable]: Параметры метода.$Id[object]: Идентификатор запроса.
- Возвращает:
[hashtable]— готовый к отправке MCP-ответ.
Регион: HTTP Server (Логика HTTP-сервера)
Invoke-RequestHandler- Назначение: Обрабатывает полный жизненный цикл одного HTTP-запроса.
- Процесс:
- Настраивает CORS-заголовки.
- Обрабатывает
OPTIONS-запросы (CORS preflight). - Проверяет, что метод запроса —
POST. - Читает и проверяет тело запроса.
- Парсит JSON и преобразует его в хэш-таблицу.
- Вызывает
Test-MCPRequestдля валидации. - Передает запрос в
Invoke-MCPMethodдля обработки. - Сериализует ответ обратно в JSON и отправляет его клиенту.
- Обрабатывает все возможные ошибки на этом пути.
- Параметры:
$Context[System.Net.HttpListenerContext]: Контекст HTTP-запроса от .NET-слушателя.
Start-MCPServer- Назначение: Главная функция, которая инициализирует и запускает HTTP-слушатель.
- Процесс:
- Создает и настраивает объект
System.Net.HttpListener. - Запускает
listener.Start(). - Входит в бесконечный цикл
while ($listener.IsListening), ожидая входящие подключения. - Для каждого подключения вызывает
Invoke-RequestHandler. - Корректно останавливает сервер при завершении процесса.
- Создает и настраивает объект
4. Поток выполнения запроса
- Клиент отправляет
POSTзапрос сContent-Type: application/jsonна URL сервера. Start-MCPServerпринимает запрос и передает его вInvoke-RequestHandler.Invoke-RequestHandlerвалидирует HTTP-заголовки, метод и парсит JSON-тело.- Валидный MCP-запрос передается в
Invoke-MCPMethod. Invoke-MCPMethodопределяет, что вызван методtools/callс инструментомrun-script.- Параметры (скрипт, таймаут и т.д.) передаются в
Invoke-PowerShellScript. Invoke-PowerShellScriptвыполняет скрипт в изолированной среде.- Результат выполнения возвращается по цепочке вызовов, форматируется в стандартный JSON-RPC ответ и отправляется клиенту функцией
Invoke-RequestHandler.
5. Расширение функциональности
Для добавления нового «инструмента» (помимо run-script) разработчику необходимо:
- Добавить описание нового инструмента в блок
"tools/list"функцииInvoke-MCPMethod. - Добавить новую ветку
caseдля этого инструмента вswitch ($toolName)внутри блока"tools/call"вInvoke-MCPMethod. - Реализовать логику для нового инструмента.