Skip to main content
Glama

ssh_copy_file

Facilitates file transfer between local and remote servers using specified SSH connections. Supports directory creation at the target path for efficient file management.

Instructions

Copy files between local and remote servers or between remote servers

Input 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

Input Schema (JSON Schema)

{ "properties": { "createDirectories": { "default": true, "description": "Create target directories if they don't exist", "type": "boolean" }, "sourceConnectionId": { "description": "Source SSH connection ID (use \"local\" for local files)", "type": "string" }, "sourcePath": { "description": "Source file path", "type": "string" }, "targetConnectionId": { "description": "Target SSH connection ID (use \"local\" for local files)", "type": "string" }, "targetPath": { "description": "Target file path", "type": "string" } }, "required": [ "sourceConnectionId", "sourcePath", "targetConnectionId", "targetPath" ], "type": "object" }

Implementation Reference

  • Main handler function implementing ssh_copy_file tool. Handles local-to-local, local-to-remote, remote-to-local, and remote-to-remote file transfers using fs.copyFile, NodeSSH.putFile/getFile, with directory creation and temp file for remote-remote.
    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 input parameters for ssh_copy_file tool: source/target connection IDs ("local" or SSH ID), paths, and createDirectories option.
    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-292 (registration)
    Tool registration in ListTools handler: defines name 'ssh_copy_file', description, and inputSchema matching CopyFileSchema.
    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)
    Registration in CallToolRequestSchema switch statement: routes 'ssh_copy_file' calls to handleSSHCopyFile handler.
    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/widjis/mcp-ssh'

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