analyze_image
Extract detailed metadata from image files to understand format, dimensions, and technical specifications for analysis and processing.
Instructions
Get detailed metadata about an image
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the image file |
Implementation Reference
- src/index.ts:336-383 (handler)The main execution handler for the 'analyze_image' tool within the CallToolRequestSchema switch statement. It validates the image path, retrieves metadata and thumbnail, and returns structured JSON content or error.case "analyze_image": { const { path: imagePath } = request.params.arguments as { path: string }; if (!imagePath) { throw new McpError(ErrorCode.InvalidParams, "Image path is required"); } if (!fs.existsSync(imagePath)) { throw new McpError(ErrorCode.InvalidRequest, `Image not found: ${imagePath}`); } try { const metadata = await getImageMetadata(imagePath); const thumbnail = await generateThumbnail(imagePath); return { content: [ { type: "text", text: JSON.stringify({ filename: metadata.filename, format: metadata.format, dimensions: `${metadata.width}x${metadata.height}`, size: { bytes: metadata.size, kilobytes: (metadata.size / 1024).toFixed(2), megabytes: (metadata.size / (1024 * 1024)).toFixed(2) }, created: metadata.created.toISOString(), modified: metadata.modified.toISOString(), path: metadata.path, thumbnail }, null, 2) } ] }; } catch (error) { return { content: [ { type: "text", text: `Error analyzing image: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/index.ts:237-250 (schema)The input schema definition for the 'analyze_image' tool, registered in the ListToolsRequestSchema response. Defines the required 'path' parameter.{ name: "analyze_image", description: "Get detailed metadata about an image", inputSchema: { type: "object", properties: { path: { type: "string", description: "Path to the image file" } }, required: ["path"] } },
- src/index.ts:234-329 (registration)The ListToolsRequestSchema handler that registers and lists the 'analyze_image' tool among others.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "analyze_image", description: "Get detailed metadata about an image", inputSchema: { type: "object", properties: { path: { type: "string", description: "Path to the image file" } }, required: ["path"] } }, { name: "resize_image", description: "Resize an image and save to a new file", inputSchema: { type: "object", properties: { input: { type: "string", description: "Path to the input image file" }, output: { type: "string", description: "Path to save the resized image" }, width: { type: "number", description: "Target width in pixels" }, height: { type: "number", description: "Target height in pixels (optional)" }, fit: { type: "string", description: "Fit method: cover, contain, fill, inside, outside", enum: ["cover", "contain", "fill", "inside", "outside"] } }, required: ["input", "output", "width"] } }, { name: "convert_format", description: "Convert an image to a different format", inputSchema: { type: "object", properties: { input: { type: "string", description: "Path to the input image file" }, output: { type: "string", description: "Path to save the converted image" }, format: { type: "string", description: "Target format: jpeg, png, webp, avif, tiff, etc.", enum: ["jpeg", "png", "webp", "avif", "tiff", "gif"] }, quality: { type: "number", description: "Quality level (1-100, for formats that support it)" } }, required: ["input", "output", "format"] } }, { name: "scan_directory", description: "Scan a directory for images and return metadata", inputSchema: { type: "object", properties: { directory: { type: "string", description: "Directory path to scan for images" }, recursive: { type: "boolean", description: "Whether to scan subdirectories recursively" } }, required: ["directory"] } } ] }; });
- src/index.ts:70-103 (helper)Core helper function called by analyze_image handler to fetch and cache image metadata using sharp and fs.async function getImageMetadata(imagePath: string): Promise<ImageMetadata> { // Check cache first if (imageMetadataCache.has(imagePath)) { return imageMetadataCache.get(imagePath)!; } try { // Use fs.promises.stat instead of fsExtra.stat const stats = await fs.promises.stat(imagePath); const metadata = await sharp(imagePath).metadata(); const imageMetadata: ImageMetadata = { path: imagePath, filename: path.basename(imagePath), format: metadata.format || path.extname(imagePath).replace('.', ''), width: metadata.width, height: metadata.height, size: stats.size, created: stats.birthtime, modified: stats.mtime }; // Cache the metadata imageMetadataCache.set(imagePath, imageMetadata); return imageMetadata; } catch (error) { console.error(`Error getting metadata for ${imagePath}:`, error); throw new McpError( ErrorCode.InternalError, `Failed to process image: ${error instanceof Error ? error.message : String(error)}` ); } }
- src/index.ts:108-122 (helper)Helper function to generate a base64-encoded thumbnail of the image, used in analyze_image response.async function generateThumbnail(imagePath: string, maxWidth = 300): Promise<string> { try { const buffer = await sharp(imagePath) .resize({ width: maxWidth, withoutEnlargement: true }) .toBuffer(); return `data:image/${path.extname(imagePath).replace('.', '')};base64,${buffer.toString('base64')}`; } catch (error) { console.error(`Error generating thumbnail for ${imagePath}:`, error); throw new McpError( ErrorCode.InternalError, `Failed to generate thumbnail: ${error instanceof Error ? error.message : String(error)}` ); } }