Skip to main content
Glama

ssh_copy_file

Copy files between local and remote servers or between remote servers using SSH connections. Specify source and target paths with connection IDs to transfer files securely.

Instructions

Copy files between local and remote servers or between remote servers

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
createDirectoriesNoCreate target directories if they don't exist
sourceConnectionIdYesSource SSH connection ID (use "local" for local files)
sourcePathYesSource file path
targetConnectionIdYesTarget SSH connection ID (use "local" for local files)
targetPathYesTarget file path

Implementation Reference

  • Implementation of the ssh_copy_file tool handler. Handles four copy scenarios: local-to-local using fs.copyFile, local-to-remote using putFile, remote-to-local using getFile, and remote-to-remote using temporary local file.
    private async handleSSHCopyFile(args: unknown) { const params = CopyFileSchema.parse(args); try { // Handle different copy scenarios if (params.sourceConnectionId === 'local' && params.targetConnectionId === 'local') { // Local to local copy await fs.copyFile(params.sourcePath, params.targetPath); return { content: [ { type: 'text', text: `Successfully copied ${params.sourcePath} to ${params.targetPath} (local to local)`, }, ], }; } else if (params.sourceConnectionId === 'local') { // Local to remote const targetSSH = connectionPool.get(params.targetConnectionId); if (!targetSSH) { throw new McpError( ErrorCode.InvalidParams, `Target connection ID '${params.targetConnectionId}' not found` ); } if (params.createDirectories) { const targetDir = path.dirname(params.targetPath); await targetSSH.execCommand(`mkdir -p "${targetDir}"`); } await targetSSH.putFile(params.sourcePath, params.targetPath); return { content: [ { type: 'text', text: `Successfully copied ${params.sourcePath} to ${params.targetConnectionId}:${params.targetPath}`, }, ], }; } else if (params.targetConnectionId === 'local') { // Remote to local const sourceSSH = connectionPool.get(params.sourceConnectionId); if (!sourceSSH) { throw new McpError( ErrorCode.InvalidParams, `Source connection ID '${params.sourceConnectionId}' not found` ); } if (params.createDirectories) { const targetDir = path.dirname(params.targetPath); await fs.mkdir(targetDir, { recursive: true }); } await sourceSSH.getFile(params.targetPath, params.sourcePath); return { content: [ { type: 'text', text: `Successfully copied ${params.sourceConnectionId}:${params.sourcePath} to ${params.targetPath}`, }, ], }; } else { // Remote to remote const sourceSSH = connectionPool.get(params.sourceConnectionId); const targetSSH = connectionPool.get(params.targetConnectionId); if (!sourceSSH) { throw new McpError( ErrorCode.InvalidParams, `Source connection ID '${params.sourceConnectionId}' not found` ); } if (!targetSSH) { throw new McpError( ErrorCode.InvalidParams, `Target connection ID '${params.targetConnectionId}' not found` ); } // Use a temporary local file for remote-to-remote transfer const tempFile = `/tmp/mcp-ssh-temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; try { await sourceSSH.getFile(tempFile, params.sourcePath); if (params.createDirectories) { const targetDir = path.dirname(params.targetPath); await targetSSH.execCommand(`mkdir -p "${targetDir}"`); } await targetSSH.putFile(tempFile, params.targetPath); await fs.unlink(tempFile); // Clean up temp file return { content: [ { type: 'text', text: `Successfully copied ${params.sourceConnectionId}:${params.sourcePath} to ${params.targetConnectionId}:${params.targetPath}`, }, ], }; } catch (error) { // Clean up temp file on error try { await fs.unlink(tempFile); } catch {} throw error; } } } catch (error) { throw new McpError( ErrorCode.InternalError, `File copy failed: ${error instanceof Error ? error.message : String(error)}` ); } }
  • Zod schema defining the input parameters for the ssh_copy_file tool, including source/target connection IDs and paths.
    const CopyFileSchema = z.object({ sourceConnectionId: z.string().describe('Source SSH connection ID (use "local" for local files)'), sourcePath: z.string().describe('Source file path'), targetConnectionId: z.string().describe('Target SSH connection ID (use "local" for local files)'), targetPath: z.string().describe('Target file path'), createDirectories: z.boolean().default(true).describe('Create target directories if they don\'t exist') });
  • src/index.ts:280-293 (registration)
    Tool registration in the ListToolsRequestSchema response, defining the name, description, and input schema for ssh_copy_file.
    name: 'ssh_copy_file', description: 'Copy files between local and remote servers or between remote servers', inputSchema: { type: 'object', properties: { sourceConnectionId: { type: 'string', description: 'Source SSH connection ID (use "local" for local files)' }, sourcePath: { type: 'string', description: 'Source file path' }, targetConnectionId: { type: 'string', description: 'Target SSH connection ID (use "local" for local files)' }, targetPath: { type: 'string', description: 'Target file path' }, createDirectories: { type: 'boolean', default: true, description: 'Create target directories if they don\'t exist' } }, required: ['sourceConnectionId', 'sourcePath', 'targetConnectionId', 'targetPath'] }, },
  • src/index.ts:491-492 (registration)
    Dispatch case in the CallToolRequestSchema handler that routes ssh_copy_file calls to the handleSSHCopyFile method.
    case 'ssh_copy_file': return await this.handleSSHCopyFile(args);

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/mahathirmuh/mcp-ssh-server'

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