Skip to content

rayss868/termssh-mcp

Repository files navigation

TermSSH MCP Banner

TermSSH MCP

Terminal-first SSH access for MCP clients, AI agents, and remote automation.

Turn remote machines into agent-friendly, interactive terminal workflows — not just one-shot command execution.

GitHub MCP Terminal First Interactive SSH File Upload MIT License


✨ Why TermSSH MCP

Most SSH tooling for AI workflows is built around run command → get output → done.

That falls apart when the real task is interactive:

  • installers ask questions
  • shells keep state
  • debugging needs multiple steps
  • deployments need uploads plus terminal control
  • agents need to observe, react, and continue

TermSSH MCP is built for that gap.

Instead of pretending everything is a single command, it gives MCP clients a real operator-style workflow:

open a shell → write input → read output → keep context → upload files → continue working


🧠 What makes it different

Terminal-first

Interactive terminal sessions are the core model, not an afterthought.

Agent-ready

Designed for MCP clients, coding agents, and automation loops.

Stateful workflows

Reuse active sessions so multi-step tasks feel natural and reliable.

Upload included

Move scripts, configs, payloads, and generated artifacts over SFTP.

Cross-platform

Works against Linux and Windows SSH targets.

Clean tool surface

Focused MCP tools for terminal control and remote file delivery.


🚀 Core capabilities

  • Interactive SSH terminal sessions
  • Incremental terminal read / write flow
  • Managed terminal session reuse by default
  • Optional forced multi-session creation
  • Local file upload through SFTP
  • Direct text and base64 content upload
  • Terminal resize support
  • Linux and Windows SSH target support
  • MCP-native interface for AI tooling

🧰 Tool set

Upload a local file from the MCP host machine to the remote SSH server using SFTP.

Parameters

  • localPath — local source file path
  • remotePath — destination path on the remote host
  • createDirectories — create missing parent directories if needed
  • overwrite — replace an existing remote file if present
  • mode — optional POSIX mode such as 0644

Upload direct text or base64 content to the remote server.

Parameters

  • content — raw text or base64 payload
  • encodingutf8 or base64
  • remotePath — destination path on the remote host
  • createDirectories — create missing parent directories if needed
  • overwrite — replace an existing remote file if present
  • mode — optional POSIX mode such as 0644

Start an interactive remote terminal session.

Parameters

  • cwd — optional working directory after shell startup
  • shell — optional shell binary
  • platformHintauto, linux, or windows
  • elevated — attempt su elevation when configured
  • cols — terminal width
  • rows — terminal height
  • env — optional environment variables
  • multiSession — set true to force a new managed session instead of reusing an existing one

Write input into an active terminal session.

Parameters

  • sessionId — target session id
  • input — text to send
  • appendNewline — append a newline automatically if needed

Read buffered output from a terminal session.

Parameters

  • sessionId — target session id
  • sinceSequence — only return output newer than a given sequence number
  • maxChars — limit the size of returned output
  • waitForMs — optional short polling delay

Resize an active terminal session.

Parameters

  • sessionId — target session id
  • cols — new width
  • rows — new height

Close a terminal session locally.

Parameters

  • sessionId — target session id

🔄 Typical workflow

flowchart LR
    A[terminal-start] --> B[terminal-write]
    B --> C[terminal-read]
    C --> D{Need file?}
    D -- Yes --> E[upload-file / upload-content]
    D -- No --> F{Continue session?}
    E --> F
    F -- Yes --> B
    F -- No --> G[terminal-close]
Loading

This works especially well for:

  • interactive package installs
  • remote setup and provisioning
  • deployments with artifact upload
  • debugging services across multiple steps
  • stateful shell workflows where context matters

🛠 Installation

Clone the repository

git clone https://github.com/rayss868/termssh-mcp.git
cd termssh-mcp
npm install
npm run build

Install globally

npm install -g termssh-mcp

⚙ Configuration

TermSSH MCP supports two configuration modes:

  1. Direct CLI flags — good for quick tests or a single server
  2. Vault file — recommended for real usage, especially when you want multiple VPS accounts and one active target

Direct CLI parameters

Required

  • host — hostname or IP address of the remote machine
  • user — SSH username

Optional

  • port — SSH port, default 22
  • password — SSH password
  • key — path to a private SSH key file
  • sudoPassword — optional password for sudo-oriented workflows
  • suPassword — optional password for su-based elevation
  • timeout — SSH ready timeout in milliseconds, default 60000
  • maxChars — command-length validation limit, default 1000; use none or 0 for unlimited mode

Vault mode

Vault mode lets you store multiple SSH accounts in one JSON file and choose the target account per MCP tool call.

