Skip to main content
Glama
HSOS6Miyabi

ChatGPT SSH & SFTP MCP Server

by HSOS6Miyabi

ChatGPT SSH & SFTP MCP Server

A self-hosted remote MCP server for SSH command execution and SFTP file management in ChatGPT Chat Mode. Implemented with the official MCP Python SDK and Paramiko. Includes a single-user, in-memory SSH connection registry, strict SSH host-key checks, bounded command responses, and an optional HTTP bearer token.

Capabilities

Tool

Purpose

ssh_profiles

List named SSH targets without disclosing credentials

ssh_connect

Connect via configured profile, password, key file, or inline private key

ssh_connections

List active connections

ssh_disconnect

Close an active connection

ssh_execute

Run arbitrary remote shell commands and return stdout, stderr, status, timeout flags

sftp_list

List a remote directory

sftp_stat

Read remote file metadata

sftp_read

Read a file range in UTF-8 or Base64

sftp_write

Create, replace, or append a remote file

sftp_mkdir

Create a remote directory

sftp_rename

Rename or move a remote path

sftp_delete

Remove a remote file or empty directory

sftp_chmod

Set remote Unix permissions

sftp_upload

Upload a file from the MCP host's transfer directory

sftp_download

Download a file to the MCP host's transfer directory

Supports arbitrary SSH destinations reachable from the MCP server's network and custom SSH ports. Sessions survive MCP HTTP requests while the same Python process remains running; idle SSH connections expire automatically. Run a single process; a restart invalidates connection IDs.

Related MCP server: ssh-agent-mcp

Prerequisites

  • Python 3.10 or later on the MCP host (Linux, macOS, or Windows).

  • Reachability from the MCP host to target servers' SSH ports.

  • Valid SSH host keys in a private known_hosts file.

  • A secure transport from ChatGPT to the MCP endpoint: Secure MCP Tunnel or a TLS-enabled reverse proxy with authentication.

  • ChatGPT account/workspace permission to add custom MCP tools with write capabilities.

Compatibility: As of October 2026, OpenAI documentation says that ChatGPT Business and Enterprise/Edu support custom MCP write/modify actions in Chat Mode. Plus/Pro custom MCP access remains restricted to read/fetch actions. Installing this server cannot change those permissions. ChatGPT connects to remote MCP servers rather than a directly attached localhost HTTP endpoint.

References: Connect custom MCP servers, Connect and test a plugin, Secure MCP Tunnel.

Install and run

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[test]'
mkdir -p transfers "$HOME/.ssh"

For example, to trust the SSH host key for example.com at port 2222:

ssh-keyscan -p 2222 example.com > /tmp/target_hostkey
ssh-keygen -lf /tmp/target_hostkey
# Independently compare the printed fingerprint against the one from your server administrator.
cat /tmp/target_hostkey >> "$HOME/.ssh/known_hosts"
chmod 600 "$HOME/.ssh/known_hosts"
rm /tmp/target_hostkey

Use a standard SSH key in ~/.ssh (or set SSH_MCP_KEY_ROOT to another private directory). To define reusable targets:

cp profiles.example.json profiles.json
chmod 600 profiles.json
export SSH_MCP_PROFILES_FILE="$PWD/profiles.json"
# For the production profile in profiles.example.json:
export PRODUCTION_SSH_PASSWORD='your-password'

Edit the example profile names and hosts before using them. A password_env entry reads a secret from the MCP process environment. A key_path entry refers to a private key stored on the MCP host; paths are confined to SSH_MCP_KEY_ROOT. A key passphrase can be supplied using the passphrase_env profile setting.

Start a private MCP HTTP endpoint:

chatgpt-ssh-mcp
# http://127.0.0.1:8000/mcp

python -m ssh_mcp is equivalent. The endpoint binds to localhost by default. For a Tunnel or a trusted local MCP client, this can be used without a public listener. You can also set MCP_TRANSPORT=stdio for MCP stdio clients or a stdio Secure MCP Tunnel.

