process_and_upload_image_from_url
Process an image from a URL by optimizing, resizing, and converting it to WebP format, then upload it to Vercel Blob storage. Ideal for efficient image management.
Instructions
Process an image from a URL (optimize, resize, convert to WebP) and upload to Vercel Blob
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| height | No | Height to resize the image to (default: 300) | |
| imageUrl | Yes | URL of the image to process | |
| newName | Yes | New name for the processed image (without extension) | |
| width | No | Width to resize the image to (default: 550) |
Implementation Reference
- src/index.ts:354-375 (handler)Handler logic specific to the 'process_and_upload_image_from_url' tool: destructures arguments, validates required fields, downloads the image buffer from the URL using downloadImage helper, and processes/uploads using the shared processAndUploadImageBuffer function.else if (toolName === "process_and_upload_image_from_url") { // Process image from URL const { imageUrl, newName, width = 550, height = 300 } = args as { imageUrl: string; newName: string; width?: number; height?: number; }; if (!imageUrl || !newName) { throw new McpError( ErrorCode.InvalidParams, "imageUrl and newName are required" ); } // Download the image from the URL const imageBuffer = await downloadImage(imageUrl); // Process and upload the image result = await processAndUploadImageBuffer(imageBuffer, newName, width, height); }
- src/index.ts:117-142 (schema)Tool schema definition including name, description, and input schema with properties for imageUrl (required), newName (required), width, and height.{ name: "process_and_upload_image_from_url", description: "Process an image from a URL (optimize, resize, convert to WebP) and upload to Vercel Blob", inputSchema: { type: "object", properties: { imageUrl: { type: "string", description: "URL of the image to process" }, newName: { type: "string", description: "New name for the processed image (without extension)" }, width: { type: "number", description: "Width to resize the image to (default: 550)" }, height: { type: "number", description: "Height to resize the image to (default: 300)" } }, required: ["imageUrl", "newName"] } }
- src/index.ts:194-298 (helper)Core helper function that takes an image Buffer, resizes and optimizes to PNG (_small.png), converts to WebP, saves to temp files, checks for existing blobs, uploads if new to Vercel Blob, and returns URLs and paths.async function processAndUploadImageBuffer( imageBuffer: Buffer, newName: string, width: number = 550, height: number = 300 ): Promise<any> { // Process results const results = { png: { localPath: "", blobUrl: "" }, webp: { localPath: "", blobUrl: "" } }; // Create temporary directory for processed images const tempDir = await createTempDir(); // Process PNG version const optimizedBuffer = await sharp(imageBuffer) .resize(width, height) .png({ quality: 80, effort: 6 }) .toBuffer(); const smallFileName = `${newName}_small.png`; const smallFilePath = path.join(tempDir, smallFileName); await fs.writeFile(smallFilePath, optimizedBuffer); results.png.localPath = smallFilePath; // Check if PNG already exists in Vercel Blob storage let pngUrl = ""; try { const existingUrl = await list({ prefix: smallFileName }); if (existingUrl.blobs.length > 0) { pngUrl = existingUrl.blobs[0].url; } else { // Upload if not found const { url } = await put(smallFileName, optimizedBuffer, { access: "public", contentType: "image/png" }); pngUrl = url; } } catch (error) { console.error(`Failed to check/upload PNG blob: ${error}`); throw new McpError( ErrorCode.InternalError, `Failed to upload PNG to Vercel Blob: ${error}` ); } results.png.blobUrl = pngUrl; // Process WebP version const optimizedBufferWebp = await sharp(imageBuffer) .webp({ quality: 80, effort: 6 }) .toBuffer(); const webpFileName = `${newName}.webp`; const webpFilePath = path.join(tempDir, webpFileName); await fs.writeFile(webpFilePath, optimizedBufferWebp); results.webp.localPath = webpFilePath; // Check if WebP already exists in Vercel Blob storage let webpUrl = ""; try { const existingUrlWebp = await list({ prefix: webpFileName }); if (existingUrlWebp.blobs.length > 0) { webpUrl = existingUrlWebp.blobs[0].url; } else { // Upload if not found const { url } = await put(webpFileName, optimizedBufferWebp, { access: "public", contentType: "image/webp" }); webpUrl = url; } } catch (error) { console.error(`Failed to check/upload WebP blob: ${error}`); throw new McpError( ErrorCode.InternalError, `Failed to upload WebP to Vercel Blob: ${error}` ); } results.webp.blobUrl = webpUrl; return { success: true, message: `Successfully processed and uploaded image: ${newName}`, results: { png: { fileName: smallFileName, localPath: results.png.localPath, blobUrl: results.png.blobUrl }, webp: { fileName: webpFileName, localPath: results.webp.localPath, blobUrl: results.webp.blobUrl } } }; }
- src/index.ts:152-162 (helper)Helper function to download an image from a given URL using axios and return it as a Buffer.async function downloadImage(url: string): Promise<Buffer> { try { const response = await axios.get(url, { responseType: 'arraybuffer' }); return Buffer.from(response.data, 'binary'); } catch (error) { console.error(`Failed to download image from URL: ${url}`, error); throw new Error(`Failed to download image from URL: ${url}`); } }
- src/index.ts:88-145 (registration)Registration of available tools via ListToolsRequestSchema handler, including this tool in the tools array.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "process_and_upload_image", description: "Process a local image file (optimize, resize, convert to WebP) and upload to Vercel Blob", inputSchema: { type: "object", properties: { imagePath: { type: "string", description: "Path to the image file to process" }, newName: { type: "string", description: "New name for the processed image (without extension)" }, width: { type: "number", description: "Width to resize the image to (default: 550)" }, height: { type: "number", description: "Height to resize the image to (default: 300)" } }, required: ["imagePath", "newName"] } }, { name: "process_and_upload_image_from_url", description: "Process an image from a URL (optimize, resize, convert to WebP) and upload to Vercel Blob", inputSchema: { type: "object", properties: { imageUrl: { type: "string", description: "URL of the image to process" }, newName: { type: "string", description: "New name for the processed image (without extension)" }, width: { type: "number", description: "Width to resize the image to (default: 550)" }, height: { type: "number", description: "Height to resize the image to (default: 300)" } }, required: ["imageUrl", "newName"] } } ] }; });