伪终端会话服务器

PTY MCP Server是一个提供交互式伪终端会话的服务,支持AI助手如Claude Code与需要完整终端模拟的程序(如vim、ssh、less、top、交互式REPLs等)进行交互。

  • by dblmca
  • JavaScript
  • 本地部署
  • 更新于
在 GitHub 查看 dblmca/pty-mcp

使用说明

PTY MCP服务器

MCP(模型上下文协议)服务器,为Claude Code等AI助手提供交互式PTY(伪终端)会话。这允许与需要完全终端模拟的程序进行交互,如vim、ssh、less、top、交互式REPL等。

LLM部署说明

本节为LLM自主部署此MCP服务器提供了完整的分步说明。

先决条件

启动前,确保系统具有:

  • Node.js>=18.0.0(node --version 检查)
  • npm(附带Node.js)
  • 为本机模块构建工具

要检查/安装必备组件:

# Check Node.js version
node --version  # Should be >= 18.0.0

# If Node.js is missing or outdated, install via nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20

# Install build tools (required for node-pty native module)
# Ubuntu/Debian:
sudo apt-get update && sudo apt-get install -y python3 make g++

# macOS:
xcode-select --install

# Fedora/RHEL:
sudo dnf install -y python3 make gcc-c++

步骤1:克隆存储库

# Create MCP servers directory if it doesn't exist
mkdir -p ~/mcp-servers
cd ~/mcp-servers

# Clone the repository
git clone https://github.com/dblmca/pty-mcp.git
cd pty-mcp

步骤2:安装依赖项

npm install

这将安装:

  • @modelcontextprotocol/sdk -用于服务器实现的MCP SDK
  • node-pty -原生PTY绑定(需要构建工具)

故障排除 node-pty 构建失败:

# If npm install fails with node-pty errors, install build dependencies first
sudo apt-get install -y python3 make g++  # Ubuntu/Debian
# Then retry
npm install

步骤3:使用Claude Code注册

关键的:克劳德代码不使用 ~/.claude/.mcp.json 直接。您必须使用CLI:

# Add to user config (available in all projects)
claude mcp add -s user pty-mcp -- node ~/mcp-servers/pty-mcp/server.js

如果使用不同的安装路径,请相应调整:

claude mcp add -s user pty-mcp -- node /full/path/to/pty-mcp/server.js

步骤4:验证安装

# List registered MCP servers
claude mcp list

# Should show pty-mcp with status

步骤5:测试服务器

重新启动Claude Code后,使用以下命令进行测试:

1. Call pty_spawn with no arguments to create a shell session
2. Call pty_read to see the shell prompt
3. Call pty_write with input: "echo hello\r"
4. Call pty_read to see the output
5. Call pty_kill to clean up

工具参考

pty_spawn

创建新的交互式PTY会话。

参数 类型 必填 默认 说明
command string 否 用户shell 要运行的命令
args string[] 否 [] 命令参数
cwd string 否 当前目录 工作目录
cols number No 120 端子列(最多500个)
rows number No 30 终端行数(最多200行)
env object 否 {} 其他环境变量

退货:

{
  "session_id": "abc123def456...",
  "pid": 12345,
  "command": "/bin/bash",
  "cols": 120,
  "rows": 30
}

pty_write

向PTY会话发送输入。支持转义序列。

参数 类型 必填 说明
session_id string 是 来自的会话ID pty_spawn
input string 是 要发送的输入

逃生顺序:

