Skip to main content
ClaudeWave
hanoak avatar
hanoak

unsplash-mcp-server

View on GitHub

Production-ready Model Context Protocol (MCP) server for the Unsplash API — search & fetch photos, collections, topics, users, and stats, with built-in attribution and download-tracking compliance. For Claude, Cursor, and any MCP client. Unofficial.

MCP ServersOfficial Registry1 stars0 forksTypeScriptMITUpdated today
Install in Claude Code / Claude Desktop
Method: NPX · @hanoak/unsplash-mcp-server
Claude Code CLI
claude mcp add unsplash -- npx -y @hanoak/unsplash-mcp-server
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "unsplash": {
      "command": "npx",
      "args": ["-y", "@hanoak/unsplash-mcp-server"],
      "env": {
        "UNSPLASH_ACCESS_KEY": "<unsplash_access_key>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
UNSPLASH_ACCESS_KEY
Use cases

MCP Servers overview

# unsplash-mcp-server

[![npm version](https://img.shields.io/npm/v/@hanoak/unsplash-mcp-server.svg)](https://www.npmjs.com/package/@hanoak/unsplash-mcp-server)
[![npm downloads](https://img.shields.io/npm/dm/@hanoak/unsplash-mcp-server.svg)](https://www.npmjs.com/package/@hanoak/unsplash-mcp-server)
[![CI](https://github.com/hanoak/unsplash-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/hanoak/unsplash-mcp-server/actions/workflows/ci.yml)
[![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![node: >=20](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](#requirements)
[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](./CONTRIBUTING.md)

A production-ready [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for the [Unsplash API](https://unsplash.com/developers). It gives AI assistants — Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, and any MCP client — tools to search and fetch Unsplash photos, collections, topics, users, and stats, with **Unsplash-guideline compliance built in** (ready-to-use attribution and download tracking).

> [!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 the [Unsplash API Terms & Guidelines](https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines).

## Table of contents

- [Features](#features)
- [Quick start](#quick-start)
- [Example interaction](#example-interaction)
- [Configuration](#configuration)
- [Tools](#tools)
  - [Tool reference](#tool-reference)
  - [Output shape](#output-shape)
  - [Resources & prompts](#resources--prompts)
- [Example prompts](#example-prompts)
- [Attribution & compliance](#attribution--compliance)
- [Rate limits](#rate-limits)
- [Handling of Unsplash text](#handling-of-unsplash-text)
- [Privacy & security](#privacy--security)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Requirements](#requirements)
- [Compatibility](#compatibility)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact & community](#contact--community)
- [License](#license)

## Features

- **21 tools** across photos, search, users, collections, topics, and stats.
- **Compliance built in** — every photo comes with ready-to-use attribution (plain text + UTM-tagged HTML), and a dedicated `unsplash_track_download` tool for the download-tracking guideline.
- **Content safety** — `content_filter=high` by default on search and random photos.
- **Flexible image URLs** — each photo returns `raw`/`full`/`regular`/`small`/`thumb` sizes, plus a `raw` imgix base for custom sizes (`?w=&h=&q=&fm=&fit=`).
- **Token-efficient output** — full Unsplash responses are trimmed to a compact shape (URLs + metadata as text, never base64 image blobs) to keep model context small.
- **Robust** — typed failures returned as MCP `isError` results the model can recover from, plus retries/backoff, timeouts, `403` hourly-limit handling, and rate-limit surfacing.
- **Safe** — access-key redaction in all error output, an SSRF guard on download URLs, and untrusted-text handling guidance for indirect prompt-injection defence.
- **Lean & modern** — ESM, Node 20+, zero-install via `npx`, no telemetry.

## Quick start

### 1. Get an Unsplash access key

Register an application at **[unsplash.com/developers](https://unsplash.com/developers)** → **New Application** → accept the API terms → copy its **Access Key** (not the Secret Key). New apps start on the **Demo** tier (50 requests/hour); the **Production** tier (5,000/hour) requires Unsplash's review from your app dashboard. See [Rate limits](#rate-limits).

### 2. Add the server to your MCP client

**Claude Desktop** — edit `claude_desktop_config.json`:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```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. See [Configuration](#configuration) for every supported variable.

<details>
<summary><b>Other clients (Claude Code, Cursor, VS Code, Windsurf, generic stdio)</b></summary>

**Claude Code** (CLI):

```bash
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 same `mcpServers` block as Claude Desktop above.

**Windsurf** — `~/.codeium/windsurf/mcp_config.json`: same `mcpServers` block as Claude Desktop above.

**VS Code** — `.vscode/mcp.json` (note the top-level key is `servers`, not `mcpServers`):

```json
{
  "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 over **stdio** with:

```bash
UNSPLASH_ACCESS_KEY=your_access_key npx -y @hanoak/unsplash-mcp-server
```

Point your client's stdio transport at `command: npx`, `args: ["-y", "@hanoak/unsplash-mcp-server"]`, and pass the key via `env`.

</details>

### 3. Try it

Restart your client and ask:

> _"Find me a photo of mountains on Unsplash and show the attribution."_

## Example interaction

A typical flow: the model calls `unsplash_search_photos`, picks a result, presents the image with its attribution, and calls `unsplash_track_download` when it actually uses the photo.

> **You:** Find a landscape photo of a foggy pine forest and credit the photographer.
>
> **Assistant:** _(calls `unsplash_search_photos` with `query: "foggy pine forest"`, `orientation: "landscape"`, picks the best result, then calls `unsplash_track_download` with its `download_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):

<details>
<summary><b>Example tool output</b></summary>

```json
{
  "photo": {
    "id": "Dwu85P9SOIk",
    "description": "brown rocky mountain under blue sky during daytime",
    "width": 6000,
    "height": 4000,
    "color": "#734940",
    "blur_hash": "L6Pj0^i_.AyE_3t7t7R**0o#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 a `rate_limit` object (`limit`, `remaining`) read from the Unsplash response headers. List/search tools wrap results in `photos`/`collections`/`users`/`topics` arrays with pagination fields (`total`, `total_pages`, `count`, `page`, `per_page`).

</details>

## Configuration

Configuration is entirely via environment variables — no config files, no flags for secrets.

| Environment variable  | Required        | Description                                                                                                                             |
| --------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `UNSPLASH_ACCESS_KEY` | **yes**         | Your Unsplash API access key. The server exits at startup with a clear message if it is missing or blank.                               |
| `UNSPLASH_APP_NAME`   | **recommended** | Your registered Unsplash app name, used as the attribution `utm_source`. Defaults to a generic value (with a startup warning) if unset. |
| `LOG_LEVEL`           | no              | `debug` \| `info` \| `warn` \| `error` (default `info`). All logs go to **stderr**; stdout carries only the MCP protocol.               |

CLI flags: `--version` and `--help` are supported (e.g. `npx @hanoak/unsplash-mcp-server --version`).

## Tools

All tools are namespaced `unsplash_*` and are **read-only** (annotated `readOnlyHint: true`) except `unsplash_track_download`, which registers a download event and so is marked non-read-only. Parameters map to the Unsplash API; `per_page` and stats `quantity` are clamped to a max of **30**, and `page` is 1-based.

| Domain          | Tools                                                                            |
| --------------- | -------------------------------------------------------------------------------- |
| **Photos**      | `random_photo`, `list_photos`, `get_photo`, `photo_statistics`, `track_download` |
| **Search
ai-agentsclaudeclaude-desktopimagesllmmcpmcp-servermodel-context-protocolmodelcontextprotocolphotosstock-photostypescriptunsplashunsplash-api

What people ask about unsplash-mcp-server

What is hanoak/unsplash-mcp-server?

+

hanoak/unsplash-mcp-server is mcp servers for the Claude AI ecosystem. Production-ready Model Context Protocol (MCP) server for the Unsplash API — search & fetch photos, collections, topics, users, and stats, with built-in attribution and download-tracking compliance. For Claude, Cursor, and any MCP client. Unofficial. It has 1 GitHub stars and was last updated today.

How do I install unsplash-mcp-server?

+

You can install unsplash-mcp-server by cloning the repository (https://github.com/hanoak/unsplash-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is hanoak/unsplash-mcp-server safe to use?

+

hanoak/unsplash-mcp-server has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.

Who maintains hanoak/unsplash-mcp-server?

+

hanoak/unsplash-mcp-server is maintained by hanoak. The last recorded GitHub activity is from today, with 0 open issues.

Are there alternatives to unsplash-mcp-server?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy unsplash-mcp-server to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: hanoak/unsplash-mcp-server
[![Featured on ClaudeWave](https://claudewave.com/api/badge/hanoak-unsplash-mcp-server)](https://claudewave.com/repo/hanoak-unsplash-mcp-server)
<a href="https://claudewave.com/repo/hanoak-unsplash-mcp-server"><img src="https://claudewave.com/api/badge/hanoak-unsplash-mcp-server" alt="Featured on ClaudeWave: hanoak/unsplash-mcp-server" width="320" height="64" /></a>

More MCP Servers

unsplash-mcp-server alternatives