Open-source
12 мая 2026 · 11 мин чтения · AI Platforms

ssh-chat-mcp: SSH/SFTP для ИИ-агентов без конфигов и постоянных секретов

MCP-сервер от AI Platforms под лицензией MIT. Временные SSH/SFTP-сессии через чат: модель подключается, выполняет команды и файловые операции, отключается - и секреты стираются из памяти. Без конфигов, без env-переменных, без дискового хранения кредов.

  • MCP
  • SSH
  • SFTP
  • agents
  • security
  • AI Platforms
  • open-source
  • tool-use

Зачем агенту SSH без конфигов

Когда ИИ-агенту нужно не просто ответить текстом, а реально зайти на сервер, проверить состояние, залить файлы, перезапустить сервис и выйти - обычного prompt-а уже недостаточно. Нужен инструментальный слой.

У SSH-автоматизации обычно одна и та же боль: всё завязано на конфиги, inventory-файлы, переменные окружения и сохранённые ключи. Для стабильного production-хоста это иногда нормально. Для агентного сценария - уже нет. LLM-клиент не должен помнить инфраструктуру после окончания чата. MCP-сервер не должен хранить хосты и ключи на диске.

ssh-chat-mcp делает ставку на другой режим: zero-config по-настоящему. Вы запускаете сервер без аргументов. В чате передаёте модели host и креды. Она вызывает connect, работает, вызывает disconnect - и секреты стираются из RAM. Никакого предзаданного конфига, никакого хранения на диске, никакой миграции секретов между сессиями.

Публичный репозиторий: github.com/aiplatforms-ru/ssh-chat-mcp. npm: ssh-chat-mcp.

Ключевые архитектурные решения

In-memory connections

Все соединения хранятся в RAM в Map<string, ConnectionDescriptor>. На disconnect секреты очищаются, объект удаляется - никакого дискового следа.

Redaction выходных данных

Закрываются поля password, passphrase, privateKey, sudoPassword, token, apiKey, Authorization, secret, PEM-блоки и text patterns.

POSIX shell quoting

Каждая cwd/command-интерполяция обёрнута в безопасное quoting. Валидация Linux-username строго по ^[a-z_][a-z0-9_-]{0,31}$.

exec_as через sudo -iu

Привилегированные действия - строго ограниченный путь: sudo -S -p '' -iu <user> -- bash -lc <command>. Пароль через stdin, не в командной строке.

SFTP напрямую, без scp

upload_file, upload_directory, download_file, read_remote_file, write_remote_file - всё через встроенный SFTP, без внешних утилит.

Долгие команды без таймаута

exec_start/exec_as_start возвращают jobId немедленно. exec_status читает stdout/stderr инкрементально. exec_cancel останавливает процесс.

Как устроен сервер: разбор кода

index.ts - MCP stdio и молчание на старте

Сервер регистрирует инструменты MCP, поднимает stdio transport и не пишет ничего в stdout до получения JSON-RPC. Это важная дисциплина: stdout зарезервирован для протокола. Если сервер печатает «добро пожаловать» - он сломан по стандарту MCP.

В CI это тоже закреплено: GitHub Actions гоняет build-and-test на Ubuntu и Windows под Node 20 и 22, а на Linux есть smoke-start, который проверяет, что сервер стартует молча.

connectionManager.ts - жизненный цикл соединения

Все соединения живут в in-memory Map<connectionName, ConnectionDescriptor>. У каждого - статус, metadata и блок secrets. На disconnect секреты не просто забываются логически - на них вызывается очистка, и сам объект удаляется из менеджера.

exec.ts - выполнение команд

  • exec - обычное выполнение с опциональным cwd, обёрнутое в cd <quoted cwd> && <command>.
  • exec_as - запуск через sudo -S -p '' -iu <runAs> -- bash -lc <command>, где runAs строго валидирован.
  • sudoPassword передаётся через stdin и никогда не логируется.
  • Сбор stdout и stderr в буферы, таймаут с принудительным завершением канала.
  • Возврат exitCode и signal.
  • Redaction выходных данных перед отправкой в MCP-клиент.

Долгие команды: exec_start / exec_as_start

Для команд, которые могут превысить tool timeout клиента (деплой, установка пакетов, сборка), используется паттерн start → status:

  • exec_start открывает SSH-канал и немедленно возвращает jobId.
  • exec_status читает stdout/stderr инкрементально через stdoutOffset / stderrOffset.
  • exec_cancel шлёт сигнал удалённой группе процессов и закрывает канал.
  • exec_remove очищает in-memory буферы после завершения.

Это держит MCP-транспорт отзывчивым: первый вызов только открывает канал, логи читаются по jobId позже.

sftp.ts - файловые операции

upload_directory - рекурсивная загрузка с исключениями по basename. Symlink-ы не следуются по умолчанию. Родительские директории создаются только при явном mkdirParents. write_remote_file - удобный способ залить текстовый конфиг в /tmp, а потом sudo mv на место.

redact.ts и shellQuote.ts - сердцевина безопасности

Redaction не декларативный, а практический. В коде и тестах закрываются поля password, passphrase, privateKey, sudoPassword, token, apiKey, Authorization, secret, PEM-блоки и text patterns вроде password= и Authorization: Bearer .... POSIX quoting защищает от shell injection в каждом вызове.

Честные ограничения безопасности

Host-key checking выключен по дизайну - цена zero-config (нет on-disk known_hosts). Ответственность за доверие хосту - на пользователе. Нет blacklist-а деструктивных команд - сервер не песочница, контроль остаётся на стороне MCP-клиента. Пароль или приватный ключ, переданные в чат, видны в транскрипте - предпочитайте локальные и приватные клиенты. Сервер не заменяет Ansible и fleet management; это инструмент для точечных, временных операций.

Сценарии, где это реально нужно

Deploy-агент

Залить проект через upload_directory, собрать, написать systemd-unit, перезапустить сервис и отключиться - полный цикл за один чат-сеанс.

Incident-response агент

Диагностика через exec, чтение логов, правка конфига через write_remote_file, перезапуск сервиса - без ручного захода по SSH.

Infra-ассистент

Поднять новый хост: залить nginx-конфиг в /tmp, перенести sudo mv, проверить nginx -t, reload. Всё через инструменты.

Аудит и проверка

Быстро проверить состояние нового сервера: whoami, hostname, pwd, systemctl status, journalctl, ls, read_remote_file - и уйти.

Привилегированные шаги

exec_as для установки systemd-unit или правки конфигов от root, строго через sudo -iu с валидированным runAs.

Приватный контур

С локальными LLM-клиентами (LM Studio, Claude Code локально) данные и команды не выходят из периметра - идеально для on-premise.

Практическая интеграция в агентный цикл

Типовой рабочий цикл

Самая полезная часть проекта начинается там, где ssh-chat-mcp становится не отдельным инструментом, а частью agent loop:

1. Агент уточняет, на какой хост нужно зайти, под каким пользователем и с каким типом доступа.

2. Вызывает connect - получает временную сессию.

3. Проводит короткую разведку: diagnose, whoami, hostname, pwd, systemctl status, journalctl, ls, read_remote_file.

4. Делает точечное действие: загружает файлы, пишет конфиг, запускает команду, переключается на exec_as.

5. Проверяет результат: тест конфига, статус процесса, повторное чтение логов, smoke-check.

6. Вызывает disconnect - даже если задача завершилась с ошибкой.

Хорошее правило: один хост = один краткий цикл = один disconnect в конце. Не держите соединение дольше, чем нужно.

Конкретные паттерны

Deploy-агент: connectupload_directoryexec (сборка) → exec_as (привилегированный шаг) → read_remote_file (проверка) → disconnect.

Incident-response: connectexec (диагностика) → read_remote_file (логи) → exec_as (правка конфига) → exec (проверка) → disconnect.

Infra-ассистент: залить systemd/nginx/cron-конфиг в /tmp через write_remote_file, потом sudo mv на место и перезагрузить сервис.

Важный момент: агенту не нужно «знать SSH». Ему нужно уметь пользоваться инструментами. ssh-chat-mcp делает этот слой явным и контролируемым. Этот подход мы разбирали в статье ИИ-агенты с tool-use: как модель сама ищет данные и добирает контекст.

Интеграция с MCP-клиентами

Сервер работает с любым stdio MCP-клиентом: Claude Code, Codex, Kilo, LM Studio, Cursor. Регистрация везде одна и та же:

{
  "mcpServers": {
    "ssh-chat": {
      "command": "node",
      "args": ["/absolute/path/to/ssh-chat-mcp/build/index.js"]
    }
  }
}

Больше ничего настраивать не нужно - это осознанная позиция проекта.

Инструменты сервера

ИнструментЧто делаетОсобенности
connect Открыть SSH-сессию host, username, password или privateKey, port, passphrase, keepalive. Креды только в RAM.
disconnect Закрыть SSH+SFTP и стереть креды Секреты очищаются, объект удаляется из менеджера.
list_connections Метаданные активных соединений Не содержит секретов - только статус и нечувствительные поля.
diagnose Локальная MCP/SSH диагностика Без аргументов - проверка живости сервера. С connectionName - SSH probe: ok / ssh_unresponsive / ssh_error.
exec Выполнить shell-команду cwd оборачивается в cd <quoted cwd> && <command>. Возвращает stdout, stderr, exitCode, signal.
exec_as Команда от другого пользователя sudo -S -p '' -iu <runAs> -- bash -lc <command>. runAs валидирован. Пароль через stdin.
exec_start / exec_as_start Долгая команда - немедленный jobId Для деплоя, сборки, установки пакетов. Не блокирует MCP-транспорт.
exec_status Чтение stdout/stderr по jobId Инкрементально через stdoutOffset / stderrOffset.
exec_cancel / exec_remove Остановка / очистка job Сигнал удалённой группе процессов, закрытие канала, очистка буферов.
upload_file / upload_directory SFTP-загрузка Рекурсивно, exclude по basename, symlink-ы не следуются, mkdirParents опционально.
download_file SFTP-скачивание на локальный диск Прямой SFTP, без внешних утилит.
read_remote_file / write_remote_file Чтение/запись текстовых файлов read с redaction и лимитом maxBytes. write - удобно для конфигов в /tmp.

Внедряем агентов с tool-use под ваш контур

ssh-chat-mcp - один из кирпичиков в нашем подходе к агентным системам. Если вам нужен ИИ-агент, который не только советует, но и действует - с RAG, MCP, приватными LLM и on-premise безопасностью - опишите задачу. Предложим архитектуру и план пилота.