MCP Servers

模型上下文协议服务器、框架、SDK 和模板的综合目录。

I
Image Downloader MCP

Image Search and Download (DuckDuckGo) MCP for Claude Desktop

创建于 6/8/2026
更新于 about 4 hours ago
Repository documentation and setup instructions

image-downloader-mcp

A local stdio-based MCP server for Claude Desktop that can search for images and download selected images without Chrome automation or paid API keys.

This project was built for video editing workflows, especially YouTube Shorts, TikTok, Instagram Reels, documentaries, sports edits, story videos, and any project where you need timestamped images or B-roll assets.

The main use case is simple:

  1. Write or generate a video script with timestamps.
  2. Ask Claude Desktop to use this MCP server.
  3. Claude searches for relevant images.
  4. Claude downloads images into your local folder.
  5. Each downloaded image is renamed according to the timestamp and scene description.
  6. You drag the files directly into your video editor.

Example script:

0:00 - Lionel Messi walks onto the field
0:05 - Argentina fans celebrate in the stadium
0:10 - Close-up of a football boot kicking the ball
0:15 - Trophy celebration scene

Expected downloaded files:

00-00_lionel-messi-walks-onto-field.jpg
00-05_argentina-fans-celebrate-stadium.jpg
00-10_football-boot-kicking-ball.jpg
00-15_trophy-celebration-scene.jpg

Why this project exists

Claude Desktop can use MCP servers to call local tools, but many existing image search MCP options rely on browser automation, Chrome, paid API keys, or services that are not ideal for local creative workflows.

This project focuses on a practical local setup:

  • No Chrome automation
  • No paid API key
  • Works through Claude Desktop local MCP
  • Uses Node.js and TypeScript
  • Exposes proper MCP tools over stdio
  • Saves files locally
  • Supports timestamp-based video editing workflows
  • Handles safe filenames and duplicate filenames
  • Validates downloaded files before saving them

Features

  • Local MCP server for Claude Desktop
  • Stdio transport
  • Node.js and TypeScript
  • Official MCP TypeScript SDK
  • Zod input validation
  • No paid API key required
  • Image search using a public DuckDuckGo image search method
  • Single image download tool
  • Batch image download tool
  • Timeline-based image search and download tool
  • Custom filename support
  • Timestamp-based filename generation
  • Safe filename sanitization
  • Duplicate filename handling with _2, _3, etc.
  • Preserves correct file extension based on detected image type
  • Content-Type validation
  • File signature validation
  • Maximum file size protection
  • Request timeout protection
  • Windows-friendly paths
  • Cross-platform-friendly code where possible
  • Logs to stderr only so stdout does not interfere with MCP protocol messages

MCP tools included

This server exposes five tools:

  1. search_images
  2. download_image
  3. download_images
  4. download_images_for_timeline
  5. get_download_folder

Tool: search_images

Searches for image results.

Input

{
  "query": "Argentina fans celebrating in stadium photo",
  "maxResults": 10,
  "safeSearch": "moderate"
}

Fields

| Field | Type | Required | Description | | ------------ | ------ | -------: | ----------------------------------------- | | query | string | Yes | Image search query | | maxResults | number | No | Number of results to return, from 1 to 50 | | safeSearch | string | No | strict, moderate, or off |

Output

Returns image results with fields such as:

{
  "query": "Argentina fans celebrating in stadium photo",
  "provider": "duckduckgo",
  "count": 10,
  "results": [
    {
      "title": "Example title",
      "imageUrl": "https://example.com/image.jpg",
      "thumbnailUrl": "https://example.com/thumb.jpg",
      "sourceUrl": "https://example.com/article",
      "sourceDomain": "example.com",
      "width": 1200,
      "height": 800
    }
  ]
}

Tool: download_image

Downloads one image URL into the configured download folder.

Input

{
  "imageUrl": "https://example.com/image.jpg",
  "fileName": "00-05_argentina-fans-celebrate-stadium",
  "sourceUrl": "https://example.com/source-page"
}

Fields

| Field | Type | Required | Description | | ----------- | ------ | -------: | --------------------------------------------- | | imageUrl | string | Yes | Direct image URL | | fileName | string | No | Custom filename without needing the extension | | sourceUrl | string | No | Source page URL for attribution/reference |

Output

