Skip to main content
Glama

What Is This?

SSH MCP Server lets you manage remote Linux servers through natural language in VS Code Copilot Chat. Instead of switching to a terminal and remembering SSH commands, you just ask:

"Check disk usage on production-web"

"Show me the last 200 lines of /var/log/nginx/error.log on staging"

"Download /var/log/syslog from web-server-01 for incident INC-2026-0309"

The server enforces strict security policies — no raw shell access, all commands go through pre-approved templates, parameters are regex-validated, secrets in output are auto-redacted, and privileged operations require an approval workflow.

Related MCP server: mcpHydroSSH

Features

  • 23 MCP tools — host discovery, session management, command execution (sync + background), file transfer, SFTP operations, SSH key management, certificate lifecycle, approval workflows

  • Template-only execution — no raw shell; every command matches a registered template with regex-validated parameters

  • 3-tier security model — read-only (Tier 0), controlled mutation with confirmation (Tier 1), privileged with approval workflow (Tier 2)

  • Automatic secret redaction — AWS keys, bearer tokens, passwords, private keys are scrubbed from output

  • Tamper-evident audit log — every operation is logged with hash-chain integrity verification

  • Short-lived SSH certificates — issue and revoke certificates with TTL enforcement via a local CA

  • Persistent SSH sessions — connection pooling with keepalive probes and configurable idle timeout

  • Background command execution — run long-running template commands asynchronously with output polling

  • Path traversal protection.. sequences blocked in all path parameters and file transfers

  • Transfer policy — allowed paths, blocked extensions, size limits, mandatory justification for downloads

Quick Start

Prerequisites

  • Python 3.11+

  • VS Code with GitHub Copilot extension

  • SSH access to at least one remote Linux host


Install

As vscode plugin

https://marketplace.visualstudio.com/items?itemName=bhayanak.ssh-mcp-server-secure

Python package: https://pypi.org/project/ssh-mcp-server-copilot/


Install from Source (for development / contributing)

git clone https://github.com/bhayanak/ssh-mcp-server.git
cd ssh-mcp-server

python -m venv .venv
source .venv/bin/activate   # macOS/Linux
# .venv\Scripts\activate    # Windows

pip install -e ".[dev]"

For local development, create .vscode/mcp.json pointing to the local source:

{
  "servers": {
    "ssh-mcp": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/bin/python",
      "args": ["-m", "ssh_mcp.server"],
      "env": {
        "SSH_MCP_CONFIG_DIR": "${workspaceFolder}/config",
        "SSH_MCP_HOSTS_FILE": "${workspaceFolder}/config/hosts.json",
        "SSH_MCP_TEMPLATES_FILE": "${workspaceFolder}/config/templates.json",
        "SSH_MCP_AUDIT_LOG_DIR": "${workspaceFolder}/audit_logs",
        "SSH_MCP_CERT_DATA_DIR": "${workspaceFolder}/cert_data",
        "SSH_MCP_APPROVAL_DATA_DIR": "${workspaceFolder}/approval_data",
        "SSH_MCP_SSH_KNOWN_HOSTS_FILE": "~/.ssh/known_hosts"
      }
    }
  }
}

Configure Your Hosts

Edit the hosts file with your actual servers. If you used ssh-mcp-server-copilot init, edit ~/.ssh-mcp/hosts.json. If developing from source, edit config/hosts.json.

[
  {
    "host_id": "my-server",
    "hostname": "192.168.1.10",
    "port": 22,
    "ssh_user": "deploy",
    "labels": {"env": "production", "role": "web"},
    "description": "Production web server",
    "allowed_roles": ["operator", "admin"]
  }
]

Field

Required

Description

host_id

Yes

Unique identifier (alphanumeric, dots, dashes)

hostname

Yes

IP address or FQDN

port

No

SSH port (default: 22)

ssh_user

Yes*

Remote SSH username. If empty, uses your OS username

labels

No

Key-value tags for organization

description

No

Human-readable description

allowed_roles

No

Which roles can access this host (default: operator, admin)

Set Up SSH Access

Your SSH key must be authorized on each host:

# Generate a key if you don't have one
ssh-keygen -t ed25519 -C "your-email@example.com"

