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)
    }

Tool Definition Quality

Score is being calculated. Check back soon.

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