Shipback SFTP

Implantações via SFTP para hospedagem compartilhada (cPanel, Plesk, qualquer host SFTP) que um agente de IA pode desfazer: cada implantação faz backup dos arquivos que substitui no servidor, e a restauração os recoloca, mas recusa se um arquivo ativo foi editado desde então.

Documentação

Shipback SFTP

test

Deixe o agente implantar. Mantenha o desfazer.

É tarde, e o agente diz "Implantado ✓". Então o formulário de contato do cliente sumiu. O agente sobrescreveu um arquivo que alguém tinha corrigido manualmente no cPanel na semana passada, e hospedagem compartilhada não tem git revert.

O Shipback implanta uma pasta em qualquer host SFTP: cPanel, Plesk, DirectAdmin, um VPS simples. Cada implantação pode ser desfeita com um comando. Você pode executá-lo você mesmo, criar scripts, ou entregá-lo ao Claude Code, Cursor ou qualquer cliente MCP.

  • Backup antes de cada sobrescrita. A cópia no servidor de cada arquivo que uma implantação substitui é salva em _backup-<time>/ no servidor, antes do upload começar.
  • Desfazer com um comando. --restore coloca esses arquivos de volta e remove os arquivos que a implantação adicionou.
  • Não desfaz por cima de uma edição ao vivo. Se alguém alterou um arquivo no servidor após a implantação, a restauração para e nomeia o arquivo. Nada é tocado a menos que você passe --force, e mesmo assim a cópia editada é salva em backup primeiro.
  • Restaurações também podem ser desfeitas. Uma restauração faz backup do que substitui, da mesma forma que uma implantação faz.
  • Seguro para agentes. O servidor MCP não tem opção para excluir arquivos do servidor ou pular o backup. Uma implantação só executa o plano exato que o agente visualizou: se um arquivo mudou no meio do caminho, ele recusa.
  • Detecta a divergência. --pull --dry-run mostra o que mudou no servidor desde sua última implantação, para que edições feitas ao vivo no cPanel não sejam sobrescritas por acidente.

Não é necessário git ou shell SSH no servidor, apenas SFTP. Ele precisa de Node 18+. Os testes rodam em Windows, macOS e Linux com Node 18, 20 e 22 a cada push. As senhas ficam no chaveiro do sistema operacional e nunca passam pelo modelo.

Ele já rodou em produção. O mecanismo de implantação por baixo enviou aldo.today 235 vezes desde setembro de 2026 (2.907 arquivos para um host cPanel). Restauração e o servidor MCP são novos na versão 0.1.

Início rápido

npm install -g shipback-sftp          # installs the shipback and shipback-mcp commands
cd ~/sites                            # any folder with a sites.json in it (format below)
shipback mysite --dry-run             # see the plan; asks for the password once and stores it
shipback mysite                       # deploy
shipback mysite --restore             # changed your mind? undo it

Sem instalação global? npx -p shipback-sftp shipback mysite --dry-run funciona da mesma forma. --sites <file> aponta para um sites.json em outra pasta.

A partir do código-fonte: git clone https://github.com/aldohushi1-stack/shipback-sftp.git, npm install, depois node bin/cli.js onde quer que estes documentos digam shipback.

sites.json, uma entrada por site:

{
  "sites": [
    {
      "name": "mysite",
      "host": "server123.example-host.com",
      "port": 22,
      "username": "cpaneluser",
      "remoteRoot": "/home/cpaneluser/public_html",
      "localDir": "/Users/you/sites/mysite",
      "ignore": ["drafts/", "*.psd"]
    }
  ]
}

Muitos hosts compartilhados rodam SFTP em sua própria porta em vez de 22 (verifique SSH Access no seu painel de controle), e alguns só aceitam conexões de IPs na lista de permissões. Se uma conexão expirar, verifique esses dois primeiro. Use "privateKeyPath" em vez de uma senha se o seu host tiver sua chave.

Comandos

shipback <site> --dry-run                 # what a deploy would upload
shipback <site>                           # deploy: backup, upload, record
shipback <site> --local <folder>          # deploy a different folder than localDir
shipback <site> --pull --dry-run          # what changed on the server since the last deploy?
shipback <site> --pull                    # bring those changes down (local copies backed up first)
shipback <site> --backups                 # list backups: what each run overwrote, added, deleted
shipback <site> --restore --dry-run       # what an undo of the latest deploy would do
shipback <site> --restore [<backup>]      # undo it (or name an older _backup-… folder)
shipback <site> --prune --keep 10         # tidy old backups; refuses any holding the only copy of a file
shipback --history [site]                 # what went up, when, from where

Adicione --json a qualquer comando para saída legível por máquina. Uma restauração recusada sai com código 4.

--mirror (excluir arquivos do servidor que não estão na pasta local) e --no-backup existem para humanos que sabem que os querem. As ferramentas do agente não os oferecem, e o guard hook bloqueia o Claude de digitá-los.

Como funciona o desfazer

Cada implantação grava _backup-YYYY-MM-DD-HHMM/ na raiz remota. Ele contém:

  • a cópia no servidor de cada arquivo que a implantação sobrescreveu ou excluiu
  • .backup.json, um registro do que a implantação adicionou, e um SHA-256 de cada arquivo que deixou no servidor

