pty-mcp
pty-mcp
Сервер MCP (Model Context Protocol), предоставляющий ИИ-агентам интерактивные терминальные сессии — локальные оболочки, SSH, последовательные порты и постоянные удаленные сессии, которые сохраняются при разрыве соединения.
Создан для системных администраторов и сетевых инженеров, которым нужна помощь ИИ в реальном управлении серверами и устройствами, а не просто в генерации кода.

Зачем это нужно
ИИ-агенты запускают команды в неинтерактивных оболочках. Они не могут:
Подключаться по SSH к серверу и взаимодействовать с запущенными процессами
Подключаться к маршрутизаторам или коммутаторам через последовательную консоль
Отслеживать логи и реагировать на возникновение конкретного события
Сохранять состояние сессии между несколькими командами
Ждать перезагрузки сервера и определять момент, когда он снова станет доступен
pty-mcp решает все эти задачи, предоставляя реальные PTY-сессии через MCP.
Без pty-mcp ИИ-агенты вынуждены использовать циклы sleep 30 && check_status, расходуя ресурсы процессора и API-запросы в ожидании событий. С помощью wait_for агент блокируется на стороне сервера до тех пор, пока событие не произойдет. Меньше опросов, меньше энергопотребления, лучше для белых медведей. 🐻❄️
Варианты использования
Администрирование серверов
# Reboot a server and wait until it's back online
create_local_session("ping myserver")
read_output(wait_for: "bytes from", timeout: 300)
→ blocks until server responds after reboot (~80s, one tool call)Управление сетевыми устройствами
# Connect to a router via serial console
create_serial_session(port: "/dev/ttyUSB0", baud: 9600)
send_input("show interfaces status")
read_output(wait_for: "\\$")Мониторинг логов и оповещение
# Watch logs and act when something happens
create_ssh_session(host: "prod", user: "admin")
send_input("tail -f /var/log/app.log")
read_output(wait_for: "ERROR|CRITICAL", timeout: 3600)
→ returns the error line + context when it appearsДлительные задачи, сохраняющиеся при разрыве соединения
create_ssh_session(host: "server", user: "admin", persistent: true)
send_input("apt upgrade -y")
detach_session() → close Claude Code, task continues
# Reconnect later to check resultВозможности
Функция | Описание |
Локальный терминал | Интерактивные сессии bash/python/node на локальной машине |
SSH-сессии | Подключение к удаленным хостам с аутентификацией по ключу/паролю, поддержка SSH config |
Последовательный порт | Подключение к устройствам через последовательный порт (IoT, встраиваемые системы, сетевое оборудование) |
Постоянные сессии | Сессии сохраняются при разрыве SSH-соединения через демон |
Подключение/Отключение | Отключение от запущенной сессии и повторное подключение позже |
Управляющие клавиши | Отправка ctrl+c, ctrl+d, клавиш со стрелками, tab, escape |
Определение стабилизации | Ожидание стабилизации вывода перед возвратом (умный тайм-аут) |
Сопоставление с шаблоном |
|
Ограниченная память | Кольцевой буфер предотвращает нехватку памяти (OOM) в длительных сессиях (v0.2.0) |
Журнал аудита | Опциональный добровольный журнал операций — запись команд |
Архитектура
┌─────────────────────────────────────────────────────┐
│ AI Agent (Claude Code, etc.) │
│ │
│ MCP Tools: create_local_session, send_input, │
│ send_control, read_output, close_session │
└──────────────────────┬──────────────────────────────┘
│ JSON-RPC stdio
┌──────────────────────┴──────────────────────────────┐
│ pty-mcp (MCP Server) │
│ │
│ Session Manager │
│ ├── LocalSession (local PTY via creack/pty) │
│ ├── SSHSession (remote PTY via x/crypto/ssh) │
│ ├── SerialSession (serial port via go.bug.st) │
│ └── RemoteSession (persistent via ai-tmux) │
└─────────────────────────────────────────────────────┘
Persistent mode (ai-tmux):
pty-mcp ──SSH──▶ ai-tmux client ──Unix socket──▶ ai-tmux server (daemon)
├── PTY: bash
├── PTY: ssh admin@router
└── PTY: tail -f /var/log/syslogБыстрый старт
Плагин Claude Code (рекомендуется)
Автоматически устанавливает бинарный файл и регистрирует MCP-сервер:
claude plugin marketplace add raychao-oao/pty-mcp
claude plugin install pty-mcp@pty-mcpПерезапустите Claude Code — бинарный файл загрузится автоматически при запуске сессии, затем перезапустите еще раз для активации. Ручной ввод claude mcp add не требуется.
Обновление:
claude plugin marketplace update pty-mcp
claude plugin update pty-mcp@pty-mcpПерезапустите Claude Code — новый бинарный файл загрузится автоматически при запуске сессии, затем перезапустите еще раз для применения обновления.
Ручная установка
Установка + регистрация одной командой (macOS / Linux / WSL2):
curl -fsSL https://raw.githubusercontent.com/raychao-oao/pty-mcp/main/install.sh | sh
claude mcp add pty-mcp -- /usr/local/bin/pty-mcpПерезапустите Claude Code, и инструменты станут доступны.
Загрузка из GitHub Releases:
Перейдите в Releases, загрузите бинарный файл для вашей платформы и сделайте его исполняемым:
Платформа | Бинарный файл |
macOS (Apple Silicon) |
|
macOS (Intel) |
|
Linux (x86_64) / WSL2 |
|
Linux (ARM64) |
|
chmod +x pty-mcp-*
sudo mv pty-mcp-* /usr/local/bin/pty-mcp
claude mcp add pty-mcp -- /usr/local/bin/pty-mcpСборка из исходного кода (требуется Go 1.25+):
go install github.com/raychao-oao/pty-mcp@latest
claude mcp add pty-mcp -- $(go env GOPATH)/bin/pty-mcpПримечания по WSL2
pty-mcp работает в WSL2 «из коробки». Используйте бинарный файл для Linux:
# Inside WSL2
curl -fsSL https://raw.githubusercontent.com/raychao-oao/pty-mcp/main/install.sh | sh
claude mcp add pty-mcp -- /usr/local/bin/pty-mcpОпционально: Установка ai-tmux на удаленные серверы
Для постоянных сессий, которые сохраняются при разрыве SSH-соединения, установите ai-tmux на удаленный сервер:
# Download for your server's architecture
curl -fsSL https://raw.githubusercontent.com/raychao-oao/pty-mcp/main/install.sh | sh
# Or just copy the binary:
scp /usr/local/bin/ai-tmux your-server:/usr/local/bin/ai-tmuxПримеры использования
После регистрации ИИ-агент может использовать следующие инструменты MCP:
Локальная интерактивная оболочка:
create_local_session() → {session_id, type: "local"}
send_input(session_id, "cd /tmp && ls") → {output: "...", is_complete: true}
send_input(session_id, "python3") → start Python REPL
send_input(session_id, "print('hello')") → {output: "hello\n>>>"}
send_control(session_id, "ctrl+d") → exit Python
close_session(session_id)SSH на удаленный сервер:
create_ssh_session(host: "myserver", user: "admin")
send_input(session_id, "top")
send_control(session_id, "ctrl+c") → stop topОжидание шаблона (v0.2.0):
create_local_session("ping myserver")
read_output(session_id, wait_for: "bytes from", timeout: 300)
→ blocks until server responds or 5 min timeout
send_input(session_id, "docker-compose up")
read_output(session_id, wait_for: "ready|error", timeout: 60, context_lines: 3)
→ returns matched line + 3 lines of contextОтправка секрета / пароля (v0.3.0):
# AI detects a password prompt, calls send_secret instead of handling the password itself
create_ssh_session(host: "router", user: "admin")
read_output(session_id, wait_for: "Password:") → session is waiting for input
send_secret(session_id, prompt: "Router admin password:")
→ native GUI dialog appears on the operator's screen (macOS: system dialog,
WSL2: Windows Get-Credential, Linux: zenity/kdialog)
→ operator types password — it is sent directly to the PTY session
→ AI only sees: {success: true, length: 12}
→ password never appears in AI context or logsПостоянная сессия (сохраняется при разрыве SSH):
create_ssh_session(host: "server", user: "admin", persistent: true)
send_input(session_id, "make build") → start long build
detach_session(session_id) → disconnect, build continues
# Later (even after restart):
list_remote_sessions(host: "server", user: "admin") → see running sessions
create_ssh_session(host: "server", user: "admin", session_id: "abc123") → reattach
send_input(session_id, "echo $?") → check build resultИнструменты MCP
Инструмент | Описание |
| Запуск локального интерактивного терминала (bash, python3, node и т.д.) |
| SSH-подключение к удаленному хосту (поддерживает псевдонимы SSH config) |
| Подключение к устройству через последовательный порт |
| Отправка команды и ожидание стабилизации вывода |
| Чтение вывода, опциональное ожидание шаблона ( |
| Отправка управляющих клавиш (ctrl+c, ctrl+d, стрелки, tab и т.д.) |
| Запрос секрета у оператора через графический диалог; отправка в PTY-сессию без раскрытия в контексте ИИ или логах ¹ |
| Список всех активных сессий |
| Закрытие сессии (завершение удаленного PTY) |
| Отключение с сохранением работы удаленного PTY |
| Список постоянных сессий на удаленном хосте |
¹ Поддержка платформы для
send_secret: macOS использует нативный диалог пароля (osascript). WSL2 используетpowershell.exe Get-Credential(графический диалог Windows). Linux с графическим сервером используетzenityилиkdialog. В безголовом Linux используется/dev/tty.
Журнал аудита
pty-mcp включает опциональную функцию журнала аудита, которая записывает каждую команду send_input в центральный коллектор. Это позволяет командам проверять и отслеживать действия ИИ-агентов во время сессии.
Важно: Это добровольный, самоотчетный журнал операций. Он полагается на то, что операторы решат включить его и запустить коллектор. Поскольку pty-mcp работает на собственной машине оператора, технического механизма принудительного ведения журнала нет — недобросовестный оператор может просто запустить pty-mcp без включенного аудита. Эта функция обеспечивает прослеживаемость для команд, которые хотят этого, но она не является заменой системным инструментам аудита (например, auditd, пересылка syslog, запись SSH-сессий) в средах, где требуется соответствие требованиям аудита.
Что записывается
Временная метка, идентификатор оператора, ID сессии, тип сессии (локальная/ssh/serial), целевой хост
Точный ввод, отправленный через
send_input(включая вводraw=true, например, выбор в меню)Фрагмент вывода (первые 2 КБ) после каждой команды
cmd_id, связывающий команду с ее выводом
send_secret никогда не логируется — секреты, введенные через графический диалог, не появляются в журнале аудита.
Настройка
Каждый оператор запускает один раз для создания конфигурации и генерации токена:
pty-mcp audit initЭто создает файл ~/.config/pty-mcp/config (chmod 600) со случайно сгенерированным токеном и выводит токен для передачи администратору коллектора.
Администратор коллектора запускает сервер (используя токен из вывода init):
PTY_MCP_AUDIT_TOKEN=<token-from-init> \
pty-mcp audit serve --port 9099 --log /var/log/pty-mcp-audit.jsonlВключите аудит после установки URL коллектора в конфигурации:
# Edit config and set: audit-url=http://your-collector:9099
pty-mcp audit enable
# Restart Claude Code to applyЧтобы временно остановить логирование без потери конфигурации:
pty-mcp audit disableОператоры без файла конфигурации не затрагиваются — аудит по умолчанию выключен.
Режимы аудита
Режим | Поведение |
| Команды выполняются независимо от того, был ли записан лог; записи ставятся в очередь и повторяются в фоновом режиме |
|
|
Просмотр логов
Логи хранятся в формате JSONL (один JSON-объект на строку), читаются стандартными инструментами:
# All commands by operator ray
grep '"user":"ray"' /var/log/pty-mcp-audit.jsonl | jq .
# Commands sent to a specific host
jq 'select(.target == "root@prod01")' /var/log/pty-mcp-audit.jsonlai-tmux: Демон постоянного терминала
ai-tmux — это легковесный демон, который работает на удаленных серверах, поддерживая PTY-сессии активными при разрывах SSH-соединения. Думайте о нем как о tmux, разработанном для ИИ-агентов.
Установка на удаленный сервер
# Cross-compile for Linux
GOOS=linux GOARCH=amd64 go build -o ai-tmux-linux ./cmd/ai-tmux/
# Copy to server
scp ai-tmux-linux server:~/ai-tmux
ssh server "chmod +x ~/ai-tmux && sudo mv ~/ai-tmux /usr/local/bin/ai-tmux"Как это работает
ai-tmux server— режим демона, прослушивает Unix-сокет, управляет PTY-сессиямиai-tmux client— режим моста, пересылает JSON-протокол через stdin/stdout (используется pty-mcp через SSH)ai-tmux list— список активных сессий
Демон автоматически запускается, когда pty-mcp подключается с параметром persistent: true. Сессии завершаются после 30 минут бездействия.
Поддержка SSH Config
pty-mcp читает ~/.ssh/config для разрешения псевдонимов хостов:
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519create_ssh_session(host: "myserver", user: "admin")
# Automatically resolves hostname, port, and identity fileТребования
Go 1.25+
Для последовательного порта: соответствующие права доступа к устройству
Для постоянных сессий: бинарный файл
ai-tmuxна удаленном сервере
Журнал изменений
См. CHANGELOG.md для истории версий.
Лицензия
MIT
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/raychao-oao/pty-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server