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
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. - Реалізувати логіку для нового інструмента.