--restore lê esse registro e verifica cada arquivo ao vivo primeiro:

Arquivo ao vivo agoraA restauração faz
exatamente o que a implantação envioucoloca a cópia antiga de volta (ou a remove, se a implantação a adicionou)
já é a cópia antiganada; conta como já correto
diferente de ambosconflito: para, nomeia o arquivo, não muda nada (--force substitui)

Antes de gravar qualquer coisa, a restauração salva os arquivos ao vivo atuais em uma nova pasta _backup-… com seu próprio registro, para que --restore nessa pasta leve você adiante novamente. Ela também limpa os caminhos restaurados de .deploy-manifest.json, para que a próxima implantação os compare por conteúdo em vez de confiar em hashes desatualizados.

As pastas de backup são ignoradas por implantações e pulls, e nunca são excluídas exceto por --prune.

Use a partir de um agente de IA (MCP)

shipback-mcp (bin/mcp.js) é um servidor MCP via stdio.

Claude Code

claude mcp add shipback-sftp -- npx -y -p shipback-sftp shipback-mcp --sites /path/to/sites.json

Cursor, Claude Desktop e outros (mcp.json / claude_desktop_config.json):

{
  "mcpServers": {
    "shipback-sftp": {
      "command": "npx",
      "args": ["-y", "-p", "shipback-sftp", "shipback-mcp", "--sites", "/path/to/sites.json"]
    }
  }
}

No Windows, se o cliente não conseguir iniciar npx, use "command": "cmd" com "/c", "npx" no início de args. Após uma instalação global, "command": "shipback-mcp" também funciona, e a partir de um clone é node com bin/mcp.js como primeiro argumento.

Execute qualquer comando CLI para um site uma vez primeiro (por exemplo shipback mysite --backups). Isso armazena a senha no chaveiro do sistema operacional, onde o servidor MCP a lê. O modelo nunca a vê. Para CI, você pode definir SFTP_PASSWORD no ambiente do servidor.

FerramentaFaz
list_sitesos sites configurados (sem senhas)
preview_deployo que enviaria; retorna um planId
deployenvia esse plano; recusa se algo mudou desde a visualização
check_server_changesarquivos editados ou adicionados no servidor ao vivo desde a última implantação
pulltraz esses para a pasta local (cópias locais com backup)
list_backupsbackups, mais recentes primeiro, com o que cada execução mudou
preview_restoreo que um desfazer colocaria de volta e removeria, além de conflitos; retorna um planId
restoreexecuta esse desfazer; recusa em conflitos a menos que force
historyimplantações, pulls e restaurações recentes

O que as ferramentas deixam de fora é deliberado: não há espelhamento/exclusão, nenhuma forma de pular o backup e nenhuma poda de backups.

Agentes sem shell: a fila de drop-box

Algumas configurações de agente podem gravar arquivos, mas não podem executar comandos. Enquanto o aplicativo local estiver rodando (npm start, ou start.bat no Windows), qualquer coisa que possa gravar um arquivo pode enfileirar um trabalho:

queue/<name>.request.json   { "action": "deploy", "site": "mysite", "dryRun": true, "note": "new homepage" }
queue/<name>.result.json    ← written when it finishes, with a .log.txt beside it

Ações: deploy, preview, pull, restore, backups, prune.

O aplicativo local

npm start abre uma pequena interface em http://127.0.0.1:4646: adicionar sites, visualizar, implantar, puxar, arrastar uploads avulsos, navegar no servidor e ver o histórico. Ele só responde a solicitações da sua própria máquina.

Guard hook do Claude Code

Se o Claude também executar o CLI diretamente, adicione bin/claude-guard.js como um hook PreToolUse. Ele bloqueia --mirror e --no-backup em comandos de shell, arquivos de fila e chamadas de API, e diz ao Claude o porquê. Você ainda pode executá-los você mesmo em um terminal. Após npm install -g shipback-sftp, o arquivo está na pasta npm root -g imprime, em shipback-sftp/bin/.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|PowerShell|Write|Edit|MultiEdit",
        "hooks": [{ "type": "command", "command": "node /path/to/shipback-sftp/bin/claude-guard.js" }]
      }
    ]
  }
}

Testes

npm test

A suíte usa node:test e não precisa de rede. Implantação, restauração, o CLI e o servidor MCP são cada um também exercitados de ponta a ponta contra um servidor SFTP real iniciado dentro da execução do teste.

Limites

  • Ele compara por tamanho e SHA-256. A primeira implantação em um site que já tem arquivos lê as cópias no servidor de quaisquer arquivos do mesmo tamanho para compará-los.
  • Os backups ficam no mesmo servidor que o site. Eles protegem contra implantações ruins, não contra a perda da conta de hospedagem. Mantenha também os backups do seu próprio host.
  • Arquivos acima de 8 MB com o mesmo tamanho em ambos os lados são considerados inalterados quando não há hash de manifesto para comparar.

Licença

MIT © 2026 Aldo Hushi

Roda o aldo.today. Feito na BlueprintAU.