mcp-ssh-gateway

mcp-ssh-gateway

An MCP server that acts as a boundary agent, giving LLMs and automation systems controlled SSH-based access to remote machines for tasks like administration, diagnostics, and security research.

Category
访问服务器

README

mcp-ssh-gateway

mcp-ssh-gateway is an MCP-native boundary agent for remote operational capability.

It gives LLMs and automation systems controlled arms and legs into selected remote machines through SSH-based connections. Those machines may provide shell access, specialized hardware, local tools, storage, network adjacency, compute capacity, or access to isolated infrastructure.

The gateway is useful for work such as systems automation, remote administration, diagnostics, troubleshooting, penetration testing, offensive security research, and AI-assisted operational workflows.

The project is not a general orchestration platform, not a replacement for configuration management systems, and not an unrestricted remote shell broker. It is a narrow operational boundary between orchestration systems and real environments.

Core Idea

LLMs are good at reasoning, planning, and interpreting complex output. Real systems require tools, hardware, shell access, network locality, and execution environments.

mcp-ssh-gateway bridges those worlds.

The gateway owns SSH identities, connection configuration, capability discovery, capability caching, execution logging, and transport mechanics. The orchestrator receives operational capability through MCP tools, but does not directly manage passwords, private keys, target addresses, or network topology.

The orchestrator gets capability, not custody.

Architectural Shape

LLM / MCP client
        ↓
FastMCP tool surface
        ↓
mcp-ssh-gateway
    ├── node registry
    ├── connection pool
    ├── execution logging
    └── transport orchestration
            ├── direct SSH
            └── reverse tunnel SSH
                    ↓
          remote node environments

Each configured node represents a trusted operational arm into a remote environment. The gateway manages SSH identities, connections, and execution, and exposes those capabilities back through MCP tools.

This allows an LLM to inspect available nodes, select the most appropriate machine for a task, and coordinate workflows across multiple remote systems.

MCP Tools

Tool Description
get_node_status List all nodes and their connection states
get_node_info Get detailed node facts (use refresh=true for explicit manual refresh)
get_agent_public_key Retrieve the agent's SSH public key for node enrollment
add_node Deprecated. Enroll a new direct-mode node via password bootstrap. Kept only for existing test harnesses — do not call it from an MCP client or LLM workflow, since that would mean typing a real SSH password into a model prompt. Use the CLI instead.
enable_node Enable a node (use validate=true to probe connectivity)
disable_node Disable a node and close its connection
remove_node Remove a node from the pool and registry
run_command_on_node Execute a command on a named node
upload_file_to_node Upload a file to a named node via SFTP
download_file_from_node Download a file from a named node via SFTP

Connection Modes

Direct Mode

Direct mode is used when the remote machine is reachable from the gateway.

The gateway opens outbound SSH connections directly to the target. This is the simpler model and works well for internal infrastructure, VPN-connected environments, trusted networks, and static lab environments.

Reverse Tunnel Mode

Reverse tunnel mode is used when the remote environment is not directly reachable from the gateway.

In this model, the remote machine initiates connectivity toward the gateway, exposes its local SSH service through a reverse tunnel, and the gateway connects back through the exposed local port.

This is useful for NATed environments, outbound-only infrastructure, headless devices, remote labs, and restricted networks.

The current configuration value is still:

{
  "mode": "tunnel"
}

The documentation uses “reverse tunnel mode” to describe the operational model clearly.

Runbooks and Skills

The gateway is intended to work together with runbooks, skills, procedures, and higher-level orchestration systems such as Open WebUI, n8n, OpenClaw, or other MCP-compatible clients.

The gateway provides operational reach. The orchestrator provides reasoning and workflow composition.

Paired with runbooks and skills, an LLM can plan larger workflows and execute them through real environments while keeping actions visible and attributable.

Current Implementation Status

The project is in an active implementation phase.

Implemented:

  • MCP startup and full node-lifecycle tool surface (see MCP Tools above)
  • node registry and connection pool with direct SSH via Paramiko
  • node enrollment via password bootstrap (add_node)
  • agent SSH identity generation and key retrieval (get_agent_public_key)
  • node handshake — facts collection via resources/node/handshake.sh
  • structured command execution, SFTP upload, and SFTP download
  • reverse tunnel probing through already-exposed local ports

Evolving:

  • capability discovery and normalized capability cache
  • execution history model
  • task routing support

Not yet implemented:

  • full agent-side reverse tunnel SSH listener
  • end-to-end reverse tunnel establishment lifecycle
  • advanced capability orchestration

Documentation must continue to distinguish implemented behavior from intended architecture.

Build and Test

python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install pytest
pytest

Run

The current startup path expects a valid connection configuration file.

python app.py --connection-config ./connections.json

Provisioning a Node (CLI)