Vault CLI parameter

  • vault — path to a vault JSON file

If --vault is provided, startup resolves accounts from the vault. If no vault is provided, TermSSH MCP falls back to direct CLI config.

Account selection behavior

  • MCP tools now expose an account parameter in the built tool schema
  • when vault mode is enabled, account should be set to one of the keys under accounts
  • if account is omitted, runtime now fails with a clear error instead of silently choosing an account
  • this was verified against live SSH MCP runtime: no account → reject, valid account → connect successfully

Example vault file

File: termssh-mcp-vault.json

{
  "activeAccount": "production",
  "accounts": {
    "production": {
      "host": "1.2.3.4",
      "port": 22,
      "user": "root",
      "key": "C:\\keys\\id_ed25519"
    },
    "staging": {
      "host": "5.6.7.8",
      "port": 22,
      "user": "ubuntu",
      "password": "example-password"
    }
  }
}

Important key behavior

  • In vault mode, key must point to a private key file path
  • toSshConfigFromVault() reads that file and passes the key contents to ssh2
  • This fixes the private-key parsing issue that happens if a file path is sent directly as privateKey

🧩 MCP configuration examples

Recommended: vault-based MCP config

{
  "mcpServers": {
    "termssh-mcp": {
      "command": "node",
      "args": [
        "build/index.js",
        "--vault=./termssh-mcp-vault.json",
        "--timeout=30000",
        "--maxChars=none"
      ]
    }
  }
}

MCP tool call example with account

{
  "account": "production",
  "cwd": "/var/www/app",
  "platformHint": "linux",
  "multiSession": true
}

MCP behavior when account is omitted

If you call a vault-backed tool without account, runtime rejects the call and tells you to choose one of the configured account names.

Direct CLI example

{
  "mcpServers": {
    "termssh-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "termssh-mcp",
        "--",
        "--host=1.2.3.4",
        "--port=22",
        "--user=root",
        "--password=pass",
        "--timeout=30000",
        "--maxChars=none"
      ]
    }
  }
}

Direct CLI with SSH key

{
  "mcpServers": {
    "termssh-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "termssh-mcp",
        "--",
        "--host=example.com",
        "--user=root",
        "--key=/path/to/private/key",
        "--timeout=30000"
      ]
    }
  }
}

Real local-project vault pattern

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "node",
      "args": [
        "D:/All_project/own/AI_Coder/MCP_Tools/ssh-mcp/build/index.js",
        "--vault=D:/All_project/own/AI_Coder/MCP_Tools/ssh-mcp/termssh-mcp-vault.json",
        "--timeout=1200000",
        "--maxChars=50000"
      ]
    }
  }
}

🤖 Claude Code example

Register the server in Claude Code with direct credentials:

claude mcp add --transport stdio termssh-mcp -- npx -y termssh-mcp -- --host=YOUR_HOST --user=YOUR_USER --password=YOUR_PASSWORD

Register the server in Claude Code with a vault file:

claude mcp add --transport stdio termssh-mcp -- node build/index.js --vault=./termssh-mcp-vault.json --timeout=120000 --maxChars=none

With SSH key authentication:

claude mcp add --transport stdio termssh-mcp -- npx -y termssh-mcp -- --host=example.com --user=root --key=/path/to/private/key

With extended timeout:

claude mcp add --transport stdio termssh-mcp -- npx -y termssh-mcp -- --host=192.168.1.100 --user=admin --password=your_password --timeout=120000 --maxChars=none

✅ Verified vault workflow

The vault flow has been verified against a live SSH connection:

This means the recommended production path is now:

MCP config → --vault=... → active account selection → interactive terminal session


🎯 Great fit for

Developers

  • remote shell access from AI coding tools
  • stateful debugging sessions
  • script and config delivery

DevOps / infra teams

  • service inspection
  • deployment support
  • multi-step remote operations

Agent builders

  • terminal-native MCP workflows
  • reusable sessions
  • controlled remote automation loops

🏗 Development

Build the project:

npm run build

Run tests:

npm test

Use the MCP Inspector:

npm run inspect

📁 Project structure


🗺 Roadmap ideas

  • richer session metadata inspection
  • better remote session observability
  • optional session persistence features
  • more examples for Claude Code and MCP tools
  • deployment-oriented workflow templates

🔐 Security note

TermSSH MCP gives remote access to systems over SSH. Use it only on infrastructure you own or are explicitly authorized to manage.


📜 License

Released under the MIT License.


🤝 Contributing

Contributions are welcome. See CONTRIBUTING.md for contribution guidance and CODE_OF_CONDUCT.md for expected behavior.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages