Skip to main content
Glama

sftp_tool

Upload or download files between local systems and SSH servers using SFTP protocol for secure file transfer operations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
serverNameYesSSH server name
actionYesAction: upload or download
localPathYesLocal file path (absolute)
remotePathYesRemote file path

Implementation Reference

  • The primary handler function for the sftp_tool. It validates input, establishes SSH/SFTP connection, executes upload or download based on action, and returns structured response or error.
    export default async (request: any) => {
        try {
            // 解析请求参数
            const { serverName, action, localPath, remotePath } = request.params.arguments;
    
            // 验证参数
            if (!serverName || !action || !localPath || !remotePath) {
                throw new Error("Missing required parameters: serverName, action, localPath, remotePath");
            }
    
            if (action !== 'upload' && action !== 'download') {
                throw new Error('Invalid action. Must be "upload" or "download".');
            }
    
            // 获取SSH连接
            const conn = await getSSHConnection(serverName);
    
            // 获取SFTP会话
            const sftp = await getSFTPSession(conn);
    
            let result;
            try {
                // 执行文件操作
                if (action === 'upload') {
                    result = await uploadFile(sftp, localPath, remotePath);
                } else {
                    result = await downloadFile(sftp, remotePath, localPath);
                }
            } finally {
                // 关闭SFTP会话
                sftp.end();
            }
    
            // 返回成功结果
            return {
                content: [
                    {
                        type: "text",
                        text: JSON.stringify({
                            message: result,
                            action: action,
                            localPath: localPath,
                            remotePath: remotePath
                        }, null, 2)
                    }
                ]
            };
        } catch (error) {
            // 返回错误结果
            return {
                content: [
                    {
                        type: "text",
                        text: JSON.stringify({
                            error: error instanceof Error ? error.message : String(error)
                        }, null, 2)
                    }
                ],
                isError: true
            };
        }
    };
  • JSON schema defining the input parameters for the sftp_tool: serverName, action (upload/download), localPath, remotePath.
    export const schema = {
        name: "sftp_tool",
        description: "Connect to SSH server and upload/download files",
        type: "object",
        properties: {
            serverName: {
                type: "string",
                description: "SSH server name",
            },
            action: {
                type: "string",
                description: "Action: upload or download",
                enum: ["upload", "download"],
            },
            localPath: {
                type: "string",
                description: "Local file path (absolute)",
            },
            remotePath: {
                type: "string",
                description: "Remote file path",
            },
        },
        required: ["serverName", "action", "localPath", "remotePath"]
    };
  • Helper function to retrieve or establish a cached SSH connection using environment variable SSH_{serverName}_URI (format: user:pass@host:port).
    async function getSSHConnection(serverName: string): Promise<Client> {
        // 如果已有连接,直接返回
        if (sshConnections[serverName]) {
            return sshConnections[serverName];
        }
    
        // 从环境变量获取连接信息
        const sshUri = process.env[`SSH_${serverName}_URI`];
        if (!sshUri) {
            throw new Error(`SSH_${serverName}_URI environment variable must be set.`);
        }
    
        // 解析连接信息
        const [usernameAndpassword, HostAndport] = sshUri.split('@');
        const [username, password] = usernameAndpassword.split(':');
        const [host, port] = HostAndport.split(':');
    
        // 创建新连接
        return new Promise((resolve, reject) => {
            const conn = new Client();
    
            conn.on('ready', () => {
                sshConnections[serverName] = conn;
                resolve(conn);
            });
    
            conn.on('error', (err) => {
                delete sshConnections[serverName];
                reject(new Error(`SSH connection error: ${err.message}`));
            });
    
            conn.on('end', () => {
                delete sshConnections[serverName];
            });
    
            conn.connect({
                host: host,
                port: parseInt(port),
                username: username,
                password: password
            });
        });
    }
  • Helper function for uploading a local file to remote path via SFTP, ensuring the remote directory exists first.
    async function uploadFile(sftp: any, localPath: string, remotePath: string): Promise<string> {
        try {
            // 确保远程目录存在
            const remoteDir = path.dirname(remotePath);
            await ensureRemoteDir(sftp, remoteDir);
    
            // 上传文件
            return new Promise((resolve, reject) => {
                sftp.fastPut(localPath, remotePath, {}, (err: any) => {
                    if (err) {
                        reject(new Error(`Upload failed: ${err.message}`));
                    } else {
                        resolve(`File uploaded successfully to ${remotePath}`);
                    }
                });
            });
        } catch (error) {
            throw new Error(`Upload operation failed: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
  • Helper function for downloading a remote file to local path via SFTP, ensuring the local directory exists first.
    async function downloadFile(sftp: any, remotePath: string, localPath: string): Promise<string> {
        try {
            // 确保本地目录存在
            const localDir = path.dirname(localPath);
            await ensureLocalDir(localDir);
    
            // 下载文件
            return new Promise((resolve, reject) => {
                sftp.fastGet(remotePath, localPath, {}, (err: any) => {
                    if (err) {
                        reject(new Error(`Download failed: ${err.message}`));
                    } else {
                        resolve(`File downloaded successfully to ${localPath}`);
                    }
                });
            });
        } catch (error) {
            throw new Error(`Download operation failed: ${error instanceof Error ? error.message : String(error)}`);
        }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xiaoguomeiyitian/ToolBox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server