SSH MCP Server
resmiAjanınızdan SSH üzerinden komut çalıştırın, dosya taşıyın, günlükleri arayın ve makineleri denetleyin.
SSH MCP ile neler yapabilirsiniz?
- Güvenlik önlemleriyle komut çalıştırın — Asistanınızdan
ssh_execaracılığıyla tek veya toplu komutlar çalıştırmasını isteyin; sunucuya ulaşmadan önce geri döndürülemez işlemleri engelleyen yıkıcı komut korumasıyla. - Uzak dosyaları okuyun, yazın ve listeleyin — Dosyaları incelemek veya değiştirmek için
ssh_file_read,ssh_file_writevessh_file_listkullanın; atomik yazma ve isteğe bağlı SHA-256 doğrulamasıyla. - Günlükleri arayın ve sunucu sağlığını kontrol edin — Dosyalar ve konteynerler arasında
ssh_log_searchveyassh_log_tailsorgulayın veyassh_snapshotvessh_audit_baselineile yapılandırılmış bir sağlık anlık görüntüsü alın. - Bütünlük kontrolleriyle dosya aktarın —
ssh_uploadvessh_downloadaracılığıyla dosya ve dizinleri yükleyin veya indirin; eski cihazlar için otomatik eski scp yedekleme desteğiyle. - Uzun süreli arka plan işlerini yönetin — Yavaş işlemleri
ssh_execile ayırın ve bağlantı kopmalarına dayanarakssh_job_status,ssh_job_outputvessh_job_killile takip edin.
Dokümantasyon
SSH MCP Server — Yapay zeka ajanları için uzak sunucu araçları
|
|
Bir SSH MCP sunucusu — hata ayıklama, geliştirme ve sunucu bakımında size ve yapay zeka ajanınıza zaman ve token kazandıran çok amaçlı bir araç. SSH üzerinden komut çalıştırın, dosya taşıyın, günlükleri okuyun ve makineleri denetleyin — bir bulut VPS'i, fiziksel bir sunucu veya dolabınızda duran BusyBox yönlendiriciniz. |
Makinenizde zaten bulunan OpenSSH istemcisini kullanır: anahtarlarınız, ~/.ssh/config, atlama sunucularınız, aracı iletiminiz. Hiçbir şey paketlenmez, derlenecek bir şey yok, yerel bağlama yok.
Claude Code, Codex CLI, Cline, opencode, Gemini CLI, Qwen Code, Hermes ve diğer MCP istemcileriyle çalışır.
Kurulum · Araçlar · Kurulum · Güvenlik · Yol Haritası · Belgeler · Değişiklik Günlüğü
30 saniyede kurulum
Küresel kurulum gerekmez. npx paketi ilk kullanımda indirir:
npx -y @hypnosis/ssh-mcp-server
MCP istemcinize ekleyin — örneğin Claude Code — her proje için:
claude mcp add ssh -s user \
-e SSH_PROFILES_FILE="$HOME/.claude/ssh-profiles.json" \
-- npx -y @hypnosis/ssh-mcp-server
Veya elle yazın — çoğu istemcinin paylaştığı yapılandırma biçiminde aynı sunucu:
{
"mcpServers": {
"ssh": {
"command": "npx",
"args": ["-y", "@hypnosis/ssh-mcp-server"],
"env": {
"SSH_PROFILES_FILE": "~/.claude/ssh-profiles.json"
}
}
}
}
Ardından en az bir makineyle ~/.claude/ssh-profiles.json oluşturun:
{
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin",
"privateKeyPath": "~/.ssh/your_private_key"
}
}
}
Bağlanmak için bu yeterlidir.
Codex, opencode, Qwen Code ve diğer istemciler SSH MCP sunucusunu kurma bölümünde ele alınmıştır.
Eklenti olarak kurulum
Bazı istemciler — örneğin Claude Code — her şeyi bunun yerine bir eklenti olarak alabilir:
/plugin marketplace add hypnosis/ssh-mcp-server
/plugin install ssh-mcp-server@ssh-mcp-server
Eklenti, SSH_PROFILES_FILE aksini söylemediği sürece ~/.claude/ssh-profiles.json dosyasını okur, bu yüzden
önce bu dosyayı oluşturun; sunucu, makineleriniz yüklü olarak başlar.
Gereksinimler
Node.js 18+ ve PATH üzerinde bir sistem ssh istemcisi. Windows'ta anahtar tabanlı bir profil kullanın;
parola ve parola tümcesi profilleri şu anda kullanılamaz.
Sabitlenmiş bir sürümü, çevrimdışı çalışmayı veya her başlatmada daha az kayıt defteri kontrolünü mü tercih edersiniz:
npm install -g @hypnosis/ssh-mcp-server, ardından npx yerine komut olarak ssh-mcp-server kullanın.
Bu kimler için
- DevOps ve SRE'ler daha hızlı denetimler, olay kontrolleri ve rutin sunucu işleri isteyenler.
- Vibe kodlayıcılar ve bağımsız geliştiriciler bir yapay zeka asistanıyla ürün çıkaran ve yaptıklarını kendi sunucularında çalıştıranlar.
- Sistem yöneticileri ve platform mühendisleri kısıtlanmamış bir ham kabuk yerine yapılandırılmış araçlar isteyenler.
- Kendi VPS'lerini çalıştıran geliştiriciler ve küçük ekipler adanmış bir operasyon ekibi olmadan.
- Ev laboratuvarı, NAS ve yönlendirici sahipleri yararlı donanımları modern protokollerini geride bırakmış olanlar.
Neden ham kabuk yerine bir SSH MCP sunucusu
Daha az token, daha düşük yapay zeka maliyetleri
Ham bir kabuk, yapay zeka ajanına bir yangın hortumu verir: tekrarlanan komutlar, ASCII tablolar ve günlük dökümleri. Bu gürültüyü sunucunun bir resmine dönüştürmek için token yakar — sizin paranız.
Daha hızlı sunucu hata ayıklama
Amaca yönelik araçlar rutin kontrolleri toplar, gürültülü çıktıyı sınırlar ve önemli olan kısmı döndürür. Ajan, terminal çıktısını çevirmek için daha az zaman harcar ve çözüme daha çabuk ulaşır.
Daha az tahmin, daha az yapay zeka hatası
Yapılandırılmış yanıtlar neyin bulunduğunu, neyin ölçülemediğini ve neyin kısaltıldığını söyler. Bu, ajanın boşlukları bir halüsinasyonla doldurmasına daha az yer bırakır — ve size daha az kötü düzeltme, daha sakin dağıtımlar ve daha güvenilir kod verir.
SSH uyumluluğu: modern sunucular, eski donanımlar ve Windows
Mevcut OpenSSH kurulumunuzu kullanın
Paketlenmiş SSH uygulaması yok, yerel bağlama yok, platform başına yeniden derleme yok. Komutlar
sistem ssh istemcisini kullanır, böylece anahtarlarınız, ~/.ssh/config, atlama sunucularınız ve aracı
iletiminiz bir terminalde yaptığınız gibi çalışmaya devam eder. Desteklendiğinde, hedef başına paylaşılan bir
çoğullama bağlantısı, komut başına değil, bir kez kimlik doğrulamanız anlamına gelir.
Eski sunucular, yönlendiriciler ve NAS cihazları için SSH desteği
Modern bir scp ile bir yönlendiriciye dosya gönderin ve şunu elde edin:
scp app.conf router:/etc/
# scp: subsystem request failed on channel 0
Hiçbir şey bozuk değil — güncel bir scp yeni protokolü konuşur ve yönlendirici bunu bilmez.
Bir terminalde şimdi bir forum konusu okumaya gider ve fazladan bir bayrakla geri gelirsiniz. Burada hiçbir şey
yapmazsınız: aktarım denenir, ret tanınır, eski protokol bunun yerine kullanılır
ve bu makine hatırlanır, böylece bir sonraki dosya doğrudan oraya gider.
Daha eski SSH istemcileri ve eksik araçlar için geri dönüşler
Eski donanım bir çıkmaz sokak değil, bir geri dönüş alır. Modern bir özellik eksik olduğunda, sunucu mümkün olduğunda eski yolu seçer:
| Makineniz | Ne elde edersiniz |
|---|---|
| Modern dosya aktarımı için çok küçük bir yönlendirici veya NAS | Dosya yine de ulaşır — eski protokol otomatik olarak kullanılır |
| On yıllık bir sunucu | İş akışı yine de çalışır; sadece komut başına yeniden kullanmak yerine yeni bir bağlantı açar |
| Dosya karmalama yolu olmayan sadeleştirilmiş bir görüntü | Yükleme, kimsenin kontrol etmediği bir eşleşme iddia etmek yerine "doğrulanamadı" der |
| Bir aracın basitçe kurulu olmadığı bir makine | Yanıt "ölçülmedi" der — asla "hiçbir şey yok" gibi okunan bir sıfır değil |
Model Context Protocol için tasarlandı
Resmi MCP SDK üzerine inşa edilmiştir, baştan sona TypeScript, 2500+ birim testi ve mocks yerine gerçek konteynerlere karşı çalışan canlı bir test paketi.
Ham SSH vs bir SSH MCP sunucusu: aynı iş, iki yol
SSH sunucu sağlık kontrolü
Durum: Yeni bir dağıtım yapıldı. Sunucu yavaş hissediliyor ve disk, bellek, hizmetler, konteynerler veya hatalardan hangisinin suçlu olduğunu bilmiyorsunuz.
Soru: "Bu makine sağlıklı mı?"
Ham SSH
$ 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'.
Bu hâlâ kısaltılmış bir sonuç. Tam bir kontrol, her biri kendi çıktı biçimine sahip CPU, hizmet
durumları, konteyner sayıları ve son hatalar için daha fazla komut gerektirir. Daha da kötüsü, ss olmayan bir
makine, bağlantı noktası kontrolü hiç çalışmadığında sıfır dinleyiciye sahipmiş gibi görünebilir.
Yapılandırılmış MCP sonucu
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": []
}
Ajanın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| Birkaç komut ve ASCII tablolar | Tek sonuçta adlandırılmış alanlar | Tek çağrı, adlandırılmış alanlar ve daha az gidiş-dönüş |
| Eksik bir araç boş çıktı gibi görünebilir | unavailable neyin ölçülmediğini adlandırır | Daha az tahmin ve daha az kötü düzeltme |
| Diskler, hizmetler ve hatalar arasında sıralarsınız | Sorun sinyalleri zaten yüzeye çıkarılmıştır | Daha hızlı hata ayıklama |
Tam bir ssh_audit_baseline sonucu, bir avuç ham komut çıktısından daha uzun olabilir —
laboratuvar ölçümümüzde yaklaşık 1.077 token'e karşılık 765. Tasarruf, tek bir yanıtı kısaltmaktan değil,
tam iş akışından gelir.
Gerçek bir sorun giderme oturumunda, amaca yönelik araçlar 49 ayrı komut çağrısını 4 MCP çağrısına indirdi. Her ek çağrı, birikmiş konuşmayla birlikte başka bir model turu başlatır. İstem önbelleğe alma, tekrarlanan girdinin maliyetini azaltabilir, ancak yeni komutlar ve çıktıları yine de bağlam tüketir. Daha az gidiş-dönüş, oturum genelinde daha az token, daha az tekrarlanan analiz ve cevaba daha hızlı bir yol anlamına gelir.
Nabızdan ziyade tüm resme mi ihtiyacınız var? ssh_audit_baseline sistem, disk,
bellek, bağlantı noktaları, sshd, başarısız birimler, Docker, güvenlik duvarı ve güncellemeleri toplar. Bulgular
KRİTİK / UYARI / TAMAM olarak gelir; ölçülmeyen bölümler sıfır gibi sessizce okunmak yerine adlandırılır.
Linux sunucu günlük araması
Durum: API zaman aşımına uğruyor, ancak aynı mesaj nginx, syslog, journald veya normal kullanıcınızla okuyamadığınız bir uygulama günlüğünde olabilir.
Soru: "Bu hata nereden geldi?"
Ham SSH
$ 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
Üçüncü komut temiz görünüyor, ancak 2>/dev/null ayrıca bir izin hatasını gizledi. "Hiçbir şey
eşleşmedi" ve "hiçbir şey okunmadı" artık aynı görünüyor. Yoğun bir günlük ayrıca binlerce
satır döndürebilir ve olayın geri kalanını ajanın bağlamından itebilir.
Yapılandırılmış MCP sonucu
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
}
Ajanın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| Dört arama ve dört çıktı | Dosyalar ve globlar arasında tek arama | Daha az token ve gidiş-dönüş |
| İzin hataları kaybolabilir | files_unreadable kaçırılan her yolu adlandırır | Yanlış "günlükler temiz" sonucu yok |
| Çıktı yararlı bir sınır olmadan büyüyebilir | limited ve truncated her kesmeyi ortaya çıkarır | Kısmi sonuçlardan daha güvenli kararlar |
since sunucunun saatini kullanır, namesOnly: true yalnızca eşleşen yolları döndürür ve
ssh_log_tail tek çağrıda birkaç günlüğün son N satırını okur.
Güvenli uzak yapılandırma düzenlemeleri
Durum: Canlı bir sunucuda bir nginx yapılandırmasını değiştirmeniz gerekiyor. Bağlantının kopması, yanlış mod veya kontrolsüz bir kopya, hizmeti bozuk bir dosyayla bırakabilir.
Soru: "Kısmi bir dosya bırakmadan bu yapılandırmayı değiştirebilir miyim?"
Ham SSH
$ 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
Sıfır çıkış kodu kabuğun bittiğini söyler. Hangi baytların indiğini kanıtlamaz ve >
yeninin ilk baytı gelmeden önce eski dosyayı kısalttı. Bağlantı yazma sırasında koparsa,
hizmet kısmi bir yapılandırmayla bırakılır.
Yapılandırılmış MCP sonucu
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 }]
}
Ajanın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| Hedef, kopya tamamlanmadan önce kısaltılır | Tam bir geçici dosya, tek bir yeniden adlandırmayla onu değiştirir | Yarım yazılmış yapılandırma yok |
| Yalnızca çıkış kodu | Baytlar ve doğrulama sonucu adlandırılır | Gerçekte neyin indiğini bilirsiniz |
| İzinler kabuk metninin içinde yaşar | sudo, mode ve verify dosya başına alanlardır | Öngörülebilir sahiplik ve daha az alıntı hatası |
verified üç dürüst sonuca sahiptir: verified, sunucuda karma aracı olmadığında unavailable,
ve doğrulama istenmediğinde skipped. Okumalar için ssh_file_read bir
yol listesi kabul eder; ssh_file_list globları, özyinelemeyi, boyutları ve modları işler.
sudo ile toplu SSH komutları çalıştırın
Durum: Bir dağıtım hazır, ancak trafik taşınmadan önce nginx sözdizimi, hizmet durumu ve son hataların tümü kontrol edilmelidir. Başarısız bir kontrol, birleşik bir dökümün içinde kaybolmamalıdır.
Soru: "Tüm ön kontrol kontrolleri geçti mi?"
Ham SSH
$ 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
Üç bağlantı, üç alakasız çıktı döndürür. Komutlar ; ile birleştirilirse, kabuk
yalnızca son çıkış kodunu bildirir; && ile birleştirilirse, sonraki kontroller
ilk başarısızlıktan sonra kaybolur.
Yapılandırılmış MCP sonucu
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
}
Ajanın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| Üç çağrı ve alakasız çıktılar | Tek sıralı komut listesi | Daha az gidiş-dönüş |
| Birleşik bir kabuk ara durumu gizleyebilir | Her komut kendi exit_code değerini korur | Kaçırılan başarısız kontrol yok |
sudo ve alıntılama komut metninde tekrarlanır | sudo tüm topluluğa uygulanır | Daha az alıntı hatası |
Yıkıcı komut koruması, ilk komut çalışmadan önce tüm listeyi kontrol eder. Bir
giriş reddedilirse, diğer her giriş çalıştırılmadı olarak işaretlenir ve sunucuya hiçbir şey gönderilmez.
Her komut kendi stdout ve stderr değerini taşır. Çalışıp hiçbir şey yazdırmayan bir komutun boş bir dizesi vardır; hiç çalışmamış bir komutta ise bu alan hiç bulunmaz, bu yüzden ikisi karıştırılamaz. Komut başına 128 KB'ı aşan çıktıda her iki uç da korunur — tablolar için baş, günlükler için son — aradaki dikiş yeri kesilen miktarı belirtir ve clipped_bytes ne kadarının kesildiğini söyler. Kesme işlemi bayt sınırlarında yapılır ve bir karakterin kenarına geri adım atar, böylece kırpılmış bir yanıt asla bir değiştirme işareti taşımaz.
sudo sunucuya terminal olmadan ulaşır: profilin yanıtı standart girdi üzerinden sudo'ye verilir. Hangi sırrın kullanılacağı, profil bir tane belirttiğinde sudoPassword'ten, aksi halde password'ten gelir — anahtarla giriş yapan bir profilin hiç oturum açma parolası yoktur ve bir makine ikisini ayrı tutuyorsa oturum açma parolası yanlış yanıttır. Yanıtlayacak bir şey olmadığında, yanıt bunu belirtir ve çıkış yollarını adlandırır; sudo'nun -S ve askpass yardımcıları hakkındaki kendi tavsiyesini bırakmak yerine. Kendi standart girdisini okuyan bir komuta asla parola verilmez, aksi halde bu parola veriye karışırdı.
Uzun süreli SSH işlerini çalıştırın
Durum: Bir yedekleme veya taşıma işlemi aracı oturumundan daha uzun sürecek. Bağlantı kapanabilir, ancak yine de durumuna, çıktısına ve çıkış koduna daha sonra ihtiyacınız var.
Soru: "Bu iş konuşmadan sağ çıkacak mı?"
Ham SSH
$ ssh admin@server.example.com 'pg_dump app | gzip > /srv/backups/app.sql.gz'
client_loop: send disconnect: Broken pipe
Terminal gitti. Artık yeniden bağlanmanız, süreci bulmanız, hedef dosyayı incelemeniz ve yedeklemenin tamamlanıp tamamlanmadığını veya yarıda durup durmadığını tahmin etmeniz gerekiyor.
Yapılandırılmış MCP sonucu
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"
}
Aracın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| İş tek bir SSH oturumuna bağlı | Uzak işin kalıcı bir kimliği var | Güvenli bağlantı kesmeler ve yeniden başlatmalar |
| Yeniden bağlanmak süreçleri ve dosyaları aramak demek | Durum ve çıkış kodu adlandırılmış durumlara sahip | Tamamlanıp tamamlanmadığını tahmin etmek yok |
| Çıktıyı yeniden okumak eski metni tekrarlar | Çıktı bir bayt konumundan devam eder | Uzun işlerde daha düşük token kullanımı |
İş durumu bu sunucunun belleğinde değil, uzak diskte yaşar. ssh_job_status, running, finished ve lost arasında ayrım yapar; ssh_job_output son bayt konumundan devam eder; ve ssh_job_kill yalnızca kabuğu değil, tüm süreç grubunu sinyaller.
Dosyaları eski yönlendiricilere ve NAS cihazlarına aktarın
Durum: Güncel bir OpenSSH istemcisi SFTP'yi dener, ancak yönlendirici veya NAS yalnızca klasik scp protokolünü anlar. Dosya yine de sağlam bir şekilde ulaşmalı ve hedefini güvenle değiştirmelidir.
Soru: "Bu eski cihaz hâlâ doğrulanmış bir dosya alabilir mi?"
Ham SSH
$ scp app.conf operator@router:/etc/app.conf
subsystem request failed on channel 0
scp: Connection closed
Olağan sonraki adım, eski bayrağı hatırlamak, kopyalamayı yeniden denemek ve ardından ayrı bir karma komutu çalıştırmaktır — cihazda bir karma aracı varsa.
Yapılandırılmış MCP sonucu
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
}]
}
Aracın kazandıkları
| Ham SSH | Yapılandırılmış MCP | Kazancınız |
|---|---|---|
| Modern SFTP modu ilk hatada durur | Klasik scp geri dönüşü otomatiktir ve hatırlanır | Eski donanım hâlâ çalışıyor |
| Başarılı bir kopya bütünlüğü kanıtlamaz | SHA-256 doğrulamasının adlandırılmış bir sonucu var | Bozulma başarı ile karıştırılmaz |
| Doğrudan değiştirme kısmi bir hedef bırakabilir | Aktarımdan sonra geçici bir dosya yerine taşınır | Çalışan dosya kesintilerden sağ çıkar |
Cihazda ne sha256sum ne de openssl varsa, sonuç unavailable der ve sahte bir eşleşme bildirmek yerine nedeni belirtir. Tüm dizinler recursive: true kullanır ve karmalarını tek bir toplu işlemde doğrular.
Yapay zeka aracıları için yıkıcı komut koruması
Koruma, bir komut SSH'ye ulaşmadan önce yerel olarak çalışır. Kurtarılabilir işlemleri, veriyi tutan kabı yok edenlerden ayırır ve zincirler ile toplu işlemler içindeki komut sırasını kontrol eder.
Yıkıcı bir zinciri başlamadan durdurun
Güvenli bir yedekle-ve-değiştir dizisi:
cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old && rm -rf /srv/app
Yanlış sırada aynı işlemler:
rm -rf /srv/app && cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old
# REFUSED before the first command runs
Kabuk dizini siler ve ancak o zaman yedekleme kaynağının gittiğini keşfeder. Koruma, daha sonraki adımların daha önceki bir adım tarafından zaten yok edilmiş bir hedefi okuduğunu görür, bu yüzden tüm çağrı makinenizde kalır. Aynı kontrol dropdb app && pg_dump app > backup.sql'i de yakalar.
Geri döndürülemez kaybı reddedin, kurtarılabilir değişiklikler hakkında uyarın
| Reddedildi — kabın kendisi | Yalnızca uyarıldı — içeriği |
|---|---|
DROP DATABASE, dropdb | DROP TABLE, TRUNCATE, DELETE FROM |
docker volume rm, docker compose down -v | docker rm -f <name> |
crontab -r | bir işi düzenleme |
mkfs, wipefs -a, lvremove, zfs destroy | chmod 777 |
reboot, shutdown, halt | git reset --hard |
docker compose down -v reddedilir çünkü -v adlandırılmış Docker birimlerini, bir veritabanı birimi de dahil olmak üzere kaldırır. -v olmadan, hizmetleri durdurmak aynı geri döndürülemez eylem olarak ele alınmaz.
Dosya sistemi kökünün, bir ev dizininin veya /etc, /var ve /usr gibi sistem ağaçlarının özyinelemeli silinmesi de reddedilir; bir sembolik bağlantının oraya götürdüğü durumlar dahil. rm -rf "$DIR"/* gibi çözümlenmemiş bir hedef de reddedilir: "kontrol edilemedi" "güvenli" olarak ele alınmaz.
Durdurduğunuz şeyi adlandırın
Hedefini adlandırmak yerine bulan bir komut gönderilmez. Sunucu onu genişletir ve hedefin arkasında ne olduğuyla yanıtlar:
docker kill $(docker ps -q --filter ancestor=web)
# BLOCKED — would stop:
# edge — web:latest, Up 34 days, 0.0.0.0:8443->8443/tcp
Bir süreç için yanıt, kullanımda olduğunu gösteren işaretleri ekler: ne kadar süredir çalıştığı, hangi bağlantı noktalarında bağlantı kabul ettiği, kaç bağlantı taşıdığı. Adlandırılmış hedefler ekstra bir maliyet gerektirmez ve sessizce geçer — docker kill web-1, kill 4871, systemctl stop app.
Devam etmek için durdurulan şeyi adlandırın. Adlar, komutun gerçekte ulaştığı şeyle karşılaştırılır, bu yüzden başka bir şeye kaymış bir maske onaylanmak yerine reddedilir:
docker kill $(docker ps -q --filter ancestor=web) # CONFIRMED-KILL: edge
Komut satırları üzerinde bir desen kendi başına bir durumdur. Onu taşıyan komutun kendisiyle eşleşir, bu yüzden onu çalıştıran kabuk hedeften önce sinyallenir ve yanıt ortasında kesilir. Böyle bir vuruş onaylanmaz, yeniden yazılır — sayıyla veya bir karakterin bir sınıf olarak yazılmasıyla, böylece desen kendisiyle eşleşmeyi bırakır:
pkill -f relay
# BLOCKED — two ways through:
# kill 4871
# pkill -f '[r]elay' # CONFIRMED-KILL: 4871
Üç sonuç ayrı kalır: hedefler bulundu, genişletme hiçbir şeye ulaşmadı ve soracak bir şey yok — makinede motor yok, kırpılmış bir yanıt, başarısız bir bağlantı. Son ikisi de reddedir: bilmemek devam etmek için bir neden değildir.
Kasıtlı bir yıkıcı komutu onaylayın
Hiçbir şey kalıcı olarak yasak değildir. İncelenmiş bir komuta # CONFIRMED-DESTRUCTIVE ekleyin ve geçmesine izin verilir. Koruma bir toplu işlemdeki bir girdiyi reddettiğinde, tüm toplu işlem yürütmeden önce durur, bu yüzden sunucu asla yarı çalıştırılmış bir işlemden sonra bırakılmaz.
Koruma tek bir çağrı içinde çalışır. Bir çağrıdaki silmeyi sonraki çağrıdaki bir okumayla bağlayamaz veya tanımadığı araçlar hakkında akıl yürütemez. Bir emniyet kemeridir, bir politika motoru değil: kurtarılabilir işlemler sizin kararınız olmaya devam eder. Yol kısıtlamaları ve tırnak işareti kuralları docs/security.md içinde belgelenmiştir.
Araçlar
Sunucu işlemleri için 18 SSH MCP aracı. Tam parametreler ve örnekler docs/tools.md içinde yaşar.
| Araç | Ne yapar |
|---|---|
ssh_exec | Yıkıcı komut koruması ve isteğe bağlı ayırma ile bir komut veya toplu işlem çalıştırın |
ssh_file_read | Bir veya birkaç dosyayı, metin veya ikili olarak okuyun |
ssh_file_write | Atomik yeniden adlandırma ve isteğe bağlı SHA-256 doğrulaması ile dosyalar yazın |
ssh_file_list | İsteğe bağlı glob ve özyineleme ile bir dizini listeleyin |
ssh_upload | SSH üzerinden bir dosya veya dizin yükleyin, bütünlük kontrolleriyle ikili güvenli; bir dizin hedefi değiştirir veya içine birleşir |
ssh_download | SSH üzerinden bir dosya veya dizin indirin, bütünlük kontrolleriyle ikili güvenli |
ssh_job_status | Arka plan işinin durumu: çalışıyor, tamamlandı veya kayboldu |
ssh_job_output | Bir bayt konumundan birikmiş çıktıyı okuyun |
ssh_job_list | İşleri listeleyin, TTL'lerini aşan tamamlanmış olanları süpürün |
ssh_job_kill | Bir işin tüm süreç grubunu sinyalle |
ssh_log_tail | Bir veya birkaç günlüğün son N satırı, glob destekli; ada göre bir kapsayıcı |
ssh_log_search | Günlükler arasında veya bir kapsayıcının günlüğünde desen araması |
ssh_snapshot | Tek seferlik sağlık anlık görüntüsü: hizmetler, kaynaklar, Docker, ağ, hatalar |
ssh_monitor | Taşıma kontrolü: istatistikler, yeniden yükleme, test, listeleme, kapatma |
ssh_audit_baseline | Sistem, disk, bellek, ağ, ssh, hizmetler, Docker, güvenlik duvarı, güncellemeler |
ssh_tls_check | Bir alan adı için sertifika sona erme, SAN, zincir ve yenileme kancası |
ssh_disk_breakdown | Diskin nereye gittiği: du ilk-N, Docker, journald, önbellekler |
ssh_service_status | systemctl status artı bir birim için journalctl kuyruğu |
MCP aracı güvenlik ek açıklamaları
Standart MCP ek açıklamaları istemcilere hangi araçların salt okunur, yıkıcı, idempotent veya açık dünya olduğunu söyler. Tam tabloya bakın.
SSH komutlarını çalıştırın ve uzak dosyaları yönetin
Komutlar, dosya okuma ve yazma, dizin listeleme — bir makinedeki sıradan iş, her yanıt zaten ayrıştırılmış.
Uzun süreli SSH işlerini izleyin
Yavaş iş beklenmek yerine ayrılır ve takip edilir: her bakış ne kadar ilerlediğini söyler.
Günlükleri arayın ve sunucu sağlığını kontrol edin
Dosyaların ve kapsayıcıların günlükleri ve makinenin tek seferlik bir resmi, çıktı sınırlandırılmış, böylece bir kuyruk bağlam penceresini yemez.
SSH üzerinden dosya yükleyin ve indirin
Bütünlük kontrolleriyle ikili güvenli aktarımlar. Ayrıntılar docs/transfer.md içinde.
İkili ve büyük dosyalar için
ssh_upload/ssh_downloadkullanın — base64 parçaları ve heredoc'lar ikili güvenli veya atomik değildir.
SSH üzerinden Linux sunucularını denetleyin
Salt okunur ve tek bir gidiş-dönüşte toplu. Ayrıntılar docs/audit.md içinde.
Windows SSH uyumluluk modu
Windows otomatik olarak uyumluluk modunu kullanır. Bağlantı çoğullaması kullanılamadığında, sunucu komut başına bir bağlantıya geçer. Aynı araçlar anahtar tabanlı SSH üzerinden kullanılabilir kalır — ayrı bir kurulum veya Windows'a özgü bir uygulama yoktur.
Yıkıcı komut koruması Yapay zeka aracıları için yıkıcı komut koruması içinde ele alınmıştır.
SSH MCP sunucusunu kurun
Önce 30 saniyede kurulum paketini çalıştırın, ardından bir profil dosyası oluşturun.
SSH bağlantı profilleri oluşturun
İstediğiniz yere koyun — aracınızın kendi yapılandırmasının yanına koymak olağan seçimdir. Aşağıdaki örnekler ~/.claude/ssh-profiles.json kullanır; diğer araçlar için dizini değiştirin (~/.codex/, ~/.qwen/, ~/.config/opencode/):
{
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin",
"port": 22,
"privateKeyPath": "~/.ssh/your_private_key"
}
}
}
Açıkça bir SSH profili seçin
Sunucunun geri döndüğü bir profil yoktur: her biri farklı bir makinedir ve yanlış makineye gönderilen bir komut, bir hata mesajının sonradan geri alamayacağı bir şeydir. İsimsiz sorun ve yanıt, aralarından seçim yapılacak isimleri listeler:
ssh_exec({ command: "uptime" })
→ No profile specified. Name one explicitly: production
Sunucunun SSH için kullanamadığı bir profil — host yok, username yok veya mode: "local" — şikayet etmeden atlanır ve tanımadığı alanlara dokunulmaz, böylece dosya diğer araçlarla paylaşılabilir. Bozuk bir alana sahip bir profil farklı bir durumdur: alan ve değerle birlikte adlandırılır ve sağlıklı komşuları çalışmaya devam eder.
Her profil isteğe bağlı olarak, dosya araçlarının dokunabileceği yolları beyaz veya kara listeye alan bir pathSecurity bloğu alır — docs/security.md içine bakın.
Anahtarla giriş yapan ancak uzak tarafta sudo gerektiren bir profil bir sudoPassword alır — sudo ile yanıtlanan sır, birçok makinede oturum açma parolası değildir. Buraya değil, sırlar dosyasında tutun.
SSH parolalarını ve parola ifadelerini profillerin dışında tutun
Anahtarları tercih edin. Bir parola veya şifrelenmiş anahtar parolası kaçınılmazsa, bunu ayrı bir gizli dosyada tutun, asla profil dosyasının içinde değil:
{
"secretsFile": "~/.config/ssh-mcp/secrets.json",
"profiles": {
"production": {
"host": "server.example.com",
"username": "admin"
}
}
}
Gizli dosya profil adına göre anahtarlanır — bkz. secrets.json.example:
{
"production": { "password": "..." },
"buildbox": { "sudoPassword": "..." }
}
sudoPassword, o makinede sudo'e verilen yanıttır. Anahtarla giriş yapan bir profilin sunacak giriş parolası yoktur ve ikisi farklıysa giriş parolası yanlış yanıttır; o olmadan password kullanılır.
Gizli dosya yalnızca sizin tarafınızdan okunabilir olmalıdır (chmod 600). Göreli yollar profil dosyasından çözümlenir; gizli bilgiler argv dışında tutulur ve günlüklerde maskelenir. Bkz. kimlik bilgileri güvenliği.
Claude Code, Codex ve diğer MCP istemcilerini yapılandırın
Kullandığınız istemciyi seçin ve aynı profil dosyasına yönlendirin.
Claude Code
Tek komut; -s user sunucuyu her projede kullanılabilir yapar:
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
~/.config/opencode/opencode.json içine koyun:
{
"$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
Diğerleriyle aynı şekilde tek komut:
qwen mcp add ssh \
-e SSH_PROFILES_FILE="$HOME/.qwen/ssh-profiles.json" \
npx -y @hypnosis/ssh-mcp-server
Diğer MCP istemcileri
Gemini CLI, Hermes, Cline, bir editör eklentisi veya kendi aracınız aynı şekilde çalışır. Tek ihtiyaçları olan çalıştırılacak bir komut ve bir ortam değişkenidir.
MCP istemcinizi yeniden başlatın
İstemciyi yeniden başlatın, ardından profilin yüklendiğini doğrulamak için ssh_monitor({ action: "list" }) komutunu çalıştırın.
SSH MCP sunucu yapılandırması
| Değişken | Ne işe yarar | Varsayılan |
|---|---|---|
SSH_PROFILES_FILE | Profiller JSON dosyasının yolu — zorunlu | — |
SSH_MCP_LOG_LEVEL | debug, info, warn, error | info |
LOG_LEVEL | Yedek, yalnızca SSH_MCP_LOG_LEVEL ayarlanmadığında kullanılır | info |
SSH_MCP_LOG_TIMESTAMP | Günlük satırlarında zaman damgaları | true |
SSH_MCP_CONTROL_PERSIST | Son komuttan sonra paylaşılan bağlantının açık kaldığı saniye; 0 onu hemen kapatır | 600 |
SSH_MCP_CONTROL_DIR | Kontrol soketlerinin bulunduğu yer | ~/.ssh/ssh-mcp |
SSH_MCP_PROFILES_CACHE_TTL | Profil önbellek TTL'si, ms | 60000 |
SSH_MCP_PROFILES_WATCH | Profil dosyası değiştiğinde yeniden yükle | true |
Paylaşılan bağlantı bilinçli olarak bu süreçten daha uzun yaşar: çıkışta kapatmak, aynı makinedeki başka bir pencerenin kullandığı kanalı keser.
SSH MCP sunucu sınırlamaları
Her sınırlama size etrafından dolaşmanın yolunu söyler. Bir araç bir şey yapamıyorsa bunu söyler ve makinede doğrudan komut çalıştıran ssh_exec'u adlandırır — desteklenmeyen bir günlük sürücüsü, makinede olmayan bir yardımcı program, bu sunucunun konuşmadığı bir motor. Araçların nerede bittiğini önceden bilmeniz gerekmez: ret, önemli olduğu anda bunu söyler.
Üç ret, kabuk hakkında bilinçli olarak sessiz kalır, çünkü orada yanlış yanıt budur: profilinizin yasakladığı bir yol (kendi kuralınızın etrafından dolaşmak bir çözüm değildir), hatalı biçimlendirilmiş bir çağrı (çözüm çağrının içindedir) ve ssh_exec'un kendisinden gelen bir ret.
- İptal: iptal edilen bir çağrı artık sunucudaki komutu da durdurur ve aynı bağlantı üzerinden ikinci bir çağrı olarak gönderilir. Sunucuda
/procyoksa, komut bunun yerinepsaracılığıyla bulunur. FreeBSD doğrulanmamıştır: orada doğru davranış garanti edilmez. Dosya aktarımları vessh_snapshothiç iptal kabul etmez. - Atomik yazmalar: BSD ve macOS, dosya sistemleri arası yeniden adlandırmaları önceden kontrol edemez.
SSH MCP sunucu yol haritası
-
macOS SSH ana bilgisayarlarına karşı tam test çalıştırması
-
Windows'ta uçtan uca uyumluluk çalıştırması
-
Çoklu ana bilgisayar denetimleri — tek çağrıda birden fazla SSH profili arasında sağlık karşılaştırması
-
Mevcut
~/.ssh/config'ten profil içe aktarma -
Büyük dosyalar ve kararsız bağlantılar için sürdürülebilir aktarımlar
-
Uzaktan işlem zaman çizelgesi — komutlar, aktarımlar ve koruma kararları tek bir denetim izinde
-
Hazır SSH sorun giderme playbook'ları
-
Kabuğa inmeden kapsayıcı günlükleri— TAMAMLANDI:ssh_log_tailvessh_log_searchbir kapsayıcı adı alır, docker'a nereye yazdığını sorar ve bu dosyayı diğer günlüklerle aynı mekanizmayla okur -
Sizi çıkmaza sokan bir ret— TAMAMLANDI: her sınırlama artıkssh_exec'u geçiş yolu olarak adlandırır, böylece bir aracın sınırına ulaşmak bir tahmin oyunu yerine tek bir cümleye mal olur -
Modele ulaşan yanıtlar— TAMAMLANDI: komut çıktısı, eşleşen günlük satırları, makine adları ve anlık görüntü bölümleri yalnızca metinde değil, alanlarda da taşınır -
Daha küçük MCP araç şemaları— TAMAMLANDI: araç listesi %10 hafifledi ve ayrılmış bir iş artık körlemesine yoklanmak yerine yazdığı son satırları gösterir -
Kök altında uzun işler— TAMAMLANDI: ayrılmış bir işsudoile çalışır ve kök olarak izlenir ve yalnızca anahtarlı bir profilsudo'a kendisudoPasswordile yanıt verir
SSH MCP sunucusunu geliştirin ve test edin
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
Canlı paket, gerçek kapsayıcılara karşı çalışır — biri BusyBox, biri coreutils — çünkü ikisi sessizce anlaşmaz ve bir sahte, onu yazanla aynı fikirdedir. Düzen için docs/architecture.md dosyasına bakın.
SSH MCP Sunucusunu beğendiniz mi? ⭐
Aracı beğendiyseniz, GitHub'da bir yıldız verin — projenin daha fazla kişi tarafından keşfedilmesine yardımcı olur.
SSH MCP sunucusuna katkıda bulunun
Sorunlar ve çekme istekleri github.com/hypnosis/ssh-mcp-server adresinde memnuniyetle karşılanır.
Lisans
MIT — bkz. LICENSE.