{
  "success": true,
  "imageUrl": "https://example.com/image.jpg",
  "sourceUrl": "https://example.com/source-page",
  "filePath": "C:\\<PATH>\\MCP\\ImageDownloads\\00-05_argentina-fans-celebrate-stadium.jpg",
  "fileName": "00-05_argentina-fans-celebrate-stadium.jpg",
  "contentType": "image/jpeg",
  "bytes": 245120
}

Tool: download_images

Downloads multiple images.

Input

{
  "images": [
    {
      "imageUrl": "https://example.com/image-one.jpg",
      "fileName": "scene-one",
      "sourceUrl": "https://example.com/source-one"
    },
    {
      "imageUrl": "https://example.com/image-two.png",
      "fileName": "scene-two",
      "sourceUrl": "https://example.com/source-two"
    }
  ]
}

Output

{
  "downloaded": 2,
  "failed": 0,
  "results": [
    {
      "success": true,
      "imageUrl": "https://example.com/image-one.jpg",
      "sourceUrl": "https://example.com/source-one",
      "filePath": "C:\\<PATH>\\MCP\\ImageDownloads\\scene-one.jpg",
      "fileName": "scene-one.jpg",
      "contentType": "image/jpeg",
      "bytes": 245120
    }
  ]
}

Tool: download_images_for_timeline

This is the main YouTube workflow tool.

Given a list of timestamped scenes, the tool searches for relevant images and downloads the requested number of images for each timestamp.

Input

{
  "items": [
    {
      "timestamp": "0:00",
      "scene": "Lionel Messi walks onto the field",
      "searchQuery": "Lionel Messi walking onto football field photo",
      "count": 1
    },
    {
      "timestamp": "0:05",
      "scene": "Argentina fans celebrate in the stadium",
      "searchQuery": "Argentina football fans celebrating stadium photo",
      "count": 1
    }
  ],
  "safeSearch": "moderate"
}

Fields

| Field | Type | Required | Description | | ------------- | ------ | -------: | ---------------------------------------------------------- | | items | array | Yes | Timeline items | | timestamp | string | Yes | Timestamp such as 0:05, 00:05, or 01:02:15 | | scene | string | Yes | Scene description used for filename generation | | searchQuery | string | No | Specific image search query. If omitted, the scene is used | | count | number | No | Number of images to download for that timestamp | | safeSearch | string | No | strict, moderate, or off |

Output

{
  "downloaded": 2,
  "failed": 0,
  "results": [
    {
      "success": true,
      "timestamp": "0:00",
      "scene": "Lionel Messi walks onto the field",
      "imageUrl": "https://example.com/image.jpg",
      "sourceUrl": "https://example.com/source-page",
      "filePath": "C:\\<PATH>\\MCP\\ImageDownloads\\00-00_lionel-messi-walks-onto-field.jpg",
      "fileName": "00-00_lionel-messi-walks-onto-field.jpg",
      "contentType": "image/jpeg",
      "bytes": 245120
    }
  ]
}

Tool: get_download_folder

Returns the active download folder and basic runtime limits.

Input

{}

Output

{
  "downloadFolder": "C:\\<PATH>\\MCP\\ImageDownloads",
  "exists": true,
  "maxFileSizeBytes": 10485760,
  "timeoutMs": 15000
}

Filename behavior

The project generates clean, sortable filenames for video editing.

Timestamp conversion

0:05      -> 00-05
00:05     -> 00-05
1:23      -> 01-23
01:02:15  -> 01-02-15

Scene conversion

Lionel Messi walks onto the field

becomes:

lionel-messi-walks-onto-field

Final filename

00-00_lionel-messi-walks-onto-field.jpg

Duplicate handling

If a file already exists:

00-05_argentina-fans-celebrate-stadium.jpg

the next file becomes:

00-05_argentina-fans-celebrate-stadium_2.jpg

then:

00-05_argentina-fans-celebrate-stadium_3.jpg

Image validation

Before saving a file, the server checks:

  • The URL uses http or https
  • The server response is successful
  • The response content type looks like an image or a safe binary response
  • The downloaded file signature is a supported image type
  • The file does not exceed the configured max size
  • The request does not exceed the configured timeout

Supported image types include:

  • JPEG
  • PNG
  • WebP
  • GIF
  • AVIF
  • BMP
  • TIFF

Requirements

  • Windows, macOS, or Linux
  • Node.js 20 or newer
  • npm
  • Claude Desktop

The project was originally designed for Windows with this folder structure:

C:\<PATH>\MCP\image-downloader-mcp
C:\<PATH>\MCP\ImageDownloads

