ssh-session-mcp
ssh-session-mcp
中文 | English
ssh-session-mcp is a persistent SSH PTY session manager for MCP clients. It gives the user and the AI the same terminal session, adds a browser viewer, tracks who typed what, and keeps long-running SSH work manageable instead of stateless.

Why It Exists
Most SSH-oriented MCP servers can execute commands, but they do not manage terminal state well enough for real collaboration.
ssh-session-mcp focuses on the missing runtime layer:
One shared PTY for both the human and the AI
Browser terminal for live inspection and manual intervention
Input lock so the AI does not type over the user
Safe/full execution modes for risky commands
Configurable default policy rules plus session-level custom rule overrides
Async command tracking for long-running remote work
Multi-device and multi-connection profile support
Local debug mode for demos, offline testing, and prompt iteration
Best Fit
AI-assisted remote development on Linux boards and SSH servers
Embedded, ROS, training, and deployment hosts that need a real terminal
Users who want the AI to help, but do not want to surrender the terminal
MCP Marketplace listings where the install and demo path must be clear
Quick Start
1. Agent-First Install (Auto-download on first run)
If the goal is to let Claude Code, Codex, or OpenCode install the server automatically, prefer npx -y ssh-session-mcp in the MCP command instead of a prior global install.
For Cline Marketplace and other agent installers, see llms-install.md. This repo is structured to be one-click installable through an npx -y ssh-session-mcp --viewerPort=auto command.
Claude Code
claude mcp add --transport stdio ssh-session-mcp -- npx -y ssh-session-mcp --viewerPort=autoWindows note from the Claude Code docs: native Windows users should wrap npx with cmd /c for stdio MCP servers.
claude mcp add --transport stdio ssh-session-mcp -- cmd /c npx -y ssh-session-mcp --viewerPort=autoCodex
codex mcp add ssh-session-mcp -- npx -y ssh-session-mcp --viewerPort=autoOpenCode
OpenCode's opencode mcp add flow is interactive. Choose a local MCP server and use this command:
npx -y ssh-session-mcp --viewerPort=autoIf you prefer config instead of the interactive flow:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ssh-session-mcp": {
"type": "local",
"command": ["npx", "-y", "ssh-session-mcp", "--viewerPort=auto"]
}
}
}This is the closest thing to "automatic installation" for stdio MCP servers today: the MCP client stores the command, and npx -y downloads the package automatically the first time it runs.
2. Fastest Local Demo
npm install -g ssh-session-mcp
ssh-session-mcp-ctl launch --local --viewerPort=autoThis starts a local shell instead of SSH and opens the browser terminal, which is the easiest way to test the MCP runtime before touching a real server.
3. Register As An MCP Server
Use the MCP server binary directly when wiring a client:
# Global install
npm install -g ssh-session-mcp
# Server command used by MCP clients
ssh-session-mcp --viewerPort=auto# Claude Code
claude mcp add --transport stdio ssh-session-mcp -- ssh-session-mcp --viewerPort=auto
# Codex CLI
codex mcp add ssh-session-mcp -- ssh-session-mcp --viewerPort=autoIf you prefer npx instead of a global install:
npx -y ssh-session-mcp --viewerPort=auto4. Connect To A Real SSH Target
Create .env from .env.example:
cp .env.example .envSSH_HOST=192.168.1.100
SSH_PORT=22
SSH_USER=username
SSH_PASSWORD=
SSH_KEY=
VIEWER_PORT=auto
AUTO_OPEN_TERMINAL=false
SSH_MCP_MODE=safeThen launch:
ssh-session-mcp-ctl launch --viewerPort=auto5. Multi-Device Config
For multiple boards or named targets, create ssh-session-mcp.config.json:
{
"defaultDevice": "board-a",
"devices": [
{
"id": "board-a",
"host": "192.168.10.58",
"port": 22,
"user": "orangepi",
"auth": { "passwordEnv": "BOARD_A_PASSWORD" },
"defaults": {
"term": "xterm-256color",
"cols": 120,
"rows": 40,
"autoOpenViewer": true,
"viewerMode": "browser"
}
}
]
}Discovery order:
--config=/path/to/config.jsonWorkspace
ssh-session-mcp.config.jsonUser-global config
Legacy
.envfallback
Important:
Config discovery is based on the MCP process working directory.
auth.passwordis intentionally unsupported. Useauth.passwordEnvorauth.keyPath.Secrets belong in
.envor the parent environment, not in repo-tracked JSON.
Viewer And Collaboration Model
The browser viewer is not decorative. It is part of the workflow:
The user can see exactly what the AI did.
The AI can pause when the user takes over.
Password prompts, pagers, and editors become visible state instead of hidden failure modes.
Session diagnostics and history turn terminal debugging into something inspectable.
Marketplace-Friendly Flow
For users:
install -> launch viewer -> connect once -> keep the session alive -> let the AI helpFor agents:
ssh-quick-connect -> ssh-run -> inspect output -> ssh-command-status if needed -> ssh-run againUse AGENT.md when you want the AI to install, inspect config, connect devices, and help the user end-to-end. Compatibility notes for older agent setups remain in AI_AGENT_GUIDE.md.
Core Differences From A Stateless MCP SSH Wrapper
Shared PTY instead of one-off command execution
Actor-aware transcript markers for user, system, and agent input
Terminal-state checks before dangerous or nonsensical writes
Auto cleanup for sessions and viewer processes
Session-scoped browser viewer with diagnostics and history
Local debug mode with
--localfor offline testing
Operation Modes
Mode | Behavior |
| Default. Blocks obviously dangerous, interactive, or streaming commands when they are a poor fit for autonomous execution. |
| Allows broader control and warns less, while still blocking extreme cases such as obvious destructive abuse. |
Input Lock
Mode | Who can type |
| User and AI |
| Only the user |
| Only the selected agent |
If the terminal is locked by the user, ssh-run, ssh-session-send, and ssh-session-control return a blocked response instead of forcing input into the PTY.
MCP Tools
Recommended Daily Tools
Tool | Purpose |
| Connect or reuse the default target and optionally open the viewer |
| Execute a command with completion detection and exit-code capture |
| Inspect sessions, viewer state, and operation mode |
| Poll async command progress |
| Retry flaky commands with backoff |
| Inspect inherited defaults and current session custom policy rules |
| Add or update a session-level custom policy rule |
| Remove a session-level custom policy rule |
| Reset session custom rules back to inherited defaults |
Full Tool Catalog
Tool | Purpose |
| Open a session with explicit SSH parameters |
| Send raw PTY input |
| List configured devices and defaults |
| Read buffered terminal output by offset |
| Long-poll for output and dashboard changes |
| Read line-numbered mixed terminal history |
| Send control keys such as |
| Resize the PTY |
| List tracked sessions |
| Inspect lock state, warnings, running command state, and viewer health |
| Show inherited policy defaults and the current session rule set |
| Add or update a session-specific custom policy rule |
| Remove a session-specific custom policy rule |
| Restore inherited rules for the current session |
| Choose the default session |
| Open or reuse the local viewer |
| List tracked viewer processes |
| Close a session cleanly |
| One-step connect flow for agents |
| Main command execution tool |
| Runtime overview |
| Async poller |
| Retry executor |
Local Operator Commands
These helpers are for humans on the workstation that owns the viewer:
ssh-session-mcp-ctl status
ssh-session-mcp-ctl devices
ssh-session-mcp-ctl launch --viewerPort=auto
ssh-session-mcp-ctl launch --local --viewerPort=auto
ssh-session-mcp-ctl logs --tail=60
ssh-session-mcp-ctl cleanupDefault rule library management for operators:
ssh-session-mcp-config policy list --scope=merged
ssh-session-mcp-config policy set block-kubectl-delete --pattern="\\bkubectl\\s+delete\\b" --category=dangerous --action=block --message="kubectl delete is blocked in safe mode"
ssh-session-mcp-config policy remove block-kubectl-deleteEquivalent repo-local commands also exist:
npm run launch
npm run status
npm run devices
npm run logs
npm run cleanupConfiguration Summary
Key environment variables:
Variable | Meaning | Default |
| Legacy single-target SSH host | required in legacy mode |
| Legacy single-target SSH port |
|
| Legacy single-target SSH user | required in legacy mode |
| Password auth | empty |
| Local private key path | empty |
| Runtime isolation key |
|
| Explicit config file path | auto-discovery |
| Viewer bind host |
|
| Viewer port or |
|
|
|
|
| Launch a local shell instead of SSH |
|
| Enable debug browser actions |
|
| Auto-open browser terminal |
|
|
|
|
Example config file: docs/examples/ssh-session-mcp.config.example.json
Security
The package never requires raw passwords inside tracked JSON config.
.envis ignored by git and npm.Viewer HTTP binds to localhost by default.
The MCP server treats terminal mode and input lock as first-class safety signals.
See SECURITY.md for the full policy.
Platform Notes
Windows 10/11: first-class host environment
Linux: strong fit for headless MCP + browser viewer workflows
macOS: standard Node.js path supported
Remote Linux hosts: first-class target
More detail: docs/platform-compatibility.md
Docs
Development
npm install
npm run build
npm run test
npm run validate:repo
npm run build:siteGitHub Actions included in this repo can:
run CI on push and pull request
deploy a GitHub Pages landing page from
dist/build a tagged GitHub Release with the npm package tarball attached
License
Apache-2.0. See LICENSE.
This server cannot be installed
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/Zw-awa/ssh-session-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server