Перейти к содержимому
davidka.net > 💻 🧠 Код 1001 > ⚡ Философия PowerShell > MCP сервер на PowerShe > Документация для разработчиков: MCP PowerShell HTTP Server (mcp-powershell-server-http.py)

Документация для разработчиков: MCP PowerShell HTTP Server (mcp-powershell-server-http.py)

  • автор:

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 (Вспомогательные функции)
  1. Write-Log
    • Назначение: Выводит форматированные и окрашенные сообщения в консоль с временной меткой. Основная функция для логирования.
    • Параметры:
      • $Message [string] (обязательный): Текст сообщения.
      • $Level [string] (необязательный): Уровень логирования (DEBUG, INFO, WARNING, ERROR). Влияет на цвет вывода.
  2. Test-MCPRequest
    • Назначение: Проверяет, соответствует ли входящий запрос базовым требованиям протокола JSON-RPC 2.0 (наличие полей jsonrpc: "2.0" и method).
    • Параметры:
      • $Request [hashtable] (обязательный): Запрос, десериализованный из JSON.
    • Возвращает: $true, если запрос валиден, иначе $false.
  3. New-MCPResponse
    • Назначение: Фабричная функция для создания стандартизированных объектов ответа JSON-RPC.
    • Параметры:
      • $Id [object]: Идентификатор запроса.
      • $Result [object]: Объект с успешным результатом.
      • $Error [hashtable]: Объект с информацией об ошибке.
    • Возвращает: [hashtable] с готовой структурой ответа.
  4. Test-ScriptSafety
    • Назначение: Проверяет скрипт на наличие потенциально опасных команд, перечисленных в глобальной переменной $script:RestrictedCommands.
    • Примечание: В представленной версии функция по умолчанию отключена (return $true). Для производственного использования ее следует активировать и настроить.
    • Параметры:
      • $Script [string] (обязательный): Текст PowerShell-скрипта для проверки.
    • Возвращает: $true, если скрипт безопасен, иначе $false.
Регион: Core Logic (Основная логика выполнения)
  1. Invoke-PowerShellScript
    • Назначение: Ключевая функция, отвечающая за безопасное выполнение PowerShell-скрипта.
    • Процесс:
      1. Создает новый, полностью изолированный экземпляр PowerShell ([powershell]::Create()).
      2. (Опционально) Устанавливает рабочую директорию внутри этого экземпляра.
      3. Добавляет в экземпляр текст скрипта и его параметры.
      4. Запускает выполнение асинхронно с таймаутом.
      5. Собирает потоки вывода (Output), ошибок (Error) и предупреждений (Warning).
      6. Ограничивает размер вывода (по умолчанию 10 000 символов), чтобы предотвратить передачу больших объемов данных.
      7. Очищает ресурсы (Dispose()) после завершения.
    • Параметры:
      • $Script [string] (обязательный): Код для выполнения.
      • $Parameters [hashtable]: Параметры для передачи в скрипт.
      • $TimeoutSeconds [int]: Максимальное время выполнения в секундах.
      • $WorkingDirectory [string]: Рабочая директория для скрипта.
    • Возвращает: [hashtable] с результатами: success (bool), output (string), errors (array), warnings (array), executionTime (double).
Регион: MCP Protocol Methods (Методы протокола MCP)
  1. 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-сервера)
  1. Invoke-RequestHandler
    • Назначение: Обрабатывает полный жизненный цикл одного HTTP-запроса.
    • Процесс:
      1. Настраивает CORS-заголовки.
      2. Обрабатывает OPTIONS-запросы (CORS preflight).
      3. Проверяет, что метод запроса — POST.
      4. Читает и проверяет тело запроса.
      5. Парсит JSON и преобразует его в хэш-таблицу.
      6. Вызывает Test-MCPRequest для валидации.
      7. Передает запрос в Invoke-MCPMethod для обработки.
      8. Сериализует ответ обратно в JSON и отправляет его клиенту.
      9. Обрабатывает все возможные ошибки на этом пути.
    • Параметры:
      • $Context [System.Net.HttpListenerContext]: Контекст HTTP-запроса от .NET-слушателя.
  2. Start-MCPServer
    • Назначение: Главная функция, которая инициализирует и запускает HTTP-слушатель.
    • Процесс:
      1. Создает и настраивает объект System.Net.HttpListener.
      2. Запускает listener.Start().
      3. Входит в бесконечный цикл while ($listener.IsListening), ожидая входящие подключения.
      4. Для каждого подключения вызывает Invoke-RequestHandler.
      5. Корректно останавливает сервер при завершении процесса.

4. Поток выполнения запроса

  1. Клиент отправляет POST запрос с Content-Type: application/json на URL сервера.
  2. Start-MCPServer принимает запрос и передает его в Invoke-RequestHandler.
  3. Invoke-RequestHandler валидирует HTTP-заголовки, метод и парсит JSON-тело.
  4. Валидный MCP-запрос передается в Invoke-MCPMethod.
  5. Invoke-MCPMethod определяет, что вызван метод tools/call с инструментом run-script.
  6. Параметры (скрипт, таймаут и т.д.) передаются в Invoke-PowerShellScript.
  7. Invoke-PowerShellScript выполняет скрипт в изолированной среде.
  8. Результат выполнения возвращается по цепочке вызовов, форматируется в стандартный JSON-RPC ответ и отправляется клиенту функцией Invoke-RequestHandler.

5. Расширение функциональности

Для добавления нового «инструмента» (помимо run-script) разработчику необходимо:

  1. Добавить описание нового инструмента в блок "tools/list" функции Invoke-MCPMethod.
  2. Добавить новую ветку case для этого инструмента в switch ($toolName) внутри блока "tools/call" в Invoke-MCPMethod.
  3. Реализовать логику для нового инструмента.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *