You write code with Claude Code, Cursor, or Codex. The last step is still dragging files into a 2006-era FTP window.
coolFTP fixes the last step. Your agent runs coolftp deploy, and you watch every file land on your server, live.
Or install the CLI: npm i -g coolftp
› ship it to the server ⏺ coolftp_deploy(message: "nav fix + og tags") via coolFTP app (port 51422) · Running build: npm run build · Scanning ./dist ↑ index.html 4.1 KB ↑ css/site.css 12.8 KB ↑ js/nav.js 2.2 KB ✔ Deployed to coolftp.com in 1.8s: +0 ~3 -0 (a91c2e0 on main) ⏺ Live. Three changed files went up; 214 unchanged files were skipped because their hashes matched the manifest on the server. ›
Every FTP client assumes a human is clicking. coolFTP assumes a human is watching and an agent is doing.
coolftp init my-server in the project. It writes a tiny .coolftp.json so nobody has to remember hosts or paths again, agents included.claude mcp add coolftp -- coolftp mcp. Claude Code gets coolftp_deploy, coolftp_diff, coolftp_ls, coolftp_read and friends. Any other agent just calls the CLI.◆ claude-code diff …/my-site → coolftp.com ok 0.6s ◆ claude-code deploy …/my-site: nav fix + og tags ok 1.8s ◆ cursor read coolftp.com:/.htaccess ok 0.2s ◆ codex upload …/assets/hero.webp running Coding agents drive this app through a local hub on port 51422. Nothing listens outside 127.0.0.1. Each call carries the agent name.
No ribbon toolbars. No "site manager wizard". The things a working developer needs, and a couple of things no other client has.
Key auth with your existing ssh-agent, or a password if you must. FTPS and plain FTP for the shared hosts that never upgraded.
A manifest on the server records the SHA-256 of every file it has. Deploys upload only what changed, even if timestamps lie.
Each deploy stores the commit, branch, dirty flag, message, byte count and which agent ran it. "What is live right now?" has an answer.
Every call an agent makes shows up as it happens, with the arguments in plain words. Failures flash the window.
Fifteen typed tools for Claude Code and any MCP client. Sites, diff, deploy, rollback, ls, read, write, upload, download, rename, delete, history.
.git, node_modules, .env and logs never go up. Add a .coolftpignore for the rest, gitignore syntax.
coolftp rollback puts the server back to the commit that was live before. Any deploy in history can be restored by id. Your working tree is never touched.
Give a site its public URL and every deploy fetches the homepage and the changed pages afterwards, then reports the status codes. Agents stop guessing.
When an agent asks to delete, deploy with --delete, or roll back, the app pops a yes/no on your screen. Two minutes with no answer means no.
Set "build": "npm run build" in the project file and every deploy runs it first, agent-triggered or not.
Files you deleted locally are listed as stale and left alone until you pass --delete. A first deploy into a folder with other files refuses to delete them at all.
SFTP host keys are remembered on first use and a changed key is refused. Passwords are encrypted with the Windows user account, never plain text.
Local on the left, remote on the right, drag and drop from Explorer, preview text files in place, keyboard driven.
Transfers retry on their own. If a deploy still dies halfway, what landed is recorded, and the next run finishes the rest instead of starting over.
Close the desktop app and the CLI and MCP server keep working in-process. Same commands, same config, on a headless box or in CI.
FileZilla and CuteFTP are fine tools from a different era. Here is the honest comparison.
| coolFTP | FileZilla | CuteFTP | rsync / scp | |
|---|---|---|---|---|
| SFTP with ssh-agent keys | yes | yes | yes | yes |
| Uploads only files whose content changed | yes, by hash | by size or time | by size or time | yes |
| Deploy history with git commit | yes | no | no | no |
| Driveable by Claude Code / MCP | built in | no | no | shell only |
| Shows agent actions live in a GUI | yes | no | no | no |
| Asks you before an agent deletes anything | yes | n/a | n/a | no |
| Roll back to the previous live version | one command | no | no | by hand |
| Checks the site answers after deploying | yes | no | no | no |
| Refuses a changed SSH host key | yes | yes | yes | yes |
| Per-project config committed with the code | .coolftp.json | global XML | global | scripts |
| Runs a build step before deploy | yes | no | macros | scripts |
| Works on shared hosts with FTP only | yes | yes | yes | no |
| Price | free, MIT | free, GPL | paid | free |
Three commands from install to deploy. Everything the desktop app does, the CLI does too, so this works on a server with no screen.
# install the CLI (works with or without the desktop app) npm i -g coolftp # add a server over SFTP, using your existing key or ssh-agent coolftp site add coolftp.com --host coolftp.com --user deploy --root /var/www/html --url https://coolftp.com # or a shared host over FTPS with a password coolftp site add oldhost --host ftp.oldhost.net --user me --protocol ftps --password ... --root /public_html # connect once to check it and record the host key coolftp site test coolftp.com
# in your project folder: link it to the site, deploy the dist folder, build first coolftp init coolftp.com --local-dir dist --build "npm run build" # what would go up coolftp diff # upload only the changed files coolftp deploy -m "v1" # also remove files you deleted locally coolftp deploy --delete # git commit, then deploy coolftp deploy --commit -m "fix nav" # put the previous live version back coolftp rollback # what went live, when, from which commit, by whom coolftp history
claude mcp add coolftp -- coolftp mcp # then, in Claude Code, just say: "deploy this"
Project file (.coolftp.json): { "site": "coolftp.com", "localDir": "dist", "build": "npm run build", "ignore": ["*.map"] }.
Commit it. Anyone on the team, human or agent, deploys the same way.
Windows installer and portable build. macOS and Linux builds come from the same Electron source; run npm run dist to build them yourself until signed builds are published.
Not signed yet, so SmartScreen will ask twice. Verify the SHA-256 on the releases page if that matters to you. It should.
At <remote root>/.coolftp/manifest.json, alongside a .htaccess with Require all denied. Apache and LiteSpeed honour it. On nginx add a location ~ /\.coolftp deny rule, or point remoteRoot one level above the web root. The manifest contains file paths and hashes, never contents or credentials.
The first deploy has no manifest, so coolFTP walks the remote tree and compares sizes. Files it has never seen are treated as stale and never deleted unless you pass --delete. After that first deploy, hashes take over.
Encrypted with the Windows Data Protection API under your user account, in sites.json in your profile. Another user on the same PC, or a copy of the file taken elsewhere, cannot decrypt them. SSH keys with the ssh-agent are still the better option, because then nothing secret is stored at all. The app never sends passwords to the interface or to agents. Agents only ever see hasPassword: true.
Not without you. When an agent asks to delete a path, deploy with --delete, or roll back, the desktop app shows a dialog and waits for your click; no answer in two minutes counts as no. Deleting the site root is refused outright. A first deploy into a folder that already has files refuses to remove them. Every call is logged with the agent name. And if the worst happens anyway, coolftp rollback restores the previous commit.
No. The CLI and the MCP server run everything in-process when the app is closed. When the app is open they route through it, so you get the live view and share its open connection.
Because the same TypeScript core runs the CLI, the MCP server and the app, and because ssh2 and basic-ftp are the most battle-tested SFTP and FTP libraries in any language that also ships a GUI toolkit. The bundle is bigger than a native app. The code is smaller.