Skip to main content
Glama

mcp-image-compression

by InhiblabCore
common.ts3.26 kB
import axios from 'axios'; import fs from 'fs'; import { readFile } from "fs/promises"; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; import sharp from 'sharp'; import { ImageContent } from '@modelcontextprotocol/sdk/types.js'; import { fileTypeFromBuffer } from "file-type"; // 定义类型 type ImageSource = string; export async function compressAndStoreImage( imageUrl: ImageSource, outputDir: string, quality = 80, format = 'jpg', ): Promise<string> { try { // 校验输出目录 if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } let inputBuffer: Buffer; // 判断是否是网络地址 if (/^https?:\/\//.test(imageUrl)) { // 下载网络图片 const response = await axios.get(imageUrl, { responseType: 'arraybuffer', timeout: 10000 }); inputBuffer = Buffer.from(response.data, 'binary'); } else { // 读取本地图片 if (!fs.existsSync(imageUrl)) { throw new Error(`Local file not found: ${imageUrl}`); } inputBuffer = await fs.promises.readFile(imageUrl); } // 读取文件原始名称 const originalFilename = path.basename(imageUrl); const originalExt = path.parse(originalFilename).ext; // 生成唯一文件名 const outputFilename = format ? `${uuidv4()}.${format}` : `${uuidv4()}${originalExt}`; const outputPath = path.join(outputDir, outputFilename); await sharp(inputBuffer) // @ts-ignore .toFormat(format ? format : originalExt?.replace('.', ''), { quality, }) .toFile(outputPath); return outputPath; } catch (error) { throw new Error(`Image processing failed`); } } export function isImageSource(str: string): boolean { // 匹配常规图片地址 if (/\.(jpe?g|png|gif|webp|bmp|svg|avif)(\?[^#]*)?(#[^\s]*)?$/i.test(str)) { return true; } // 匹配Base64数据URI if (/^data:image\/(jpe?g|png|gif|webp|bmp|svg\+xml|avif);base64,/i.test(str)) { return true; } // 可选:匹配无扩展名但包含图片路由的情况(如CDN地址) // 示例:/image/12345?format=jpg if (/\/(image|img|photo|pic)s?\/[^/]+(\?.*?(format|type)=(jpe?g|png|gif|webp|bmp|svg|avif))/i.test(str)) { return true; } return false; } /** * Generates an image content object from a URL, file path, or buffer. */ export const imageContent = async ( input: { url: string } | { path: string } | { buffer: Buffer }, ): Promise<ImageContent> => { let rawData: Buffer; if ("url" in input) { const response = await fetch(input.url); if (!response.ok) { throw new Error(`Failed to fetch image from URL: ${response.statusText}`); } rawData = Buffer.from(await response.arrayBuffer()); } else if ("path" in input) { rawData = await readFile(input.path); } else if ("buffer" in input) { rawData = input.buffer; } else { throw new Error( "Invalid input: Provide a valid 'url', 'path', or 'buffer'", ); } const mimeType = await fileTypeFromBuffer(rawData); const base64Data = rawData.toString("base64"); return { type: "image", data: base64Data, mimeType: mimeType?.mime ?? "image/png", } as const; };

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/InhiblabCore/mcp-image-compression'

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