Skip to main content
Glama

task_transfer_multi

Execute multiple SFTP file transfers with glob pattern support (*, ?, []) for uploading or downloading batches of files between local and remote servers.

Instructions

Lance des transferts SFTP multiples avec support de patterns glob (*, ?, []).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
aliasYesAlias du serveur cible.
directionYes
filesYesListe des fichiers à transférer
rappelNoDéfinit un rappel en secondes.

Implementation Reference

  • server.js:511-543 (registration)
    Full registration of the 'task_transfer_multi' tool, including schema definition and inline handler function that queues the job and delegates execution to sftp module.
    server.registerTool( "task_transfer_multi", { title: "Transférer plusieurs fichiers/dossiers (SFTP)", description: "Lance des transferts SFTP multiples avec support de patterns glob (*, ?, []).", inputSchema: z.object({ alias: z.string().describe("Alias du serveur cible."), direction: z.enum(['upload', 'download']), files: z.array(z.object({ local: z.string().describe("Chemin local ou pattern glob (ex: /home/*.txt)"), remote: z.string().describe("Chemin distant") })).describe("Liste des fichiers à transférer"), rappel: z.number().optional().describe("Définit un rappel en secondes.") }) }, async (params) => { const job = queue.addJob({ type: 'sftp', ...params, status: 'pending', files: params.files }); history.logTask(job); sftp.executeMultiTransfer(job.id); const finalJob = await waitForJobCompletion(job.id, config.syncTimeout); if (finalJob) { return { content: [{ type: "text", text: `Résultat transferts multiples (tâche ${finalJob.id}):\n${JSON.stringify(finalJob, null, 2)}` }] }; } else { return { content: [{ type: "text", text: `Tâche de transferts multiples ${job.id} initiée en arrière-plan.` }] }; } } );
  • The core handler function for the tool: creates a queue job with multi-file params, logs to history, triggers sftp execution, awaits short completion or reports background task.
    const job = queue.addJob({ type: 'sftp', ...params, status: 'pending', files: params.files }); history.logTask(job); sftp.executeMultiTransfer(job.id); const finalJob = await waitForJobCompletion(job.id, config.syncTimeout); if (finalJob) { return { content: [{ type: "text", text: `Résultat transferts multiples (tâche ${finalJob.id}):\n${JSON.stringify(finalJob, null, 2)}` }] }; } else { return { content: [{ type: "text", text: `Tâche de transferts multiples ${job.id} initiée en arrière-plan.` }] }; } }
  • Input schema using Zod for validating tool parameters: server alias, direction, array of local/remote file paths (supporting globs), optional reminder.
    { title: "Transférer plusieurs fichiers/dossiers (SFTP)", description: "Lance des transferts SFTP multiples avec support de patterns glob (*, ?, []).", inputSchema: z.object({ alias: z.string().describe("Alias du serveur cible."), direction: z.enum(['upload', 'download']), files: z.array(z.object({ local: z.string().describe("Chemin local ou pattern glob (ex: /home/*.txt)"), remote: z.string().describe("Chemin distant") })).describe("Liste des fichiers à transférer"), rappel: z.number().optional().describe("Définit un rappel en secondes.") }) },
  • Helper function specifically invoked by the tool handler for multi-transfers; delegates to the general executeTransfer which handles job.files array.
    async function executeMultiTransfer(jobId) { const job = queue.getJob(jobId); if (!job) return queue.log('error', `Tâche introuvable: ${jobId}`); // Utilise la même fonction mais avec support multi-fichiers return executeTransfer(jobId); }
  • Core helper implementing SFTP transfers: connects via ssh2-sftp-client, expands glob patterns, handles upload/download for multiple files/directories, reports success/fail counts to queue.
    async function executeTransfer(jobId) { const job = queue.getJob(jobId); if (!job) return queue.log('error', `Tâche introuvable: ${jobId}`); let sftp = null; try { const serverConfig = await serverManager.getServer(job.alias); queue.updateJobStatus(jobId, 'running'); sftp = new SftpClient(); // Configuration de la connexion const config = { host: serverConfig.host, port: 22, username: serverConfig.user, readyTimeout: 20000, retries: 3, retry_factor: 2, retry_minTimeout: 2000 }; if (serverConfig.keyPath) { config.privateKey = await fs.readFile(serverConfig.keyPath); } else if (serverConfig.password) { config.password = serverConfig.password; } else { throw new Error(`Aucune méthode d'authentification pour '${job.alias}'.`); } await sftp.connect(config); // Déterminer si on traite plusieurs fichiers const files = job.files || [{ local: job.local, remote: job.remote }]; const isMultiple = Array.isArray(job.files) && job.files.length > 1; let successCount = 0; let failedFiles = []; let totalFiles = 0; // Traiter chaque fichier for (let i = 0; i < files.length; i++) { const file = files[i]; const progress = isMultiple ? ` (${i + 1}/${files.length})` : ''; try { if (job.direction === 'upload') { const localFiles = await expandFileList(file.local); totalFiles += localFiles.length; for (const localFile of localFiles) { queue.log('info', `Transfert${progress}: ${localFile}`); await handleUpload(sftp, localFile, file.remote); successCount++; } } else if (job.direction === 'download') { const downloadedCount = await handleDownload(sftp, file.remote, file.local); totalFiles += downloadedCount; successCount += downloadedCount; } } catch (err) { queue.log('error', `Échec transfert ${file.local || file.remote}: ${err.message}`); failedFiles.push({ file: file.local || file.remote, error: err.message }); } } await sftp.end(); // Génération du rapport let status = successCount === totalFiles ? 'completed' : 'partial'; let output = `Transfert ${job.direction}: ${successCount}/${totalFiles} fichiers réussis`; if (failedFiles.length > 0) { output += `\nÉchecs: ${failedFiles.map(f => f.file).join(', ')}`; if (successCount === 0) status = 'failed'; } queue.updateJobStatus(jobId, status, { output, failedFiles }); } catch (err) { queue.updateJobStatus(jobId, 'failed', { error: err.message }); } finally { if (sftp) { try { await sftp.end(); } catch (e) { // Ignorer les erreurs de fermeture } } } }

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/fkom13/mcp-sftp-orchestrator'

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