SSH MCP Server
resmiJalankan perintah, pindahkan file, cari log, dan audit mesin melalui SSH dari agen Anda.
Apa yang bisa Anda lakukan dengan SSH MCP?
- Menjalankan perintah dengan pengaman — Minta asisten Anda untuk mengeksekusi perintah tunggal atau batch melalui
ssh_exec, dengan perlindungan perintah destruktif yang memblokir operasi ireversibel sebelum mencapai server. - Membaca, menulis, dan mendaftar file jarak jauh — Gunakan
ssh_file_read,ssh_file_write, danssh_file_listuntuk memeriksa atau memodifikasi file, dengan penulisan atomik dan verifikasi SHA-256 opsional. - Mencari log dan memeriksa kesehatan server — Kueri
ssh_log_searchataussh_log_taildi seluruh file dan kontainer, atau dapatkan gambaran kesehatan terstruktur denganssh_snapshotdanssh_audit_baseline. - Transfer file dengan pemeriksaan integritas — Unggah atau unduh file dan direktori melalui
ssh_uploaddanssh_download, dengan fallbackscplama otomatis untuk perangkat yang lebih tua. - Kelola pekerjaan latar belakang yang berjalan lama — Lepaskan operasi lambat dengan
ssh_execdan lacak melaluissh_job_status,ssh_job_output, danssh_job_kill, yang tetap bertahan saat koneksi terputus.
Dokumentasi
SSH MCP Server — Perkakas server jarak jauh untuk agen AI
|
|
Server SSH MCP — perkakas serbaguna yang menghemat waktu dan token bagi Anda serta agen AI dalam debugging, pengembangan, dan pemeliharaan server. Jalankan perintah, pindahkan berkas, baca log, dan audit mesin melalui SSH — VPS cloud, mesin bare-metal, atau router BusyBox yang tersimpan di lemari Anda. |
Server ini menggunakan klien OpenSSH yang sudah ada di mesin Anda: kunci Anda, ~/.ssh/config Anda, host lompatan Anda, penerusan agen Anda. Tidak ada yang dibundel, tidak ada yang perlu dikompilasi, tidak ada pengikatan native.
Berfungsi dengan Claude Code, Codex CLI, Cline, opencode, Gemini CLI, Qwen Code, Hermes, dan klien MCP lainnya.
Instalasi · Perkakas · Pengaturan · Keamanan · Peta Jalan · Dokumentasi · Catatan Perubahan
Instalasi dalam 30 detik
Tidak diperlukan instalasi global. npx mengunduh paket pada penggunaan pertama:
npx -y @hypnosis/ssh-mcp-server
Tambahkan ke klien MCP Anda — Claude Code, misalnya — untuk setiap proyek:
claude mcp add ssh -s user \
-e SSH_PROFILES_FILE="$HOME/.claude/ssh-profiles.json" \
-- npx -y @hypnosis/ssh-mcp-server
Atau tulis secara manual — server yang sama dalam bentuk konfigurasi yang digunakan sebagian besar klien:
{
"mcpServers": {
"ssh": {
"command": "npx",
"args": ["-y", "@hypnosis/ssh-mcp-server"],
"env": {
"SSH_PROFILES_FILE": "~/.claude/ssh-profiles.json"
}
}
}
}
Lalu buat ~/.claude/ssh-profiles.json dengan setidaknya satu mesin:
{
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin",
"privateKeyPath": "~/.ssh/your_private_key"
}
}
}
Itu sudah cukup untuk terhubung.
Codex, opencode, Qwen Code, dan klien lainnya dibahas di Menyiapkan server SSH MCP.
Instal sebagai plugin
Beberapa klien — Claude Code, misalnya — dapat menggunakan semuanya sebagai plugin:
/plugin marketplace add hypnosis/ssh-mcp-server
/plugin install ssh-mcp-server@ssh-mcp-server
Plugin membaca ~/.claude/ssh-profiles.json kecuali SSH_PROFILES_FILE menyatakan sebaliknya, jadi
buat berkas itu terlebih dahulu dan server akan muncul dengan mesin-mesin Anda sudah dimuat.
Persyaratan
Node.js 18+ dan klien ssh sistem pada PATH. Di Windows, gunakan profil berbasis kunci;
profil kata sandi dan frasa sandi saat ini tidak tersedia.
Lebih suka versi tetap, pekerjaan luring, atau satu pemeriksaan registri lebih sedikit setiap peluncuran:
npm install -g @hypnosis/ssh-mcp-server, lalu gunakan ssh-mcp-server sebagai perintah, bukan
npx.
Untuk siapa server ini
- DevOps dan SRE yang menginginkan audit lebih cepat, pemeriksaan insiden, dan pekerjaan server rutin.
- Vibe coders dan pembangun indie yang mengirim dengan asisten AI dan menjalankan apa yang mereka bangun di server mereka sendiri.
- Administrator sistem dan insinyur platform yang menginginkan perkakas terstruktur, bukan shell mentah tanpa batasan.
- Pengembang dan tim kecil yang menjalankan VPS sendiri tanpa tim operasi khusus.
- Pemilik homelab, NAS, dan router yang perangkat kerasnya masih berguna tetapi protokolnya sudah usang.
Mengapa server SSH MCP, bukan shell mentah
Lebih sedikit token, biaya AI lebih rendah
Shell mentah memberi agen AI aliran data berlebihan: perintah berulang, tabel ASCII, dan tumpukan log. Itu menghabiskan token untuk mengubah kebisingan itu menjadi gambaran server — uang Anda.
Debugging server lebih cepat
Perkakas yang dirancang khusus menggabungkan pemeriksaan rutin, membatasi keluaran yang bising, dan mengembalikan bagian yang penting. Agen menghabiskan lebih sedikit waktu menerjemahkan keluaran terminal dan lebih cepat menemukan perbaikan.
Lebih sedikit tebakan, lebih sedikit kesalahan AI
Jawaban terstruktur menyatakan apa yang ditemukan, apa yang tidak dapat diukur, dan apa yang dipotong. Itu memberi agen lebih sedikit ruang untuk mengisi celah dengan halusinasi — dan memberi Anda lebih sedikit perbaikan yang buruk, penerapan yang lebih tenang, dan kode yang lebih andal.
Kompatibilitas SSH: server modern, perangkat lama, dan Windows
Gunakan pengaturan OpenSSH yang sudah ada
Tidak ada implementasi SSH yang dibundel, tidak ada pengikatan native, tidak ada kompilasi ulang per platform. Perintah menggunakan
klien ssh sistem, jadi kunci Anda, ~/.ssh/config Anda, host lompatan Anda, dan penerusan agen Anda
semuanya tetap berfungsi persis seperti di terminal. Jika didukung, satu koneksi
multipleks bersama per tujuan berarti Anda mengautentikasi sekali, bukan sekali per perintah.
Dukungan SSH untuk server lama, router, dan perangkat NAS
Kirim berkas ke router dengan scp modern dan Anda mendapatkan ini:
scp app.conf router:/etc/
# scp: subsystem request failed on channel 0
Tidak ada yang rusak — scp saat ini berbicara protokol baru, dan router tidak mengetahuinya.
Di terminal, Anda sekarang harus membaca forum dan kembali dengan bendera tambahan. Di sini Anda tidak
melakukan apa pun: transfer dicoba, penolakan dikenali, protokol lama digunakan sebagai gantinya,
dan mesin itu diingat sehingga berkas berikutnya langsung sampai.
Cadangan untuk klien SSH lama dan perkakas yang hilang
Perangkat lama mendapat cadangan, bukan jalan buntu. Saat fitur modern tidak tersedia, server mengambil jalan lama jika memungkinkan:
| Mesin Anda | Yang Anda dapatkan |
|---|---|
| Router atau NAS terlalu kecil untuk transfer berkas modern | Berkas tetap sampai — protokol lama digunakan otomatis |
| Server dari sepuluh tahun lalu | Alur kerja tetap berjalan; hanya membuka koneksi baru per perintah, bukan memakai ulang |
| Citra yang dipreteli tanpa cara untuk menghitung hash berkas | Unggahan menyatakan "tidak dapat memverifikasi", bukan mengklaim kecocokan yang tidak diperiksa siapa pun |
| Mesin yang tidak memiliki perkakas tertentu | Jawaban menyatakan "tidak diukur" — tidak pernah nol yang terbaca sebagai "tidak ada apa-apa" |
Dibangun untuk Model Context Protocol
Dibangun di atas SDK MCP resmi, TypeScript di seluruh kode, 2500+ pengujian unit plus rangkaian langsung yang berjalan terhadap kontainer nyata, bukan tiruan.
SSH mentah vs server SSH MCP: pekerjaan yang sama, dua cara
Pemeriksaan kesehatan server SSH
Situasi: Penerapan baru saja dilakukan. Server terasa lambat, dan Anda tidak tahu apakah disk, memori, layanan, kontainer, atau kesalahan yang menjadi penyebab.
Pertanyaan: "Apakah mesin ini sehat?"
SSH mentah
$ uptime
10:42:17 up 18 days, 3:21, 2 users, load average: 0.42, 0.31, 0.28
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 40G 35G 5.0G 87% /
overlay overlay 40G 35G 5.0G 87% /var/lib/docker/overlay2/...
$ free -h
total used free shared buff/cache available
Mem: 7.7Gi 4.9Gi 612Mi 121Mi 2.2Gi 2.5Gi
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● api-worker.service loaded failed failed API background worker
$ docker ps -a
CONTAINER ID IMAGE STATUS PORTS
8e14d0b41c2a api:latest Up 3 minutes 0.0.0.0:8080->8080/tcp
65b894af2430 worker:latest Exited (1) 2 minutes ago
$ ss -tulpn
Netid State Local Address:Port Process
tcp LISTEN 0.0.0.0:22 users:(("sshd",pid=842,fd=3))
tcp LISTEN 0.0.0.0:8080 users:(("docker-proxy",pid=1942,fd=4))
$ journalctl -p err --since -1h | tail -50
Aug 20 10:39:14 prod api-worker[22104]: database connection timed out
Aug 20 10:39:14 prod systemd[1]: api-worker.service: Failed with result 'exit-code'.
Itu pun masih hasil yang diringkas. Pemeriksaan lengkap membutuhkan lebih banyak perintah untuk CPU, status
layanan, jumlah kontainer, dan kesalahan terbaru, masing-masing dengan format keluaran sendiri. Lebih buruk lagi, mesin
tanpa ss bisa terlihat seperti tidak memiliki pendengar sama sekali ketika pemeriksaan port tidak pernah dijalankan.
Hasil MCP terstruktur
ssh_snapshot({ "profile": "production" })
{
"disk_pct": 87,
"mem_pct": 64,
"cpu_pct": 12,
"load": "0.42 0.31 0.28",
"containers": 7,
"ports": 14,
"services_running": 3,
"recent_errors": 21,
"unavailable": []
}
Yang diperoleh agen
| SSH mentah | MCP terstruktur | Keuntungan Anda |
|---|---|---|
| Beberapa perintah dan tabel ASCII | Kolom bernama dalam satu hasil | Satu panggilan, kolom bernama, dan lebih sedikit perjalanan bolak-balik |
| Perkakas yang hilang bisa terlihat seperti keluaran kosong | unavailable menyebutkan apa yang tidak diukur | Lebih sedikit tebakan dan lebih sedikit perbaikan buruk |
| Anda memilah disk, layanan, dan kesalahan | Sinyal masalah sudah dimunculkan | Debugging lebih cepat |
Hasil ssh_audit_baseline lengkap bisa lebih panjang daripada beberapa keluaran perintah mentah —
sekitar 1.077 token dibanding 765 dalam pengukuran lab kami. Penghematan datang dari alur kerja
lengkap, bukan dari membuat satu respons lebih pendek.
Dalam sesi pemecahan masalah nyata, perkakas yang dirancang khusus mengurangi 49 panggilan perintah terpisah menjadi 4 panggilan MCP. Setiap panggilan tambahan memulai giliran model lain dengan percakapan yang terakumulasi. Cache prompt dapat mengurangi biaya masukan berulang, tetapi perintah baru dan keluarannya tetap mengonsumsi konteks. Lebih sedikit perjalanan bolak-balik berarti lebih sedikit token di seluruh sesi, lebih sedikit analisis berulang, dan jalur lebih cepat menuju jawaban.
Butuh gambaran menyeluruh, bukan hanya denyut nadi? ssh_audit_baseline menggabungkan sistem, disk,
memori, port, sshd, unit yang gagal, Docker, firewall, dan pembaruan. Temuan tiba sebagai
KRITIS / PERINGATAN / OK; bagian yang tidak diukur disebutkan, bukan diam-diam terbaca sebagai nol.
Pencarian log server Linux
Situasi: API mengalami waktu tunggu, tetapi pesan yang sama mungkin ada di nginx, syslog, journald, atau log aplikasi yang tidak dapat Anda baca dengan pengguna normal Anda.
Pertanyaan: "Dari mana kesalahan itu berasal?"
SSH mentah
$ grep -i "timeout" /var/log/nginx/error.log
2026/08/20 10:38:54 [error] upstream timed out while reading response header
$ grep -i "timeout" /var/log/syslog
Aug 20 10:39:14 prod api-worker[22104]: database connection timed out
$ grep -i "timeout" /var/log/app/*.log 2>/dev/null
$ journalctl -u api --since "1 hour ago" | grep -i timeout
Aug 20 10:39:14 prod api[22104]: database connection timed out after 30000ms
Perintah ketiga terlihat bersih, tetapi 2>/dev/null juga menyembunyikan kesalahan izin. "Tidak ada
yang cocok" dan "tidak ada yang dibaca" kini terlihat identik. Log yang sibuk juga dapat mengembalikan ribuan
baris dan mendorong sisa insiden keluar dari konteks agen.
Hasil MCP terstruktur
ssh_log_search({ "profile": "production",
"path": ["/var/log/nginx/error.log", "/var/log/syslog", "/var/log/app/*.log"],
"query": "timeout", "context": 2, "since": "1h" })
{
"matches": 34,
"lines": [
{ "file": "/var/log/nginx/error.log", "line": 4821,
"text": "upstream timed out while reading response header", "context": false },
{ "file": "/var/log/nginx/error.log", "line": 4822,
"text": "client closed connection", "context": true }
],
"files_searched": 6,
"files_unreadable": ["/var/log/app/private"],
"files_skipped": 12,
"files_undated": [],
"limited": false,
"truncated": false
}
Yang diperoleh agen
| SSH mentah | MCP terstruktur | Keuntungan Anda |
|---|---|---|
| Empat pencarian dan empat keluaran | Satu pencarian di seluruh berkas dan glob | Lebih sedikit token dan perjalanan bolak-balik |
| Kesalahan izin bisa hilang | files_unreadable menyebutkan setiap jalur yang terlewat | Tidak ada kesimpulan palsu "log bersih" |
| Keluaran bisa tumbuh tanpa batas yang berguna | limited dan truncated menampilkan setiap pemotongan | Keputusan lebih aman dari hasil parsial |
since menggunakan jam server, namesOnly: true mengembalikan hanya jalur yang cocok, dan
ssh_log_tail membaca N baris terakhir dari beberapa log dalam satu panggilan.
Pengeditan konfigurasi jarak jauh yang aman
Situasi: Anda perlu mengganti konfigurasi nginx di server langsung. Koneksi terputus, mode salah, atau salinan yang tidak diperiksa dapat membuat layanan dengan berkas rusak.
Pertanyaan: "Dapatkah saya mengganti konfigurasi ini tanpa meninggalkan berkas parsial?"
SSH mentah
$ sudo sh -c 'cat > /etc/nginx/conf.d/api.conf' <<'EOF'
server {
listen 80;
location / { proxy_pass http://127.0.0.1:8080; }
}
EOF
$ echo $?
0
Kode keluar nol mengatakan shell selesai. Itu tidak membuktikan byte mana yang mendarat, dan >
memotong berkas lama sebelum byte pertama berkas baru tiba. Jika koneksi terputus
di tengah penulisan, layanan dibiarkan dengan konfigurasi parsial.
Hasil MCP terstruktur
ssh_file_write({ "profile": "production",
"files": [{ "path": "/etc/nginx/conf.d/api.conf",
"content": "server {\n listen 80;\n location / { proxy_pass http://127.0.0.1:8080; }\n}\n",
"mode": "644", "sudo": true, "verify": true }] })
{
"files": [{ "path": "/etc/nginx/conf.d/api.conf", "written": true,
"verified": "verified", "reason": null, "bytes": 79 }]
}
Yang diperoleh agen
| SSH mentah | MCP terstruktur | Keuntungan Anda |
|---|---|---|
| Target dipotong sebelum salinan selesai | Berkas temp lengkap menggantikannya dengan satu penggantian nama | Tidak ada konfigurasi setengah tertulis |
| Hanya kode keluar | Byte dan hasil verifikasi disebutkan | Anda tahu apa yang benar-benar mendarat |
| Izin ada di dalam teks shell | sudo, mode, dan verify adalah kolom per berkas | Kepemilikan dapat diprediksi dan lebih sedikit kesalahan tanda kutip |
verified memiliki tiga hasil jujur: verified, unavailable saat server tidak memiliki perkakas hash,
dan skipped saat verifikasi tidak diminta. Untuk pembacaan, ssh_file_read menerima
daftar jalur; ssh_file_list menangani glob, rekursi, ukuran, dan mode.
Jalankan perintah SSH batch dengan sudo
Situasi: Penerapan sudah siap, tetapi sintaks nginx, status layanan, dan kesalahan terbaru harus semua diperiksa sebelum lalu lintas dipindahkan. Satu pemeriksaan yang gagal tidak boleh hilang di dalam tumpukan gabungan.
Pertanyaan: "Apakah semua pemeriksaan pra-penerapan lulus?"
SSH mentah
$ ssh admin@server.example.com 'sudo nginx -t'
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ ssh admin@server.example.com 'sudo systemctl is-active nginx'
active
$ ssh admin@server.example.com 'sudo tail -5 /var/log/nginx/error.log'
2026/08/20 10:38:54 [error] upstream timed out while reading response header
Tiga koneksi mengembalikan tiga keluaran yang tidak terkait. Jika perintah digabung dengan ;, shell
hanya melaporkan kode keluar terakhir; jika digabung dengan &&, pemeriksaan berikutnya hilang
setelah kegagalan pertama.
Hasil MCP terstruktur
ssh_exec({ "profile": "production",
"command": ["nginx -t", "systemctl is-active nginx",
"tail -5 /var/log/nginx/error.log"],
"sudo": true })
{
"commands": [
{ "command": "nginx -t", "exit_code": 0, "truncated": false, "clipped_bytes": 0,
"stdout": "", "stderr": "nginx: configuration file /etc/nginx/nginx.conf test is successful\n" },
{ "command": "systemctl is-active nginx", "exit_code": 0, "truncated": false,
"clipped_bytes": 0, "stdout": "active\n", "stderr": "" },
{ "command": "tail -5 /var/log/nginx/error.log", "exit_code": 0, "truncated": false,
"clipped_bytes": 0, "stdout": "2026/08/21 09:14:02 [error] upstream timed out\n", "stderr": "" }
],
"job_id": null
}
Yang diperoleh agen
| SSH mentah | MCP terstruktur | Keuntungan Anda |
|---|---|---|
| Tiga panggilan dan keluaran tidak terkait | Satu daftar perintah berurutan | Lebih sedikit perjalanan bolak-balik |
| Shell gabungan dapat menyembunyikan status antara | Setiap perintah mempertahankan exit_code sendiri | Tidak ada pemeriksaan gagal yang terlewat |
sudo dan tanda kutip diulang dalam teks perintah | sudo berlaku untuk seluruh batch | Lebih sedikit kesalahan tanda kutip |
Pengawal perintah destruktif memeriksa seluruh daftar sebelum perintah pertama dijalankan. Jika satu
entri ditolak, setiap entri lain ditandai sebagai tidak dijalankan dan tidak ada yang dikirim ke server.
Setiap perintah membawa stdout dan stderr masing-masing. Perintah yang berjalan dan tidak mencetak apa pun memiliki string kosong; perintah yang tidak pernah berjalan tidak memiliki bidang seperti itu sama sekali, sehingga keduanya tidak dapat dibingungkan. Output lebih dari 128 KB per perintah menyimpan kedua ujungnya — bagian awal untuk tabel, bagian akhir untuk log — dengan sambungan di antaranya yang menyebutkan jumlahnya, dan clipped_bytes memberi tahu berapa banyak yang dipotong. Pemotongan terjadi pada batas byte dan mundur ke tepi karakter, sehingga jawaban yang terpotong tidak pernah membawa tanda pengganti.
sudo menjangkau server tanpa terminal: jawaban profil diserahkan ke sudo pada input standar. Rahasia mana yang digunakan berasal dari sudoPassword ketika profil menyebutkan satu dan dari password jika tidak — profil yang masuk dengan kunci tidak memiliki kata sandi login sama sekali, dan di mana mesin memisahkan keduanya, kata sandi login adalah jawaban yang salah. Jika tidak ada yang bisa dijawab, balasannya menyatakan demikian dan menyebutkan jalan keluarnya, alih-alih meninggalkan saran sudo sendiri tentang -S dan pembantu askpass. Perintah yang membaca input standarnya sendiri tidak pernah diberi kata sandi, yang seharusnya tercampur ke dalam data.
Menjalankan pekerjaan SSH yang berumur panjang
Situasi: Cadangan atau migrasi akan berjalan lebih lama dari sesi agen. Koneksi mungkin tertutup, tetapi Anda masih memerlukan status, output, dan kode keluarnya nanti.
Pertanyaan: "Apakah pekerjaan ini akan bertahan dari percakapan?"
SSH Mentah
$ ssh admin@server.example.com 'pg_dump app | gzip > /srv/backups/app.sql.gz'
client_loop: send disconnect: Broken pipe
Terminal sudah hilang. Anda sekarang harus terhubung kembali, menemukan prosesnya, memeriksa file target, dan menebak apakah cadangan selesai atau berhenti di tengah jalan.
Hasil MCP Terstruktur
ssh_exec({ "profile": "production",
"command": "pg_dump app | gzip > /srv/backups/app.sql.gz",
"detach": true })
{
"commands": [{
"command": "pg_dump app | gzip > /srv/backups/app.sql.gz",
"exit_code": null,
"truncated": false,
"timed_out": false,
"blocked": false,
"blocked_reason": null,
"not_run": false,
"warning": null
}],
"job_id": "mst0f2q1-9ab3c4d5"
}
Apa yang diperoleh agen
| SSH Mentah | MCP Terstruktur | Keuntungan Anda |
|---|---|---|
| Pekerjaan terikat pada satu sesi SSH | Pekerjaan jarak jauh memiliki id persisten | Pemutusan dan mulai ulang yang aman |
| Menghubungkan kembali berarti mencari proses dan file | Status dan kode keluar memiliki status bernama | Tidak perlu menebak apakah selesai |
| Membaca output lagi mengulangi teks lama | Output berlanjut dari offset byte | Penggunaan token lebih rendah pada pekerjaan panjang |
Status pekerjaan tersimpan di disk jarak jauh, bukan di memori server ini. ssh_job_status membedakan running, finished, dan lost; ssh_job_output melanjutkan dari offset byte terakhir; dan ssh_job_kill memberi sinyal ke seluruh grup proses alih-alih hanya shell-nya.
Mentransfer file ke router lama dan perangkat NAS
Situasi: Klien OpenSSH saat ini mencoba SFTP, tetapi router atau NAS hanya memahami protokol scp klasik. File tetap harus tiba dengan utuh dan mengganti targetnya dengan aman.
Pertanyaan: "Dapatkah perangkat lama ini masih menerima file yang terverifikasi?"
SSH Mentah
$ scp app.conf operator@router:/etc/app.conf
subsystem request failed on channel 0
scp: Connection closed
Langkah berikutnya yang biasa adalah mengingat bendera lama, mencoba salinan lagi, lalu menjalankan perintah hash terpisah — jika perangkat memiliki alat hash sama sekali.
Hasil MCP Terstruktur
ssh_upload({ "profile": "router", "local_path": "./app.conf",
"remote_path": "/etc/app.conf", "sudo": true,
"mode": "644", "owner": "root:root", "verify": true })
{
"files": [{
"path": "/etc/app.conf",
"written": true,
"verified": "verified",
"reason": null,
"bytes": 1284
}]
}
Apa yang diperoleh agen
| SSH Mentah | MCP Terstruktur | Keuntungan Anda |
|---|---|---|
| Mode SFTP modern berhenti pada kesalahan pertama | Fallback scp klasik otomatis dan diingat | Perangkat lama masih berfungsi |
| Salinan yang berhasil tidak membuktikan integritas | Verifikasi SHA-256 memiliki hasil bernama | Korupsi tidak disalahartikan sebagai keberhasilan |
| Penggantian langsung dapat meninggalkan target parsial | File sementara dipindahkan ke tempatnya setelah transfer | File yang berfungsi selamat dari gangguan |
Jika perangkat tidak memiliki sha256sum maupun openssl, hasilnya mengatakan unavailable dan menyebutkan alasannya alih-alih melaporkan kecocokan palsu. Seluruh direktori menggunakan recursive: true dan memverifikasi hash-nya dalam satu batch.
Perlindungan perintah destruktif untuk agen AI
Penjaga berjalan secara lokal, sebelum perintah mencapai SSH. Ia memisahkan operasi yang dapat dipulihkan dari yang menghancurkan wadah yang menampung data, dan ia memeriksa urutan perintah di dalam rantai dan batch.
Menghentikan rantai destruktif sebelum dimulai
Urutan cadangkan-dan-ganti yang aman:
cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old && rm -rf /srv/app
Operasi yang sama dalam urutan yang salah:
rm -rf /srv/app && cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old
# REFUSED before the first command runs
Shell akan menghapus direktori dan baru kemudian menemukan bahwa sumber cadangan sudah hilang. Penjaga melihat bahwa langkah-langkah berikutnya membaca target yang sudah dihancurkan oleh langkah sebelumnya, sehingga seluruh panggilan tetap di mesin Anda. Pemeriksaan yang sama menangkap dropdb app && pg_dump app > backup.sql.
Menolak kehilangan yang tidak dapat dipulihkan, memperingatkan tentang perubahan yang dapat dipulihkan
| Ditolak — wadah itu sendiri | Hanya diperingatkan — isinya |
|---|---|
DROP DATABASE, dropdb | DROP TABLE, TRUNCATE, DELETE FROM |
docker volume rm, docker compose down -v | docker rm -f <name> |
crontab -r | mengedit satu pekerjaan |
mkfs, wipefs -a, lvremove, zfs destroy | chmod 777 |
reboot, shutdown, halt | git reset --hard |
docker compose down -v ditolak karena -v menghapus volume Docker bernama, termasuk volume database. Tanpa -v, menghentikan layanan tidak diperlakukan sebagai tindakan tidak dapat dipulihkan yang sama.
Penghapusan rekursif akar sistem file, direktori rumah, atau pohon sistem seperti /etc, /var, dan /usr juga ditolak, termasuk ketika symlink mengarah ke sana. Target yang tidak terselesaikan seperti rm -rf "$DIR"/* juga ditolak: "tidak dapat memeriksa" tidak diperlakukan sebagai "aman".
Sebutkan apa yang Anda hentikan
Perintah yang menemukan targetnya alih-alih menyebutkannya tidak dikirim. Server memperluasnya dan menjawab dengan apa yang ada di balik target:
docker kill $(docker ps -q --filter ancestor=web)
# BLOCKED — would stop:
# edge — web:latest, Up 34 days, 0.0.0.0:8443->8443/tcp
Untuk sebuah proses, jawabannya menambahkan tanda bahwa proses itu sedang digunakan: berapa lama telah berjalan, port mana yang menerima koneksi, berapa banyak koneksi yang dibawanya. Target bernama tidak memerlukan biaya tambahan dan berjalan dalam diam — docker kill web-1, kill 4871, systemctl stop app.
Untuk melanjutkan, sebutkan apa yang sedang dihentikan. Nama-nama diperiksa terhadap apa yang sebenarnya dijangkau perintah, sehingga topeng yang telah bergeser ke hal lain ditolak alih-alih dikonfirmasi:
docker kill $(docker ps -q --filter ancestor=web) # CONFIRMED-KILL: edge
Pola pada baris perintah adalah kasus tersendiri. Pola itu cocok dengan perintah yang membawanya, sehingga shell yang menjalankannya diberi sinyal sebelum target dan balasannya terputus di tengah. Serangan seperti itu tidak dikonfirmasi tetapi ditulis ulang — dengan nomor, atau dengan satu karakter yang ditulis sebagai kelas sehingga pola berhenti mencocokkan dirinya sendiri:
pkill -f relay
# BLOCKED — two ways through:
# kill 4871
# pkill -f '[r]elay' # CONFIRMED-KILL: 4871
Tiga hasil tetap terpisah: target ditemukan, perluasan tidak mencapai apa pun, dan tidak ada yang bisa ditanyakan — tidak ada mesin di mesin, jawaban terpotong, koneksi yang gagal. Dua yang terakhir juga merupakan penolakan: tidak tahu bukan alasan untuk melanjutkan.
Mengonfirmasi perintah destruktif yang disengaja
Tidak ada yang dilarang secara permanen. Tambahkan # CONFIRMED-DESTRUCTIVE ke perintah yang telah ditinjau dan perintah itu diizinkan lewat. Ketika penjaga menolak satu entri dalam batch, seluruh batch berhenti sebelum eksekusi, sehingga server tidak pernah ditinggalkan setelah operasi setengah berjalan.
Penjaga bekerja dalam satu panggilan. Ia tidak dapat menghubungkan penghapusan dalam satu pemanggilan dengan pembacaan di pemanggilan berikutnya, atau bernalar tentang alat yang tidak dikenalnya. Ia adalah sabuk pengaman, bukan mesin kebijakan: operasi yang dapat dipulihkan tetap menjadi keputusan Anda. Pembatasan jalur dan aturan kutipan didokumentasikan di docs/security.md.
Alat
18 alat MCP SSH untuk operasi server. Parameter lengkap dan contoh ada di docs/tools.md.
| Alat | Apa yang dilakukannya |
|---|---|
ssh_exec | Menjalankan satu perintah atau batch, dengan penjaga perintah destruktif dan pelepasan opsional |
ssh_file_read | Membaca satu atau beberapa file, teks atau biner |
ssh_file_write | Menulis file dengan rename atomik dan verifikasi SHA-256 opsional |
ssh_file_list | Mendaftar direktori, dengan glob dan rekursi opsional |
ssh_upload | Mengunggah file atau direktori melalui SSH, aman biner dengan pemeriksaan integritas; direktori menggantikan target atau menggabungkannya |
ssh_download | Mengunduh file atau direktori melalui SSH, aman biner dengan pemeriksaan integritas |
ssh_job_status | Status pekerjaan latar belakang: berjalan, selesai, atau hilang |
ssh_job_output | Membaca output yang terakumulasi dari offset byte |
ssh_job_list | Mendaftar pekerjaan, membersihkan yang selesai melewati TTL-nya |
ssh_job_kill | Memberi sinyal ke seluruh grup proses pekerjaan |
ssh_log_tail | N baris terakhir dari satu atau beberapa log, glob didukung; wadah berdasarkan nama |
ssh_log_search | Pencarian pola di seluruh log, atau melalui log wadah |
ssh_snapshot | Snapshot kesehatan satu kali: layanan, sumber daya, Docker, jaringan, kesalahan |
ssh_monitor | Kontrol transport: statistik, muat ulang, uji, daftar, tutup |
ssh_audit_baseline | Sistem, disk, memori, jaringan, ssh, layanan, Docker, firewall, pembaruan |
ssh_tls_check | Kedaluwarsa sertifikat, SAN, rantai, dan hook pembaruan untuk domain |
ssh_disk_breakdown | Ke mana disk pergi: du top-N, Docker, journald, cache |
ssh_service_status | systemctl status plus ekor journalctl untuk satu unit |
Anotasi keamanan alat MCP
Anotasi MCP standar memberi tahu klien alat mana yang hanya-baca, destruktif, idempoten, atau dunia-terbuka. Lihat tabel lengkap.
Menjalankan perintah SSH dan mengelola file jarak jauh
Perintah, pembacaan dan penulisan file, daftar direktori — pekerjaan biasa di mesin, setiap jawaban sudah diurai.
Memantau pekerjaan SSH yang berumur panjang
Pekerjaan lambat dilepaskan dan diikuti alih-alih ditunggu: setiap pandangan mengatakan seberapa jauh ia berjalan.
Mencari log dan memeriksa kesehatan server
Log file dan wadah, serta gambaran satu kali mesin, dengan output dibatasi sehingga ekor tidak memakan jendela konteks.
Mengunggah dan mengunduh file melalui SSH
Transfer aman biner dengan pemeriksaan integritas. Detail di docs/transfer.md.
Untuk biner dan file besar gunakan
ssh_upload/ssh_download— potongan base64 dan heredoc tidak aman biner atau atomik.
Mengaudit server Linux melalui SSH
Hanya-baca dan digabungkan menjadi satu perjalanan pulang-pergi. Detail di docs/audit.md.
Mode kompatibilitas Windows SSH
Windows menggunakan mode kompatibilitas secara otomatis. Ketika multipleksing koneksi tidak tersedia, server beralih ke satu koneksi per perintah. Alat yang sama tetap tersedia melalui SSH berbasis kunci — tanpa pengaturan terpisah atau implementasi khusus Windows.
Penjaga perintah destruktif tercakup dalam Perlindungan perintah destruktif untuk agen AI.
Menyiapkan server SSH MCP
Jalankan paket dari Instal dalam 30 detik terlebih dahulu, lalu buat file profil.
Membuat profil koneksi SSH
Letakkan di mana pun Anda suka — di samping konfigurasi agen Anda sendiri adalah pilihan yang biasa. Contoh di bawah menggunakan ~/.claude/ssh-profiles.json; untuk agen lain ganti direktori (~/.codex/, ~/.qwen/, ~/.config/opencode/):
{
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin",
"port": 22,
"privateKeyPath": "~/.ssh/your_private_key"
}
}
}
Pilih profil SSH secara eksplisit
Tidak ada profil yang menjadi fallback server: masing-masing adalah mesin yang berbeda, dan perintah yang dikirim ke mesin yang salah bukanlah sesuatu yang dapat dibatalkan oleh pesan kesalahan setelahnya. Tanyakan tanpa nama dan jawabannya mencantumkan nama untuk dipilih:
ssh_exec({ command: "uptime" })
→ No profile specified. Name one explicitly: production
Profil yang tidak dapat digunakan server untuk SSH — tanpa host, tanpa username, atau mode: "local" — dilewati tanpa keluhan, dan bidang yang tidak dikenali dibiarkan saja, sehingga file dapat dibagikan dengan alat lain. Profil dengan bidang yang rusak adalah kasus yang berbeda: profil itu disebutkan bersama bidang dan nilainya, dan tetangga yang sehat tetap berfungsi.
Setiap profil secara opsional mengambil blok pathSecurity yang memasukkan daftar putih atau daftar hitam jalur yang boleh disentuh alat file — lihat docs/security.md.
Profil yang masuk dengan kunci tetapi membutuhkan sudo di sisi jauh mengambil sudoPassword — rahasia yang dijawab sudo, yang di banyak mesin bukan kata sandi login. Simpan di file rahasia alih-alih di sini.
Menjaga kata sandi SSH dan frasa sandi keluar dari profil
Utamakan kunci. Jika kata sandi atau frasa sandi kunci terenkripsi tidak dapat dihindari, simpan dalam file rahasia terpisah, jangan pernah di dalam profil itu sendiri:
{
"secretsFile": "~/.config/ssh-mcp/secrets.json",
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin"
}
}
}
File rahasia dikunci berdasarkan nama profil — lihat secrets.json.example:
{
"production": { "password": "..." },
"buildbox": { "sudoPassword": "..." }
}
sudoPassword adalah jawaban yang diberikan sudo di mesin tersebut. Profil yang masuk dengan kunci tidak memiliki kata sandi masuk untuk ditawarkan, dan jika keduanya berbeda, kata sandi masuk adalah jawaban yang salah; tanpanya, password digunakan.
File rahasia harus hanya dapat dibaca oleh Anda (chmod 600). Jalur relatif diselesaikan dari file profil; rahasia tetap di luar argv dan disamarkan dalam log. Lihat keamanan kredensial.
Konfigurasikan Claude Code, Codex, dan klien MCP lainnya
Pilih klien yang Anda gunakan dan arahkan ke file profil yang sama.
Claude Code
Satu perintah; -s user membuat server tersedia di setiap proyek:
claude mcp add ssh -s user \
-e SSH_PROFILES_FILE="$HOME/.claude/ssh-profiles.json" \
-- npx -y @hypnosis/ssh-mcp-server
Codex CLI
codex mcp add ssh \
--env SSH_PROFILES_FILE="$HOME/.codex/ssh-profiles.json" \
-- npx -y @hypnosis/ssh-mcp-server
opencode
Letakkan di ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ssh": {
"type": "local",
"command": ["npx", "-y", "@hypnosis/ssh-mcp-server"],
"enabled": true,
"environment": {
"SSH_PROFILES_FILE": "~/.config/opencode/ssh-profiles.json"
}
}
}
}
Qwen Code
Satu perintah, sama seperti yang lain:
qwen mcp add ssh \
-e SSH_PROFILES_FILE="$HOME/.qwen/ssh-profiles.json" \
npx -y @hypnosis/ssh-mcp-server
Klien MCP lainnya
Gemini CLI, Hermes, Cline, plugin editor, atau agen Anda sendiri bekerja dengan cara yang sama. Yang mereka butuhkan hanyalah perintah untuk dijalankan dan satu variabel lingkungan.
Mulai ulang klien MCP Anda
Mulai ulang klien, lalu jalankan ssh_monitor({ action: "list" }) untuk mengonfirmasi profil dimuat.
Konfigurasi server SSH MCP
| Variabel | Fungsinya | Default |
|---|---|---|
SSH_PROFILES_FILE | Jalur ke JSON profil — wajib | — |
SSH_MCP_LOG_LEVEL | debug, info, warn, error | info |
LOG_LEVEL | Cadangan, hanya digunakan saat SSH_MCP_LOG_LEVEL tidak disetel | info |
SSH_MCP_LOG_TIMESTAMP | Stempel waktu di baris log | true |
SSH_MCP_CONTROL_PERSIST | Detik koneksi bersama tetap aktif setelah perintah terakhir; 0 menutupnya segera | 600 |
SSH_MCP_CONTROL_DIR | Tempat soket kontrol berada | ~/.ssh/ssh-mcp |
SSH_MCP_PROFILES_CACHE_TTL | TTL cache profil, ms | 60000 |
SSH_MCP_PROFILES_WATCH | Muat ulang file profil saat berubah | true |
Koneksi bersama sengaja bertahan lebih lama dari proses ini: menutupnya saat keluar akan memutus saluran yang digunakan jendela lain di mesin yang sama.
Keterbatasan server SSH MCP
Setiap batasan memberi tahu Anda cara mengatasinya. Alat yang tidak dapat melakukan sesuatu akan mengatakannya dan menyebutkan ssh_exec, yang menjalankan perintah langsung di mesin — driver log yang tidak didukung, utilitas yang tidak dimiliki mesin, mesin yang tidak dapat diajak bicara oleh server ini. Anda tidak perlu tahu sebelumnya di mana alat berakhir: penolakan itu mengatakannya, pada saat hal itu penting.
Tiga penolakan sengaja tetap diam tentang shell, karena di sana itulah jawaban yang salah: jalur yang dilarang profil Anda (mengelilingi aturan Anda sendiri bukanlah perbaikan), panggilan yang salah format (perbaikannya ada di panggilan), dan penolakan dari ssh_exec itu sendiri.
- Pembatalan: panggilan yang dibatalkan sekarang juga menghentikan perintah di server, dikirim sebagai panggilan kedua melalui koneksi yang sama. Jika server tidak memiliki
/proc, perintah ditemukan melaluipssebagai gantinya. FreeBSD tidak diverifikasi: perilaku yang benar di sana tidak dijamin. Transfer file danssh_snapshottidak menerima pembatalan sama sekali. - Penulisan atomik: BSD dan macOS tidak dapat memeriksa terlebih dahulu penggantian nama lintas sistem file.
Peta jalan server SSH MCP
-
Uji coba penuh terhadap host SSH macOS
-
Uji kompatibilitas ujung-ke-ujung di Windows
-
Audit multi-host — bandingkan kesehatan di beberapa profil SSH dalam satu panggilan
-
Impor profil dari
~/.ssh/configyang ada -
Transfer yang dapat dilanjutkan untuk file besar dan koneksi tidak stabil
-
Linimasa operasi jarak jauh — perintah, transfer, dan keputusan pengawal dalam satu jejak audit
-
Buku pedoman pemecahan masalah SSH siap pakai
-
Log kontainer tanpa turun ke shell— SELESAI:ssh_log_taildanssh_log_searchmenerima nama kontainer, menanyakan docker ke mana ia menulis, dan membaca file itu dengan mekanisme yang sama seperti log lainnya -
Penolakan yang membuat Anda buntu— SELESAI: setiap batasan kini menyebutkanssh_execsebagai jalan keluar, sehingga mencapai tepi alat hanya membutuhkan satu kalimat, bukan permainan menebak -
Jawaban yang sampai ke model— SELESAI: keluaran perintah, baris log yang cocok, nama mesin, dan bagian snapshot berjalan di bidang, bukan hanya di teks -
Skema alat MCP yang lebih kecil— SELESAI: daftar alat menjadi 10% lebih ringan, dan pekerjaan terpisah kini menampilkan baris terakhir yang ditulisnya, bukan dipantau secara buta -
Pekerjaan panjang di bawah root— SELESAI: pekerjaan terpisah berjalan dengansudodan diikuti sebagai root, dan profil khusus kunci menjawabsudodengansudoPasswordmiliknya sendiri
Kembangkan dan uji server SSH MCP
npm install
npm run build # tsc
npx tsc --noEmit # types, plus dead declarations
npm run test:unit # unit tests
npm run lab:up # start the two test containers
npm run test:live # live suite against those containers
Rangkaian uji langsung berjalan terhadap kontainer nyata — satu BusyBox, satu coreutils — karena keduanya berbeda pendapat secara diam-diam, dan tiruan setuju dengan siapa pun yang menulisnya. Lihat docs/architecture.md untuk tata letaknya.
Suka SSH MCP Server? ⭐
Jika Anda menyukai alat ini, beri bintang di GitHub — ini membantu lebih banyak orang menemukan proyek ini.
Berkontribusi ke server SSH MCP
Masalah dan permintaan tarik diterima di github.com/hypnosis/ssh-mcp-server.
Lisensi
MIT — lihat LICENSE.