sshmng
Gerenciador de sessões SSH baseado em MCP para equipes de backend Linux
Documentação
sshmng
sshmng é um gerenciador SSH unificado que cobre todos os formatos de conexão — direta, saltos transparentes ssh -J, bastiões interativos, proxies de transporte — em um único binário sem dependências que suporta atualização automática. Ele funciona como um servidor MCP para agentes de IA (Claude Code / Hermes / etc.) e uma CLI sshmng ssh para humanos, ambos baseados na mesma configuração. Quando algo falha, o Agente lê o rastreamento da falha, corrige a configuração e tenta novamente — autocorreção em ciclo fechado, sem intervenção humana.
Recursos
- Bastiões interativos que realmente funcionam: a maioria das ferramentas SSH desiste de bastiões baseados em menu. A árvore de decisão
LoginFlowdo sshmng (enviar + esperar, glob ou regexre:) conduz o menu até fazer login no destino — e quando o texto do menu muda, o rastreamento da falha volta para o Agente para que ele possa corrigir o padrão e tentar novamente - Ciclo de configuração autocorretiva: o Agente lê
error/login_trace, chamaupdate_*para corrigir o padrão LoginFlow quebrado, tentaloginnovamente — fecha o ciclo de diagnóstico sem necessidade de acompanhamento humano - Assistente de configuração em um comando:
sshmng installcria o diretório de configuração + modelo, detecta automaticamente Agentes de IA instalados (Claude Code / Hermes / OpenCode) e se injeta nas configurações deles com backups com timestamp;sshmng doctorverifica se tudo está conectado - Uma configuração, duas interfaces: servidor MCP para agentes de IA (Claude Code / Hermes / OpenCode / Claude Desktop / Cursor), CLI
sshmng sshpara humanos. Mesmoconfig.json, mesmos padrões direto / Padrão A (ssh -J) / Padrão B (bastião) — configure um servidor uma vez, use-o de qualquer lado - Gerenciamento explícito de sessão: trio
login→run_in_session→close_session; comandos consecutivos compartilham cwd / env / trabalhos em segundo plano, diferente dossh host cmdde uso único - Transferência de arquivos sftp:
upload/downloadtransferem arquivos individuais por um canal sftp dedicado, separado do canal de comandos PTY; degradação graciosa quando indisponível.upload_dir/download_dirtransferem árvores de diretórios recursivamente, concorrente (padrão 4), política de conflito sobrescrever / pular / renomear.relay_transfertransmite um arquivo de uma sessão para N outras via sshmng (sem disco local, fanout 1:N, fonte lida uma vez) - Diagnóstico de comandos:
run_in_sessiontimeout com Ctrl-C automático + drenagem, retornatimed_out/ctrl_c_sent;get_tracerecupera o histórico de comandos (incluindo raw_output, ctrl_c_sent) - Chave de host TOFU: a primeira conexão registra a chave pública em
known_hosts; alterações são rejeitadas ("host key changed, possible MITM") - CRUD de configuração: famílias de ferramentas
list_*/get_*/update_*gerenciam SSHServer / Jumphost / Proxy, com semântica JSON Merge Patch RFC 7396
Instalação e Build
sshmng é um único binário sem dependências de runtime. Escolha uma opção:
# Option 0: one-click install — downloads release, places on PATH
# macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/jim58246/sshmng/main/install.sh | bash
# Windows (PowerShell):
irm https://raw.githubusercontent.com/jim58246/sshmng/main/install.ps1 | iex
# Option 1: download release binary (recommended, no Go required)
# From https://github.com/jim58246/sshmng/releases, pick the binary for your OS/Arch
chmod +x sshmng
# Option 2: go install (requires Go 1.25+)
go install github.com/jim58246/sshmng/cmd/sshmng@latest
# Option 3: clone and build locally
git clone https://github.com/jim58246/sshmng.git
cd sshmng && go build -o sshmng ./cmd/sshmng
Ou deixe seu Agente de IA instalá-lo para você: copie o prompt em docs/agent-install-prompt.md e cole no Claude Code / Cursor / Hermes / OpenCode — o Agente baixará o binário, o colocará em PATH e executará sshmng install para você.
macOS: binários baixados pelo navegador carregam um atributo de quarentena do Gatekeeper — execute xattr -d com.apple.quarantine sshmng antes do primeiro uso. Binários go install / go build não precisam disso (compilação local). Binários atualizados automaticamente também não precisam (veja docs/auto-update.md).
Depois de obter o binário, execute sshmng install para criar ~/.sshmng/ e injetar nos Agentes de IA instalados (Claude Code / Hermes / OpenCode, etc.). Veja Quick Start.
Recomendado: antes de executar install, mova o binário para um local estável no seu PATH (ex.: mv sshmng /usr/local/bin/, ou confie em ~/go/bin/ se você usou go install). sshmng install registra o caminho absoluto do binário nas configurações do Agente, e sshmng doctor verifica se ele corresponde ao executável em execução — escolher um local estável antecipadamente evita reexecutar a instalação após uma movimentação posterior.
Build a partir do código-fonte
# Plain build (version.Version is "dev", self-update is disabled)
go build -o sshmng ./cmd/sshmng
# Inject version via ldflags (self-update needs a real version number)
go build -ldflags="-X github.com/jim58246/sshmng/internal/version.Version=v1.2.3" -o sshmng ./cmd/sshmng
Sem ldflags, version.Version assume o padrão "dev", caso em que tanto sshmng update quanto a goroutine de atualização automática na inicialização do mcp são ignoradas.
Execute:
./sshmng # Print help
./sshmng mcp # Start MCP server (what Agent configs use)
./sshmng install # First-time setup wizard
./sshmng doctor # Verify setup
./sshmng version # Print version / commit / date
./sshmng version --check # Check latest version against source
./sshmng update # Self-update to latest release
./sshmng mcp --config /path/to/config.json # MCP server with custom config
SSHMNG_HOME=/custom/dir ./sshmng mcp # MCP server with custom home
./sshmng server list [keywords...] # List SSH servers (AND match on name/addr/tags)
./sshmng server get <name> # Show SSH server details (full auth)
./sshmng jumphost list|get ... # Same for jumphosts
./sshmng proxy list|get ... # Same for proxies
./sshmng ssh <name> [command] # Interactive login; <name> also resolves to a jumphost (bastion). Non-interactive command needs a shell — bastions (ssh_j=false) and raw devices (raw=true) reject it
./sshmng file upload <name> <local> <remote> # File transfer via sftp (also: download, upload-dir, download-dir, relay)
./sshmng file relay <src-name> <src-path> <dst-path> --to <dst1,dst2> # 1:N fanout to multiple servers
Quick Start
# 1. Build
go build -o sshmng ./cmd/sshmng
# 2. First-time install (creates ~/.sshmng/ + injects into installed AI Agents)
./sshmng install
# 3. Verify config
./sshmng doctor
# 4. Restart your Agent, have it call sshmng:
# "list_ssh_servers" → should return an empty array
# "add an SSH server named prod-web-01 at 10.0.0.1:22 with password ..."
# "login to prod-web-01 and run df -h"
Não interativo:
./sshmng install --yes --agents claude-code,hermes
Para fallback de configuração manual e etapas de integração por Agente, veja docs/agents.md.
Visão Geral das Ferramentas MCP
21 ferramentas no total:
| Categoria | Ferramenta | Descrição |
|---|---|---|
| Consulta de configuração | list_ssh_servers / list_jumphosts / list_proxies | Correspondência AND de múltiplas palavras-chave em nome/endereço/tags (separadas por espaço, sem diferenciar maiúsculas, autenticação oculta) |
| Consulta de configuração | get_ssh_server / get_jumphost / get_proxy | Registro único por nome (autenticação completa) |
| Atualização de configuração | update_ssh_server / update_jumphost / update_proxy | JSON Merge Patch RFC 7396; null exclui, objeto mescla/cria |
| Sessão | login(name) → {sid, sftp_available, mode, tags} | Dial + LoginFlow + injeção de RC + configuração do canal sftp. mode: shell = shell unix (use run_in_session); raw = sem shell unix, ex.: switch de rede (use send_in_session/read_in_session). tags espelham as tags configuradas no servidor (dicas humano→IA) |
| Sessão | run_in_session(sid, cmd, timeout_ms?, max_output_bytes?) | Executa comando, retorna output/exit_code/timed_out/truncated/total_bytes. Rejeitado em sessões raw |
| Sessão | send_in_session(sid, input) | Primitiva de terminal: digita no PTY. O servidor interpreta escapes estilo C (\r=Enter, \n, \t, \e=ESC, \uXXXX=Ctrl-C etc., \\=barra invertida literal), o restante verbatim. Apenas sessões ociosas; funciona em todas as sessões |
| Sessão | read_in_session(sid, wait_ms?, max_bytes?) | Primitiva de terminal: lê nova saída do PTY desde a última leitura (absorção silenciosa, saída não lida permanece na fila). Retorna output/more/idle_ms |
| Sessão | close_session(sid) | Força o fechamento, rastreamento retido por 10 minutos |
| Sessão | stat() | Lista todos os resumos de sessões ativas (incluindo sftp_available, mode, tags) |
| Diagnóstico | get_trace(sid, last_n?, trunc_output?) | Recupera histórico de comandos (incluindo ctrl_c_sent, saída raw) |
| Transferência de arquivos | upload(sid, src, dst, timeout_ms?) | Local → remoto, via sftp |
| Transferência de arquivos | download(sid, src, dst, timeout_ms?) | Remoto → local, via sftp |
| Transferência de arquivos | upload_dir(sid, src, dst, conflict?, concurrency?, timeout_ms?) | Árvore de diretórios local → remoto, sftp recursivo, concorrente padrão 4, política de conflito sobrescrever/pular/renomear |
| Transferência de arquivos | download_dir(sid, src, dst, conflict?, concurrency?, timeout_ms?) | Árvore de diretórios remoto → local, sftp recursivo, concorrente padrão 4, política de conflito sobrescrever/pular/renomear |
| Transferência de arquivos | relay_transfer(src_sid, src_path, dst_sids[], dst_path, timeout_ms?) | Transmite um arquivo remoto de uma sessão para N outras via sshmng (sem disco local, fanout 1:N, fonte lida uma vez); requer sftp na fonte + todos os destinos; falhas parciais retornam ok:false (verifique o campo ok, não IsError) |
Dispositivos raw (switches etc.,
raw: true) não têm shell unix: o login pula a detecção de shell / injeção de RC, erun_in_sessioné rejeitado. Conduza-os com as primitivas de terminalsend_in_session+read_in_session: envie um comando (anexe\r— o servidor interpreta escapes estilo C, então Enter funciona quer o cliente transmita um CR real ou os dois caracteres\r), leia a saída, julgue a conclusão pelo conteúdo +idle_ms, lide com prompts de paginação (---- More ----) conforme a convenção do dispositivo — o servidor não inclui receitas de fornecedores. As mesmas primitivas funcionam em sessões unix para programas persistentes (tail -f,top,vim). Clientes MCP serializam chamadas de ferramentas, então as primitivas só são utilizáveis enquanto a sessão está ociosa (nunca durante umrun_in_sessionem execução).
Notas de Segurança
- Armazenamento em texto puro: v1 armazena senha / passphrase em texto puro em
config.json, documentado explicitamente; se inaceitável, criptografe todo oconfig.jsoncomage/gpgvocê mesmo, descriptografe antes do uso - Chave de host TOFU: habilitada por padrão; a primeira conexão registra a chave pública em
~/.sshmng/known_hosts, alterações são rejeitadas ("host key changed, possible MITM"). Pode ser desabilitada por entidade viahost_key_verify: false(pula completamente a leitura/escrita de known_hosts, perde a proteção contra MITM — apenas para bastiões de intranet confiáveis, etc.); excluir uma chave registrada ainda exige editar manualmente~/.sshmng/known_hosts, sem suporte de ferramenta - Rastreamento contém dados sensíveis:
Send(estágio LoginFlow),Output(fluxo raw do PTY) podem conter senhas; o rastreamento é apenas em memória, retido por 10 minutos apósclose_sessione então limpo automaticamente, nunca persistido em disco - stdout nunca deve registrar logs: JSON-RPC é dedicado ao stdout; logs de operação vão para o arquivo rotativo especificado por
config.log_path(10MB / 5 arquivos, permissões 0600), ou sem logs se não configurado; erros de bootstrap vão para stderr - Escopo de autenticação (v1): apenas Password + PrivateKey suportados; sem keyboard-interactive / agente SSH / certificado SSH / 2FA (se seu ambiente exigir isso, extensão v2 ou interação codificada no LoginFlow)
Atualização Automática
sshmng verifica silenciosamente atualizações em uma goroutine em segundo plano na inicialização do mcp (escreve apenas log log_path, nunca stdout). Desative via {"auto_update_enabled": false}. Atualização manual: sshmng update. Limitado pelo GitHub? Baixe o asset com seu navegador e execute sshmng update --file <path> (ignora a cota da API; aceita .tar.gz, .tar ou um diretório extraído). Verificação de versão: sshmng version --check. Fonte personalizada: defina update_url (veja docs/auto-update.md para layout de fonte auto-hospedada, notas macOS, modo --file e fluxo de release).
Testes e Desenvolvimento
# Run all tests (with race detector)
go test -race ./...
Para cobertura de testes e detalhes de desenvolvimento, veja docs/development.md (apenas em chinês — traduções bem-vindas).
Documentação
- Referência de configuração — referência completa dos campos do config.json, restrições de formato Padrão A/B, exemplos
- Guia de integração de Agentes — configuração detalhada para Claude Code / Hermes Agent / OpenCode / Claude Desktop, depuração com MCP Inspector, fluxo de configuração inicial, fluxo típico de chamadas
- Prompt de instalação do Agente — prompt copiável para seu Agente de IA instalar sshmng de ponta a ponta
- Atualização automática — layout de fonte HTTP auto-hospedada, notas macOS, fluxo de release
- Arquitetura e desenvolvimento — estrutura de pacotes, designs principais, despacho de subcomandos, cobertura de testes (apenas em chinês — traduções bem-vindas)
- Documento de design — especificação completa do design (sentinel PTY, LoginFlow, máquina de estados de sessão, etc.) (apenas em chinês — traduções bem-vindas)
- Plano de implementação — progresso da implementação v1 (apenas em chinês — traduções bem-vindas)
Status
Estágio v1: cliente executa standalone, stdio de processo único, configuração armazenada localmente. Documento de design: docs/ssh-session-manager-design.md (apenas em chinês — traduções bem-vindas).
Contribuindo
Sinta-se à vontade para abrir issues para bugs e solicitações de recursos.
Licença
MIT — Copyright (c) 2026 jim58246