Skip to main content

SSH & SFTP MCP Server (ssh-mcp-vn)

MCP server SSH/SFTP cho nhiều máy chủ Windows/Linux. Từ 0.7.0 server chỉ gồm sáu tool: chạy lệnh, tạo thư mục, liệt kê thư mục, upload/download file có xác minh SHA-256 và liệt kê server đã cấu hình. Durable job, nProx Runner, PTY và các tool SFTP legacy đã bị gỡ; xem CHANGELOG để biết cách chuyển đổi.

Verified file transfers

sftp_upload and sftp_download use configured aliases only, with no inline credentials, file content or Base64. Both return {server_name,source_path,destination_path,bytes_transferred, sha256,verification}; verification is always sha256, even without an expected digest.

Input Contract
local_path Required nonempty POSIX-relative file path inside the MCP host's SFTP_STAGING_ROOT, not the caller device; upload source or download destination. Example: release/app.zip.
remote_path Required absolute file path using forward slashes, inside the alias's transfer roots. Examples: /srv/releases/app.zip, C:/releases/app.zip.
server_name Optional configured alias; default null selects the only configured server. Required with multiple aliases. Example: build.
expected_sha256 Optional 64-hex-digit source digest; default null. Example: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad.
overwrite Optional boolean, default false (atomic no-clobber). True permits atomic replacement of an existing regular file.

Configure an absolute existing SFTP_STAGING_ROOT on the MCP host and optional per-alias allowed_transfer_roots, for example ["/srv/releases", "/srv/backups"] or ["C:/releases", "C:/backups"]. An empty list allows only canonical remote login home and its descendants, not the whole filesystem. Parents must already exist: transfers do not create directories. Paths reject traversal, symlinks, junction/reparse traversal, devices and alternate data streams. Keep these roots private to trusted transfer/service accounts; SFTP metadata does not replace filesystem ACLs or protection against another privileged writer.

SFTP_MAX_FILE_SIZE is a positive byte limit, default 2147483648 (2 GiB), checked before and during streaming and independent temporary-file readback. Source bytes are incrementally hashed; a securely named exclusive sibling temporary file is independently SHA-256 checked before atomic publication. Remote overwrite requires the server's POSIX-rename extension; there is no delete-and-rename fallback. Local no-clobber uses a same-directory hard link and requires filesystem support. Neither operation replays automatically. On uncertain disconnect/publication, inspect the destination and named .part-* sibling before deciding what to do; temporary evidence is deliberately retained. Only definite pre-publication failures clean their validated temporary file. Source files remain untouched.

Example upload:

{"local_path":"release/app.zip","remote_path":"/srv/releases/app.zip","server_name":"build","overwrite":false}

Call sftp_download with the same shape to fetch a file into staging; create the destination folder (for example logs) inside staging first. File bytes never enter MCP JSON.

Hướng dẫn cài đặt

Chạy qua UVX (Được khuyến nghị)

Bạn có thể chạy trực tiếp server này qua uvx mà không cần phải tải hay cài đặt thủ công:

uvx ssh-mcp-vn==0.7.1

Các tính năng chính

  • Multi-host: tương tác với nhiều máy chủ mà không cần chạy nhiều instance.
  • Thực thi qua SSH: chạy lệnh shell trên máy chủ từ xa.
  • Quản lý thư mục: tạo và liệt kê thư mục từ xa.
  • Truyền file có xác minh: SFTP upload/download với SHA-256, giới hạn root và ghi nguyên tử.

Cấu hình (Khuyên dùng qua File JSON)

Vì mảng cấu hình có thể khá dài và việc viết chuỗi JSON dính liền với các dấu \ (escape) trong cấu hình môi trường sẽ phức tạp, bạn nên tách cấu hình ra một file JSON riêng biệt.

Bước 1: Tạo một file có tên ssh_servers.json ở bất kỳ đâu trên máy của bạn (ví dụ C:\Users\BiNgo\.codex\ssh_servers.json) và điền danh sách các server dạng mảng thuần túy.

Ưu tiên dùng SSH key qua key_path và user vận hành riêng có sudo. Không nên để root + password plaintext làm cấu hình mặc định.

