picete-mcp
v1.0.0
Published
MCP Server for local image processing — inspired by picete.com
Maintainers
Readme
PicEte MCP Server
Free Online Image Tools — now available as an MCP server for AI assistants.
Inspired by picete.com — a suite of powerful image processing tools that run entirely on your machine via the Model Context Protocol (MCP).
Installation
Global install (recommended)
npm install -g picete-mcpRun directly with npx
npx picete-mcpAI Platform Configuration
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"picete-mcp": {
"command": "npx",
"args": ["picete-mcp"]
}
}
}Cursor
In Cursor, go to Settings > MCP Servers and add:
- Name:
picete-mcp - Type:
command - Command:
npx picete-mcp
Claude Code
Run inside your project directory:
claude mcp add picete-mcp -- npx picete-mcpOr add to ~/.claude/settings.json:
{
"mcpServers": {
"picete-mcp": {
"command": "npx",
"args": ["picete-mcp"]
}
}
}Tools Overview
PicEte MCP Server provides 13 tools for image processing. All tools accept source file paths (absolute or relative to the working directory) and write output files to the system temp directory by default.
1. convert
Convert an image to a different format.
Parameters
| Name | Type | Required | Default | Description |
|-----------|--------|----------|---------|--------------------------------------|
| source | string | yes | — | Path to the source image file |
| format | string | yes | — | Target format: jpeg, png, webp, gif |
| quality | number | no | 80 | Output quality (1–100, jpeg/webp only) |
Returns
{
"success": true,
"source": "/path/to/input.png",
"output": "/tmp/convert-xxx.jpg",
"format": "jpeg",
"quality": 80
}Example
Convert a PNG to JPEG with 90% quality:
{
"source": "./screenshot.png",
"format": "jpeg",
"quality": 90
}2. resize
Resize an image to specified dimensions.
Parameters
| Name | Type | Required | Default | Description |
|-------------------|---------|----------|---------|--------------------------------------|
| source | string | yes | — | Path to the source image file |
| width | number | no | — | Target width in pixels |
| height | number | no | — | Target height in pixels |
| fit | string | no | cover | Fit mode: cover, contain, fill, inside, outside |
| keep_aspect_ratio | boolean | no | true | Whether to maintain aspect ratio |
At least one of width or height must be provided.
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"output": "/tmp/resize-xxx.png",
"width": 800,
"height": null,
"fit": "cover",
"keep_aspect_ratio": true
}Example
Resize to 800px wide, maintaining aspect ratio:
{
"source": "./photo.jpg",
"width": 800
}3. compress
Compress an image by reducing quality, with optional max file size target.
Parameters
| Name | Type | Required | Default | Description |
|-----------------|--------|----------|---------|--------------------------------------|
| source | string | yes | — | Path to the source image file |
| quality | number | no | 80 | Output quality (1–100) |
| target_format | string | no | — | Target format: jpeg, png, webp, gif |
| max_size_bytes | number | no | — | Max file size in bytes; quality iteratively reduced to meet target |
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"output": "/tmp/compress-xxx.jpg",
"quality": 80,
"original_size_bytes": 245760,
"compressed_size_bytes": 58321,
"savings_percent": 76.27
}Example
Compress to under 50 KB:
{
"source": "./photo.jpg",
"quality": 80,
"max_size_bytes": 50000
}4. extract-colors
Extract dominant colors from an image using k-means clustering.
Parameters
| Name | Type | Required | Default | Description | |-------------|--------|----------|---------|------------------------------------| | source | string | yes | — | Path to the source image file | | color_count | number | no | 5 | Number of colors to extract (1–20) |
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"color_count": 5,
"colors": [
{
"hex": "#2a5c8a",
"rgb": { "r": 42, "g": 92, "b": 138 },
"hsl": { "h": 210, "s": 53, "l": 35 },
"percentage": 34.5
}
]
}Example
Extract 8 dominant colors:
{
"source": "./logo.png",
"color_count": 8
}5. image-to-base64
Convert an image to a base64-encoded data URL or raw base64 string.
Parameters
| Name | Type | Required | Default | Description |
|-----------|---------|----------|---------|--------------------------------------|
| source | string | yes | — | Path to the source image file |
| format | string | no | — | Optional target format for encoding |
| data_url | boolean | no | true | Return full data: URL vs raw base64 |
Returns
{
"success": true,
"source": "/path/to/image.png",
"data_url": "data:image/png;base64,iVBORw0KGgo...",
"base64_length": 45678,
"format": "original"
}Example
Get raw base64 string (no data URL prefix):
{
"source": "./icon.png",
"data_url": false
}6. split-image
Split an image into a grid of tiles.
Parameters
| Name | Type | Required | Default | Description | |------------|--------|----------|---------|--------------------------------------| | source | string | yes | — | Path to the source image file | | rows | number | yes | — | Number of rows to split into | | cols | number | yes | — | Number of columns to split into | | overlap_px | number | no | 0 | Overlap between tiles in pixels |
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"rows": 2,
"cols": 3,
"overlap_px": 0,
"original_width": 1200,
"original_height": 800,
"tile_width": 400,
"tile_height": 400,
"tiles": [
{ "row": 1, "col": 1, "path": "/tmp/tile-r1c1-xxx.png", "x": 0, "y": 0, "width": 400, "height": 400 }
]
}Example
Split a large image into 4 tiles (2x2) with 10px overlap:
{
"source": "./map.png",
"rows": 2,
"cols": 2,
"overlap_px": 10
}7. metadata
Read detailed metadata from an image file.
Parameters
| Name | Type | Required | Default | Description | |--------|--------|----------|---------|--------------------------------| | source | string | yes | — | Path to the source image file |
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"width": 1920,
"height": 1080,
"format": "jpeg",
"file_size_bytes": 245760,
"has_alpha": false,
"color_space": "srgb",
"channels": 3,
"depth": "uchar",
"density": 72,
"chroma_subsampling": "4:2:0",
"is_animated": false,
"page_count": 1,
"background": null,
"icc_embedded": true,
"exif_present": true,
"exif_size_bytes": 4028,
"iptc_present": false,
"xmp_present": false
}Example
{
"source": "./photo.jpg"
}8. batch
Apply a sequence of operations (resize, convert, compress) to multiple images.
Parameters
| Name | Type | Required | Default | Description | |------------|----------|----------|---------|--------------------------------------| | sources | string[] | yes | — | Array of paths to source images | | operations | object[] | yes | — | Array of operations to apply | | output_dir | string | no | — | Optional output directory |
Each operation object:
| Field | Type | Required | Description |
|-----------|--------|----------|------------------------------------|
| type | string | yes | resize, convert, or compress |
| width | number | no | Width (for resize) |
| height | number | no | Height (for resize) |
| fit | string | no | Fit mode (for resize) |
| format | string | no | Target format (for convert) |
| quality | number | no | Quality (for convert/compress) |
Returns
{
"success": true,
"results": [
{
"source": "/path/to/image1.jpg",
"steps": [
{ "step": 1, "operation": "resize", "output": "/tmp/batch-step-1-resize-xxx.png" },
{ "step": 2, "operation": "convert", "output": "/tmp/batch-step-2-convert-xxx.jpg" }
],
"final": "/tmp/batch-step-2-convert-xxx.jpg"
}
]
}Example
Resize then convert to JPEG for two images:
{
"sources": ["./photo1.jpg", "./photo2.jpg"],
"operations": [
{ "type": "resize", "width": 800 },
{ "type": "convert", "format": "jpeg", "quality": 85 }
]
}9. optimize-for-web
Optimize an image for web delivery — resize, convert to optimal format, and compress in one step.
Parameters
| Name | Type | Required | Default | Description |
|---------------|--------|----------|---------|--------------------------------------|
| source | string | yes | — | Path to the source image file |
| max_width | number | no | 1920 | Max width in pixels (no enlargement) |
| quality | number | no | 80 | Output quality (1–100) |
| output_format | string | no | webp | Target format: jpeg, png, webp, gif |
Returns
{
"success": true,
"source": "/path/to/image.png",
"output": "/tmp/optimized-for-web-xxx.webp",
"before": {
"width": 4000,
"height": 2250,
"format": "png",
"size_bytes": 2457600
},
"after": {
"width": 1920,
"height": 1080,
"format": "webp",
"size_bytes": 123456
},
"savings_percent": 94.97,
"operations_applied": [
{ "type": "resize", "max_width": 1920, "fit": "inside", "without_enlargement": true },
{ "type": "convert", "target_format": "webp" },
{ "type": "compress", "quality": 80 }
]
}Example
{
"source": "./original.png",
"max_width": 1200,
"quality": 85,
"output_format": "webp"
}10. prepare-for-vision-api
Prepare an image for AI Vision APIs — resize for optimal token consumption, re-encode, and estimate costs.
Parameters
| Name | Type | Required | Default | Description | |------------------|--------|----------|---------|--------------------------------------| | source | string | yes | — | Path to the source image file | | max_longest_side | number | no | 2048 | Max length of the longest side | | quality | number | no | 85 | Output quality (1–100) | | target_format | string | no | auto | Target format (auto-selected) |
Returns
{
"success": true,
"source": "/path/to/image.jpg",
"output": "/tmp/vision-ready-xxx.webp",
"before": {
"width": 4000,
"height": 3000,
"format": "jpeg",
"size_bytes": 2457600
},
"after": {
"width": 2048,
"height": 1536,
"format": "webp",
"size_bytes": 345678
},
"token_estimate": 800,
"token_estimate_formula": "ceil(2048/512) * ceil(1536/512) * 100 = 800",
"max_longest_side": 2048,
"suggestions": [
"Suitable for most vision models (e.g., GPT-4o, Claude 3.5 Sonnet, Gemini Pro Vision).",
"Token estimate is a simplified calculation: ceil(w/512) * ceil(h/512) * 100. Actual usage varies by API provider."
]
}Example
Optimize for vision API with 1024px limit:
{
"source": "./highres.jpg",
"max_longest_side": 1024,
"quality": 90
}11. favicon
Generate a complete set of favicon files from a source image.
Parameters
| Name | Type | Required | Default | Description | |------------|--------|----------|------------------------------|--------------------------------------| | source | string | yes | — | Source image (minimum 180×180) | | output_dir | string | no | System temp directory | Output directory for generated files |
Returns
{
"success": true,
"source": "/path/to/source.png",
"output_dir": "/tmp",
"files": {
"favicon-16x16.png": "/tmp/favicon-16x16.png",
"favicon-32x32.png": "/tmp/favicon-32x32.png",
"apple-touch-icon.png": "/tmp/apple-touch-icon.png",
"favicon.ico": "/tmp/favicon.ico"
},
"sizes": {
"favicon-16x16.png": 285,
"favicon-32x32.png": 1023,
"apple-touch-icon.png": 8456,
"favicon.ico": 4286
}
}Example
{
"source": "./logo.png",
"output_dir": "./my-site/public"
}12. compare-images
Compare two images using MSE, SSIM, or pixel-diff.
Parameters
| Name | Type | Required | Default | Description |
|---------|--------|----------|---------|--------------------------------------|
| source1 | string | yes | — | Path to the first image |
| source2 | string | yes | — | Path to the second image |
| metric | string | no | mse | Comparison metric: mse, ssim, diff |
Returns
For mse:
{
"success": true,
"source1": "/path/to/img1.jpg",
"source2": "/path/to/img2.jpg",
"metric": "mse",
"dimensions": { "width": 1920, "height": 1080, "pixels": 2073600 },
"mse": 124.5,
"percent": 0.05
}For ssim:
{
"success": true,
"source1": "/path/to/img1.jpg",
"source2": "/path/to/img2.jpg",
"metric": "ssim",
"dimensions": { "width": 1920, "height": 1080, "pixels": 2073600 },
"ssim": 0.9587
}For diff:
{
"success": true,
"source1": "/path/to/img1.jpg",
"source2": "/path/to/img2.jpg",
"metric": "diff",
"dimensions": { "width": 1920, "height": 1080, "pixels": 2073600 },
"diff_pixels": 15000,
"diff_percent": 0.72,
"diff_image": "/tmp/diff-highlight-xxx.png"
}Example
Compare two images with SSIM:
{
"source1": "./original.png",
"source2": "./compressed.png",
"metric": "ssim"
}13. collage
Create a collage from multiple images — horizontal, vertical, or grid layout.
Parameters
| Name | Type | Required | Default | Description |
|-----------|----------|----------|--------------|------------------------------------|
| sources | string[] | yes | — | Array of paths to source images |
| direction | string | no | horizontal | Layout: horizontal, vertical, grid |
| gap | number | no | 0 | Gap between images in pixels |
| columns | number | no | — | Column count (required for grid) |
Returns
{
"success": true,
"sources": ["/path/to/img1.jpg", "/path/to/img2.jpg"],
"output": "/tmp/collage-xxx.png",
"direction": "horizontal",
"gap": 10,
"source_count": 2,
"size_bytes": 123456
}Example
Create a 3-column grid collage with 5px gaps:
{
"sources": ["./img1.jpg", "./img2.jpg", "./img3.jpg", "./img4.jpg"],
"direction": "grid",
"columns": 3,
"gap": 5
}Usage
Build
npm run buildCompiles TypeScript from src/ to JavaScript in dist/.
Start
npm startStarts the MCP server using the compiled output at dist/index.js.
Development
# Clone and install dependencies
git clone <repo-url>
cd picete-mcp
npm install
# Build continuously on changes
npx tsc --watch
# In another terminal, test with a local MCP client
# or pipe JSON-RPC messages directly:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.jsLicense
ISC
Powered by PicEte — Free Online Image Tools.
