Skip to main content
Glama
compress-images.ts3.89 kB
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import fs from 'fs-extra'; import path from 'path'; import sharp from 'sharp'; export default function registerCompressImagesTool(server: McpServer) { server.registerTool( 'compress-images', { title: 'Compress Images', description: 'Compresses image files to reduce file size while maintaining quality.', inputSchema: { input_files: z.array(z.string()).describe('Array of image file paths to compress'), output_dir: z.string().optional().describe('Output directory (defaults to same as input)'), quality: z.number().min(1).max(100).optional().default(80).describe('Compression quality (1-100)'), format: z.enum(['jpeg', 'png', 'webp']).optional().default('jpeg').describe('Output format'), max_width: z.number().optional().describe('Maximum width in pixels'), max_height: z.number().optional().describe('Maximum height in pixels'), }, }, async (params: { input_files: string[]; output_dir?: string; quality?: number; format?: 'jpeg' | 'png' | 'webp'; max_width?: number; max_height?: number; }) => { try { const { input_files, output_dir, quality = 80, format = 'jpeg', max_width, max_height } = params; // Validate input files exist for (const file of input_files) { if (!(await fs.pathExists(file))) { return { content: [{ type: 'text', text: `Error: Input file does not exist: ${file}` }], isError: true, }; } } const outputDirectory = output_dir || path.dirname(input_files[0]); await fs.ensureDir(outputDirectory); const compressedFiles: string[] = []; // Process each image for (const inputFile of input_files) { const fileName = path.basename(inputFile, path.extname(inputFile)); const outputFileName = `${fileName}_compressed.${format}`; const outputPath = path.join(outputDirectory, outputFileName); // Get original file size const originalStats = await fs.stat(inputFile); const originalSize = originalStats.size; // Process image with Sharp let sharpInstance = sharp(inputFile); // Resize if specified if (max_width || max_height) { sharpInstance = sharpInstance.resize(max_width, max_height, { fit: 'inside', withoutEnlargement: true, }); } // Set format and quality if (format === 'jpeg') { sharpInstance = sharpInstance.jpeg({ quality }); } else if (format === 'png') { sharpInstance = sharpInstance.png({ quality: quality / 100 }); } else if (format === 'webp') { sharpInstance = sharpInstance.webp({ quality }); } // Save compressed image await sharpInstance.toFile(outputPath); // Get compressed file size const compressedStats = await fs.stat(outputPath); const compressedSize = compressedStats.size; const compressionRatio = ((originalSize - compressedSize) / originalSize * 100).toFixed(1); compressedFiles.push( `${outputPath} (${originalSize} → ${compressedSize} bytes, ${compressionRatio}% reduction)` ); } return { content: [ { type: 'text', text: `Successfully compressed ${input_files.length} images:\n${compressedFiles.join('\n')}`, }, ], }; } catch (error: any) { return { content: [{ type: 'text', text: `Error compressing images: ${error.message}` }], isError: true, }; } } ); }

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