[
  {
    "name": "toppion-linux",
    "host": "192.168.1.100",
    "user": "ops",
    "key_path": "C:\\Users\\BiNgo\\.ssh\\toppion_ops_ed25519",
    "port": 22
  },
  {
    "name": "toppion-registry",
    "host": "192.168.1.101",
    "user": "ops",
    "key_path": "C:\\Users\\BiNgo\\.ssh\\toppion_ops_ed25519"
  },
  {
    "name": "toppion-master",
    "host": "192.168.1.102",
    "user": "ops",
    "key_path": "C:\\Users\\BiNgo\\.ssh\\toppion_ops_ed25519"
  }
]

Bước 2: Cập nhật mcp_config.json của ArcticFactory chỉ truyền vào biến SSH_CONFIG_FILE trỏ đến file đó:

{
  "mcpServers": {
    "ssh-server": {
      "command": "uvx",
      "args": [
        "ssh-mcp-vn==0.7.1"
      ],
      "env": {
        "SSH_CONFIG_FILE": "C:\\Users\\NamHT\\ssh_servers.json"
      }
    }
  }
}

Lấy danh sách server từ NProx API

Khi inventory được quản lý tập trung, truyền --url-host và đặt token trong biến môi trường SSH_URL_HOST_TOKEN. URL phải là HTTPS; token không được đưa vào args, log hoặc output tool.

{
  "mcpServers": {
    "ssh-server": {
      "command": "uvx",
      "args": [
        "ssh-mcp-vn==0.7.1",
        "--url-host",
        "https://nprox.dev/api/external/devops/servers"
      ],
      "env": {
        "SSH_URL_HOST_TOKEN": "<NPROX_API_TOKEN>",
        "SSH_REMOTE_POLICY": "{\"windows-build\":{\"allowed_transfer_roots\":[\"C:/releases\"]}}"
      }
    }
  }
}

Endpoint phải trả về object có mảng servers; mỗi item cần name, host, port và username. Nếu item không có password/key_path, MCP gọi endpoint kế bên /connection?name=<URL-encoded-name> bằng cùng Bearer token và chỉ giữ credential trong process; credential không xuất hiện trong tool schema, log hoặc kết quả.

Inventory từ API được nạp lại tự động khi cache quá SSH_URL_HOST_TTL giây (mặc định 60; 0 là nạp lại mỗi lần dùng tool), nên server thêm, xóa hoặc đổi credential ở API sẽ có hiệu lực mà không cần restart. Gọi list_ssh_servers với refresh=true để nạp lại ngay. Nếu API lỗi lúc nạp lại, server giữ inventory cũ và ghi cảnh báo ra stderr. Với file hoặc env, cache chỉ đổi khi gọi refresh=true.

SSH_REMOTE_POLICY là object JSON theo tên server, chỉ cho phép field không chứa secret allowed_transfer_roots. Nó không thể thay host, user, port hoặc credential.

Thêm server KHÔNG dùng file JSON (nhập thẳng)

Nếu chỉ có 1 server và không muốn tạo file cấu hình hay escape chuỗi JSON, bạn có thể khai báo từng biến env riêng trong mcp_config.json:

Dạng 1 — Một server (từng biến env riêng, khuyên dùng):

{
  "mcpServers": {
    "ssh-server": {
      "command": "uvx",
      "args": [
        "ssh-mcp-vn==0.7.1"
      ],
      "env": {
        "SSH_NAME": "production",
        "SSH_HOST": "192.168.1.10",
        "SSH_USER": "ops",
        "SSH_PORT": "22",
        "SSH_KEY_PATH": "~/.ssh/toppion_ops_ed25519"
      }
    }
  }
}

Các biến hỗ trợ: SSH_NAME (bắt buộc), SSH_HOST (bắt buộc), SSH_USER, SSH_PORT (mặc định 22), SSH_KEY_PATH, SSH_PASSWORD.

Dạng 2 — Nhiều server (mảng JSON):

{
  "mcpServers": {
    "ssh-server": {
      "command": "uvx",
      "args": [
        "ssh-mcp-vn==0.7.1"
      ],
      "env": {
        "SSH_SERVERS": "[{\"name\": \"production\", \"host\": \"192.168.1.10\", \"user\": \"ops\", \"key_path\": \"~/.ssh/toppion_ops_ed25519\"}, {\"name\": \"staging\", \"host\": \"192.168.1.11\", \"user\": \"ops\", \"key_path\": \"~/.ssh/toppion_ops_ed25519\"}]"
      }
    }
  }
}

Thứ tự ưu tiên: SSH_URL_HOST > SSH_CONFIG_FILE > SSH_SERVERS > các biến SSH_NAME/SSH_HOST riêng lẻ. Nếu chỉ có 1 server, dùng Dạng 1 cho gọn, không cần escape JSON.

Hoặc chạy trực tiếp qua CLI với tham số --servers (dùng để test nhanh, hỗ trợ cả object đơn lẫn array):

uvx ssh-mcp-vn==0.7.1 --servers '{"name": "production", "host": "192.168.1.10", "user": "ops", "key_path": "~/.ssh/toppion_ops_ed25519"}' --smoke-test production

Các trường trong từng block JSON cấu hình

Mỗi object của một server hỗ trợ các trường sau:

  • name (bắt buộc): Tên gọi riêng cho server này (VD: "production", "staging") để giúp công cụ AI nhận biết server muốn thao tác.
  • host (bắt buộc): Địa chỉ IP hoặc Hostname của máy chủ SSH.
  • user (bắt buộc): Tên đăng nhập (username).
  • port (tùy chọn): Cổng SSH, mặc định là 22.
  • key_path (khuyên dùng): Đường dẫn tuyệt đối đến file khóa bí mật (private key).
  • password (tùy chọn, không khuyên dùng): Mật khẩu đăng nhập. Chỉ nên dùng tạm khi chưa chuyển xong sang SSH key.

Kiểm tra cấu hình và smoke test

Sau khi sửa ssh_servers.json, hãy restart/reload Codex MCP trước khi kết luận lỗi config vì MCP server đọc cấu hình khi process khởi động.

Kiểm tra config đã được đọc đúng và không in secret:

uvx ssh-mcp-vn==0.7.1 --config-file "C:\Users\BiNgo\.codex\ssh_servers.json" --validate-config

Chạy smoke test chuẩn cho toàn bộ server:

uvx ssh-mcp-vn==0.7.1 --config-file "C:\Users\BiNgo\.codex\ssh_servers.json" --smoke-test all

Smoke test dùng lệnh:

hostname && whoami && pwd && uptime

Nếu đang làm trực tiếp trong source repo, có thể dùng script:

python3 uvx/ssh/scripts/smoke_test.py --config-file "C:\Users\BiNgo\.codex\ssh_servers.json" --server all

Checklist vận hành ngắn:

  1. Dùng alias MCP thống nhất: toppion-linux, toppion-registry, toppion-master.
  2. Không phụ thuộc shell alias; MCP chỉ dùng name trong ssh_servers.json.
  3. Ưu tiên key_path; hạn chế password plaintext.
  4. Dùng user vận hành riêng có sudo; chỉ dùng root khi thật cần.
  5. Sửa config xong thì restart/reload Codex MCP rồi chạy smoke test.

Danh sách công cụ (Tools)

Tool Mục đích
ssh_execute_command Chạy một lệnh shell và chờ kết thúc (giới hạn SSH_COMMAND_TIMEOUT, mặc định 30 giây).
ssh_create_folder Tạo thư mục từ xa, tạo cả thư mục cha (mkdir -p). Cần trước khi upload vào thư mục mới.
sftp_list_directory Liệt kê tên và kích thước file trong một thư mục từ xa.
sftp_upload Upload file từ staging root của MCP host, xác minh SHA-256 và ghi nguyên tử.
sftp_download Download file từ xa vào staging root của MCP host, xác minh SHA-256 và ghi nguyên tử.
list_ssh_servers Liệt kê server đã cấu hình (không trả password). Luôn có mặt; refresh=true nạp lại inventory ngay, ví dụ sau khi thêm/xóa server ở API.

Khi chỉ cấu hình 1 server, server_name là tùy chọn. Khi có nhiều server, server_name là bắt buộc; gọi list_ssh_servers để xem alias hợp lệ.

Mọi tool chỉ nhận configured alias qua server_name; không tool nào nhận host, user, port, password hay key_path trong lời gọi. Credential chỉ nằm trong cấu hình server.

Hướng dẫn sử dụng (Usage)

ssh_execute_command
  server_name: toppion-linux
  command: df -h
ssh_create_folder
  server_name: toppion-linux
  path: /srv/releases/2026-09
sftp_list_directory
  server_name: toppion-linux
  path: /srv/releases
{"local_path":"release/app.zip","remote_path":"/srv/releases/2026-09/app.zip","server_name":"toppion-linux"}

Gọi sftp_upload với object trên; sftp_download dùng cùng shape. Mọi input đều có mô tả, ràng buộc, giá trị mặc định và ví dụ trong JSON Schema (được tests/test_tool_schema.py kiểm tra).

Biến môi trường vận hành

Biến Mặc định Ý nghĩa
SSH_COMMAND_TIMEOUT 30 Số giây tối đa ssh_execute_command chờ một lệnh kết thúc. Lệnh chạy lâu hơn cần được tách nhỏ hoặc chạy nền bằng nohup rồi đọc log.
SFTP_STAGING_ROOT không có Thư mục tuyệt đối, đã tồn tại, trên máy chạy MCP; nơi sftp_upload/sftp_download đọc và ghi file. Bắt buộc để dùng truyền file.
SFTP_MAX_FILE_SIZE 2147483648 Giới hạn kích thước file (byte, số nguyên dương) cho mỗi lần truyền.
SSH_URL_HOST_TTL 60 Số giây inventory từ --url-host được coi là còn mới (số không âm; 0 = luôn nạp lại). Giá trị sai dùng mặc định.
SSH_URL_HOST_TOKEN không có Bearer token cho --url-host; chỉ đặt trong env, không đưa vào args.

Changelog

0.7.1 - 2026-10-21

New

  • Inventory từ --url-host tự nạp lại sau SSH_URL_HOST_TTL giây (mặc định 60); lỗi API lúc nạp lại giữ inventory cũ.
  • list_ssh_servers luôn được đăng ký và nhận refresh (boolean, mặc định false) để nạp lại ngay.

0.7.0 - 2026-10-21

Breaking

  • Thu gọn server còn sáu tool: ssh_execute_command, ssh_create_folder, sftp_list_directory, sftp_upload, sftp_download, list_ssh_servers (chỉ khi cấu hình nhiều server).
  • Gỡ durable job, nProx Runner, PTY, Windows installer và các tool sftp_upload_file, sftp_download_file, sftp_upload_staged_file. Việc chạy lâu phải đi qua ssh_execute_command.
  • Gỡ inline connection (host, user, port, password, key_path) khỏi mọi tool; chỉ dùng alias trong server_name.
  • SSH_REMOTE_POLICY chỉ còn nhận allowed_transfer_roots.

Fixed

  • sftp_list_directory không còn trả ký tự xuống dòng dạng literal giữa các mục.

Xem lịch sử đầy đủ tại CHANGELOG.md.

License

MIT

Metadata

Release files for ssh-mcp-vn 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ssh-mcp-vn 0.7.1
File Size Uploaded Provenance
ssh_mcp_vn-0.7.1.tar.gz 42.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ssh-mcp-vn 0.7.1
File Interpreter ABI Platform
ssh_mcp_vn-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 64.6 kB

Release files / ssh_mcp_vn-0.7.1.tar.gz

Download URL ssh_mcp_vn-0.7.1.tar.gz
Size 42.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6f5bb5633410c57d006cdd0d0aeaee7b3fe91a6082cf7c24e1647b6a56714cf6
BLAKE2b-256 checksum
How to use checksums
849172aa5600f86a59cbc19c5689493136ca2f54b600b9b6a8907f33fbf3b45a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / ssh_mcp_vn-0.7.1-py3-none-any.whl

Download URL ssh_mcp_vn-0.7.1-py3-none-any.whl
Size 22.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0dd79a45bbc324ba45105a8a4e6dc6a7bad324d040aa160a28797c6ed705e2d
BLAKE2b-256 checksum
How to use checksums
3c7c62d61c6f2a258c955ecd782541a2d9ac9afbd13f93a2894fc4dc68c90bbb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for ssh-mcp-vn 0.7.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page