Image Processor Mcp について
Image Processor MCP は、AI アシスタント向けの画像処理サーバーです。画像のダウンロード、圧縮、ディレクトリ一括処理、ファイル名の同期、ローカル OCR に対応します。
主な機能
- 01URL または Pexels 検索で画像を取得
- 02画像の圧縮と形式変換
- 03レポート付きのディレクトリ一括処理
- 04ファイル名の正規化と参照の同期
- 05ローカル OCR によるテキスト抽出
活用シーン
- 01プロジェクト用画像の取得と最適化
- 02単一画像の変換とサイズ変更
- 03フォルダー構造を保った画像圧縮
- 04画像内テキストのローカル抽出
MCP 対応
MCP クライアントに、画像の取得、圧縮、一括処理、ファイル名同期、OCR のツールを公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
6掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | いいえ | ダウンロードする画像の URL(query を指定しない場合は必須) |
| query | string | いいえ | 画像の検索キーワード(url を指定しない場合は必須) |
| outputPath | string | いいえ | ダウンロードした画像の保存先パス |
| outputFormat | string | いいえ | 出力形式:webp、avif、jpeg、png、tiff、gif(デフォルト:元の形式を維持) |
| quality | number | いいえ | 圧縮品質 1-100(デフォルト:85) |
| lossless | boolean | いいえ | 可逆圧縮を使用します(デフォルト:false) |
| effort | number | いいえ | CPU 負荷 0-6。6 は最も遅いものの、圧縮率が最も高くなります(デフォルト:6) |
| width | number | いいえ | 目標幅の正確な値(width のみ指定した場合はアスペクト比を維持します) |
| height | number | いいえ | 正確な目標高さ(高さのみを指定した場合はアスペクト比を維持) |
| maxDimension | number | いいえ | 幅または高さがこのしきい値を超えた場合に自動リサイズします(デフォルト:2000) |
| recursiveCompress | boolean | いいえ | ファイルが目標サイズを下回るまで再圧縮します(デフォルト:false) |
| expectedSizeKB | number | いいえ | 再圧縮時の目標ファイルサイズ(KB)(デフォルト:100) |
| qualityStepDown | number | いいえ | 再圧縮の反復ごとの品質低下量(デフォルト:10) |
| minimumQualityFloor | number | いいえ | 再圧縮中に許可される最低品質(デフォルト:10) |
詳細
Image Processor MCP — 完全版ドキュメント
バージョン: 0.2.3
パッケージ: image-processor-mcp
作成者: Dhvanil Pansuriya
目次
- 概要
- インストールと設定
- ツール:download_image
- ツール:compress_image
- ツール:compress_directory
- ツール:sync_filenames
- ツール:extract_text
- ツール:get_acknowledgement
- 設定の既定値
- 対応フォーマット
- クレジットとライセンス
概要
画像のダウンロード、圧縮、バッチ処理、ファイル名の同期、OCR によるテキスト抽出、設定の確認を行う6つのツールを提供する MCP(Model Context Protocol)サーバーです。
クイックスタート
npx -y image-processor-mcp
主な機能
- URL から画像をダウンロード、またはキーワードで検索(Pexels 連携)
- 10種類の出力フォーマットで画像を個別に圧縮・変換
- 目標ファイルサイズに合わせた再帰的な圧縮
- 品質と CPU 処理量を設定できる可逆・非可逆圧縮
- サイズの大きすぎる画像を自動リサイズ
- フォルダー構造を保ちながらディレクトリー全体を一括処理
- ファイル名とディレクトリー名を正規化
- 圧縮レポートを Markdown 形式で自動生成
- レポートと合わせてファイル名の対応表を自動生成
- プロジェクトファイルをスキャンし、古いファイル名を新しいファイル名に置換
- OCR によるテキスト抽出(100以上の言語に対応し、100%ローカルで実行)
インストールと設定
npm からインストール
npm install image-processor-mcp
要件
- Node.js 18 以上
MCP の設定
Claude Desktop
{
"mcpServers": {
"image-processor-mcp": {
"command": "npx",
"args": ["-y", "image-processor-mcp"],
"env": {
"IMAGE_SEARCH_API_KEY": "your_pexels_api_key_here"
}
}
}
}
VS Code(Cline / MCP 拡張機能)
{
"mcpServers": {
"image-processor-mcp": {
"command": "npx",
"args": ["-y", "image-processor-mcp"],
"env": {
"IMAGE_SEARCH_API_KEY": "your_pexels_api_key_here"
}
}
}
}
IMAGE_SEARCH_API_KEYは任意です。download_imageでキーワード検索を行う場合にのみ必要です。無料のキーは https://www.pexels.com/api/key/ で取得できます。
1. download_image
URL から画像をダウンロードするか、キーワードで検索します。画像の圧縮や変換も任意で行えます。
モード
| モード | パラメーター | 説明 |
|---|---|---|
| URL モード | url | 画像 URL から直接ダウンロード |
| 検索モード | query | Pexels でキーワード検索 |
両方が指定された場合は、検索モードが優先されます。
パラメーター
| パラメーター | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
url | string | いいえ* | — | 画像の直接 URL |
query | string | いいえ* | — | 検索キーワード |
outputPath | string | はい | — | 保存先パス |
outputFormat | string | いいえ | original | webp、avif、jpeg、png、tiff、gif |
quality | number | いいえ | 85 | 1~100 |
lossless | boolean | いいえ | false | 可逆圧縮モード |
effort | number | いいえ | 6 | CPU 処理量 0~6 |
width | number | いいえ | — | 目標幅 |
height | number | いいえ | — | 目標高さ |
maxDimension | number | いいえ | 2000 | 自動リサイズのしきい値 |
recursiveCompress | boolean | いいえ | false | サイズ目標に向けて反復処理 |
expectedSizeKB | number | いいえ | 100 | 目標サイズ(KB) |
qualityStepDown | number | いいえ | 10 | 反復ごとの品質低下幅 |
minimumQualityFloor | number | いいえ | 10 | 品質の最小値 |
* url または query のいずれかが必須です。
データフロー
Request → type guard → Controller
├─ Search mode? → Pexels API → first hit URL
└─ URL mode? → use directly
↓
axios.get(url, arraybuffer, 30s timeout)
↓
Write to temp file → check compression params
├─ YES → ImageService.compressImage → clean temp → return result
└─ NO → move to final path → return success
レスポンス例(検索+圧縮)
{
"query": "mountain sunset",
"imageId": 12345,
"width": 1920,
"height": 1080,
"imageSize": 0,
"user": "John Doe",
"tags": "mountain sunset",
"inputPath": "...",
"outputPath": "./images/mountain.webp",
"originalSize": 500000,
"compressedSize": 80000,
"compressionRatio": 84.00,
"success": true,
"iterations": 1,
"qualitySteps": [85],
"finalQuality": 85,
"exceededTarget": false
}
エッジケース
- url または query がない:エラー — いずれかを指定する必要があります
- 検索結果が空:エラー — 画像が見つかりません
- API キーがない:エラー —
IMAGE_SEARCH_API_KEYが設定されていません - ダウンロードのタイムアウト(30秒):エラー — タイムアウトしました
- 圧縮に失敗:一時ファイルを削除し、エラーを返します
2. compress_image
品質、寸法、フォーマット、再帰的な圧縮を細かく制御しながら、画像を1枚圧縮または変換します。
パラメーター
| パラメーター | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
inputPath | string | はい | — | ソース画像のパス |
outputPath | string | はい | — | 出力先のパス |
outputFormat | string | いいえ | webp | 出力形式 |
quality | number | いいえ | 85 | 1~100 |
lossless | boolean | いいえ | false | ロスレスモード |
effort | number | いいえ | 6 | CPU 処理負荷 0~6 |
width | number | いいえ | — | 目標の幅 |
height | number | いいえ | — | 目標の高さ |
maxDimension | number | いいえ | 2000 | 自動リサイズのしきい値 |
recursiveCompress | boolean | いいえ | false | 反復的な目標設定 |
expectedSizeKB | number | いいえ | 100 | 目標サイズ(KB) |
qualityStepDown | number | いいえ | 10 | 反復ごとの品質低下量 |
minimumQualityFloor | number | いいえ | 10 | 品質の下限 |
圧縮アルゴリズムの中核
1. Read original size + image metadata (sharp)
2. Compute resize:
- Explicit w/h? → use those
- Exceeds maxDimension? → scale proportionally
- Otherwise → no resize
3. Loop:
- sharp pipeline → apply format with quality
- If input === output → buffer (safe in-place)
- Else → write to file
- If recursive + over target + above floor → reduce quality, loop
- Else → break
4. Return CompressionResult
形式変換
| 形式 | Sharp オプション |
|---|---|
webp | {quality, lossless, effort, smartSubsample, alphaQuality:90} |
avif | {quality, lossless, effort} |
jpeg | {quality, mozjpeg:true} |
png | {compressionLevel:9} |
tiff | {quality, compression:'lzw'} |
gif | gif()(オプションなし) |
| other | WebP にフォールバックします |
レスポンス例
{
"inputPath": "./input/photo.jpg",
"outputPath": "./output/photo.webp",
"originalSize": 500000,
"compressedSize": 80000,
"compressionRatio": 84.00,
"success": true,
"iterations": 1,
"qualitySteps": [85],
"finalQuality": 85,
"exceededTarget": false
}
エッジケース
- インプレース圧縮(同じパス):破損を防ぐため、バッファーベースで処理します
- 入力ファイルが見つからない場合:エラーを伴う
success: false - 不明な形式:WebP にフォールバックします
- 再帰処理の下限:品質をこれ以上下げられない場合に停止します
- 中断:
success: falseと部分的な結果を返します
3. compress_directory
ディレクトリ内のすべての画像を再帰的に一括圧縮し、フォルダー構造を維持します。レポートとマッピングを生成します。
パラメーター
| パラメーター | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
inputDir | string | はい | — | ソースディレクトリ |
outputDir | string | はい | — | 出力ディレクトリ |
outputFormat | string | いいえ | webp | 出力形式 |
quality | number | いいえ | 85 | 1~100 |
lossless | boolean | いいえ | false | ロスレスモード |
effort | number | いいえ | 6 | CPU 処理負荷 0~6 |
maxDimension | number | いいえ | 2000 | 自動リサイズのしきい値 |
normalizeFilename | boolean | いいえ | false | ファイル名を整える |
filenameReplaceChars | string | いいえ | , -, ., & | 置換する文字 |
filenameCase | string | いいえ | lowercase | 大文字・小文字の変換 |
normalizeDirname | boolean | いいえ | false | ディレクトリ名を整える |
dirnameReplaceChars | string | いいえ | , -, ., & | ディレクトリ名で置換する文字 |
dirnameCase | string | いいえ | lowercase | ディレクトリ名の大文字・小文字 |
recursiveCompress | boolean | いいえ | false | 反復的な目標設定 |
expectedSizeKB | number | いいえ | 100 | 目標サイズ(KB) |
qualityStepDown | number | いいえ | 5 (schema) / 10 (code) | 反復ごとの品質低下量 |
minimumQualityFloor | number | いいえ | 10 | 品質の下限 |
データフロー
Request → type guard → Controller
├─ Validate input directory exists
├─ Apply defaults, build FileNamingOptions
├─ Scan all image files (recursive)
├─ Filter out SVG (restricted)
├─ For each file:
│ ├─ Compute output path (preserves structure, normalizes, changes ext)
│ └─ Run ImageService.compressImage
├─ Generate report (.image-processor-mcp/reports/)
└─ Generate mappings JSON (.image-processor-mcp/mappings/)
出力パスのアルゴリズム
relativePath = inputDir → inputFile difference
1. Dir naming enabled → normalize each directory component
2. File naming enabled → normalize basename
3. Replace extension with .{outputFormat}
4. Prepend outputDir
normalizeName
Replace each char → '_', collapse multiple '_', trim edges, apply case
生成されるファイル
.image-processor-mcp/
├── reports/scan-report-{timestamp}.md
└── mappings/mappings-{timestamp}.json
レスポンス例
{
"success": true,
"totalFiles": 10,
"successful": 9,
"failed": 1,
"totalOriginalSize": 5000000,
"totalCompressedSize": 1200000,
"overallReduction": 76.00,
"durationMs": 5432,
"reportPath": ".image-processor-mcp/reports/scan-report-2026-05-29-15-30-00.md",
"mappingsPath": ".image-processor-mcp/mappings/mappings-2026-05-29-15-30-00.json"
}
エッジケース
- 入力ディレクトリが見つからない場合:早期にエラーとなり、ファイルは書き込まれません
- SVG ファイル:通知なく除外されます
- バッチ処理中の中断:処理済みの部分的な結果を返します
- すべてのファイルの処理に失敗した場合:マッピングファイルは生成されません
- 画像が見つからない場合:空のレポートを返します
4. sync_filenames
プロジェクトファイルをスキャンし、圧縮後に古いファイル名への参照をすべて新しいファイル名に置き換えます。
パラメーター
| パラメーター | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
scanDir | string | はい | — | スキャンするディレクトリ |
mappingFilePath | string | いいえ | — | マッピング JSON ファイルへのパス |
mappings | array | いいえ | — | インラインの {oldFileName, newFileName}[] |
includeExtensions | array | いいえ | html,js,ts,css,md,json... | スキャンする拡張子 |
excludeDirectories | array | いいえ | node_modules,.git,build,dist... | スキップするディレクトリ |
dryRun | boolean | いいえ | true | プレビューのみ |
検証
mappingFilePath を使用する場合:
- ファイルが存在し、有効な JSON であること
- Mappings 配列が存在し、空でないこと
- 各エントリに
oldFileNameとnewFileName(文字列)が含まれていること - ファイル名
mappings-(.+).jsonからタイムスタンプを抽出すること - 対応するレポートが存在すること:
reports/scan-report-{timestamp}.md
対応するレポートがない場合 → 操作は拒否されます(古いマッピングの使用を防ぎます)。
データフロー
Request → type guard → Controller
├─ mappingFilePath?
│ YES → ReferenceService.readMappingFile → validate against report
│ NO → use inline mappings
├─ dryRun = args.dryRun !== false
├─ ReferenceService.scanReferences:
│ ├─ Collect files recursively (filtered by extension, excluding dirs)
│ ├─ For each file:
│ │ ├─ For each mapping:
│ │ │ ├─ Regex-escape oldFileName, count occurrences
│ │ │ ├─ Build line-by-line details
│ │ │ ├─ Build preview (3 lines context)
│ │ │ └─ If !dryRun: replace in content
│ │ └─ If modified: write file
│ └─ Return UpdateRefResult
└─ ReportService.generateSyncReport → .image-processor-mcp/syncs/
生成されるファイル
.image-processor-mcp/syncs/sync-report-{timestamp}.md (live)
.image-processor-mcp/syncs/dry-run/sync-report-{timestamp}.md (dry-run)
応答例
Dry run — no files were modified.
Mapping source: .image-processor-mcp/mappings/mappings-2026-05-29-15-30-00.json
Files scanned: 42
Files with matches: 3
Total replacements: 12
--- Matches ---
[src/components/Header.tsx]
"logo.png" → "logo.webp" (5x)
Preview: ... context lines ...
Line 15:23 "logo.png" → "logo.webp"
... and 3 more (see report)
Report saved to: .image-processor-mcp/syncs/dry-run/sync-report-2026-05-29-15-31-00.md
エッジケース
- マッピングファイルが見つからない:パスを含むエラー
- 無効な JSON:解析エラー
- 対応するレポートがない:詳細な拒否メッセージ
- どちらのソースも指定されていない:選択肢を説明するエラー
- 一致が見つからない:情報メッセージ
- 正規表現の特殊文字:適切にエスケープされます
- バイナリファイル:拡張子リストによって除外されます
5. extract_text
OCR(tesseract.js)を使用して、画像から印刷された可視テキストを抽出します。すべてローカルで実行されます。
パラメーター
| パラメーター | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
imagePath | string | はい | — | 画像ファイルへのパス |
language | string | いいえ | eng | 言語コード(複数指定する場合は + を使用) |
rectangle | object | いいえ | — | 領域 {top, left, width, height} |
outputFormat | enum | いいえ | text | text、blocks、hocr、tsv |
preprocess | boolean | いいえ | true | グレースケール化+自動回転 |
データフロー
Request → type guard → OcrController → OcrService.recognize
├─ Validate path (exists, not dir, not empty, not SVG)
├─ Validate rectangle (positive dimensions)
├─ Build sharp pipeline:
│ ├─ Convert unsupported formats to PNG
│ └─ Preprocess: grayscale + rotate
├─ runOcr:
│ ├─ Serialized via jobQueue (one at a time)
│ ├─ getWorker: reuse / reinitialize / create
│ ├─ worker.recognize()
│ └─ Recycle worker every 500 jobs
└─ Return ExtractTextResult
ワーカーのライフサイクル
| 状態 | アクション |
|---|---|
| ワーカーが存在し、言語が同じ | そのまま再利用 |
| ワーカーが存在し、言語が異なる | worker.reinitialize(language) |
| ワーカーがない | createWorker(language, 1, ...) |
| 500 ジョブ実行後 | setImmediate(recycleWorker) |
| ワーカーエラー | errorHandler が参照を null に設定 |
| SIGINT/トランスポート終了 | shutdown() → 終了 |
対応する入力形式
| ネイティブ対応 | PNG に自動変換 |
|---|---|
| bmp、jpg、jpeg、png | tiff、heic、heif、webp*、gif* |
| pbm、pgm、ppm | その他すべて |
* tesseract.js は webp と gif をネイティブにサポートしていますが、変換チェックの対象になります。コードは OCR_SUPPORTED_EXTENSIONS に含まれていない拡張子をすべて変換します。webp と gif はこのリストに含まれているため、変換されません。
制限事項
- 手書きテキスト:サポートされていません
- SVG ファイル:拒否されます(ベクター形式)
- 空の画像:空の文字列を返します(エラーではありません)
- 初回実行時:CDN から言語データ(約 2MB)をダウンロードします
応答例(text 形式)
{
"success": true,
"text": "Extracted text content",
"confidence": 92.5,
"words": 42,
"language": "eng",
"durationMs": 1234,
"preprocessed": true
}
エッジケース
- SVG:明示的に拒否
- 未対応の形式:PNG に自動変換
- ワーカーのクラッシュ:自動復旧(errorHandler が参照を null に設定)
- 中止:DOMException を捕捉 → キャンセルされた結果
- 空のファイル(0 バイト):明示的に拒否
- パスがディレクトリ:明示的に拒否
6. get_acknowledgement
すべてのツール、デフォルト、形式、環境変数に関する包括的なドキュメントを返します。
パラメーター
なし — 空の入力スキーマ。
応答
すべての設定定数から動的に生成される、完全な Markdown ドキュメントです。
| セクション | ソース |
|---|---|
| 6 つすべてのツール | ハードコードされた説明 |
| 設定のデフォルト値 | DEFAULTS + CONFIG_DESCRIPTIONS |
| サポートされる入力形式 | SUPPORTED_EXTENSIONS + INPUT_EXTENSION_DESCRIPTIONS |
| サポートされる出力形式 | SUPPORTED_OUTPUT_FORMATS + OUTPUT_FORMAT_DESCRIPTIONS |
| 同期スキャンのデフォルト値 | DEFAULT_EXTENSIONS + DEFAULT_EXCLUDE_DIRS |
| 制限付き拡張子 | RESTRICTED_EXTENSIONS |
| 環境変数 | ハードコード |
| クレジット | ハードコード |
実装
ToolController.handleGetAcknowledgement()
// Synchronous — no abort signal, no async
// Returns { content: [{ type: 'text', text: markdown }] }
エッジケース
ありません。常に成功し、パラメーターも I/O もありません。
設定のデフォルト値
| パラメーター | デフォルト値 | 説明 |
|---|---|---|
quality | 85 | 非可逆形式の圧縮品質(1~100) |
lossless | false | 可逆圧縮(WebP、PNG、GIF、AVIF) |
effort | 6 | CPU の処理負荷(0~6)。値が大きいほどファイルサイズが小さくなります |
maxDimension | 2000 | 自動リサイズのしきい値(ピクセル) |
expectedSizeKB | 100 | 再帰圧縮の目標ファイルサイズ |
qualityStepDown | 10 | 再帰処理の反復ごとの品質低下量 |
minimumQualityFloor | 10 | 再帰処理中の最低品質(1~100) |
outputFormat | webp | デフォルトの出力形式 |
filenameCase | lowercase | ファイル名の大文字・小文字の変換 |
dirnameCase | lowercase | ディレクトリ名の大文字・小文字の変換 |
filenameReplaceChars | [' ', '-', '.', '&'] | ファイル名で _ に置き換える文字 |
dirnameReplaceChars | [' ', '-', '.', '&'] | ディレクトリ名で _ に置き換える文字 |
サポートされる形式
入力形式(35 以上)
.jpg、.jpeg、.png、.gif、.bmp、.tiff、.tif、.webp、.avif、.svg、.heic、.heif、.ico、.cur、.jp2、.j2k、.jpf、.jpx、.jpm、.mj2、.jxr、.wdp、.hdp、.psd、.psb、.dds、.tga、.vda、.icb、.vst、.pbm、.pgm、.ppm、.pnm、.pfm、.exr、.hdr、.hrd、.pic、.pict、.pct、.xbm、.xpm、.wal、.cut、.ras、.sun、.sgi、.rgb、.rgba、.bw、.pcx、.pcd、.iff、.lbm
出力形式(10)
| 形式 | 説明 |
|---|---|
webp | Google WebP。非可逆・可逆のどちらにも優れています。透過に対応しています。 |
avif | AV1 ベース。JPEG より 30~50%小さくなります。エンコードは低速です。 |
jpeg | 幅広い互換性があります。透過には対応していません。 |
png | 透過対応の可逆形式です。グラフィックやロゴに最適です。 |
tiff | 高画質です。印刷・出版向けです。ファイルサイズは最大です。 |
gif | アニメーションと透過に対応しています。256 色です。 |
heif | HEVC ベース。Apple エコシステム向けです。 |
jp2 | JPEG 2000。ウェーブレットベース。医療・映画向けです。 |
jxl | JPEG XL。次世代形式です。JPEG を可逆で再エンコードできます。 |
pdf | 画像を PDF ページに変換します。 |
制限付き拡張子
.svg — SVG ファイルは一括圧縮時にスキップされます(ベクター形式のため、sharp で安全に圧縮すると描画が崩れる可能性があります)。
クレジットとライセンス
作成者
Dhvanil Pansuriya
| GitHub | https://github.com/pansuriyadhvanil/ |
| https://linkedin.com/in/dhvanil-pansuriya/ | |
| パッケージ | npm の image-processor-mcp |
技術クレジット
| 技術 | 役割 |
|---|---|
| Model Context Protocol SDK | MCP サーバーのフレームワーク |
| sharp | 高性能な画像処理 |
| tesseract.js | OCR によるテキスト抽出 — 100%ローカルで動作し、API キーは不要です |
| Pexels | 画像検索用の無料ストックフォト API |
| axios | HTTP クライアント |
| fs-extra | 拡張ファイルシステム |
ライセンス
MIT ライセンス — 詳細は LICENSE をご覧ください。
Image-Processor-MCP
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。