pty-mcp
pty-mcp
AIエージェントにインタラクティブなターミナルセッション(ローカルシェル、SSH、シリアルポート、切断後も維持される永続的なリモートセッション)を提供するMCP(Model Context Protocol)サーバーです。
単なるコード生成ではなく、実際のサーバーやデバイス管理をAIに支援させたいシステム管理者やネットワークエンジニアのために構築されました。

なぜ必要なのか
AIエージェントは非インタラクティブなシェルでコマンドを実行します。そのため、以下のようなことができません。
サーバーにSSH接続し、実行中のプロセスと対話する
シリアルコンソール経由でルーターやスイッチに接続する
ログを監視し、特定のイベントが発生したときに反応する
複数のコマンド間でセッション状態を保持する
サーバーの再起動を待ち、復旧したことを検知する
pty-mcpは、MCP上で実際のPTYセッションを提供することで、これらすべてを解決します。
pty-mcpがない場合、AIエージェントは sleep 30 && check_status のようなループに頼ることになり、CPUサイクルと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設定サポートを使用してリモートホストに接続 |
シリアルポート | シリアル経由でデバイス(IoT、組み込み、ネットワーク機器)に接続 |
永続セッション |
|
アタッチ/デタッチ | 実行中のセッションからデタッチし、後で再接続 |
制御キー | 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-mcpClaude Codeを再起動してください。セッション開始時にバイナリが自動ダウンロードされます。その後、もう一度再起動して有効化してください。手動での claude mcp add は不要です。
アップデート:
claude plugin marketplace update pty-mcp
claude plugin update pty-mcp@pty-mcpClaude 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-mcpClaude 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-mcpWSL2に関する注意点
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使用例
登録が完了すると、AIエージェントは以下の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 resultMCPツール
ツール | 説明 |
| ローカルインタラクティブターミナル(bash, python3, node等)を開始 |
| リモートホストへSSH接続(SSH設定のエイリアスをサポート) |
| シリアルポートデバイスへ接続 |
| コマンドを送信し、出力が安定するまで待機 |
| 出力を読み取る。オプションでパターン待機が可能( |
| 制御キーを送信(ctrl+c, ctrl+d, 矢印, tab等) |
| GUIダイアログを通じてオペレーターにシークレットの入力を促す。AIコンテキストやログにさらすことなくPTYセッションへ送信 ¹ |
| アクティブなセッションを一覧表示 |
| セッションを閉じる(リモートPTYを終了) |
| 切断するが、リモートPTYは実行し続ける |
| リモートホスト上の永続セッションを一覧表示 |
¹
send_secretのプラットフォームサポート: macOSはネイティブのパスワードダイアログ(osascript)を使用します。WSL2はpowershell.exe Get-Credential(Windows GUIダイアログ)を使用します。ディスプレイサーバーを備えたLinuxはzenityまたはkdialogを使用します。ヘッドレスLinuxは/dev/ttyにフォールバックします。
監査ログ
pty-mcpには、すべての send_input コマンドを中央コレクターに記録するオプションの監査ログ機能が含まれています。これにより、チームはセッション中にAIエージェントが何を行ったかをレビューおよび追跡できます。
重要: これは任意かつ自己申告型の操作ログです。オペレーターが有効化し、コレクターを実行することを選択する必要があります。pty-mcpはオペレーター自身のマシン上で動作するため、ログを強制する技術的なメカニズムはありません。準拠していないオペレーターは、監査を有効にせずにpty-mcpを実行できてしまいます。この機能は、それを望むチームに追跡可能性を提供しますが、監査コンプライアンスが求められる環境において、システムレベルの監査ツール(auditd、syslog転送、SSHセッション記録など)の代わりにはなりません。
記録される内容
タイムスタンプ、オペレーターID、セッションID、セッションタイプ(ローカル/ssh/シリアル)、ターゲットホスト
send_inputを介して送信された正確な入力(メニュー選択などのraw=true入力を含む)各コマンド後の出力スニペット(最初の2 KB)
コマンドと出力を紐付ける
cmd_id
send_secret は決してログに記録されません。GUIダイアログ経由で入力されたシークレットは監査ログには表示されません。
セットアップ
各オペレーターが一度だけ実行して設定を作成し、トークンを生成します:
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(1行につき1つの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 はリモートサーバー上で動作する軽量なデーモンで、SSH切断後もPTYセッションを維持します。AIエージェントのために設計された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— ブリッジモード。stdin/stdout経由でJSONプロトコルを転送します(SSH経由でpty-mcpが使用)ai-tmux list— アクティブなセッションを一覧表示
pty-mcpが persistent: true で接続すると、デーモンが自動起動します。セッションは30分間非アクティブになると終了します。
SSH設定のサポート
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