However, the code can be configured to use another folder through environment variables.


Windows setup

Create folders:

New-Item -ItemType Directory -Force "C:\<PATH>\MCP"
New-Item -ItemType Directory -Force "C:\<PATH>\MCP\ImageDownloads"
New-Item -ItemType Directory -Force "C:\<PATH>\MCP\image-downloader-mcp"

Clone or place the project here:

cd C:\<PATH>\MCP\image-downloader-mcp

Install dependencies:

npm.cmd install

Build:

npm.cmd run build

Confirm the build exists:

Test-Path "C:\<PATH>\MCP\image-downloader-mcp\build\index.js"

Expected:

True

Why use npm.cmd on Windows PowerShell?

On some Windows systems, PowerShell blocks npm.ps1 because script execution is disabled.

If this happens:

npm.ps1 cannot be loaded because running scripts is disabled on this system

use:

npm.cmd install
npm.cmd run build

Alternatively, you can allow local scripts for the current Windows user:

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

Then reopen PowerShell.


Manual local test

Run:

node "C:\<PATH>\MCP\image-downloader-mcp\build\index.js"

Expected behavior:

  • The process starts.
  • It stays running.
  • It logs only to stderr.
  • It does not print normal logs to stdout.

Stop it with:

Ctrl + C

Claude Desktop configuration

Open Claude Desktop config:

notepad "$env:APPDATA\Claude\claude_desktop_config.json"

Example config:

{
  "mcpServers": {
    "image-downloader-mcp": {
      "command": "C:\\Program Files\\nodejs\\node.exe",
      "args": [
        "C:\\<PATH>\\MCP\\image-downloader-mcp\\build\\index.js"
      ],
      "env": {
        "IMAGE_DOWNLOAD_DIR": "C:\\<PATH>\\MCP\\ImageDownloads",
        "HTTP_TIMEOUT_MS": "15000",
        "MAX_FILE_SIZE_BYTES": "10485760",
        "DDG_REGION": "us-en",
        "USER_AGENT": "image-downloader-mcp/1.0.0"
      }
    }
  }
}

If you already have other MCP servers, add only the image-downloader-mcp block inside your existing mcpServers object.

Validate the JSON:

node -e "const fs=require('fs'),path=require('path'); JSON.parse(fs.readFileSync(path.join(process.env.APPDATA,'Claude','claude_desktop_config.json'),'utf8')); console.log('valid JSON')"

Expected:

valid JSON

Then fully restart Claude Desktop:

  1. Close the Claude Desktop window.
  2. Quit Claude from the system tray.
  3. Reopen Claude Desktop.
  4. Go to Settings.
  5. Open Developer.
  6. Check Local MCP servers.
  7. Confirm image-downloader-mcp shows as running.

Test in Claude Desktop

Ask Claude:

Use the image-downloader MCP to tell me the active download folder.

Then test the timeline workflow:

Use the image-downloader MCP to find and download images for this YouTube video script. Download one image per timestamp. Rename each downloaded image according to the timestamp and scene description so I can drag them directly into my video editor.

0:00 - Lionel Messi walks onto the field
0:05 - Argentina fans celebrate in the stadium
0:10 - Close-up of a football boot kicking the ball
0:15 - Trophy celebration scene

Then check:

Get-ChildItem "C:\<PATH>\MCP\ImageDownloads"

Expected filenames:

00-00_lionel-messi-walks-onto-field.jpg
00-05_argentina-fans-celebrate-stadium.jpg
00-10_close-up-of-a-football-boot-kicking-the-ball.jpg
00-15_trophy-celebration-scene.jpg

Environment variables

You can configure the server through Claude Desktop config.

| Variable | Default | Description | | --------------------- | -------------------------------------- | ------------------------------------ | | IMAGE_DOWNLOAD_DIR | C:\<PATH>\MCP\ImageDownloads on Windows | Folder where images are saved | | HTTP_TIMEOUT_MS | 15000 | Timeout for search/download requests | | MAX_FILE_SIZE_BYTES | 10485760 | Maximum allowed image size | | DDG_REGION | us-en | DuckDuckGo region | | USER_AGENT | image-downloader-mcp/1.0.0 | User agent for outbound requests |


.env.example

