Skip to main content
Glama

compress

Compress files or directories into a ZIP archive with customizable options like encryption, password protection, and compression level.

Instructions

Compress local files or directories into a ZIP file

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inputYes
optionsNo
outputYes

Implementation Reference

  • The main handler function for the 'compress' tool. It processes input file(s)/directory(ies), reads their contents, prepares data for compression, calls the compressData helper, writes the resulting ZIP to the output path, and returns success/error messages.
      execute: async (args) => {
      try {
        const outputPath = args.output;
        // Separate CompressionOptions and other options
        const { overwrite, ...compressionOptions } = args.options || {};
        const shouldOverwrite = overwrite ?? false;
    
        // Check if output path already exists
        if ((await exists(outputPath)) && !shouldOverwrite) {
          throw new Error(
            `Output file ${outputPath} already exists. Set overwrite: true to overwrite.`
          );
        }
    
        // Create output directory (if it doesn't exist)
        const outputDir = path.dirname(outputPath);
        if (!(await exists(outputDir))) {
          await fs.mkdir(outputDir, { recursive: true });
        }
    
        // Prepare input files
        const inputPaths = Array.isArray(args.input) ? args.input : [args.input];
        const filesToCompress: { name: string; data: Uint8Array }[] = [];
    
        // Process each input path
        for (const inputPath of inputPaths) {
          if (!(await exists(inputPath))) {
            throw new Error(`Input path not found: ${inputPath}`);
          }
    
          const stats = await fs.stat(inputPath);
    
          if (stats.isDirectory()) {
            // Process directory
            const baseDir = path.basename(inputPath);
            const files = await getAllFiles(inputPath);
    
            for (const relPath of files) {
              const fullPath = path.join(inputPath, relPath);
              const data = await fs.readFile(fullPath);
              // Maintain relative path structure
              filesToCompress.push({
                name: path.join(baseDir, relPath),
                data: new Uint8Array(data),
              });
            }
          } else {
            // Process single file
            const data = await fs.readFile(inputPath);
            filesToCompress.push({
              name: path.basename(inputPath),
              data: new Uint8Array(data),
            });
          }
        }
    
        if(compressionOptions?.level && compressionOptions.level > 9) {
          compressionOptions.level = 9;
        }
    
        if(compressionOptions?.level && compressionOptions.level < 0) {
          compressionOptions.level = 0;
        }
    
        // Execute compression
        const result = await compressData(filesToCompress, compressionOptions);
    
        // Write result to file
        await fs.writeFile(outputPath, result);
    
        return {
          content: [
            {
              type: "text",
              text: `Compression completed. Created ${outputPath} file containing ${filesToCompress.length} files.`,
            },
          ],
        };
      } catch (error) {
        return {
          content: [{ type: "text", text: `Compression failed: ${formatError(error)}` }],
        };
      }
    },
  • Zod schema defining the parameters for the compress tool: input (file/dir path or array), output ZIP path, and options (compression level, password, etc.).
    parameters: z.object({
      input: z.union([
        z.string(), // Single file or directory path
        z.array(z.string()), // Multiple file or directory paths
      ]),
      output: z.string(), // Output ZIP file path
      options: z
        .object({
        level: z.number().min(0).max(9).optional(),
        comment: z.string().optional(),
        password: z.string().optional(),
        encryptionStrength: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
        overwrite: z.boolean().optional(),
        })
        .optional(),
      }),
  • src/index.ts:64-167 (registration)
    The server.addTool call that registers the 'compress' tool with name, description, parameters schema, and execute handler.
    server.addTool({
      name: "compress",
      description: "Compress local files or directories into a ZIP file",
      parameters: z.object({
        input: z.union([
          z.string(), // Single file or directory path
          z.array(z.string()), // Multiple file or directory paths
        ]),
        output: z.string(), // Output ZIP file path
        options: z
          .object({
          level: z.number().min(0).max(9).optional(),
          comment: z.string().optional(),
          password: z.string().optional(),
          encryptionStrength: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
          overwrite: z.boolean().optional(),
          })
          .optional(),
        }),
        execute: async (args) => {
        try {
          const outputPath = args.output;
          // Separate CompressionOptions and other options
          const { overwrite, ...compressionOptions } = args.options || {};
          const shouldOverwrite = overwrite ?? false;
    
          // Check if output path already exists
          if ((await exists(outputPath)) && !shouldOverwrite) {
            throw new Error(
              `Output file ${outputPath} already exists. Set overwrite: true to overwrite.`
            );
          }
    
          // Create output directory (if it doesn't exist)
          const outputDir = path.dirname(outputPath);
          if (!(await exists(outputDir))) {
            await fs.mkdir(outputDir, { recursive: true });
          }
    
          // Prepare input files
          const inputPaths = Array.isArray(args.input) ? args.input : [args.input];
          const filesToCompress: { name: string; data: Uint8Array }[] = [];
    
          // Process each input path
          for (const inputPath of inputPaths) {
            if (!(await exists(inputPath))) {
              throw new Error(`Input path not found: ${inputPath}`);
            }
    
            const stats = await fs.stat(inputPath);
    
            if (stats.isDirectory()) {
              // Process directory
              const baseDir = path.basename(inputPath);
              const files = await getAllFiles(inputPath);
    
              for (const relPath of files) {
                const fullPath = path.join(inputPath, relPath);
                const data = await fs.readFile(fullPath);
                // Maintain relative path structure
                filesToCompress.push({
                  name: path.join(baseDir, relPath),
                  data: new Uint8Array(data),
                });
              }
            } else {
              // Process single file
              const data = await fs.readFile(inputPath);
              filesToCompress.push({
                name: path.basename(inputPath),
                data: new Uint8Array(data),
              });
            }
          }
    
          if(compressionOptions?.level && compressionOptions.level > 9) {
            compressionOptions.level = 9;
          }
    
          if(compressionOptions?.level && compressionOptions.level < 0) {
            compressionOptions.level = 0;
          }
    
          // Execute compression
          const result = await compressData(filesToCompress, compressionOptions);
    
          // Write result to file
          await fs.writeFile(outputPath, result);
    
          return {
            content: [
              {
                type: "text",
                text: `Compression completed. Created ${outputPath} file containing ${filesToCompress.length} files.`,
              },
            ],
          };
        } catch (error) {
          return {
            content: [{ type: "text", text: `Compression failed: ${formatError(error)}` }],
          };
        }
      },
    });
  • The core compression helper function used by the compress tool handler. Uses @zip.js/zip.js to create ZIP files from file data arrays.
    export async function compressData(
      data: Uint8Array | Blob | string | { name: string, data: Uint8Array | Blob | string }[],
      options: CompressionOptions = {}
    ): Promise<Uint8Array> {
      const zipWriter = new zip.ZipWriter(new zip.Uint8ArrayWriter(), {
        level: options.level || 5,
        password: options.password,
        encryptionStrength: options.encryptionStrength
      });
    
      try {
        if (Array.isArray(data)) {
          // Handle multiple file compression
          for (const item of data) {
            let fileData: Uint8Array | Blob | string = item.data;
            
            // Convert string to Uint8Array
            if (typeof fileData === 'string') {
              const encoder = new TextEncoder();
              fileData = encoder.encode(fileData);
            }
            
            await zipWriter.add(item.name, 
              typeof fileData === 'string' 
                ? new zip.TextReader(fileData)
                : fileData instanceof Blob 
                  ? new zip.BlobReader(fileData) 
                  : new zip.Uint8ArrayReader(fileData)
            );
          }
        } else {
          // Handle single file compression
          let fileData = data;
          
          // Convert string to Uint8Array
          if (typeof fileData === 'string') {
            const encoder = new TextEncoder();
            fileData = encoder.encode(fileData);
          }
          
          await zipWriter.add('file', 
            typeof fileData === 'string' 
              ? new zip.TextReader(fileData)
              : fileData instanceof Blob 
                ? new zip.BlobReader(fileData) 
                : new zip.Uint8ArrayReader(fileData)
          );
        }
    
        return await zipWriter.close();
      } catch (error: any) {
        throw new Error(`Compression failed: ${error.message}`);
      }
    }
  • Type definition for CompressionOptions used in compressData and tool options.
    export interface CompressionOptions {
      level?: number; // Compression level (0-9)
      password?: string; // Password protection
      encryptionStrength?: 1 | 2 | 3; // Encryption strength (1-3)
    }
Install Server

Other Tools

Related Tools

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/7gugu/zip-mcp'

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