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, 임베디드, 네트워크 장비)에 연결 |
지속적 세션 |
|
Attach/Detach | 실행 중인 세션에서 분리하고 나중에 다시 연결 |
제어 키 | 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로 이동하여 플랫폼에 맞는 바이너리를 다운로드하고 실행 권한을 부여하세요:
플랫폼 | 바이너리 |
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, 세션 유형(로컬/ssh/직렬), 대상 호스트
send_input을 통해 전송된 정확한 입력 (메뉴 선택과 같은raw=true입력 포함)각 명령 후 출력 스니펫 (처음 2KB)
명령과 출력을 연결하는
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(줄당 하나의 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— 데몬 모드, 유닉스 소켓에서 수신 대기, 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