Open the Secure MCP Tunnel documentation, create a tunnel in your OpenAI organization/workspace, and follow the official tunnel-client setup. Configure the tunnel to forward to:

http://127.0.0.1:8000/mcp

Keep both the SSH MCP server and tunnel client running. In ChatGPT Plugins, select Add custom MCP server → Tunnel, then the corresponding tunnel ID. This avoids exposing SSH control tools through an internet-facing web listener. You can also use the documented tunnel-client --mcp-command option with the stdio transport.

Public HTTPS endpoint

Use a reverse proxy such as Caddy or nginx. A minimal Caddy configuration is in Caddyfile.example. Keep the MCP HTTP listener on 127.0.0.1 and terminate TLS at the proxy. Set both a long bearer token and explicit public host allowlist:

export MCP_BEARER_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(48))')"
export MCP_ALLOWED_HOSTS='mcp.example.com,mcp.example.com:*'
chatgpt-ssh-mcp

Configure your ChatGPT custom MCP connection with endpoint https://mcp.example.com/mcp and API key / Bearer authentication, supplying the bearer token in ChatGPT's connection settings. Do not send the bearer token as part of a prompt. API-key authentication availability may vary by ChatGPT connection/publishing flow; consult the current plugin settings. Alternatively, use an authenticated Secure MCP Tunnel or a properly configured OAuth-capable gateway. Public publication workflows may require OAuth.

The built-in allowlist checks the incoming Host header. To add additional allowed browser origins, use MCP_ALLOWED_ORIGINS (comma-separated HTTPS origin URLs). This server is intended for one trusted operator; a shared token provides shared access to all active connections. Create separate deployments for different people or security boundaries.

Docker (optional)

Build the included Dockerfile or adapt compose.example.yml. The container runs without root privileges (UID 10001). Prepare private, read-only SSH material under secrets/ssh, a secrets/profiles.json file owned/readable by UID 10001, and a writable transfers directory. Set MCP_BEARER_TOKEN and MCP_ALLOWED_HOSTS before starting the Compose example. Expose the public HTTPS hostname through your own reverse proxy; only local port 8000 is published in the Compose example.

ChatGPT connection and use

  1. Open ChatGPT on the web and navigate to Plugins → + → Add custom MCP server (subject to account/workspace permissions).

  2. Select a Secure MCP Tunnel or enter your publicly reachable https://.../mcp endpoint; configure matching authentication.

  3. Create/install the resulting plugin. Start a new Chat Mode conversation and select the plugin with @.

  4. Ask the model to call ssh_profiles, ssh_connect(profile="staging"), and then use the returned connection_id for operations. ChatGPT may request confirmation for write actions.

Example requests:

  • "Connect to the staging SSH profile and run uname -a."

  • "List /var/log with SFTP on that connection."

  • "Read the first 32 KB of /etc/nginx/nginx.conf and tell me what it configures."

  • "Create /tmp/hello.txt with content Hello using SFTP."

  • "Run python3 -c 'print(2 + 2)' over SSH."

Credential handling: Prefer a named profile with password_env or key_path. Direct ssh_connect(password=...) and ssh_connect(private_key=...) are supported for flexibility, but those arguments may appear in ChatGPT conversation or tool-call records. The server does not include secrets in successful responses or persist them to disk. Never paste permanent privileged credentials into chat when a profile is available.

File-transfer semantics

The sftp_read and sftp_write tools transfer content through MCP responses/arguments, supporting UTF-8 and Base64. Large files can be read in segments using offset and length. sftp_upload and sftp_download operate on files in SSH_MCP_TRANSFER_ROOT on the MCP host, not on the ChatGPT user's computer; conversation attachments do not automatically become local files in that directory. Place files into the transfer directory using your own secure file delivery process.