# Copy to each host
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@192.168.1.10

# Load into ssh-agent (required — the MCP server uses the agent)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Verify access
ssh deploy@192.168.1.10 "echo OK"

Add host keys to known_hosts:

ssh-keyscan -H 192.168.1.10 >> ~/.ssh/known_hosts

Start Using

  1. Open the workspace in VS Code

  2. The MCP server auto-starts from .vscode/mcp.json

  3. Open Copilot Chat (Cmd+Shift+I / Ctrl+Shift+I)

  4. Switch to "Agent" mode (critical — only Agent mode can invoke MCP tools)

  5. Verify tools are loaded — click the tools icon in the chat input bar, you should see 23 tools from ssh-mcp

Now just ask in natural language:

> List all my SSH hosts
> Check disk usage on my-server
> Show me the last 100 lines of /var/log/syslog on my-server
> What's the status of nginx on my-server?

Tools (23)

Tier 0 — Read-Only (No Confirmation)

Tool

Description

list_hosts

List all configured SSH hosts with labels and metadata

get_host_facts

Get OS, uptime, kernel info from a host

get_audit_logs

View the tamper-evident audit trail

list_templates

List available command templates

list_pending_approvals

View pending approval requests

Session Management

Tool

Description

ssh_connect

Open a persistent SSH session (returns session_id for reuse)

ssh_disconnect

Close a persistent session

ssh_list_sessions

List active sessions and remaining connection slots

ssh_session_ping

Health-check a session (liveness, idle time, uptime)

Tier 1 — Controlled Mutation (Confirmation Required)

Tool

Description

run_ssh_command

Execute a template command on a host (supports session_id for persistent connections)

transfer_file

Download/upload files via SFTP with path and extension policies (supports session_id)

Background Command Execution

Tool

Description

run_ssh_command_background

Start a template command in the background (returns job_id)

poll_background_job

Read accumulated stdout/stderr of a background job (redacted)

list_background_jobs

List all background jobs (running + completed)

cancel_background_job

Cancel a running background job

Enhanced SFTP

Tool

Description

sftp_list_directory

List files in a remote directory (within allowed paths)

sftp_delete

Delete a remote file (within allowed paths, requires justification)

Tier 2 — Privileged (Approval Required)

Tool

Description

add_ssh_key

Register a public SSH key with TTL enforcement

remove_ssh_key

Revoke a registered SSH key

issue_cert

Issue a short-lived SSH certificate via the local CA

revoke_cert

Revoke a certificate and delete its PEM

request_approval / approve_request

Approval workflow for privileged ops

Configuration

Command Templates

Templates define which commands can be executed. Edit config/templates.json:

[
  {
    "template_id": "disk_usage",
    "description": "Show disk usage summary",
    "command": "df -h",
    "allowed_params": {},
    "allowed_roles": ["developer", "operator", "admin"],
    "timeout_seconds": 10,
    "risk_level": "low"
  },
  {
    "template_id": "tail_log",
    "description": "Tail the last N lines of a log file",
    "command": "tail -n {lines} {log_path}",
    "allowed_params": {
      "lines": "^[0-9]{1,5}$",
      "log_path": "^/var/log/[a-zA-Z0-9_./-]+$"
    },
    "allowed_roles": ["operator", "admin"],
    "timeout_seconds": 15,
    "risk_level": "low"
  }
]

Each parameter is validated against a regex pattern before substitution. Path traversal (..) is blocked automatically.

Environment Variables

All configuration is via environment variables with the SSH_MCP_ prefix:

Variable

Default

Description

SSH_MCP_CONFIG_DIR

~/.ssh-mcp

Base config directory (all other paths derive from this)

SSH_MCP_HOSTS_FILE

{config_dir}/hosts.json

Path to hosts configuration

SSH_MCP_TEMPLATES_FILE

{config_dir}/templates.json

Path to command templates

SSH_MCP_AUDIT_LOG_DIR

{config_dir}/audit_logs

Audit log directory

SSH_MCP_CERT_DATA_DIR

{config_dir}/cert_data

Certificate storage directory

SSH_MCP_APPROVAL_DATA_DIR