IMAGE_DOWNLOAD_DIR=C:\<PATH>\MCP\ImageDownloads
HTTP_TIMEOUT_MS=15000
MAX_FILE_SIZE_BYTES=10485760
DDG_REGION=us-en
USER_AGENT=image-downloader-mcp/1.0.0

Troubleshooting

Claude does not show the MCP server

Check that the build exists:

Test-Path "C:\<PATH>\MCP\image-downloader-mcp\build\index.js"

Validate the Claude config:

node -e "const fs=require('fs'),path=require('path'); JSON.parse(fs.readFileSync(path.join(process.env.APPDATA,'Claude','claude_desktop_config.json'),'utf8')); console.log('valid JSON')"

Fully quit and restart Claude Desktop.

Check logs:

notepad "$env:APPDATA\Claude\logs\mcp.log"
notepad "$env:APPDATA\Claude\logs\mcp-server-image-downloader-mcp.log"

npm.ps1 cannot be loaded

Use:

npm.cmd install
npm.cmd run build

tsc is not recognized

This usually means dependencies were not installed.

Run:

npm.cmd install
npm.cmd run build

Search fails

Possible reasons:

  • DuckDuckGo changed its public image search behavior.
  • Network request timed out.
  • SafeSearch setting filtered the results.
  • The query was too vague.

Try a more specific query, for example:

Argentina football fans celebrating stadium photo

instead of:

fans

Download fails

Possible reasons:

  • The image host blocks direct downloads.
  • The URL returns HTML instead of an image.
  • The image is larger than the configured max size.
  • The image format is unsupported.
  • The request timed out.

The timeline tool tries multiple search results before marking a scene as failed.


Safety notes

This tool downloads public web images to a local folder. It does not bypass paywalls, authentication, DRM, private accounts, or access controls.

The server includes several safety checks:

  • URL validation
  • Timeout protection
  • Maximum file size protection
  • Content-Type validation
  • File signature validation
  • Safe filename handling
  • Duplicate filename handling

However, users are still responsible for reviewing downloaded files and checking whether they have rights to use the images.


Copyright and legal disclaimer

This project helps search for and download images from public web sources. It does not grant any license to use those images.

You are responsible for checking:

  • Copyright status
  • License terms
  • Attribution requirements
  • Commercial-use restrictions
  • Personality/publicity rights
  • Platform rules for YouTube, TikTok, Instagram, or other services

For commercial or monetized videos, prefer:

  • Images you own
  • Licensed stock images
  • Public domain images
  • Creative Commons images with compatible terms
  • Official press/media kits where usage is allowed

This project does not provide legal advice.


Known limitations

  • DuckDuckGo image search is used through public web behavior, not a guaranteed paid API.
  • Search behavior may change if DuckDuckGo changes its image result format.
  • The server cannot verify copyright or image license status.
  • Some websites block direct image downloads.
  • Some images may be low quality or unrelated.
  • SafeSearch is dependent on the upstream search provider.

Recommended project structure

image-downloader-mcp/
├─ src/
│  └─ index.ts
├─ scripts/
│  └─ fix-bin-mode.mjs
├─ build/
│  └─ index.js
├─ package.json
├─ package-lock.json
├─ tsconfig.json
├─ .env.example
├─ .gitignore
├─ LICENSE
└─ README.md

Do not commit:

node_modules/
build/
.env
*.log

Commit:

src/
scripts/
package.json
package-lock.json
tsconfig.json
.env.example
.gitignore
LICENSE
README.md

Suggested GitHub publishing checklist

Before publishing:

  • Confirm there are no secrets in the repo.
  • Confirm .env is ignored.
  • Confirm node_modules is ignored.
  • Confirm build is ignored unless you intentionally want to publish compiled files.
  • Run npm.cmd install.
  • Run npm.cmd run build.
  • Run npm audit.
  • Test in Claude Desktop.
  • Test search_images.
  • Test download_image.
  • Test download_images_for_timeline.
  • Confirm the download folder works.
  • Confirm duplicate filenames are handled correctly.
  • Add repository metadata to package.json.
  • Add screenshots or a short demo GIF if desired.
  • Add clear copyright and usage disclaimers.

License

MIT License.

See LICENSE for details.


快速设置
此服务器的安装指南

安装包 (如果需要)

npx @modelcontextprotocol/server-image-downloader-mcp

Cursor 配置 (mcp.json)

{ "mcpServers": { "arnavkucheriya-image-downloader-mcp": { "command": "npx", "args": [ "arnavkucheriya-image-downloader-mcp" ] } } }