Skip to main content
Glama
copy-files.ts4.87 kB
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import fs from 'fs-extra'; import * as path from 'path'; /** * Tool: Copy Files * Registers the tool with the MCP server * @param server MCP server instance */ const registerTool = (server: McpServer) => { server.registerTool( 'copy-files', { title: 'Copy Files', description: 'Copies a file or folder to a target location. Parameters: sourcePath - Source file/folder path (required); targetPath - Target path (required); overwrite - Whether to overwrite existing files (optional, default is false); preserveTimestamps - Whether to preserve timestamps (optional, default is true)', inputSchema: { sourcePath: z.string(), targetPath: z.string(), overwrite: z.boolean().optional(), preserveTimestamps: z.boolean().optional() } }, async ({ sourcePath, targetPath, overwrite = false, preserveTimestamps = true }) => { try { // Check if the source file exists if (!(await fs.pathExists(sourcePath))) { return { content: [ { type: 'text', text: `Error: Source file or folder ${sourcePath} does not exist` } ], isError: true }; } // Check if the target path exists const targetExists = await fs.pathExists(targetPath); if (targetExists && !overwrite) { return { content: [ { type: 'text', text: `Error: Target path ${targetPath} already exists. Set overwrite=true to overwrite.` } ], isError: true }; } // Get source file information const sourceStats = await fs.stat(sourcePath); const isDirectory = sourceStats.isDirectory(); const sourceSize = isDirectory ? await calculateDirectorySize(sourcePath) : sourceStats.size; // Ensure the target directory exists const targetDir = isDirectory ? targetPath : path.dirname(targetPath); await fs.ensureDir(targetDir); // Perform the copy operation const copyOptions: any = { overwrite: overwrite, preserveTimestamps: preserveTimestamps }; await fs.copy(sourcePath, targetPath, copyOptions); // Verify that the copy was successful if (!(await fs.pathExists(targetPath))) { return { content: [ { type: 'text', text: 'Error: Copy operation completed but target file not found' } ], isError: true }; } // Verify the copied file await fs.stat(targetPath); // Count the number of files (if it's a directory) let fileCount = 1; if (isDirectory) { fileCount = await countFilesInDirectory(targetPath); } return { content: [ { type: 'text', text: `Copy complete!\nSource path: ${sourcePath}\nTarget path: ${targetPath}\nType: ${isDirectory ? 'Folder' : 'File'}\nSize: ${Math.round(sourceSize / 1024)}KB\n${isDirectory ? `Files included: ${fileCount}` : ''}\nTimestamps preserved: ${preserveTimestamps ? 'Yes' : 'No'}` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error copying file: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); }; /** * Calculates the size of a directory. */ async function calculateDirectorySize(dirPath: string): Promise<number> { let totalSize = 0; const calculateSize = async (itemPath: string): Promise<void> => { const stats = await fs.stat(itemPath); if (stats.isDirectory()) { const items = await fs.readdir(itemPath); for (const item of items) { await calculateSize(path.join(itemPath, item)); } } else { totalSize += stats.size; } }; await calculateSize(dirPath); return totalSize; } /** * Counts the number of files in a directory. */ async function countFilesInDirectory(dirPath: string): Promise<number> { let fileCount = 0; const countFiles = async (itemPath: string): Promise<void> => { const stats = await fs.stat(itemPath); if (stats.isDirectory()) { const items = await fs.readdir(itemPath); for (const item of items) { await countFiles(path.join(itemPath, item)); } } else { fileCount++; } }; await countFiles(dirPath); return fileCount; } export default registerTool;

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/Yussefgafer/MyMCP'

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