Why a CLI, and not the add_node MCP tool. add_node takes an SSH password as a tool argument. For that to work, the password would have to pass through whatever is calling the tool — typically an LLM. No operator should type a real credential into a model prompt, and no model should be the thing asking for one. The CLI below is the channel where a human enters credentials directly, in their own terminal: the password never becomes part of any conversation, log line, or file on disk.

Prerequisites

  • Python with the project's dependencies installed (pip install -e .; see Build and Test above). paramiko and cryptography are required.
  • Network reachability from this machine to the target node's SSH port.
  • The target's current SSH password for the account you want the agent to use (e.g. pi, root, a dedicated service account). This password is used exactly once, to install a public key — it is not the credential the gateway will use going forward.

Run it

python -m agent.cli add-node

Run it from the repository root (or point --agent-key-dir / --connection-config at absolute paths — see below). With no flags, it asks you for everything it needs, one prompt at a time:

  1. Node name — a unique identifier for this node inside the gateway (e.g. pi-lab, build-box-3). This is what you'll refer to it as in run_command_on_node and friends.
  2. Host — hostname or IP address.
  3. Port — SSH port (blank defaults to 22).
  4. Username — the SSH account on the target (blank defaults to pi).
  5. SSH password — read with getpass, so it is never echoed to the terminal and never lands in shell history. This is the only prompt that cannot be skipped with a flag.

Every field except the password can also be passed as a flag, so the non-secret parts can be scripted or come from a checklist:

python -m agent.cli add-node --name pi-lab --host 10.0.0.5 --port 22 --user pi

(You'll still be prompted for the password — there is no --password flag, by design.) Add --non-interactive to make the command fail fast instead of prompting if --name/--host/--port/--user are missing — useful in scripts that want to fail loudly rather than hang waiting for input.

What it does, step by step

  1. Creates the agent key directory and the connections-config directory if they don't already exist.
  2. Generates the agent's ed25519 SSH keypair in the key directory, if one isn't already there (reused across all nodes — this is the gateway's own identity, not a per-node key). On Windows, file permissions cannot be restricted to POSIX 0600; the CLI reports this plainly and continues — it is a platform limitation, not a failure.
  3. Connects to the target once, using the password you entered, and installs the agent's public key into that account's ~/.ssh/authorized_keys (idempotent — safe to re-run against a host that already has the key).
  4. Opens a fresh, key-based connection to prove the installed key actually works, then runs a trivial remote command (echo ...) over it and checks the output — so "provisioned" means "confirmed working", not just "we didn't get an error."
  5. Appends the new node to connections.json (or wherever --connection-config points), in the exact shape the gateway already reads — {name, user, id_file, mode, port, host}. If that file already existed, it's backed up first, next to itself, as connections.json.bak-<timestamp>.
  6. Prints the exact MCP client config block for this gateway, using the real, resolved paths on your machine — ready to paste into your MCP client's config (e.g. Claude Desktop's claude_desktop_config.json, or an equivalent mcpServers block).

What to paste, and where

The command prints something like:

{
  "mcpServers": {
    "ssh-gateway": {
      "command": "C:\\Python312\\python.exe",
      "args": [
        "C:\\mcp-ssh-gateway\\app.py",
        "--transport", "stdio",
        "--agent-key-dir", "C:\\mcp-ssh-gateway\\keys",
        "--connection-config", "C:\\mcp-ssh-gateway\\connections.json"
      ]
    }
  }
}

Paste the "ssh-gateway": {...} block (or the whole thing, if this is your first server) into your MCP client's server-config file, under its mcpServers key.

If the gateway is already running: it loaded connections.json at startup and will not see the newly added node until it is restarted. The CLI does not restart it for you — restart the process yourself once you're ready to pick up the new node.

How to verify it worked

The CLI itself already does the real verification for you — step 4 above opens a genuine key-based SSH connection and runs a command through it, and the final line of output says either:

Result: NODE PROVISIONED AND VERIFIED.

or a clearly-labeled warning if the follow-up command check was inconclusive (this can still mean the node is fine — e.g. an unusual shell on the target — but it's called out rather than silently reported as success).

To double-check independently after restarting the gateway, use the get_node_status or get_node_info MCP tools (or run_command_on_node against the new node's name) once the client is connected.

Node parameters, in short

Field Meaning
--name Unique identifier for the node inside the gateway.
--host Hostname or IP address of the target.
--port SSH port (default 22).
--user SSH username on the target.
--mode Connection mode. Only direct is currently supported (matches the gateway's own add_node bootstrap logic).
--agent-key-dir Where the agent's SSH keypair lives. Defaults to keys/ under the repo root.
--connection-config Path to the connections.json-shaped file to update. Defaults to connections.json under the repo root.

Documentation

License

Apache 2.0.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选