MCP Server for FTP Access
This MCP server lets an MCP client manage files and directories on remote FTP, FTPS, and SFTP servers.
List remote directories and inspect entries/metadata.
Download remote files as UTF-8 text or base64 binary.
Upload text or base64 binary content to remote files.
Stream local files to/from the remote server when allowed by
FTP_LOCAL_ROOTS.Edit remote text by exact replacement, with optional replace-all.
Append content, creating the file if needed.
Rename or move remote files and directories.
Create and delete remote directories, and delete remote files.
Connect over FTP, FTPS with TLS, or SFTP with password or SSH key authentication.
Allows interaction with FTP servers to list directory contents, download and upload files, create directories, and delete files/directories remotely.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Server for FTP Access list the files in the /public directory"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Use the hosted FTP MCP server on Apify for remote access, or install the free local version below. See APIFY.md for hosted setup and pricing details.
MCP Server for FTP, FTPS, and SFTP Access
This Model Context Protocol (MCP) server provides file-management tools for FTP, FTPS, and SFTP servers. It supports directory listing, binary-safe downloads/uploads, text edits, appends, renames/moves, directory creation, and deletion.
Protocol support
FTP — traditional FTP, normally on port 21.
FTPS — FTP secured with TLS. Use
FTP_PROTOCOL=ftpandFTP_SECURE=true.SFTP — SSH File Transfer Protocol, normally on port 22. SFTP is a different protocol from FTPS and is already encrypted by SSH, so
FTP_SECUREdoes not apply to it.
Related MCP server: MCP SSH Server
Features
List files and directories
Download and upload text or binary files
Upload and download local files by path, streamed, so size is not limited by the request (opt-in)
Edit exact text in remote files
Append to files
Rename or move files/directories
Create and delete directories
FTP, FTPS, and SFTP support
SFTP password or SSH private-key authentication
Optional 1Password CLI private-key resolution
AES-256-GCM encrypted credential values
OS-keychain support for the encryption key
Where to get it
Apify Store — hosted MCP server with pay-per-event pricing
npm (
mcp-server-ftp)
A Cursor plugin directory listing is pending review.
Installation
Prerequisites
Node.js 18.14 or newer
An MCP-compatible client such as Claude Desktop
Installing via npm
The server is published as mcp-server-ftp:
{
"mcpServers": {
"ftp-server": {
"command": "npx",
"args": ["-y", "mcp-server-ftp"],
"env": {
"FTP_HOST": "ftp.example.com"
}
}
}
}Installing via Smithery (deprecated)
Smithery is shutting down its MCP proxy and connection management on October 31, 2026, and the Smithery CLI is deprecated. This install path will stop working then — install via npm instead.
npx -y @smithery/cli install alxspikers-team/mcp-server-ftp --client claudeCursor plugin
The repository is also a Cursor plugin: .cursor-plugin/plugin.json plus mcp.json, which runs npx -y mcp-server-ftp as ftp-server. Each FTP_* setting below is a plugin variable you set when installing or configuring the plugin in Cursor.
Building from source
git clone https://github.com/alxspiker/mcp-server-ftp.git
cd mcp-server-ftp
npm install
npm run buildConfiguration
FTP example
{
"mcpServers": {
"ftp-server": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-ftp/build/index.js"],
"env": {
"FTP_HOST": "ftp.example.com",
"FTP_PORT": "21",
"FTP_PROTOCOL": "ftp",
"FTP_USER": "your-username",
"FTP_PASSWORD": "your-password"
}
}
}
}FTPS example
FTPS uses the normal FTP client with TLS enabled:
{
"mcpServers": {
"ftp-server": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-ftp/build/index.js"],
"env": {
"FTP_HOST": "ftps.example.com",
"FTP_PORT": "21",
"FTP_PROTOCOL": "ftp",
"FTP_SECURE": "true",
"FTP_USER": "your-username",
"FTP_PASSWORD": "your-password"
}
}
}
}FTP_SECURE is only meaningful when FTP_PROTOCOL=ftp. It is ignored by the SFTP path because SFTP is already encrypted over SSH.
For a trusted FTPS server with a self-signed certificate, add "FTP_TLS_REJECT_UNAUTHORIZED": "false" to the FTPS env object. This keeps TLS encryption but disables certificate and hostname verification, so use it only when you independently trust the server and network. Verification stays enabled by default. This setting requires FTP_SECURE=true and FTP_PROTOCOL=ftp.
SFTP example
{
"mcpServers": {
"ftp-server": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-ftp/build/index.js"],
"env": {
"FTP_HOST": "sftp.example.com",
"FTP_PORT": "22",
"FTP_PROTOCOL": "sftp",
"FTP_USER": "your-username",
"FTP_PRIVATE_KEY_PATH": "~/.ssh/id_ed25519",
"FTP_PASSPHRASE": "your-key-passphrase"
}
}
}
}Configuration options
Environment variable | Applies to | Description | Default |
| all | Server hostname or IP address |
|
| all | Server port |
|
| all |
|
|
| all | Username; supports encrypted |
|
| all | Password; supports encrypted | empty |
| FTP/FTPS only | Enables TLS/FTPS for the FTP client |
|
| FTPS only | Verify the FTPS certificate and hostname; |
|
| SFTP only | SSH private-key path or | auto-detect |
| SFTP only | SSH private-key passphrase; supports encrypted | empty |
| encrypted credentials | 64-character hex AES-256 key. Prefer the OS keychain or a global environment variable for local installs. | disabled |
| local file tools | Local directories | disabled |
SFTP authentication
SFTP supports private-key and password authentication.
The server looks for a private key in this order:
FTP_PRIVATE_KEY_PATH, if set~/.ssh/id_ed25519~/.ssh/id_rsa~/.ssh/id_ecdsa
If no key is found, FTP_PASSWORD is used.
Reading an SFTP key from 1Password
FTP_PRIVATE_KEY_PATH may contain a 1Password secret reference instead of a filesystem path:
"FTP_PRIVATE_KEY_PATH": "op://Private/my-server/private key"Requirements:
The 1Password CLI (
op) must be installed and available onPATH.The CLI must already be able to authenticate, either through the desktop-app integration or
OP_SERVICE_ACCOUNT_TOKEN.
The key is resolved lazily, cached in memory for the process, and is not written to disk.
If the SSH server rejects 1Password's default exported key format, request OpenSSH format:
"FTP_PRIVATE_KEY_PATH": "op://Private/my-server/private key?ssh-format=openssh"Credential encryption
FTP_USER, FTP_PASSWORD, and FTP_PASSPHRASE may be stored as AES-256-GCM encrypted values using the enc: format.
Generate an encryption key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Store the key in the OS keychain (recommended for local installs)
npm run build
npm run store-key -- <your-64-char-hex-key>The server loads the key from macOS Keychain, Windows Credential Manager, or Linux Secret Service when available.
Alternatively, set the key globally in the process environment:
export FTP_ENCRYPTION_KEY=<your-64-char-hex-key>Do not place FTP_ENCRYPTION_KEY beside the encrypted credentials in the same local MCP config unless your deployment environment gives you no separate secret-storage mechanism.
Encrypt a value
npm run build
FTP_ENCRYPTION_KEY=<your-64-char-hex-key> npm run encrypt-env -- <plaintext-value>If the key is already available from the OS keychain or shell environment:
npm run encrypt-env -- <plaintext-value>Available tools
Tool | Description |
| List contents of a remote directory |
| Download a file; binary content is returned as base64 |
| Upload text or base64-encoded binary content |
| Create a directory |
| Delete a file |
| Delete a directory |
| Rename or move a file or directory |
| Replace exact text in a remote text file |
| Append content to a file, creating it if needed |
| Upload a local file by path, streamed; checks the remote size afterwards (needs |
| Download a remote file to a local path, streamed, without returning its contents (needs |
Tool calls return machine-readable structuredContent, and all eleven tools advertise output schemas. Version 1.2.2 introduced a compatibility shim that ensures advertised schemas use the JSON Schema 2020-12 dialect required by current MCP clients.
Transferring local files
upload-file and download-file pass file contents through the tool call itself, which suits small text files. For anything larger, such as a built single-page app or an image, the agent would have to write the whole file into the request, which most clients cannot do. upload-local-file and download-to-local instead take a path on the computer running this server and stream the file directly, so size is limited only by the connection.
They are disabled until you list the folders they may use:
"env": {
"FTP_HOST": "ftp.example.com",
"FTP_USER": "your-username",
"FTP_PASSWORD": "your-password",
"FTP_LOCAL_ROOTS": "~/Sites/build:~/Downloads/uploads"
}A path outside the allowed folders is refused before anything about it is looked up, so the reply is the same whether or not it, or its parent folder, exists.
Paths are resolved after following symbolic links, so a link inside an allowed folder that points outside it is refused. Uploads read through a single file descriptor opened after that check (with
O_NOFOLLOWwhere the platform has it), so the file can't be swapped between the check and the transfer.download-to-localwrites to a temporary file with a random name, created exclusively (O_CREAT | O_EXCL, plusO_NOFOLLOWwhere available) beside the target, and writes through its descriptor only, so a file or symbolic link planted at that name can't redirect the download.With
overwritefalse (the default), the finished download is committed with a no-replace operation (a hard link, or an exclusive copy where the file system has no hard links), so a file that appears at the target during the download is never replaced. Withoverwrite: trueit is renamed over the target. An existing symbolic link at the target is refused, and the temporary file is removed on success and on failure.upload-local-filereports the file's size and SHA-256, and compares the size the server reports afterwards (FTPSIZEor SFTPstat) with the local size.
Optional HOL Guard protection
HOL Guard has an opt-in FTP MCP profile (mcp.ftp, catalog ID command.mcp-ftp), merged in PR #4514. Use a HOL Guard release or source build that includes this contribution; releases published before the merge do not include it.
To use the profile:
Install HOL Guard and configure protection for your MCP client using its setup instructions.
Launch this server through
npx mcp-server-ftp, as shown in the npm configuration.Enable FTP MCP locally through HOL Guard's Protection Center.
When enabled, delete-directory requires human review before recursively deleting a remote directory and its contents. The other tools and unknown tools inherit the existing Guard policy. Custom grants on the device take precedence over the contributed defaults, and stronger protection requirements remain effective.
The profile is off by default. It matches npm package launches through npx; direct node build/index.js launches are outside this profile.
Security notes
Prefer SFTP when available; it uses SSH encryption and key authentication without FTPS certificate configuration.
Use
FTP_SECURE=trueonly for FTPS servers using the FTP protocol path.Use credential encryption when a client configuration would otherwise contain plaintext credentials.
Local file transfer is off unless
FTP_LOCAL_ROOTSis set. Keep the list to folders you are happy for the agent to publish from or download into; anything inside them can be uploaded to the server.FTP and SFTP transfers may use short-lived local temporary files for upload/download/append operations; those files are removed during cleanup after each operation.
Troubleshooting Windows builds
Confirm Node.js 18.14 or newer and npm are installed.
Run
npm install.Run
npm run buildornpx tsc.Start the compiled server with
node build/index.js.
License
MIT
Available Tools
11 toolsappend-fileAppend to FileA
Append content to the end of a file on the FTP server (creates the file if it does not exist). Pass encoding "base64" for binary content.
Inputs: content (required), remotePath (required), encoding. Returns: remotePath, appendedBytes
create-directoryCreate DirectoryBIdempotent
Create a new directory on the FTP server
Inputs: remotePath (required). Returns: created, remotePath
delete-directoryDelete DirectoryCDestructiveIdempotent
Delete a directory from the FTP server
Inputs: remotePath (required). Returns: deleted, remotePath
delete-fileDelete FileBDestructiveIdempotent
Delete a file from the FTP server
Inputs: remotePath (required). Returns: deleted, remotePath
download-fileDownload FileARead-only
Download a file from the FTP server. Text files are returned as-is; binary files are returned base64-encoded.
Inputs: remotePath (required). Returns: content, encoding, remotePath
download-to-localDownload To Local FileADestructiveIdempotent
Download a file from the FTP server straight to a path on this computer, streamed, without returning its contents. Only paths inside the directories listed in FTP_LOCAL_ROOTS can be written.
Inputs: localPath (required), remotePath (required), overwrite. Returns: bytes, sha256, localPath, remotePath
edit-fileEdit FileADestructive
Edit a text file on the FTP server by replacing an exact string, without re-uploading the whole file content. oldText must match exactly (including whitespace) and be unique in the file unless replaceAll is set.
Inputs: newText (required), oldText (required), remotePath (required), replaceAll. Returns: fileSize, remotePath, replacements
list-directoryList DirectoryBRead-only
List contents of an FTP directory
Inputs: remotePath (required). Returns: path, entries, fileCount, totalCount, +1 more
rename-fileRename / MoveBDestructive
Rename or move a file or directory on the FTP server
Inputs: toPath (required), fromPath (required). Returns: toPath, renamed, fromPath
upload-fileUpload FileADestructiveIdempotent
Upload a file to the FTP server. Pass encoding "base64" to upload binary content.
Inputs: content (required), remotePath (required), encoding. Returns: remotePath, bytesWritten
upload-local-fileUpload Local FileADestructiveIdempotent
Upload a file from this computer to the FTP server by path, streamed, so file size is not limited by the request. Only files inside the directories listed in FTP_LOCAL_ROOTS can be uploaded.
Inputs: localPath (required), remotePath (required). Returns: sha256, localPath, remotePath, remoteSize, +1 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Most tools target distinct FTP actions, but upload-file/upload-local-file and download-file/download-to-local overlap conceptually. Their descriptions clarify the differences (streaming, local path restrictions, returned content), so an agent can distinguish them with some care.
Names follow a mostly consistent hyphenated verb-noun pattern such as rename-file, create-directory, delete-file, and list-directory. Minor deviations like upload-local-file and download-to-local are still readable and do not mix naming conventions.
The 11 tools are well-scoped for an FTP access server, covering distinct file and directory operations without obvious bloat. Each tool has a clear role in the surface.
The set covers the core FTP lifecycle: list, create/delete directories, upload/download, append, edit, rename, and delete files. Minor gaps such as stat/permission changes or copy operations exist, but agents can work around them.
Maintenance
Related MCP Connectors
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
Give Claude only the Google Drive files you choose. Every action logged.
Use your Mac, Windows or Linux computer from ChatGPT, Claude or Codex: files, commands, documents.
Connect Claude to your Platform7n workspaces: chat, links, work and decks. One-click OAuth.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables SSH remote access to servers through Claude, allowing users to execute commands, transfer files via SFTP, and manage multiple remote connections using natural language.129MIT
- AlicenseNot gradedqualityNot gradedmaintenanceConnects Claude to remote servers via SSH to execute commands, manage files, and browse directories. It allows users to add, edit, and switch between multiple server configurations through natural language conversations.-
- AlicenseAqualityDmaintenanceEnables Claude to connect to servers via SSH, execute commands, transfer files, and manage connections through natural language.911 npm1MIT
- AlicenseAqualityDmaintenanceEnables FTP file operations such as upload, download, list, and delete directly from Claude Desktop or Claude CLI.15MIT