imagebank-mcp
v1.0.0
Published
MCP server for searching and downloading free stock images from Pexels, Unsplash and Pixabay, with automatic WebP conversion for web projects.
Maintainers
Readme
imagebank-mcp
MCP server that lets AI coding agents (Claude Code, Codex, Cursor, Antigravity, Cline, Windsurf and any MCP-compatible client) search free stock photos on Pexels, Unsplash and Pixabay, download them, and convert them to WebP directly into your project — no placeholders, no hotlinking, no manual image hunting.
Built for web developers: the agent asks for "a hero photo of artisan bread", gets real results, saves an optimized public/images/hero-artisan-bread.webp, and writes the <Image> tag pointing to it. Done.
Tools
| Tool | What it does |
|---|---|
| search_images | Searches one or all configured providers in parallel. Returns preview URL, download URL, dimensions, author and attribution link. Supports orientation and dominant-color filters. |
| download_image | Downloads a result, converts to WebP (quality and max-width configurable), saves inside the project, returns the path ready for <Image src>. Automatically fires the Unsplash download-tracking endpoint when required. |
| optimize_local_image | Same pipeline for local files. Use it when the client replaces stock photos with their own, so performance stays consistent. |
Requirements
- Node.js >= 18.17
- At least one API key (all free):
- Pexels: https://www.pexels.com/api/
- Unsplash: https://unsplash.com/developers (use the Access Key)
- Pixabay: https://pixabay.com/api/docs/
First install may take a bit longer:
sharp(image processing) downloads a prebuilt native binary for your platform. This is normal.
Installation
The recommended way is npx — nothing to install manually, each client just points at the package:
"command": "npx",
"args": ["-y", "imagebank-mcp"]API keys go in the env block of each client config. Never commit keys to a repository. Only the keys you set are used; missing providers are simply skipped.
Claude Code
Per project (.mcp.json at the project root) or global (~/.claude.json):
{
"mcpServers": {
"image-banks": {
"command": "npx",
"args": ["-y", "imagebank-mcp"],
"env": {
"PEXELS_API_KEY": "your_key",
"UNSPLASH_ACCESS_KEY": "your_key",
"PIXABAY_API_KEY": "your_key"
}
}
}
}Or via CLI:
claude mcp add image-banks -e PEXELS_API_KEY=your_key -e UNSPLASH_ACCESS_KEY=your_key -e PIXABAY_API_KEY=your_key -- npx -y imagebank-mcpCursor
.cursor/mcp.json in the project (or ~/.cursor/mcp.json global). Same JSON shape as Claude Code above.
OpenAI Codex CLI
~/.codex/config.toml:
[mcp_servers.image-banks]
command = "npx"
args = ["-y", "imagebank-mcp"]
[mcp_servers.image-banks.env]
PEXELS_API_KEY = "your_key"
UNSPLASH_ACCESS_KEY = "your_key"
PIXABAY_API_KEY = "your_key"Antigravity
Agent settings → MCP servers → add server. Uses the same JSON structure as Claude Code (mcpServers block with command, args, env).
Cline / Roo Code (VSCode)
MCP settings file (cline_mcp_settings.json): same JSON shape as Claude Code.
Windsurf
~/.codeium/windsurf/mcp_config.json: same JSON shape as Claude Code.
Gemini CLI
~/.gemini/settings.json, inside mcpServers: same JSON shape as Claude Code.
Config file locations change between client versions. If a path above doesn't match your install, check the client's MCP docs — the server block itself (
command/args/env) is identical everywhere.
Usage
You rarely call the tools explicitly. In normal use the agent decides on its own:
"Build the hero section for the bakery with a photo of fresh sourdough coming out of the oven."
The agent will call search_images (query in English, orientation: landscape), pick a result, call download_image, and write the component using the returned local path.
Explicit prompts also work:
Search 6 landscape photos of "modern dental clinic reception" on unsplash,
download the best one as hero-clinic-reception at quality 85.Recommended agent guidance
Add to your CLAUDE.md / rules file for best behavior:
Images: when the design needs photos and the client has not provided any,
use the image-banks MCP (search_images then download_image). Search in
English. Never hotlink stock URLs; always download to public/images.
Prefer client-provided photos when they exist (optimize them with
optimize_local_image). Avoid stock photos with prominent faces for paid ads.Image licensing (read this once)
All three providers allow free commercial use without attribution on the final website. Still:
- Unsplash API rule: when a photo is actually used, the download endpoint must be pinged.
download_imagedoes this automatically when you passtrackDownloadUrl. - Pixabay: permanent hotlinking is prohibited — you must self-host. This server downloads by design, so you're compliant by default.
- Model releases: none of the platforms verify consent of people appearing in photos. Avoid images with recognizable faces in paid advertising; fine for regular site sections.
- Attribution is not required but is appreciated — the
attributionUrlandauthorfields are always returned if you want to credit.
This is not legal advice; check each provider's license for your specific case.
Security
- SSRF protection:
download_imageonly acceptshttpsURLs onpexels.com,unsplash.com,pixabay.comand subdomains. Internal IPs, cloud metadata endpoints and arbitrary hosts are rejected. - Path traversal protection: filenames are sanitized to kebab-case; output and input paths must resolve inside the working directory.
- Size and type limits: downloads capped at 25 MB; content-type validated; sharp pixel-bomb limit set.
- Keys: read from env only, never logged, never echoed in tool output.
- Runs locally over stdio. Nothing is hosted; no data leaves your machine except the API calls to the providers you configured.
Local development
git clone https://github.com/romuloquintanilha/imagebank-mcp
cd imagebank-mcp
npm install
npm run build
npm test # unit + real MCP protocol + sharp pipeline tests
npm run inspector # interactive UI to call tools manuallyFor the inspector, export your keys first (export PEXELS_API_KEY=...).
License
MIT — see LICENSE. The code is MIT; the images you download are governed by each provider's own license.