Default limits: 1 MiB inline SFTP reads/writes, 1 MiB combined command output, 120-second maximum command time, 30-minute idle connection expiration, up to 32 connections. Limits can be adjusted with environment variables in .env.example. Each SSH command executes in a fresh remote session channel and is not an interactive PTY: shell state such as cd does not persist across calls. Use explicit working-directory commands or single scripts.

Configuration variables

Variable

Default

Purpose

MCP_TRANSPORT

http

http or stdio

MCP_HOST / MCP_PORT

127.0.0.1 / 8000

HTTP listening address

MCP_BEARER_TOKEN

unset

Optional HTTP bearer-token check; required for public deployments

MCP_ALLOWED_HOSTS

unset

Additional allowed HTTP Host headers; required for public proxy hostname

MCP_ALLOWED_ORIGINS

unset

Additional permitted HTTP Origin values

SSH_MCP_PROFILES_FILE

unset

Private JSON file for named server profiles

SSH_MCP_KNOWN_HOSTS

~/.ssh/known_hosts

Verified SSH server host keys

SSH_MCP_KEY_ROOT

~/.ssh

Directory allowed to contain SSH private keys

SSH_MCP_TRANSFER_ROOT

./transfers

Confined local SFTP file exchange directory

SSH_MCP_SESSION_TTL

1800

Idle SSH connection expiry in seconds

SSH_MCP_MAX_SESSIONS

32

Maximum simultaneous active SSH connections

SSH_MCP_MAX_OUTPUT_BYTES

1048576

Combined stdout/stderr limit per command

SSH_MCP_MAX_INLINE_BYTES

1048576

Maximum bytes per inline SFTP operation

SSH_MCP_MAX_COMMAND_SECONDS

120

Maximum accepted SSH command timeout

Tests

python -m pip install -e '.[test]'
pytest -q
python -m compileall -q src tests

The suite includes core SSH/SFTP behavioral tests (with simulated SSH transport), bearer authentication tests, tool registration tests, and a real MCP Streamable HTTP protocol integration test (test_mcp_integration.py) using the installed official MCP SDK. An automated GitHub Actions workflow is included for Python 3.11, 3.12, and 3.13.

To inspect and invoke the real MCP endpoint with a graphical client:

npx -y @modelcontextprotocol/inspector

Connect the inspector to http://127.0.0.1:8000/mcp or to your HTTPS endpoint.

Security

This server can execute arbitrary code with the SSH account's privileges. Run it only for trusted operators and limit SSH account privileges to the servers and paths needed. The server validates remote host keys against known_hosts and rejects untrusted hosts. It prevents MCP-host local transfer paths from escaping the configured transfer directory, but does not restrict remote target paths or commands: those operations are intentionally powerful. Protect the endpoint with a Tunnel or TLS and authentication; never publish it anonymously. Back up remote files before destructive changes.

Development and CI

Run python -m pip install -e '.[test]' in a virtual environment, then bash scripts/check.sh to compile the Python sources, execute the tests, check dependency consistency, and (when build is installed) construct wheel and source distributions.

GitHub Actions runs the full test suite on Python 3.10 through 3.13, including a Streamable HTTP handshake and MCP tool discovery using the installed official SDK. After tests pass, it builds and verifies a wheel and source archive, uploads them as workflow artifacts, and builds a Docker image. The Docker job also checks that an unauthenticated HTTP request is rejected. The pipeline does not push container images or publish to a package registry.

Remote command output and input are bounded by the configured maximum sizes. Commands have an execution timeout; a timed-out command's SSH channel is closed. SFTP files are created exclusively by default and overwrite operations require an explicit overwrite=true. Local downloaded files are created atomically. The transfer directory should be accessible only to the MCP service account.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to securely execute remote SSH commands, perform file transfers, and monitor system status through a standardized interface. It features robust security controls including command whitelisting, blacklisting, and credential isolation to prevent unauthorized operations.
    10
    11 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.
    218 npm
    37
    Apache 2.0