序列 密钥 用例
\r 输入 执行命令
\n Newline 多行输入
\t 选项卡 自动完成
\x03 Ctrl-C 中断/取消
\x04 Ctrl-D EOF/退出
\x1b 退出模式(vim,less)
\x1b[A 向上箭头 历史/导航
\x1b[B 向下箭头 历史/导航
\x1b[C 向右箭头 光标移动
\x1b[D 向左箭头 光标移动

退货:

{ "written": 5 }

pty_read

读取PTY会话的缓冲输出。

参数 类型 必填 默认 说明
session_id string 是 - 会话ID
timeout_ms number 否 100 输出等待时间(最大值:5000)
clear_buffer boolean 否 真 读取后清除缓冲区

退货:

{
  "output": "user@host:~$ ",
  "exited": false,
  "exit_code": null,
  "signal": null
}

pty_resize

调整PTY终端的大小以适应全屏应用程序。

参数 类型 必填 说明
session_id string 是 会话ID
cols number 是 新列(最多500列)
rows number Yes 新行(最多200行)

pty_kill

终止PTY会话并清理资源。

参数 类型 必填 默认 说明
session_id string 是 - 会话ID
signal string No SIGHUP 信号:SIGHUP、SIGTERM、SIGKILL、SIGINT

pty_list

列出所有活动的PTY会话。无需参数。


用法示例

SSH会话

1. pty_spawn { command: "ssh", args: ["user@192.168.1.100"] }
2. pty_read { session_id: "...", timeout_ms: 5000 }  # Wait for prompt/password
3. pty_write { session_id: "...", input: "password\r" }  # If password needed
4. pty_read { session_id: "..." }  # Get remote prompt
5. pty_write { session_id: "...", input: "hostname\r" }  # Run commands
6. pty_read { session_id: "..." }
7. pty_write { session_id: "...", input: "exit\r" }  # Disconnect
8. pty_kill { session_id: "..." }  # Cleanup

Python REPL

1. pty_spawn { command: "python3" }
2. pty_read { session_id: "..." }  # ">>> "
3. pty_write { session_id: "...", input: "import math\r" }
4. pty_write { session_id: "...", input: "print(math.pi)\r" }
5. pty_read { session_id: "..." }  # "3.141592653589793\n>>> "
6. pty_write { session_id: "...", input: "\x04" }  # Ctrl-D to exit

Vim编辑

1. pty_spawn { command: "vim", args: ["file.txt"] }
2. pty_read { session_id: "...", timeout_ms: 1000 }  # Wait for vim
3. pty_write { session_id: "...", input: "i" }  # Insert mode
4. pty_write { session_id: "...", input: "Hello, World!" }
5. pty_write { session_id: "...", input: "\x1b" }  # Escape
6. pty_write { session_id: "...", input: ":wq\r" }  # Save and quit
7. pty_kill { session_id: "..." }

互动程序(顶部,htop)

1. pty_spawn { command: "top" }
2. pty_read { session_id: "...", timeout_ms: 2000 }  # Get display
3. pty_write { session_id: "...", input: "q" }  # Quit top
   # Or: pty_write { session_id: "...", input: "\x03" }  # Ctrl-C

配置

设置 值 描述
最大会话数 10 最大并发PTY会话数
会话超时 30分钟 空闲会话自动清理
缓冲区大小 1 MB 每个会话的最大输出缓冲区
输入大小 1 MB 每次写入的最大输入
默认端子 120x30 默认列x行
最大端子 500x200 最大列x行

故障排除

注册后找不到服务器

# Verify registration
claude mcp list

# If missing, re-add
claude mcp add -s user pty-mcp -- node ~/mcp-servers/pty-mcp/server.js

# Restart Claude Code

节点pty构建失败

# Install build dependencies
sudo apt-get install -y python3 make g++

# Clear npm cache and retry
rm -rf node_modules package-lock.json
npm install

会话命令不起作用

  1. 确保您使用的是正确的 session_id 从 pty_spawn
  2. 检查会话是否已退出: pty_list 或检查 exited 领域 pty_read
  3. 对于密码提示,请使用更长时间 timeout_ms (例如,5000)

输出包含转义码

终端输出包括用于颜色和格式的ANSI转义序列。这是终端应用程序的正常行为。


安全

  • 命令仅限于标准系统路径
  • 命令名称中拒绝了Shell元字符
  • 环境变量名称已验证
  • 输入/缓冲区大小有限
  • 会话在30分钟后自动过期

Claude代码集成(Claude.md代码片段)

将此添加到您的项目 CLAUDE.md 帮助Claude Code了解如何使用此MCP服务器的文件:

### PTY MCP Server (Interactive Terminal)

The `pty-mcp` server provides interactive terminal (PTY) sessions for programs that require full terminal emulation (vim, ssh, less, top, interactive REPLs, etc.).

**Location:** `~/mcp-servers/pty-mcp/`

**When to Use:**
- Interactive programs that need terminal emulation (vim, nano, less, top, htop)
- SSH sessions
- Interactive REPLs (python, node, irb)
- Programs that require Ctrl-C, Ctrl-D, or arrow keys
- Any program that doesn't work well with the standard Bash tool

**MCP Tools:**
- `pty_spawn` - Create a new PTY session (returns session_id)
- `pty_write` - Send input to a session (supports escape sequences)
- `pty_read` - Read buffered output from a session
- `pty_resize` - Resize terminal dimensions
- `pty_kill` - Kill a session
- `pty_list` - List all active sessions

**Escape Sequences for `pty_write`:**
| Sequence | Meaning |
|----------|---------|
| `\r` | Enter/Return |
| `\x03` | Ctrl-C (interrupt) |
| `\x04` | Ctrl-D (EOF) |
| `\x1b` | Escape |
| `\x1b[A` | Arrow Up |
| `\x1b[B` | Arrow Down |
| `\x1b[C` | Arrow Right |
| `\x1b[D` | Arrow Left |

**Usage Examples:**

\`\`\`
# Basic shell session
1. pty_spawn {}                              → { session_id: "abc123" }
2. pty_read { session_id: "abc123" }         → { output: "$ " }
3. pty_write { session_id: "abc123", input: "ls -la\r" }
4. pty_read { session_id: "abc123" }         → { output: "..." }
5. pty_kill { session_id: "abc123" }

# Python REPL
1. pty_spawn { command: "python3" }
2. pty_write { session_id: "...", input: "x = 42\r" }
3. pty_write { session_id: "...", input: "print(x * 2)\r" }
4. pty_read { session_id: "..." }            → { output: "84\n>>> " }
5. pty_write { session_id: "...", input: "\x04" }  # Ctrl-D to exit

# Vim editing
1. pty_spawn { command: "vim", args: ["file.txt"] }
2. pty_write { session_id: "...", input: "i" }       # Insert mode
3. pty_write { session_id: "...", input: "Hello!" }
4. pty_write { session_id: "...", input: "\x1b" }    # Escape
5. pty_write { session_id: "...", input: ":wq\r" }   # Save and quit
\`\`\`

**Configuration:**
- Max 10 concurrent sessions
- 30-minute idle timeout (auto-cleanup)
- 1MB output buffer per session
- Default terminal: 120x30

许可证

麻省理工学院