Встановлення та налаштування
Попередні вимоги
- PowerShell 7.0+
# Перевірка версії PowerShell $PSVersionTable.PSVersion # Встановлення PowerShell 7 (за потреби) # Завантажте з https://github.com/PowerShell/PowerShell - Права доступу
- Для портів < 1024 потрібні права адміністратора.
- Права на виконання скриптів PowerShell.
- Налаштування політики виконання
# Перевірка поточної політики Get-ExecutionPolicy # Встановлення політики для дозволу виконання скриптів Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Початкове налаштування
- Навігація до директорії серверів
# Перехід до кореня модуля cd C:\powershell\modules\mcp-powershell-server # Перехід до серверів cd src\servers - Перевірка файлів
powershell # Переконайтеся, що всі необхідні файли присутні Get-ChildItem *.ps1 | Select-Object Name
Вибір режиму роботи: HTTP vs. STDIO
Перед тим, як занурюватися в деталі, важливо зрозуміти, який із двох режимів роботи сервера вам підходить. Вибір залежить від того, як і звідки ви плануєте надсилати команди.
- Режим HTTP (
mcp-powershell-http.ps1): Працює як веб-сервіс. Він приймає команди через мережу (HTTP) і може бути доступний з інших комп’ютерів або з веб-додатків. Це універсальний спосіб для мережевих інтеграцій. - Режим STDIO (
mcp-powershell-stdio.ps1): Працює як консольний додаток, керований іншим процесом. Він отримує команди через стандартний потік вводу (Standard Input) і віддає результат через стандартний потік виводу (Standard Output). Цей спосіб ідеальний для локальної інтеграції, наприклад, зgemini-cli.
Коли використовувати режим HTTP?
Обирайте HTTP, якщо вам потрібна мережева доступність:
- Віддалене керування: Клієнтський додаток (наприклад, скрипт на Python) знаходиться на іншому комп’ютері.
- Веб-інтеграція: Ви хочете викликати PowerShell з веб-панелі, надсилаючи запити за допомогою JavaScript.
- Мікросервісна архітектура: Різні сервіси у вашій мережі повинні обмінюватися командами.
- Просте тестування: Ви хочете надсилати команди за допомогою інструментів на кшталт
curlабо Postman.
Ключовий сценарій: Клієнт та сервер знаходяться в мережі та спілкуються за стандартними веб-протоколами.
Коли використовувати режим STDIO?
Обирайте STDIO для локальної та більш безпечної інтеграції:
- Інтеграція з Gemini CLI: Це основний і найчастіший сценарій.
gemini-cliсам запускаєmcp-powershell-stdio.ps1як дочірній процес і спілкується з ним напряму. - Локальні скрипти-обгортки: Ваш додаток іншою мовою (наприклад, Node.js) запускає сервер PowerShell як дочірній процес і керує ним.
- Підвищена безпека: Цей режим не відкриває мережеві порти, що виключає цілий клас мережевих загроз.
Ключовий сценарій: Клієнт та сервер працюють на одній машині, і клієнт сам керує життєвим циклом сервера.
Тепер, коли ви визначилися з режимом, переходьте до відповідного розділу нижче для отримання детальних інструкцій із запуску та використання.
Режим STDIO
Режим STDIO призначений для інтеграції з MCP-клієнтами, такими як gemini-cli.
Запуск STDIO сервера
# Прямий запуск сервера (з папки src/servers)
.\mcp-powershell-stdio.ps1
# Або з кореня проєкту
.\src\servers\mcp-powershell-stdio.ps1
Особливості режиму STDIO
- Протокол: JSON-RPC через стандартні потоки вводу-виводу
- Логування: У файл
%TEMP%\mcp-powershell-server.log - Кодування: UTF-8 для коректної роботи з українськими символами
- Сумісність: Працює з будь-якими MCP-клієнтами
Тестування режиму STDIO
# Запуск тестового сервера для перевірки (з папки src/servers)
.\test-mcp.ps1
# Або з кореня проєкту
.\src\servers\test-mcp.ps1
Приклад ручного тестування:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run-script","arguments":{"script":"Get-Date"}}}
Режим HTTP
Режим HTTP призначений для веб-інтеграцій та REST API.
Запуск HTTP сервера
# Базовий запуск (localhost:8090) з папки src/servers
.\mcp-powershell-http.ps1
# Запуск на іншому порту
.\mcp-powershell-http.ps1 -Port 9090
# Запуск на всіх інтерфейсах
.\mcp-powershell-http.ps1 -ServerHost "0.0.0.0" -Port 8080
# Запуск із конфігураційним файлом
.\mcp-powershell-http.ps1 -ConfigFile "config.json"
# Або з кореня проєкту
.\src\servers\mcp-powershell-http.ps1 -Port 8090
HTTP API ендпоінти
Усі запити надсилаються як POST на кореневий URL сервера.
URL: http://localhost:8090/
Method: POST
Content-Type: application/json
Тестування режиму HTTP
# Тест за допомогою Invoke-RestMethod
$body = @{
jsonrpc = "2.0"
id = 1
method = "tools/list"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:8090/" -Method POST -Body $body -ContentType "application/json"
# Тест за допомогою curl
curl -X POST http://localhost:8090/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Інтеграція з Gemini CLI
Автоматичне налаштування
# Запуск з автоматичним налаштуванням Gemini CLI
.\start-mcp-with-gemini.ps1 -ApiKey "your-gemini-api-key"
# З додатковими параметрами
.\start-mcp-with-gemini.ps1 -ApiKey "your-key" -ServerPort 9090 -Wait 15
Ручне налаштування
- Створення конфігурації MCP
# Створення директорії конфігурації $configDir = "$env:USERPROFILE\.config\gemini" New-Item -Path $configDir -ItemType Directory -Force # Створення файлу конфігурації MCP $config = @{ mcpServers = @{ powershell = @{ command = "pwsh" args = @("-File", "C:\path\to\mcp-powershell-stdio.ps1") env = @{} } } } | ConvertTo-Json -Depth 5 $config | Set-Content "$configDir\mcp_servers.json" -Encoding UTF8 - Використання з gemini-cli
# Інтерактивний режим gemini --mcp-config "path/to/mcp_servers.json" -i # Одиночний запит gemini --mcp-config "path/to/mcp_servers.json" -m gemini-2.5-pro -p "Виконай команду Get-Process | Select-Object -First 5"
Приклади використання
Базові команди PowerShell
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-ComputerInfo | Select-Object WindowsProductName, TotalPhysicalMemory"
}
}
}
Робота з файлами
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-ChildItem C:\\ -Directory | Select-Object Name, CreationTime | Format-Table",
"workingDirectory": "C:\\",
"timeoutSeconds": 30
}
}
}
Скрипти з параметрами
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "param($ProcessName) Get-Process -Name $ProcessName -ErrorAction SilentlyContinue",
"parameters": {
"ProcessName": "notepad"
}
}
}
}
Системний моніторинг
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "$cpu = Get-Counter '\\Processor(_Total)\\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; $memory = Get-Counter '\\Memory\\Available MBytes' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; Write-Output \"CPU: $([math]::Round($cpu, 2))%, Available Memory: $memory MB\""
}
}
}
Конфігурація
Файл config.json
{
"Port": 8090,
"Host": "localhost",
"MaxConcurrentRequests": 10,
"TimeoutSeconds": 300,
"LogLevel": "INFO",
"AllowedPaths": [
"C:\\Scripts\\",
"C:\\Tools\\",
"C:\\Temp\\"
],
"Security": {
"EnableScriptValidation": true,
"BlockDangerousCommands": true,
"RestrictedCommands": [
"Remove-Item",
"Format-Volume",
"Stop-Computer",
"Restart-Computer",
"New-ItemProperty -Path 'HKLM:*'",
"Remove-ItemProperty -Path 'HKLM:*'"
],
"AllowedModules": [
"Microsoft.PowerShell.*",
"PackageManagement",
"PowerShellGet"
]
},
"Logging": {
"LogFile": "%TEMP%\\mcp-powershell-server.log",
"MaxLogSize": "10MB",
"LogRotation": true
}
}
Змінні середовища
# Налаштування через змінні середовища
$env:MCP_PS_PORT = "8090"
$env:MCP_PS_HOST = "localhost"
$env:MCP_PS_TIMEOUT = "300"
$env:MCP_PS_LOG_LEVEL = "INFO"
Безпека
Рекомендації з безпеки
- Обмеження команд
json "RestrictedCommands": [ "Remove-Item", "Format-Volume", "Stop-Computer", "Restart-Computer", "Invoke-Expression", "iex", "& *" ] - Обмеження шляхів
json "AllowedPaths": [ "C:\\Scripts\\", "C:\\Tools\\", "C:\\Temp\\" ] - Мережеві обмеження
powershell # Обмеження доступу лише локальному хосту .\start-mcp-server.ps1 -ServerHost "127.0.0.1" - Тайм-аути
json "TimeoutSeconds": 60 // Обмеження часу виконання
Аудит та моніторинг
# Моніторинг логів у реальному часі
Get-Content "$env:TEMP\mcp-powershell-server.log" -Wait -Tail 10
# Аналіз виконаних команд
Select-String -Path "$env:TEMP\mcp-powershell-server.log" -Pattern "Виконання PowerShell скрипта"
Розширення функціональності
Додавання нових інструментів MCP
- Структура інструмента
# У функції Invoke-MCPMethod додайте новий case "my-custom-tool" { # Валідація параметрів if (-not $arguments.ContainsKey("required_param")) { return New-MCPResponse -Id $Id -Error @{ code = -32602 message = "Відсутній обов'язковий параметр 'required_param'" } }# Логіка виконання $result = Invoke-MyCustomFunction -Param $arguments.required_param # Повернення результату return New-MCPResponse -Id $Id -Result @{ content = @( @{ type = "text" text = "Результат: $result" } ) }} - Реєстрація в tools/list
powershell # Додайте опис інструмента в метод tools/list @{ name = "my-custom-tool" description = "Опис мого інструмента" inputSchema = @{ type = "object" properties = @{ required_param = @{ type = "string" description = "Обов'язковий параметр" } } required = @("required_param") } }
Приклад кастомного інструмента
# Додавання інструмента для роботи з реєстром
"registry-query" {
if (-not $arguments.ContainsKey("path")) {
return New-MCPResponse -Id $Id -Error @{
code = -32602
message = "Відсутній обов'язковий параметр 'path'"
}
}
try {
$regPath = $arguments.path
$regKey = Get-ItemProperty -Path $regPath -ErrorAction Stop
$result = $regKey | Format-List | Out-String
return New-MCPResponse -Id $Id -Result @{
content = @(
@{
type = "text"
text = "Значення реєстру за шляхом ${regPath}:`n$result"
}
)
}
}
catch {
return New-MCPResponse -Id $Id -Error @{
code = -32603
message = "Помилка запиту до реєстру: $($_.Exception.Message)"
}
}
}
Вирішення проблем
Діагностичні команди
# Перевірка версії PowerShell
$PSVersionTable.PSVersion
# Перевірка доступності порту
Test-NetConnection -ComputerName localhost -Port 8090
# Перевірка логів
Get-Content "$env:TEMP\mcp-powershell-server.log" -Tail 50
# Перевірка процесів PowerShell
Get-Process -Name pwsh*
Поширені проблеми
- “Порт уже використовується”
# Знайти процес, що використовує порт Get-NetTCPConnection -LocalPort 8090 | Get-Process # Або використати інший порт .\start-mcp-server.ps1 -Port 9090- “Доступ заборонено”
# Запуск із правами адміністратора для портів < 1024 Start-Process pwsh -Verb RunAs -ArgumentList "-File", "start-mcp-server.ps1" - “Проблеми з кодуванням”
# Перевірка кодування консолі [Console]::OutputEncoding [Console]::InputEncoding # Примусове встановлення UTF-8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::InputEncoding = [System.Text.Encoding]::UTF8 - “Скрипт не виконується”
# Перевірка політики виконання Get-ExecutionPolicy -List # Тимчасовий дозвіл powershell.exe -ExecutionPolicy Bypass -File "script.ps1"
Відлагодження (Debugging)
# Увімкнення детального логування
$DebugPreference = "Continue"
# Трасування виконання скриптів
Set-PSDebug -Trace 1
# Вимкнення трасування
Set-PSDebug -Off
API Reference
Методи MCP
initialize
Ініціалізація MCP сервера.
Запит (Request):
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05"
}
}
Відповідь (Response):
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "PowerShell Script Runner",
"version": "1.0.0",
"description": "Виконує PowerShell скрипти через MCP"
}
}
}
tools/list
Отримання списку доступних інструментів.
Запит (Request):
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
Відповідь (Response):
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "run-script",
"description": "Виконує PowerShell скрипт із заданими параметрами",
"inputSchema": {
"type": "object",
"properties": {
"script": {
"type": "string",
"description": "PowerShell код для виконання"
},
"parameters": {
"type": "object",
"description": "Параметри для скрипта (опціонально)"
},
"workingDirectory": {
"type": "string",
"description": "Робоча директорія для виконання"
},
"timeoutSeconds": {
"type": "integer",
"description": "Тайм-аут виконання в секундах",
"default": 300,
"minimum": 1,
"maximum": 3600
}
},
"required": ["script"]
}
}
]
}
}
tools/call
Виконання інструмента.
Запит (Request):
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-Date",
"timeoutSeconds": 30
}
}
}
Відповідь (Response):json { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "Вивід команди:\n\nВівторок, 25 вересня 2025 р. 14:30:45\n" } ], "isError": false, "_meta": { "executionTime": "2025-09-25 14:30:45", "success": true, "errorCount": 0, "warningCount": 0 } } }
Коди помилок
| Код | Опис |
|---|---|
| -32700 | Parse error – Помилка парсингу JSON |
| -32600 | Invalid Request – Неправильний запит |
| -32601 | Method not found – Метод не знайдено |
| -32602 | Invalid params – Неправильні параметри |
| -32603 | Internal error – Внутрішня помилка сервера |
Рівні логування
| Рівень | Опис |
|---|---|
| DEBUG | Детальна відлагоджувальна інформація |
| INFO | Загальна інформація про роботу |
| WARNING | Попередження про потенційні проблеми |
| ERROR | Помилки, що потребують уваги |
Висновок
MCP PowerShell Server надає потужний та безпечний спосіб інтеграції PowerShell з ШІ-асистентами та іншими додатками через стандартизований протокол MCP. Дотримуйтесь рекомендацій з безпеки та використовуйте логування для моніторингу роботи сервера.