{config_dir}/approval_data

Approval data directory

SSH_MCP_MAX_SESSIONS

10

Max simultaneous SSH sessions

SSH_MCP_SESSION_IDLE_TIMEOUT

300

Idle session timeout (seconds)

SSH_MCP_KEEPALIVE_INTERVAL

15

SSH keepalive interval (seconds)

SSH_MCP_KEEPALIVE_COUNT_MAX

3

Max failed keepalive probes before disconnect

SSH_MCP_MAX_BACKGROUND_JOBS

10

Max concurrent background jobs

SSH_MCP_JOB_OUTPUT_MAX_BYTES

1048576

Max output buffer per background job (1 MB)

SSH_MCP_JOB_TTL_SECONDS

3600

Background job auto-expiry (1 hour)

SSH_MCP_SSH_KNOWN_HOSTS_FILE

(none)

Path to SSH known_hosts file

SSH_MCP_REQUIRE_TWO_PARTY_APPROVAL

true

Require different user as approver

SSH_MCP_AUTH_TOKEN

(none)

Bearer token (empty = dev mode)

SSH_MCP_SSH_TIMEOUT_SECONDS

30

SSH connection timeout

Transfer Policy (Defaults)

Setting

Default

Allowed paths

/tmp/*, /var/log/*

Blocked extensions

.exe, .sh, .bat, .ps1, .dll, .so

Max file size

50 MB

Require justification for downloads

Yes

Roles

Role

Access

developer

Read-only tools, low-risk commands

operator

All Tier 0 + Tier 1 tools

admin

All tools including Tier 2 (key/cert management)

auditor

Audit log access

Security

Design Principles

  1. No raw shell — all commands go through registered templates

  2. Parameter validation — every parameter is regex-validated before substitution

  3. Path traversal blocking.. sequences rejected in all parameters and file paths

  4. Secret redaction — AWS keys, bearer tokens, passwords, private keys automatically scrubbed from output

  5. Approval workflow — privileged operations (key/cert management) require explicit approval with HMAC-verified tokens

  6. Tamper-evident audit — hash-chained audit log for forensic analysis

  7. Strict host validation — paramiko RejectPolicy by default (no auto-accepting unknown hosts)

  8. TTL enforcement — SSH certificates and keys have configurable maximum lifetimes

Approval Workflow

Tier 2 operations follow a 3-step flow:

1. request_approval  →  returns request_id + one-time approval_token
2. approve_request   →  verifies HMAC token, marks approved
3. call the tool     →  pass approval_request_id, consumed after use

With REQUIRE_TWO_PARTY_APPROVAL=true (production), a different user must approve.

Audit Log Verification

python -c "
from ssh_mcp.audit import AuditLogger
from pathlib import Path
logger = AuditLogger(Path('audit_logs'))
ok, msg = logger.verify_chain()
print(f'Chain integrity: {ok} — {msg}')
"

Testing

Unit Tests

# Run all tests
pytest tests/ -v

# With coverage
pytest tests/ -v --cov=ssh_mcp

Runtime Directories (git-ignored, auto-created)

Directory

Purpose

audit_logs/

Tamper-evident audit log (audit.jsonl)

cert_data/

CA keys, issued certificates, revocation list

approval_data/

Pending and consumed approval requests

CLI Reference

ssh-mcp-server-copilot --version          # Print version
ssh-mcp-server-copilot init               # Create ~/.ssh-mcp with default configs
ssh-mcp-server-copilot                    # Start MCP server (stdio transport)
ssh-mcp-server-copilot --config-dir PATH  # Use custom config directory
ssh-mcp-server-copilot --config-dir PATH init  # Init a custom config directory

Contributing

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/my-feature

  3. Make your changes

  4. Run tests: pytest tests/ -v

  5. Lint: ruff check src/ tests/

  6. Submit a pull request

License

MIT

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
<1hResponse time
Release cycle
Releases (12mo)
Commit activity

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • GibsonAI MCP server: manage your databases with natural language

  • Operate your own Linux servers from your LLM. Requires the SentinelX agent installed per host.

  • Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.

View all MCP Connectors

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/bhayanak/ssh-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server