Skip to main content
Glama

pty-mcp

pty-mcp MCP server

AI 에이전트에게 대화형 터미널 세션(로컬 셸, SSH, 직렬 포트, 연결이 끊겨도 유지되는 원격 세션)을 제공하는 MCP(Model Context Protocol) 서버입니다.

단순한 코드 생성을 넘어 실제 서버 및 장치 관리를 AI가 지원하도록 돕고자 하는 시스템 관리자 및 네트워크 엔지니어를 위해 제작되었습니다.

AI agent interacting with Telehack BBS via pty-mcp

목적

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 연결이 끊겨도 세션 유지

Attach/Detach

실행 중인 세션에서 분리하고 나중에 다시 연결

제어 키

ctrl+c, ctrl+d, 화살표 키, tab, escape 전송

안정화 감지

출력이 안정될 때까지 기다린 후 반환 (스마트 타임아웃)

패턴 매칭

wait_for는 출력에 정규식 패턴이 나타날 때까지 차단 (v0.2.0)

메모리 제한

링 버퍼를 사용하여 장기 실행 세션에서 OOM 방지 (v0.2.0)

감사 로그

선택적 운영 로그 — send_input 명령을 수집기로 기록하여 검토 및 추적 가능 (v0.8.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로 이동하여 플랫폼에 맞는 바이너리를 다운로드하고 실행 권한을 부여하세요:

플랫폼

바이너리

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는 계속 실행

list_remote_sessions

원격 호스트의 지속적 세션 목록 표시

¹ 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

설정 파일이 없는 운영자는 영향을 받지 않습니다 — 기본적으로 감사는 꺼져 있습니다.

감사 모드

모드

동작

best-effort (기본값)

로그 기록 여부와 관계없이 명령이 실행됨; 항목은 대기열에 추가되고 백그라운드에서 재시도됨

strict

감사 항목을 전달할 수 없는 경우 send_input이 거부됨; 로깅이 팀 정책인 경우 사용

로그 검토

로그는 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.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 — 데몬 모드, 유닉스 소켓에서 수신 대기, 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_ed25519
create_ssh_session(host: "myserver", user: "admin")
# Automatically resolves hostname, port, and identity file

요구 사항

  • Go 1.25+

  • 직렬 포트 사용 시: 적절한 장치 권한

  • 지속적 세션 사용 시: 원격 서버에 ai-tmux 바이너리 필요

변경 로그

버전 기록은 CHANGELOG.md를 참조하세요.

라이선스

MIT

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
2dRelease cycle
16Releases (12mo)

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