@hanoak/unsplash-mcp-server
About
Production-ready Model Context Protocol (MCP) server for the Unsplash API — search photos, fetch details, and stay compliant with Unsplash attribution & download-tracking guidelines. Unofficial; not affiliated with or endorsed by Unsplash.
Details
- Author
- hanoak
- Categories
- Search, Knowledge Base, Other
Jump to
Setup
Install @hanoak/unsplash-mcp-server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/hanoak/unsplash-mcp-server
Follow the installation instructions in the repository README, then restart your MCP client.
Production-ready Model Context Protocol (MCP) server for the Unsplash API — search photos, fetch details, and stay compliant with Unsplash attribution & download-tracking guidelines. Unofficial; not affiliated with or endorsed by Unsplash.
[!IMPORTANT]Unofficial project.This is not affiliated with, endorsed by, or sponsored by Unsplash. "Unsplash" is a trademark of its respective owner. You use it under your own Unsplash API account and are responsible for complying with theUnsplash API Terms & Guidelines.
- Features
- Quick start
- Example interaction
- Configuration
- OAuth sign-in (optional)
- Tools
- Tool reference
- Output shape
- Resources & prompts
Register an application atunsplash.com/developers→New Application→ accept the API terms → copy itsAccess Key(not the Secret Key). New apps start on theDemotier (50 requests/hour); theProductiontier (5,000/hour) requires Unsplash's review from your app dashboard. SeeRate limits.
Claude Desktop— editclaude_desktop_config.json:
- macOS:~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:%APPDATA%\Claude\claude_desktop_config.json
{ "mcpServers": { "unsplash": { "command": "npx", "args": ["-y", "@hanoak/unsplash-mcp-server"], "env": { "UNSPLASH_ACCESS_KEY": "your_access_key", "UNSPLASH_APP_NAME": "your_registered_app_name" } } } }
Restart the client. SeeConfigurationfor every supported variable.
claude mcp add unsplash \ --env UNSPLASH_ACCESS_KEY=your_access_key \ --env UNSPLASH_APP_NAME=your_registered_app_name \ -- npx -y @hanoak/unsplash-mcp-server
Cursor—~/.cursor/mcp.json(global) or.cursor/mcp.json(per-project): use the exact samemcpServersblock as Claude Desktop above.
Windsurf—~/.codeium/windsurf/mcp_config.json: samemcpServersblock as Claude Desktop above.
VS Code—.vscode/mcp.json(note the top-level key isservers, notmcpServers):
{ "servers": { "unsplash": { "command": "npx", "args": ["-y", "@hanoak/unsplash-mcp-server"], "env": { "UNSPLASH_ACCESS_KEY": "your_access_key", "UNSPLASH_APP_NAME": "your_registered_app_name" } } } }
Any other MCP client— run the server overstdiowith:
UNSPLASH_ACCESS_KEY=your_access_key npx -y @hanoak/unsplash-mcp-server
Point your client's stdio transport atcommand: npx,args: ["-y", "@hanoak/unsplash-mcp-server"], and pass the key viaenv.
"Find me a photo of mountains on Unsplash and show the attribution."
A typical flow: the model callsunsplash_search_photos, picks a result, presents the image with its attribution, and callsunsplash_track_downloadwhen it actually uses the photo.
You:Find a landscape photo of a foggy pine forest and credit the photographer.
Assistant:(callsunsplash_search_photoswithquery: "foggy pine forest",orientation: "landscape", picks the best result, then callsunsplash_track_downloadwith itsdownload_location)Here's a great match —Photo by Jane Doe on Unsplash— along with a ready-to-embed credit line and the image URL.
Each tool returns a compact JSON payload. Here's the shape of a single photo result (illustrative values):
{ "photo": { "id": "Dwu85P9SOIk", "description": "brown rocky mountain under blue sky during daytime", "width": 6000, "height": 4000, "color": "#734940", "blur_hash": "L6Pj0^i_.AyE_3t7t7R0o#DgR4", "urls": { "raw": "https://images.unsplash.com/photo-1465…?ixid=…", "full": "https://images.unsplash.com/photo-1465…?ixid=…&q=85", "regular": "https://images.unsplash.com/photo-1465…?ixid=…&w=1080", "small": "https://images.unsplash.com/photo-1465…?ixid=…&w=400", "thumb": "https://images.unsplash.com/photo-1465…?ixid=…&w=200" }, "photo_page": "https://unsplash.com/photos/Dwu85P9SOIk", "download_location": "https://api.unsplash.com/photos/Dwu85P9SOIk/download?ixid=…", "photographer": { "name": "Jane Doe", "username": "janedoe", "profile": "https://unsplash.com/@janedoe" }, "attribution": { "text": "Photo by Jane Doe on Unsplash", "html": "Photo by <a href=\"https://unsplash.com/@janedoe?utm_source=your_app&utm_medium=referral\">Jane Doe</a> on <a href=\"https://unsplash.com/?utm_source=your_app&utm_medium=referral\">Unsplash</a>", "photographerName": "Jane Doe", "photographerUrl": "https://unsplash.com/@janedoe?utm_source=your_app&utm_medium=referral", "unsplashUrl": "https://unsplash.com/?utm_source=your_app&utm_medium=referral" } }, "rate_limit": { "limit": 50, "remaining": 49 } }
Every tool result includes arate_limitobject (limit,remaining) read from the Unsplash response headers. List/search tools wrap results inphotos/collections/users/topicsarrays with pagination fields (total,total_pages,count,page,per_page).
Configuration is entirely via environment variables — no config files, no flags for secrets.
CLI flags:--versionand--helpare supported (e.g.npx @hanoak/unsplash-mcp-server --version).login/logoutare subcommands, not flags — see below.
-
On your app's page atunsplash.com/oauth/applications, addhttp://localhost:8734/callbackas a redirect URI, and copy theSecret key.
Set bothUNSPLASH_ACCESS_KEYandUNSPLASH_SECRET_KEYin your shell (not just the MCP client config —loginruns from your terminal).
This opens your browser to Unsplash's consent screen, captures the redirect on a short-lived local server, exchanges the code for a user access token, and saves it to~/.config/unsplash-mcp-server/credentials.json(owner-only file permissions). Unsplash user access tokensdon't expire, so this is a one-time step — no periodic re-auth.
Restart your MCP client. The 8 write/metools are now available; the 21 read-only tools are unaffected either way.
Runnpx @hanoak/unsplash-mcp-server logoutat any time to remove the stored token. To revoke it server-side, regenerate your app's secret key from the Unsplash dashboard.
All tools are namespacedunsplash_. Most areread-only(annotatedreadOnlyHint: true); the exceptions areunsplash_track_download(registers a download event) and the 8 write/metools below, all marked non-read-only and gated behindOAuth sign-in. Parameters map to the Unsplash API;per_pageand statsquantityare clamped to a max of30, andpageis 1-based.
🔒 = requiresOAuth sign-in(login) first.
Tools return trimmed, token-efficient JSON rather than raw Unsplash responses:
- Photos→id,description,width/height,color,blur_hash,urls(raw/full/regular/small/thumb),photo_page,download_location,photographer, and a ready-to-useattributionobject. SeeExample interaction.
- Users→id,username,name,bio,location,profile_url,profile_image,total_photos,total_collections.
- Collections / Topics→ title, description, counts, page link, curator/owners, and a compactcover_photo.
- Every result carries arate_limit(limit,remaining); lists/searches add pagination fields.
-
Resources— compact guides your client can pull in as context:
Prompts— ready-made tasks your client can surface directly; each expands into a guided, multi-step tool-calling task:
Natural-language asks that map cleanly onto the tools:
- "Find a photo of a foggy forest at sunrise and give me the HTML attribution."
- "Search Unsplash for 5 minimalist workspace photos in landscape orientation."
- "Get a random nature photo and show it with credit."
- "Show me the most popular photos in thewallpaperstopic."
- "What are this month's Unsplash-wide download stats?"
- "Who is the photographer behind photoDwu85P9SOIk, and how many downloads does it have?"
Every photo result includes anattributionobject with ready-to-usetextandhtml(with the required UTM parameters).When you display or use a photo, show that attribution— it credits the photographer and links back to Unsplash, as the guidelines require.
When a photo is actuallyused(embedded, downloaded, displayed), callunsplash_track_downloadwith the photo'sdownload_location. Trigger itonce per photo actually used— never once per search result. The server also sends these instructions to your MCP client on connect, so the model is nudged to do the right thing automatically.
This is a search-and-metadata tool for individual, attributed photo use —nota replacement for the core Unsplash experience, and it performsno automated bulk downloading. Please use it within theUnsplash API Guidelines. Each user operates under their own Unsplash API Terms.
Unsplash enforces aper-hourrequest budget tied to your app's tier:
The server readsX-Ratelimit-Limit/X-Ratelimit-Remainingand returns them asrate_limiton every result. When the hourly budget is exhausted, Unsplash returns403(not429), often with noRetry-After; the server surfaces this as a clear "hourly rate limit reached" error and doesnotblindly retry in-window. Transient429/5xx/network errorsareretried with backoff.
Photo descriptions, alt text, tags, EXIF, and user names/bios come from Unsplash contributors — treat them asuntrusted, third-party data, not instructions. The server returns this text purely as content and never places it anywhere privileged; your client/agent should do the same: display it, but don't act on any instructions it might contain (a defence against indirect prompt injection).
- No telemetry.This server collects nothing and phones home to no one. It contacts onlyapi.unsplash.com, using the key you provide. No analytics, no tracking.
- Verifiable provenance.Every release is published withnpm provenancevia GitHub Actions — the npm package page links each version to the exact commit and workflow run that built it.
- Key safety.Your access key is read from the environment only, sent as anAuthorization: Client-IDheader (never in a URL query string), andredacted from all error output and logsso it can't leak into pasted bug reports.
- SSRF guard.unsplash_track_downloadonly followsdownload_locationURLs on the verifiedapi.unsplash.comhost.
- To report a vulnerability, seeSECURITY.md.
- "Set UNSPLASH_ACCESS_KEY…" on startup— the key env var is missing or blank; add it to your client config'senvblock.
- Node too old— this server requiresNode 20+. Checknode --version.
- Stalenpxversion— force the latest withnpx -y @hanoak/unsplash-mcp-server@latest, or clear the cache vianpx clear-npx-cache.
- Tools not appearing— confirm the config file path and JSON are valid, then fully quit and reopen the client.
- 403/ rate limit— the Demo tier allows 50 requests/hour; wait for the hourly reset or apply for Production access. SeeRate limits.
- 401 Unauthorized— the access key is wrong or from the wrong app; copy theAccess Key(not the Secret Key) from your app dashboard.
Do I need a paid Unsplash account?No. The Unsplash API is free; you just register an app to get an access key. Higher throughput (Production tier) is a free review, not a paid plan.
Access Key vs Secret Key — which one?For the 21 read-only tools, just theAccess Key. The Secret Key is only needed forlogin(the OAuth flow behind the 8 write/metools) — seeOAuth sign-in.
Does it download or rehost images?No. It returns Unsplash-hosted image URLs (hotlink them directly) and never rehosts or returns base64 blobs.unsplash_track_downloadonly registers a download event and returns a fresh URL.
Does it work outside Claude?Yes — it's a standard stdio MCP server. Seethe client setup sectionfor Claude Code, Cursor, VS Code, Windsurf, and generic stdio.
- Node.js >= 20(Node 18 is end-of-life).
- An Unsplash API access key.
Full detail lives indocs/ROADMAP.md. In short:
- v1(shipped)— the 21 read-only tools, attribution + download-tracking compliance, the attribution resource, and thefind_photoprompt.
- v2(shipped)— the 8 OAuth write /meendpoints (profile, collections, photo metadata) via alogin/logoutCLI and the Unsplash authorization-code flow.
- v3(current)— 7 more MCP prompts covering every tool domain (seeResources & prompts). A.mcpbDesktop Extension was considered for this phase but dropped to unscheduled future scope —npxalready works across every supported client.
Changes are tracked inCHANGELOG.md; the project followsSemantic Versioning.
Contributions are welcome — seeCONTRIBUTING.mdand ourCode of Conduct. It covers local setup, the test suite, testing tools by hand with theMCP Inspector, and the versioning/deprecation policy. To report a vulnerability, seeSECURITY.md.
Maintained byHanoak S*. The fastest way to get help or propose a feature is toopen an issue— it's public, searchable, and helps the whole community. For anything else, reach out:
If this project helps you, a ⭐ onGitHubis appreciated — it aids discoverability for others looking for an Unsplash MCP server.
MIT© Hanoak S. Not affiliated with Unsplash.
Search global news using natural language. Webz.io News Search API returns the most relevant articles and content, with filters for source, country, language, date, sentiment, and category.
Fetch, convert, and search AWS documentation pages, with recommendations for related content.
Search campgrounds around the world on campertunity, check availability, and provide booking links.
The Ferryhopper MCP Server exposes ferry routes, schedules and booking redirects so an AI assistant can discover connections across Europe and the Mediterranean and send users to Ferryhopper to complete bookings.
All-in-One SEO & Web Intelligence Toolkit API from FetchSERP.
MCP server that provides read-only access to HyperKitty, the web-based email archive component of Mailman 3.
At Sunrise Apps, we believe AI agents should be limitless, especially when it comes to visual data. We created ImageSorcery to bridge the critical gap in AI's ability to interact with and manipulate images directly, all while upholding the highest standards of privacy and security.
Just Domain is the domain registrar for businesses built with AI. Its remote MCP server checks availability and returns first-year and renewal pricing, plus a link to register on justdomain.ai, with DNS and WHOIS privacy in the same place. No account, no API key, read only. Endpoint: https://mcp.justdomain.ai/
Research tools, including a Sqlite-backed document stash
Semantic search over 9 free-license stock photo sources. Hosted remote server with OAuth — no API key to paste.
SerpApi MCP Server for Google and other search engine results
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




