pty-mcp について
pty-mcpは、AIエージェントにローカルシェル、SSHホスト、シリアル機器、永続的なリモートタスクの対話型ターミナルを提供するMCPサーバーです。サーバーや機器を管理するシステム管理者とネットワークエンジニアを対象としています。
主な機能
- 01対話型ローカルシェルセッション
- 02SSHとシリアル接続
- 03永続的なリモートセッション
- 04出力パターンの待機
- 05ターミナル制御キーの送信
- 06任意の秘匿処理付き監査ログ
活用シーン
- 01サーバーを再起動して応答を待つ
- 02シリアル経由でルーターにコマンドを実行
- 03ログ内の該当イベントを監視
- 04長時間のリモートタスクから切り離す
MCP 対応
ローカル、SSH、シリアル、永続ターミナルセッションの作成・管理ツールを提供します。入力や制御キーの送信、出力の読み取り、パターン待機にも対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
pty-mcp
AI エージェントにインタラクティブなターミナルセッションを提供する MCP(Model Context Protocol)サーバーです。ローカルシェル、SSH、シリアルポート、および切断後も維持される永続的なリモートセッションを利用できます。
コード生成だけでなく、実際のサーバーやデバイスの管理を 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、組み込み機器、ネットワーク機器) |
| 永続セッション | ai-tmux デーモンにより、SSH 切断後もセッションを維持 |
| アタッチ/デタッチ | 実行中のセッションからデタッチし、後から再接続 |
| 制御キー | ctrl+c、ctrl+d、矢印キー、tab、escape を送信 |
| 出力安定検知 | 出力が安定してから返す(スマートタイムアウト) |
| パターンマッチング | 出力に正規表現パターンが現れるまで wait_for で待機(v0.2.0) |
| メモリ使用量の上限 | リングバッファにより、長時間実行セッションでの OOM を防止(v0.2.0) |
| ターミナルのリサイズ | ローカル、SSH、シリアル、永続的なリモートセッションで PTY ウィンドウをリサイズ(v0.10.0) |
| 監査ログ | 任意で記録する操作ログ。確認と追跡のため、send_input コマンドを収集先に記録(v0.8.0) |
| 監査ログの秘匿化 | 監査ログへの書き込み前に、認証情報、認証ヘッダー、PEM キーを自動的に除去(v0.10.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) | pty-mcp-darwin-arm64 |
| macOS(Intel) | pty-mcp-darwin-amd64 |
| Linux(x86_64)/WSL2 | pty-mcp-linux-amd64 |
| Linux(ARM64) | pty-mcp-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
使用例
登録すると、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 result
MCP ツール
| ツール | 説明 |
|---|---|
create_local_session | ローカルの対話型ターミナル(bash、python3、node など)を起動します |
create_ssh_session | リモートホストに SSH 接続します(SSH 設定のエイリアスに対応) |
create_serial_session | シリアルポートデバイスに接続します |
send_input | コマンドを送信し、出力が落ち着くまで待機します |
read_output | 出力を読み取ります。必要に応じてパターンの待機にも対応します(wait_for、timeout、context_lines、tail_lines) |
send_control | 制御キー(ctrl+c、ctrl+d、矢印キー、tab など)を送信します |
send_secret | GUI ダイアログで人間のオペレーターにシークレットの入力を求めます。AI コンテキストやログに露出させずに、PTY セッションへ送信します ¹ |
list_sessions | アクティブなセッションをすべて一覧表示します |
close_session | セッションを閉じます(リモート PTY を終了します) |
detach_session | 切断しますが、リモート PTY は実行したままにします |
resize_session | すべてのセッション種別で、ターミナルウィンドウのサイズ(行/列)を変更します |
list_remote_sessions | リモートホスト上の永続セッションを一覧表示します |
¹
send_secretのプラットフォーム対応状況:macOS ではネイティブのパスワードダイアログ(osascript)を使用します。WSL2 ではpowershell.exe Get-Credential(Windows GUI ダイアログ)を使用します。ディスプレイサーバーがある Linux ではzenityまたはkdialogを使用します。ヘッドレス Linux では/dev/ttyにフォールバックします。macOS/Linux では、オペレーターが 60 秒以内に応答しない場合、ダイアログが閉じられ、別のダイアログに切り替わったり再度待機したりする代わりに、呼び出しはタイムアウトエラーを返します。呼び出しをキャンセルした場合(例:Claude Code で ESC キーを押す)、同様にダイアログはただちに閉じられます。例外は WSL2 です。ダイアログにタイムアウトはなく、キャンセル時を含め、強制終了されることはありません。Windows GUI ウィンドウを開いている WSL 相互運用で起動されたプロセスを終了させると、ホスト側のターミナルがオペレーターによって閉じられるまでフリーズし(入力、スクロール、選択に応答しなくなり)、そのターミナルを閉じる以外に復旧する方法がないことが判明したためです。ダイアログはオペレーターが回答するか、自分で[キャンセル]をクリックするまで待機し、通常どおり終了します。
監査ログ
pty-mcp には、すべての send_input コマンドを中央のコレクターに記録する、オプションの監査ログ機能が含まれています。これにより、チームはセッション中に AI エージェントが行った操作を確認し、追跡できます。
重要:これは任意の自己申告型操作ログです。オペレーターが有効化を選択し、コレクターを実行することが前提です。pty-mcp はオペレーター自身のマシン上で動作するため、ログ記録を強制する技術的な仕組みはありません。規則を守らないオペレーターは、監査を有効にせずに pty-mcp を実行できます。この機能は、ログによる追跡を希望するチームに追跡可能性を提供しますが、監査コンプライアンスが求められる環境において、システムレベルの監査ツール(例:auditd、syslog 転送、SSH セッション記録)の代わりにはなりません。
記録される内容
- タイムスタンプ、オペレーターの識別情報、セッション ID、セッション種別(local/ssh/serial)、接続先ホスト
send_input経由で送信された正確な入力(メニュー選択などのraw=true入力を含む)- 各コマンド実行後の出力スニペット(最初の 2 KB)
- コマンドとその出力を関連付ける
cmd_id
send_secret は決して記録されません。GUI ダイアログから入力されたシークレットは監査ログに表示されません。
コマンドと出力スニペットは、書き込まれる前に自動的にマスキングされます。次のパターンは [REDACTED] または [PRIVATE KEY REDACTED] に置き換えられます。
- キーと値形式の認証情報:
password=、passwd:、token=、api_key=、access_key=、auth_token=、secret= - HTTP Authorization ヘッダー:
Authorization: Bearer …、Authorization: Basic …、Authorization: Token … - PEM 形式の秘密鍵ブロック:
-----BEGIN RSA PRIVATE KEY-----/-----BEGIN OPENSSH PRIVATE KEY-----
セットアップ
各オペレーターは一度だけ実行し、設定を作成してトークンを生成します。
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
設定ファイルのないオペレーターには影響しません。監査はデフォルトでオフです。
監査モード
| モード | 動作 |
|---|---|
best-effort(デフォルト) | ログが書き込まれたかどうかにかかわらずコマンドを実行します。エントリーはキューに登録され、バックグラウンドで再試行されます |
strict | 監査エントリーを配信できない場合、send_input は拒否されます。ロギングがチームのポリシー要件である場合に使用してください |
ログの確認
ログは JSONL(1 行につき JSON オブジェクト 1 つ)として保存され、標準的なツールで読み取れます。
# 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.jsonl
ai-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— ブリッジモード。JSON プロトコルを標準入力/標準出力経由で転送します(SSH 経由で pty-mcp が使用)ai-tmux list— アクティブなセッションを一覧表示します
pty-mcp が persistent: true で接続すると、デーモンが自動的に起動します。セッションは、30 分間操作がないと終了します。
pty-mcp はセッションを開く前にリモートホストで ai-tmux --version を確認し、バイナリが見つからない場合や必要な最小バージョンを下回っている場合は、明確なエラーを返します。原因不明の接続エラーにはなりません。
SSH 設定のサポート
pty-mcp は ~/.ssh/config を読み込み、ホストエイリアスを解決します。
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519
create_ssh_session(host: "myserver", user: "admin")
# Automatically resolves hostname, port, and identity file
要件
- Go 1.25+
- シリアル接続の場合:適切なデバイス権限
- 永続セッションの場合:リモートサーバー上の
ai-tmuxバイナリ
変更履歴
バージョン履歴については、CHANGELOG.md を参照してください。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。