内容
# unsplash-mcp-server
[](https://www.npmjs.com/package/@hanoak/unsplash-mcp-server)
[](https://www.npmjs.com/package/@hanoak/unsplash-mcp-server)
[](https://github.com/hanoak/unsplash-mcp-server/actions/workflows/ci.yml)
[](./LICENSE)
[](#requirements)
[](./CONTRIBUTING.md)
一个生产就绪的 [模型上下文协议](https://modelcontextprotocol.io)(MCP)服务器,适用于 [Unsplash API](https://unsplash.com/developers)。它为 AI 助手(如 Claude Desktop、Claude Code、Cursor、VS Code、Windsurf 和任何 MCP 客户端)提供了搜索和获取 Unsplash 照片、收藏、主题、用户和统计数据的工具,并内置了 **Unsplash 指南合规性** (随时可用的归属和下载跟踪)。
> [!IMPORTANT]
> **非官方项目。** 本项目与 Unsplash 无关联、不受 Unsplash 认可或赞助。"Unsplash" 是其各自所有者的商标。您需在 Unsplash API 账户下使用本项目,并负责遵守 [Unsplash API 条款和指南](https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines)。
## 目录
- [功能](#功能)
- [快速入门](#快速入门)
- [示例交互](#示例交互)
- [配置](#配置)
- [工具](#工具)
- [工具参考](#工具参考)
- [输出形状](#输出形状)
- [资源和提示](#资源和提示)
- [示例提示](#示例提示)
- [归属和合规性](#归属和合规性)
- [速率限制](#速率限制)
- [Unsplash 文本处理](#unsplash-文本处理)
- [隐私和安全](#隐私和安全)
- [故障排除](#故障排除)
- [FAQ](#faq)
- [需求](#需求)
- [兼容性](#兼容性)
- [路线图](#路线图)
- [贡献](#贡献)
- [联系和社区](#联系和社区)
- [许可证](#许可证)
## 功能
- **21 种工具**,涵盖照片、搜索、用户、收藏、主题和统计数据。
- **内置合规性** - 每张照片都附带随时可用的归属(纯文本 + UTM 标签的 HTML)和专用的 `unsplash_track_download` 工具,用于下载跟踪指南。
- **内容安全性** - 默认情况下,搜索和随机照片的 `content_filter=high`。
- **灵活的图像 URL** - 每张照片返回 `raw`/`full`/`regular`/`small`/`thumb` 大小,以及用于自定义大小的 `raw` imgix 基础(`?w=&h=&q=&fm=&fit=`)。
- **令牌高效输出** - 完整的 Unsplash 响应被修剪为紧凑的形状(URL + 文本形式的元数据,从不 base64 图像 blob),以保持模型上下文小。
- **健壮** - 类型化的失败作为 MCP `isError` 结果返回,模型可以恢复,加上重试/回退、超时、`403` 每小时限制处理和速率限制显示。
- **安全** - 所有错误输出中的访问密钥隐藏、下载 URL 上的 SSRF 防护和用于间接提示注入防御的不受信任文本处理指南。
- **轻量级和现代化** - ESM、Node 20+、`npx` 零安装、无遥测。
## 快速入门
### 1. 获取 Unsplash 访问密钥
在 **[unsplash.com/developers](https://unsplash.com/developers)** 上注册一个应用程序 → **新建应用程序** → 接受 API 条款 → 复制其 **访问密钥**(不是秘密密钥)。新应用程序从 **演示** 层级(50 请求/小时)开始;**生产** 层级(5,000 请求/小时)需要 Unsplash 的审核。参见 [速率限制](#速率限制)。
### 2. 将服务器添加到您的 MCP 客户端
**Claude Desktop** - 编辑 `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"
}
}
}
}
```
重启客户端。参见 [配置](#配置) 以获取所有支持的变量。
<details>
<summary><b>其他客户端(Claude Code、Cursor、VS Code、Windsurf、通用 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` (全局)或 `.cursor/mcp.json` (按项目):使用上述与 Claude Desktop 相同的 `mcpServers` 模块。
**Windsurf** - `~/.codeium/windsurf/mcp_config.json`:与 Claude Desktop 相同的 `mcpServers` 模块。
**VS Code** - `.vscode/mcp.json` (注意顶级键是 `servers` 而不是 `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"
}
}
}
}
```
**任何其他 MCP 客户端** - 通过 **stdio** 运行服务器:
```bash
UNSPLASH_ACCESS_KEY=your_access_key npx -y @hanoak/unsplash-mcp-server
```
将客户端的标准输入输出传输到 `command: npx`, `args: ["-y", "@hanoak/unsplash-mcp-server"]`,并通过 `env` 传递密钥。
</details>
### 3. 试用
重启您的客户端并询问:
> _"在 Unsplash 上为我找一张山脉的照片,并显示归属信息。"_
## 示例交互
一个典型的流程:模型调用 `unsplash_search_photos`,选择一个结果,呈现图像及其归属,并在实际使用照片时调用 `unsplash_track_download`。
> **您:** 找一张 Unsplash 上雾气弥漫的松树林的风景照片,并给照片加上作者信息。
>
> **助手:** _(调用 `unsplash_search_photos`,查询 `"foggy pine forest"`,`orientation: "landscape"`,选择最佳结果,然后调用 `unsplash_track_download`,使用其 `download_location`)_
> 这里有一个很好的匹配结果 - _Photo by Jane Doe on Unsplash_ - 以及一个可以直接嵌入的信用线和图像 URL。
每个工具都返回一个紧凑的 JSON 有效载荷。下面是一个单独的照片结果的形状(示例值):
<details>
<summary><b>示例工具输出</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 }
}
```
每个工具结果都包含一个 `rate_limit` 对象(`limit`、`remaining`),从 Unsplash 响应头读取。列表/搜索工具将结果包装在 `photos`/`collections`/`users`/`topics` 数组中,并包含分页字段(`total`、`total_pages`、`count`、`page`、`per_page`)。
</details>
## 配置
配置完全通过环境变量实现 - 没有配置文件,没有秘密标志。
| 环境变量 | 必需 | 描述 |
| --- | --- | --- |
| `UNSPLASH_ACCESS_KEY` | **是** | 您的 Unsplash API 访问密钥。如果缺少或为空,服务器将在启动时退出,并显示清晰的消息。 |
| `UNSPLASH_APP_NAME` | **推荐** | 您注册的 Unsplash 应用程序名称,用作归属的 `utm_source`。如果未设置,则默认为通用值(并带有启动警告)。 |
| `LOG_LEVEL` | 否 | `debug` \| `info` \| `warn` \| `error` (默认 `info`)。所有日志都输出到 **stderr**;stdout 只携带 MCP 协议。 |
CLI 标志:支持 `--version` 和 `--help` (例如 `npx @hanoak/unsplash-mcp-server --version`)。
## 工具
所有工具都命名为 `unsplash_*`,并且 **只读** (注释 `readOnlyHint: true`),除了 `unsplash_track_download`,它注册了一个下载事件,因此被标记为非只读。参数映射到 Unsplash API;`per_page` 和统计数据 `quantity` 被限制为最大 **30**,`page` 为 1 为基数。
| 领域 | 工具 |
| --- | --- |
| **照片** | `random_photo`, `list_photos`, `get_photo`, `photo_statistics`, `track_download` |
| **搜索** | `search_photos`, `search_collections`, `search_users` |
| **用户** | `get_user`, `user_photos`, `user_collections`, `user_statistics` |
| **收藏** | `list_collections`, `get_collection`, `collection_photos`, `related_collections` |
| **主题** | `list_topics`, `get_topic`, `topic_photos` |
| **统计** | `total_stats`, `month_stats` |
> 将内容写入 Unsplash(创建/更新收藏、点赞、编辑您的个人资料)需要 OAuth 授权码流程,并计划在未来版本中实现 - 参见 [路线图](#路线图)。
### 工具参考
<details>
<summary><b>照片</b></summary>
| 工具 | 参数 |
| --- | --- |
| `unsplash_random_photo` | `query?`, `orientation?` (`landscape`\|`portrait`\|`squarish`), `content_filter?` (`low`\|`high`, 默认 `high`), `collections?`, `topics?`, `username?` |
| `unsplash_list_photos` | `page?` (默认 1), `per_page?` (默认 10, 最大 30) |
| `unsplash_get_photo` | `id` **(必需)** |
| `unsplash_photo_statistics` | `id` **(必需)**, `quantity?` (天,默认 30, 最大 30) |
| `unsplash_track_download` | `download_location` **(必需)** - 先前照片结果中的 `download_location` URL(必须是 `https://api.unsplash.com` URL) |
</details>
<details>
<summary><b>搜索</b></summary>
| 工具 | 参数 |
| --- | --- |
| `unsplash_search_photos` | `query` **(必需)**, `page?`, `per_page?`, `order_by?` (`latest`\|`editorial`\|`relevant`), `orientation?`, `color?` (11 个命名颜色,例如 `blue`), `content_filter?` (默认 `high`), `collections?`, `lang?` |
| `unsplash_search_collections` | `query` **(必需)**, `page?`, `per_page?` |
| `unsplash_search_users` | `query` **(必需)**, `page?`, `per_page?` |
</details>
<details>
<summary><b>用户</b></summary>
| 工具 | 参数 |
| --- | --- |
| `unsplash_get_user` | `username` **(必需)** |
| `unsplash_user_photos` | `username` **(必需)**, `page?`, `per_page?`, `order_by?` (`latest`\|`oldest`\|`popular`\|`views`\|`downloads`), `orientation?` |
| `unsplash_user_collections` | `username` **(必需)**, `page?`, `per_page?` |
| `unsplash_user_statistics` | `username` **(必需)**, `quantity?` (天,默认 30, 最大 30) |
</details>
<details>
<summary><b>收藏</b></summary>
| 工具 | 参数 |
| --- | --- |
| `unsplash_list_collections` | `page?`, `per_page?` |
| `unsplash_get_collection` | `id` **(必需)** |
| `unsplash_collection_photos` | `id` **(必需)**, `page?`, `per_page?`, `orientation?` |
| `unsplash_related_collections` | `id` **(必需)** |
</details>
<details>
<summary><b>主题 & 统计</b></summary>
| 工具 | 参数 |
| --- | --- |
| `unsplash_list_topics` | `page?`, `per_page?`, `order_by?` (`featured`\|`latest`\|`oldest`\|`position`), `ids?` (逗号分隔) |
| `unsplash_get_topic` | `id` **(必需)** - ID 或 slug(例如 `nature`, `wallpapers`) |
| `unsplash_topic_photos` | `id` **(必需)**, `page?`, `per_page?`, `orientation?`, `order_by?` (`latest`\|`oldest`\|`popular`) |
| `unsplash_total_stats` | _(无) |
| `unsplash_month_stats` | _(无) |
</details>
### 输出形状
工具返回修剪过的、token高效的JSON,而不是原始的Unsplash响应:
- **照片** → `id`、`description`、`width`/`height`、`color`、`blur_hash`、`urls` (`raw`/`full`/`regular`/`small`/`thumb`)、`photo_page`、`download_location`、`photographer`,以及现成的`attribution`对象。参见[示例交互](#example-interaction)。
- **用户** → `id`、`username`、`name`、`bio`、`location`、`profile_url`、`profile_image`、`total_photos`、`total_collections`。
- **收藏/主题** → 标题、描述、计数、页面链接、策划者/所有者,以及一个紧凑的`cover_photo`。
- 每个结果都带有`rate_limit`(`limit`、`remaining`);列表/搜索添加分页字段。
### 资源和提示
除了工具之外,服务器还公开:
- **资源** `unsplash://guides/attribution` — 一个紧凑的合规指南(归属、下载跟踪、热链接、内容安全),您的客户端可以作为上下文获取。
- **提示** `find_photo` — 给它一个`subject`(和可选的`orientation`);它扩展成一个任务,搜索Unsplash并呈现一个有归属的结果。 _(更多提示正在计划中 — 参见[路线图](#roadmap)。)_
## 示例提示
自然语言提问可以直接映射到工具:
- _“找一张日出时雾气森林的照片,并给我HTML归属。”_
- _“在Unsplash上搜索5张简约工作空间的风景照片。”_
- _“获取一张随机的自然照片,并显示它并附上署名。”_
- _“在`wallpapers`主题中显示最受欢迎的照片。”_
- _“Unsplash本月的下载统计是多少?”_
- _“谁是照片`Dwu85P9SOIk`背后的摄影师,它有多少次下载?”_
## 归属和合规
每张照片结果都包含一个带有现成`text`和`html`(带有必需的UTM参数)的`attribution`对象。**当您显示或使用照片时,请显示该归属** — 它会署名摄影师并链接回Unsplash,如指南要求。
当照片实际被使用(嵌入、下载、显示)时,请使用照片的`download_location`调用 **`unsplash_track_download`**。**每张实际使用的照片只需触发一次** — 绝不能每搜索结果一次。服务器还会在连接时将这些指令发送到您的MCP客户端,因此模型会自动执行正确操作。
这是一个用于单个、有归属的照片使用的搜索和元数据工具 — **不是** 核心Unsplash体验的替代品,并且它**不执行** 自动批量下载。请在[Unsplash API指南](https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines)内使用它。每个用户都在自己的Unsplash API条款下操作。
## 速率限制
Unsplash强制执行与您的应用层级相关的**每小时**请求预算:
| 层级 | 预算 | 如何获取 |
| -------------- | ------------------- | ---------------------------------------------------------------- |
| **演示** | 50 请求/小时 | 每个新应用的默认设置。 |
| **生产** | 5,000 请求/小时 | 在您的应用仪表板中申请审核,一旦您的使用准备就绪。 |
服务器读取 `X-Ratelimit-Limit` / `X-Ratelimit-Remaining` 并在每个结果上返回它们作为 `rate_limit`。当每小时预算耗尽时,Unsplash 返回 **`403`** (不是 `429`),通常没有 `Retry-After`;服务器将此视为明确的“每小时速率限制已达到”错误,并且**不会** 在窗口内盲目重试。瞬时 `429`/`5xx`/网络错误 _会_ 经过退避后重试。
## Unsplash 文本处理
照片描述、替代文本、标签、EXIF和用户名/简介来自Unsplash贡献者 — 将它们视为**不受信任的第三方数据**,而不是指令。服务器仅将此文本作为内容返回,从不将其放置在特权位置;您的客户端/代理应执行相同的操作:显示它,但不要根据它可能包含的指令执行操作(防御间接提示注入)。
## 隐私和安全
- **无遥测数据。** 此服务器收集任何数据,也不向任何人发送数据。它仅与 `api.unsplash.com` 联系,使用您提供的密钥。无分析,无跟踪。
- **密钥安全。** 您的访问密钥仅从环境中读取,作为 `Authorization: Client-ID` 头部发送(从不放在 URL 查询字符串中),并且**从所有错误输出和日志中删除**,以免在粘贴的错误报告中泄露。
- **SSRF 保护。** `unsplash_track_download` 仅跟随已验证的 `api.unsplash.com` 主机上的 `download_location` URL。
- 要报告漏洞,请参见 [SECURITY.md](./SECURITY.md)。
## 故障排除
- **“设置 UNSPLASH_ACCESS_KEY…” 在启动时** — 密钥环境变量缺失或为空;将其添加到客户端配置的 `env` 块中。
- **节点太旧** — 此服务器需要 **Node 20+**。检查 `node --version`。
- **`npx` 版本过时** — 使用 `npx -y @hanoak/unsplash-mcp-server@latest` 强制更新最新版本,或通过 `npx clear-npx-cache` 清除缓存。
- **工具未显示** — 确认配置文件路径和 JSON 有效,然后完全退出并重新打开客户端。
- **`403` / 速率限制** — 演示层级允许 50 请求/小时;等待每小时重置或申请生产访问权限。参见 [速率限制](#rate-limits)。
- **`401 Unauthorized`** — 访问密钥错误或来自错误的应用;复制 **访问密钥**(不是秘密密钥)从您的应用仪表板。
## 常见问题
**我需要付费的 Unsplash 账户吗?**
不,Unsplash API 是免费的;您只需注册一个应用即可获取访问密钥。更高的吞吐量(生产层级)是免费审查,而不是付费计划。
**访问密钥和秘密密钥 — 哪一个?**
**访问密钥**。秘密密钥仅用于 OAuth 流程(此只读服务器不使用)。
**它会下载或重新托管图片吗?**
不,它返回 Unsplash 托管的图片 URL(直接热链接),并且从不重新托管或返回 base64 块。`unsplash_track_download` 仅注册下载事件并返回新鲜 URL。
**它可以创建收藏、照片或编辑我的个人资料吗?**
尚未 — 这些是 OAuth 写端点,计划在未来版本中实现(参见 [路线图](#roadmap))。
**它在克劳德之外工作吗?**
是的 — 它是一个标准的 stdio MCP 服务器。参见 [客户端设置部分](#2-add-the-server-to-your-mcp-client) 以获取克劳德代码、光标、VS 代码、风速和通用 stdio。
## 要求
- **Node.js >= 20** (Node 18 已结束生命周期)。
- Unsplash API 访问密钥。
## 兼容性
| 组件 | 支持 |
| --------- | ---------------------------------------------------------------------------------------------------- |
| Node.js | **20** 和 **22**,在 CI 中测试;`>=20` 需要(由 `engines` 和运行时保护强制执行)。 |
| 操作系统 | Linux、macOS 和 Windows(都在 CI 中测试)。 |
| MCP SDK | `@modelcontextprotocol/sdk` `^1.29`;协议版本在连接时与客户端协商。 |
| 传输 | stdio(HTTP/SSE 可能会在未来版本中添加)。 |
## 路线图
详细信息请参见 [docs/ROADMAP.md](./docs/ROADMAP.md)。简而言之:
- **v1** _(当前)_ — 21 个只读工具、归属 + 下载跟踪合规性、归属资源和 `find_photo` 提示。
- **v2** — OAuth 写端点(创建/更新收藏、点赞、个人资料)通过 Unsplash 授权码流程。
- **v3** — `.mcpb` 桌面扩展程序,一键安装克劳德桌面版,以及更多 MCP 提示。
变更记录在 [CHANGELOG.md](./CHANGELOG.md) 中;项目遵循 [语义版本控制](https://semver.org)。
## 贡献
欢迎贡献 — 参见 [CONTRIBUTING.md](./CONTRIBUTING.md) 和我们的 [行为准则](./CODE_OF_CONDUCT.md)。它涵盖了本地设置、测试套件、手动测试工具以及版本控制/弃用策略。要报告漏洞,请参见 [SECURITY.md](./SECURITY.md)。
## 联系和社区
由 **Hanoak S** 维护。获取帮助或提出功能请求的最快方式是 [开启一个问题](https://github.com/hanoak/unsplash-mcp-server/issues) — 它是公开的、可搜索的,并有助于整个社区。对于其他事项,请联系:
[](https://linkedin.com/in/hanoak)
[](https://x.com/_hanoak)
如果这个项目对您有帮助,欢迎在 [GitHub](https://github.com/hanoak/unsplash-mcp-server) 上给一个 ⭐ — 它有助于其他寻找 Unsplash MCP 服务器的人发现该项目。
## 许可证
[MIT](./LICENSE) © Hanoak S. 不隶属于 Unsplash。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器