@hanoak/unsplash-mcp-server
@hanoak/unsplash-mcp-server offers an MCP interface to Unsplash, enabling AI assistants to search, browse, manage, and comply with Unsplash guidelines through 29 tools, pre-built prompts, and resources.
Photo Discovery & Retrieval: Search photos by keyword with orientation, color, sort, language, and safety filters; get random photos (optionally filtered); browse latest featured photos; retrieve photo by ID or slug; view photo download/view statistics over days.
Search: Search collections and users by keyword.
Users: Get public profile, list a user's photos (with sorting/filters) and collections, and view user statistics.
Collections & Topics: List featured collections, get collection details, list photos within a collection, find related collections. List curated topics with sorting/filtering, get topic details, list photos in a topic.
Platform Stats: Global Unsplash total and monthly (last 30 days) statistics.
Attribution & Compliance: Every photo result includes ready-to-use text/HTML attribution with UTM parameters. A dedicated
unsplash_track_downloadtool registers download events per Unsplash guidelines.Write & Profile Management (OAuth required): Create/update/delete collections, add/remove photos, update metadata on owned photos, get/update own profile.
Content Safety: Defaults to “high” content filter for search and random photos.
Flexible Image URLs: Provides multiple sizes (
raw,full,regular,small,thumb) and a raw imgix base URL for custom resizing.Pre-built Prompts & Guides: 8 prompts for tasks like finding a photo, building a gallery, curating collections; resources for attribution, OAuth setup, and prompt usage.
Technical & Security: Returns token-efficient trimmed JSON; robust error handling with retries, timeouts, and clear rate-limit/403 messages; redacts access keys from errors; implements SSRF guard for download URLs; runs on Node.js 20+, zero-install via
npx, and includes no telemetry.
Provides tools for searching and fetching Unsplash photos, collections, topics, users, and statistics, with built-in attribution and download tracking compliance.
unsplash-mcp-server
A production-ready Model Context Protocol (MCP) server for the Unsplash API. 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). Sign in once via OAuth to also manage your own profile, collections, and photo metadata.
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.
Table of contents
Related MCP server: stock-images-mcp
Features
29 tools across photos, search, users, collections, topics, stats, and your own profile — 21 read-only out of the box, plus 8 write/
metools once you sign in.Compliance built in — every photo comes with ready-to-use attribution (plain text + UTM-tagged HTML), and a dedicated
unsplash_track_downloadtool for the download-tracking guideline.Content safety —
content_filter=highby default on search and random photos.Flexible image URLs — each photo returns
raw/full/regular/small/thumbsizes, plus arawimgix 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
isErrorresults the model can recover from, plus retries/backoff, timeouts,403hourly-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 → 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.
2. Add the server to your MCP client
Claude Desktop — edit claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%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. See Configuration for every supported variable.
Claude Code (CLI):
claude mcp add unsplash \
--env UNSPLASH_ACCESS_KEY=your_access_key \
--env UNSPLASH_APP_NAME=your_registered_app_name \
-- npx -y @hanoak/unsplash-mcp-serverCursor — ~/.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):
{
"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:
UNSPLASH_ACCESS_KEY=your_access_key npx -y @hanoak/unsplash-mcp-serverPoint your client's stdio transport at command: npx, args: ["-y", "@hanoak/unsplash-mcp-server"], and pass the key via env.
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_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_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).
Configuration
Configuration is entirely via environment variables — no config files, no flags for secrets.
Environment variable | Required | Description |
| yes | Your Unsplash API access key. The server exits at startup with a clear message if it is missing or blank. |
| recommended | Your registered Unsplash app name, used as the attribution |
| only for | Your Unsplash app's secret key. Only needed to run |
| only for | Override the default |
| no |
|
CLI flags: --version and --help are supported (e.g. npx @hanoak/unsplash-mcp-server --version). login/logout are subcommands, not flags — see below.
OAuth sign-in (optional)
The 21 core tools work out of the box with just UNSPLASH_ACCESS_KEY. To also use the 8 write/me tools (update your profile, manage collections, edit photo metadata), sign in once via OAuth:
On your app's page at unsplash.com/oauth/applications, add
http://localhost:8734/callbackas a redirect URI, and copy the Secret key.Set both
UNSPLASH_ACCESS_KEYandUNSPLASH_SECRET_KEYin your shell (not just the MCP client config —loginruns from your terminal).Run:
npx @hanoak/unsplash-mcp-server loginThis 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 tokens don'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.
Run npx @hanoak/unsplash-mcp-server logout at any time to remove the stored token. To revoke it server-side, regenerate your app's secret key from the Unsplash dashboard.
Tools
All tools are namespaced unsplash_*. Most are read-only (annotated readOnlyHint: true); the exceptions are unsplash_track_download (registers a download event) and the 8 write/me tools below, all marked non-read-only and gated behind OAuth sign-in. 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 |
|
Search |
|
Users |
|
Collections |
|
Topics |
|
Stats |
|
Me |
|
🔒 = requires OAuth sign-in (login) first.
Tool reference
Tool | Parameters | Description |
|
| A single random photo, optionally filtered. |
|
| The latest featured photos, paginated. |
|
| A single photo by ID or slug, full detail. |
|
| Download/view totals for a photo over N days. |
|
| Registers a download on real use; returns a fresh, usable download URL. |
|
| Update metadata on a photo you own. Only the fields you pass are changed. |
Tool | Parameters | Description |
|
| Keyword photo search with rich filters. |
|
| Keyword collection search. |
|
| Keyword user search. |
Tool | Parameters | Description |
|
| A user's public profile. |
|
| A user's photos, paginated. |
|
| A user's collections, paginated. |
|
| A user's download/view totals over N days. |
Tool | Parameters | Description |
|
| The latest featured collections. |
|
| A single collection by ID. |
|
| Photos within a collection, paginated. |
|
| Collections related to a given one. |
|
| Create a new collection you own. |
|
| Update a collection you own. Only the fields you pass change. |
|
| Permanently delete a collection you own. Cannot be undone. |
|
| Add a photo to a collection you own. |
|
| Remove a photo from a collection you own. |
Tool | Parameters | Description |
| (none) | Your own profile, including private fields (email, uploads remaining). |
|
| Update your own profile. Only the fields you pass are changed. |
Tool | Parameters | Description |
|
| Curated topics, paginated. |
|
| A single topic. |
|
| Photos within a topic, paginated. |
| (none) | Unsplash-wide totals (photos, downloads, …). |
| (none) | Unsplash-wide totals for the past 30 days. |
Output shape
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. See Example 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 compact
cover_photo.Every result carries a
rate_limit(limit,remaining); lists/searches add pagination fields.
Resources & prompts
Beyond tools, the server also exposes:
Resources — compact guides your client can pull in as context:
unsplash://guides/attribution— attribution, download tracking, hotlinking, content safety.unsplash://guides/oauth-setup— how to sign in for the 8 write/metools.unsplash://guides/prompts— which of the prompts below to use for a given task.
Prompts — ready-made tasks your client can surface directly; each expands into a guided, multi-step tool-calling task:
Prompt
Arguments
What it does
find_photosubject(required),orientation?Search for one photo and present it with attribution.
photo_gallerytheme(required),count?,orientation?,color?Build a themed set of photos (up to 10), each with attribution.
topic_spotlighttopic(required),count?Showcase a curated topic's best photos.
photographer_spotlightusername(required),count?A photographer's profile + their most popular work.
platform_pulse(none)
A quick Unsplash-wide stats briefing.
curate_collection🔒theme(required),count?,collection_id?Search, then build (or extend) a real collection from the matches.
describe_photo🔒id(required),description?,tags?Add a description/tags to a photo you own.
refresh_profile🔒bio?,location?,url?Update your own bio, location, or portfolio URL.
🔒 = requires OAuth sign-in first.
Example prompts
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 the
wallpaperstopic.""What are this month's Unsplash-wide download stats?"
"Who is the photographer behind photo
Dwu85P9SOIk, and how many downloads does it have?"
Attribution & compliance
Every photo result includes an attribution object with ready-to-use text and html (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 actually used (embedded, downloaded, displayed), call unsplash_track_download with the photo's download_location. Trigger it once 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 — not a replacement for the core Unsplash experience, and it performs no automated bulk downloading. Please use it within the Unsplash API Guidelines. Each user operates under their own Unsplash API Terms.
Rate limits
Unsplash enforces a per-hour request budget tied to your app's tier:
Tier | Budget | How to get it |
Demo | 50 requests/hour | Default for every new app. |
Production | 5,000 requests/hour | Apply for review in your app dashboard once your usage is ready. |
The server reads X-Ratelimit-Limit / X-Ratelimit-Remaining and returns them as rate_limit on every result. When the hourly budget is exhausted, Unsplash returns 403 (not 429), often with no Retry-After; the server surfaces this as a clear "hourly rate limit reached" error and does not blindly retry in-window. Transient 429/5xx/network errors are retried with backoff.
Handling of Unsplash text
Photo descriptions, alt text, tags, EXIF, and user names/bios come from Unsplash contributors — treat them as untrusted, 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).
Privacy & security
No telemetry. This server collects nothing and phones home to no one. It contacts only
api.unsplash.com, using the key you provide. No analytics, no tracking.Verifiable provenance. Every release is published with npm provenance via 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 an
Authorization: Client-IDheader (never in a URL query string), and redacted from all error output and logs so it can't leak into pasted bug reports.SSRF guard.
unsplash_track_downloadonly followsdownload_locationURLs on the verifiedapi.unsplash.comhost.To report a vulnerability, see SECURITY.md.
Troubleshooting
"Set UNSPLASH_ACCESS_KEY…" on startup — the key env var is missing or blank; add it to your client config's
envblock.Node too old — this server requires Node 20+. Check
node --version.Stale
npxversion — 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. See Rate limits.401 Unauthorized— the access key is wrong or from the wrong app; copy the Access Key (not the Secret Key) from your app dashboard.
FAQ
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 the Access Key. The Secret Key is only needed for login (the OAuth flow behind the 8 write/me tools) — see OAuth 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_download only registers a download event and returns a fresh URL.
Can it create collections, like photos, or edit my profile?
Yes, once you sign in — unsplash_create_collection and friends, and unsplash_update_photo/unsplash_update_my_profile. (Liking photos is not currently exposed as a tool.)
Does it work outside Claude? Yes — it's a standard stdio MCP server. See the client setup section for Claude Code, Cursor, VS Code, Windsurf, and generic stdio.
Requirements
Node.js >= 20 (Node 18 is end-of-life).
An Unsplash API access key.
Compatibility
Component | Supported |
Node.js | 20 and 22, tested in CI; |
OS | Linux, macOS, and Windows (all tested in CI). |
MCP SDK |
|
Transport | stdio (HTTP/SSE may be added in a future release). |
Roadmap
Full detail lives in docs/ROADMAP.md. In short:
v1 (shipped) — the 21 read-only tools, attribution + download-tracking compliance, the attribution resource, and the
find_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 (see Resources & prompts). A
.mcpbDesktop Extension was considered for this phase but dropped to unscheduled future scope —npxalready works across every supported client.
Changes are tracked in CHANGELOG.md; the project follows Semantic Versioning.
Contributing
Contributions are welcome — see CONTRIBUTING.md and our Code of Conduct. It covers local setup, the test suite, testing tools by hand with the MCP Inspector, and the versioning/deprecation policy. To report a vulnerability, see SECURITY.md.
Contact & community
Maintained by Hanoak S. The fastest way to get help or propose a feature is to open an issue — it's public, searchable, and helps the whole community. For anything else, reach out:
If this project helps you, a ⭐ on GitHub is appreciated — it aids discoverability for others looking for an Unsplash MCP server.
License
MIT © Hanoak S. Not affiliated with Unsplash.
Available Tools
29 toolsunsplash_add_photo_to_collectionAdd Photo to Unsplash CollectionA
Add a photo to a collection owned by the authenticated user. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. | |
| photo_id | Yes | The Unsplash photo ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false. The description adds valuable context beyond the annotations: the authentication requirement, the setup command, and the fact that the target collection must belong to the authenticated user. 'Not read-only' is consistent with the annotations, with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the action, and includes the prerequisite without excessive detail. The phrase 'Not read-only' is slightly redundant with the annotations, but it does not meaningfully hurt conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity—two required string parameters, full schema coverage, and annotations covering safety—the description is largely complete. It covers what the tool does, which collections are valid, and what the agent must do before invoking it. It does not describe duplicate-add behavior or exact return shape, but these are not essential for this operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so id and photo_id are already well documented. The description adds useful semantic context by clarifying that the collection ID must reference a collection owned by the authenticated user, which also reinforces the need for OAuth.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Add a photo to a collection') and states the critical ownership scope ('owned by the authenticated user'). This allows an agent to distinguish it from read-only collection tools and from the sibling remove_photo_from_collection without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states the prerequisite: OAuth sign-in, with the exact CLI command to run first. It does not explicitly mention when-not-to-use or name alternatives, but the add-vs-remove context and the auth requirement give sufficient situational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_collection_photosUnsplash Collection PhotosARead-only
List the photos in a collection (paginated), with URLs and ready-to-use attribution. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. | |
| page | No | Page number, 1-based. | |
| per_page | No | Items per page (clamped to a max of 30). | |
| orientation | No | Filter by photo orientation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint; the description reinforces 'Read-only' and adds behavioral details: pagination, attribution, and imgix URL customization. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, followed by actionable detail. Every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paginated list tool with 4 parameters and no output schema, the description covers purpose, pagination, return format (URLs, sizes, attribution), and usage of raw URL. It equips the agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing baseline 3. The description adds meaningful context about return values (imgix URLs, fixed sizes, attribution) and pagination, going beyond individual parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists photos in a collection, with pagination, URLs, and attribution. It distinguishes itself from sibling tools that focus on users, topics, or stats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does and how to use the output URLs, but does not provide explicit guidance on when to use this tool versus alternatives (e.g., when to use unsplash_collection_photos vs unsplash_topic_photos). No exclusions or conditions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_create_collectionCreate Unsplash CollectionA
Create a new collection owned by the authenticated user. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Title for the new collection. | |
| private | No | Create as a private collection (default false). | |
| description | No | Description for the collection. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=false, so the mutation nature is covered. The description adds value by specifying that the collection is 'owned by the authenticated user' and requiring OAuth sign-in, which are meaningful behavioral and environmental traits beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no waste. The core purpose, ownership constraint, and authentication requirement are front-loaded, and each piece of information earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create tool with only three optional parameters and no nested objects, the description covers the key operational requirements (ownership and authentication). It does not mention return value, but that is common for create operations and the output is likely a collection object.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: title, private, and description each have clear inline descriptions. The tool description does not add extra parameter semantics or examples, which is acceptable since the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Create') and resource ('a new collection') and constrains ownership to the authenticated user. It clearly distinguishes this from sibling tools like update_collection, delete_collection, and various read-only collection tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides necessary context: the tool requires OAuth authentication, and it gives a concrete prerequisite command. It does not explicitly name alternatives or when-not-to-use, but for a create operation the purpose is unambiguous and the authentication caveat is important guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_delete_collectionDelete Unsplash CollectionADestructive
Permanently delete a collection owned by the authenticated user. This cannot be undone. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true and readOnlyHint=false; the description adds meaningful context on top: the operation is irreversible ('This cannot be undone'), requires prior OAuth authentication, and repeats safety guarantee 'Not read-only.' These statements are consistent with the annotations, so no contradiction. Only failure-mode behavior (401/403/404) is left undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences and every sentence earns its place: irreversibility and scope up front, the authentication prerequisite, and an explicit disambiguation that this is not read-only. No filler, no restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the essential facts are covered: what is deleted, the ownership constraint, irreversibility, and the login prerequisite. The only missing detail is behavior on failures such as a nonexistent or non-owned collection ID, which is minor for such a simple destructive tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — the single required `id` parameter is already documented as 'The Unsplash collection ID' in the schema. The description adds no parameter-specific detail, and at this coverage level the schema carries the burden, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description pairs a specific verb ('delete') with a specific resource ('collection owned by the authenticated user') and stresses permanence. This differentiates it from siblings like create_collection and update_collection without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context is given: the target must be a collection owned by the currently signed-in user, and the exact OAuth prerequisite appears right in the description (`npx @hanoak/unsplash-mcp-server login`). It does not explicitly name exclusion conditions or reasons to prefer another sibling, but for a one-target destructive operation the usage signals are sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_get_collectionGet Unsplash CollectionARead-only
Get a single Unsplash collection by its ID. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description restates 'Read-only' without adding new behavioral context. No additional traits such as error behavior, rate limits, or return-format nuances are disclosed, but for a simple ID-based read tool the annotation coverage keeps this at a safe baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short, with the key operation front-loaded in one clear sentence. The standalone 'Read-only' sentence is technically redundant with the readOnlyHint annotation, so it does not fully earn its place, but there is no wasted wording or unnecessary background.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only lookup, the description is complete: it identifies the verb, the resource, the identifying input, and the safety posture. A return-value description is not necessary since the tool name and action make the result clear, and the annotations fill in the read-only semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single 'id' parameter is already described as the Unsplash collection ID in the schema. The description only repeats 'by its ID,' adding no further semantic guidance such as where the ID comes from or how it should be formatted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get a single Unsplash collection by its ID.' It clearly distinguishes this from listing, searching, or modifying collections, and the 'single' qualifier plus ID scoping separates it from sibling tools like unsplash_list_collections.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied but not explicit: the description says to get one collection by ID, which suggests this tool is for ID-based single-collection lookups. However, it does not explicitly say when not to use it, such as directing users to unsplash_list_collections for multiple collections or to unsplash_collection_photos for collection contents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_get_my_profileGet My Unsplash ProfileARead-only
Get the authenticated user's own Unsplash profile, including private fields (email, remaining uploads). Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, but the description adds meaningful behavioral context beyond them: it exposes that private fields are included, that OAuth sign-in is required, and the exact login command. It also reinforces read-only behavior without contradicting any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences with no fluff. The core action and unique scope are front-loaded, and the prerequisite and read-only note are placed after the main purpose. Every sentence adds needed information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, self-profile retrieval tool, the description is adequately complete. It explains what is returned (private fields like email and remaining uploads), what is required (OAuth login), and the safety profile (read-only). With annotations and an empty schema, nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters and an empty schema, so there are no parameter details needed. The baseline for 0 parameters is 4, and the description does not need to compensate for any parameter coverage gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), a precise resource ('the authenticated user's own Unsplash profile'), and important scope details ('including private fields (email, remaining uploads)'). The word 'own' clearly distinguishes it from the sibling unsplash_get_user, which retrieves another user's profile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the usage context clear: it is for the authenticated user's own profile, and it gives a concrete prerequisite ('run npx @hanoak/unsplash-mcp-server login first'). However, it does not explicitly state when not to use it or name alternatives, although 'own' and the sibling list make that inference easy.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_get_photoGet Unsplash PhotoARead-only
Get a single Unsplash photo by its ID or slug, with full detail, URLs, and ready-to-use attribution. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash photo ID or slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnly and openWorld hints; the description reinforces read-only behavior and additionally documents what the response contains: raw imgix URL, appended customization params, and fixed size variants. This adds useful behavioral detail beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the action, and every clause adds value. The raw URL example is practical and concise, providing exactly the customization guidance an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one required parameter and no output schema, the description sufficiently covers input and output: ID/slug lookup, returned detail/URLs, attribution, and available image variants. An agent can invoke the tool and interpret the response correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already describes 'id' as 'The Unsplash photo ID or slug.' The description repeats this same information and does not add new parameter-level semantics, so it stays at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific operation: get a single Unsplash photo by ID or slug, with full detail and URLs. It also distinguishes itself from sibling tools like list_photos, search_photos, and random_photo by emphasizing lookup of one specific photo.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys the main usage context: use when you have a known photo ID or slug and need that photo's detail. It does not explicitly name alternatives or exclusion conditions, but the 'single photo by ID/slug' framing makes the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_get_topicGet Unsplash TopicARead-only
Get a single Unsplash topic by its ID or slug. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash topic ID or slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. Description adds 'Read-only' which is consistent but does not provide additional behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is short and front-loaded, with no wasted words. However, it is slightly under-informative for a complete description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple single-parameter tool, the description is adequate but does not mention the return format or typical response fields, which would help an agent understand the tool's output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and already explains the parameter. The description echoes 'ID or slug' but adds no new semantic meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (get), resource (single Unsplash topic), and identifier method (ID or slug). It distinguishes from sibling tools like unsplash_topic_photos.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this vs alternatives. While the name implies simple retrieval, no usage context or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_get_userGet Unsplash UserARead-only
Get an Unsplash user's public profile by username. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | The Unsplash username (without the @). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and openWorldHint=true, covering side effects and access boundary. The description adds the qualifier 'public profile' but does not disclose other behaviors like response shape, whether the user must exist, or error semantics. Given the annotations, the bar is lower; this is adequate but not enriched.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one clear sentence plus a short 'Read-only.' that is redundant with the readOnlyHint annotation. The core sentence is front-loaded and contains no fluff, but the redundancy prevents a top score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with readOnlyHint and openWorldHint annotations, the description sufficiently captures the tool's function and scope. It lacks an explicit payload description or output details, but with no output schema the implied 'public profile' return value is enough for the simplicity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers the usernname parameter fully: type string, minLength 1, description stating 'The Unsplash username (without the @)'. The description's 'by username' adds no extra semantics beyond the schema. With 100% schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), resource ('an Unsplash user's public profile'), and scope ('by username'), making the tool's purpose unmistakable. 'Public profile' distinguishes it from sibling tools like unsplash_user_photos, unsplash_user_collections, or unsplash_user_statistics, which fetch other aspects of a user.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this tool to retrieve a user's public profile when you know the username. It does not explicitly mention alternatives or when-not-to-use, but the resource-scoping ('public profile') and the username requirement imply when it is appropriate compared to searching or other user endpoints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_list_collectionsList Unsplash CollectionsBRead-only
List the latest featured Unsplash collections (paginated). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| per_page | No | Items per page (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description replicates the readOnlyHint by saying 'Read-only', but it also adds useful context about 'latest featured' and pagination. It does not go beyond that to describe return values, ordering, or potential API-side behavior such as rate limits or clamped pagination, but the read-only annotation lowers the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and front-loaded with the core action. 'Read-only' is redundant with the annotation and adds no value, but otherwise every sentence contributes. It is concise without being sparse enough to lose meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only paginated list tool with fully described parameters and no required inputs, the description is sufficient for an agent to invoke it correctly. No output schema exists, but the 'List collections' wording naturally implies a list of collection objects. More detail about return shape or ordering would be helpful but is not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both page and per_page fully described. The description only mentions pagination generically and adds no meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action (List), a resource (Unsplash collections), and a scope (latest featured, paginated). It does not explicitly distinguish from siblings like unsplash_get_collection or unsplash_search_collections, but the wording is specific enough that an agent can infer the tool is for browsing featured collections rather than searching or retrieving a single collection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as unsplash_search_collections, unsplash_user_collections, or unsplash_get_collection. It does not mention any exclusions or conditions for choosing this over related list/search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_list_photosList Unsplash PhotosARead-only
List the latest featured Unsplash photos (paginated). Returns compact photo objects with URLs and ready-to-use attribution. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| per_page | No | Items per page (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses pagination, compact response objects, 'ready-to-use attribution', a raw imgix URL with query-param customization, and fixed sizes — valuable behavior beyond the readOnlyHint. The 'Read-only' statement aligns with the annotations, and the extra return-shape detail carries meaningful weight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three focused sentences: purpose first, then compact response shape and attribution, then the practical imgix URL customization hint. Every sentence earns its place and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must carry return-shape details — and it does, including the raw/full/regular/small/thumb variants. Combined with schema-documented parameters, an agent has enough to select this tool and interpret its result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both page and per_page, including defaults and clamping behavior. The description only reinforces 'paginated' without adding new semantic detail, so a baseline 3 is appropriate at 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with 'List the latest featured Unsplash photos (paginated)' — a specific verb, resource, and scope. This clearly distinguishes it from sibling tools like unsplash_random_photo, unsplash_search_photos, and unsplash_user_photos without needing to inspect their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'latest featured photos (paginated)' gives a clear context for when to use this tool: browsing the curated Unsplash feed page by page. It does not explicitly name when-not-to-use it or direct users to a sibling tool, so it misses the top bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_list_topicsList Unsplash TopicsBRead-only
List Unsplash topics (curated themes), paginated. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | Comma-separated topic ID(s)/slug(s) to filter to. | |
| page | No | Page number, 1-based. | |
| order_by | No | Sort order for the topics. | |
| per_page | No | Items per page (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description's 'Read-only' merely repeats that. It adds mild behavioral context by stating the listing is paginated, but it does not disclose behavioral subtleties such as default ordering, clamping behavior, or whether the filter parameter can narrow results. The description does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short, front-loaded statements with no filler. 'Read-only' is redundant with annotations but does not weaken the conciseness. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given this is a simple read-only list operation with zero required parameters and no output schema, the description provides enough context for an agent to call it correctly. It adequately conveys the resource, the paginated behavior, and the safety profile. It could be strengthened by stating that it lists all topics when no filters are applied, but the schema's optional params make this inferable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of parameters, so the baseline is 3. The description adds little beyond mentioning pagination, which is already implied by the page and per_page parameters. It does not clarify how ids interacts with pagination or what default ordering applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('List'), resource ('Unsplash topics'), and adds a useful parenthetical ('curated themes') and pagination detail. It is distinct from sibling listing tools by naming 'topics' explicitly, though it does not explicitly distinguish from very similar list tools like unsplash_list_collections or unsplash_list_photos.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, nor any exclusionary context such as 'for a single topic use get_topic'. The description only states what it does, not when to choose it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_month_statsUnsplash Monthly StatsARead-only
Get Unsplash-wide totals for the past 30 days: new photos, downloads, views, and more. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. The description reinforces read-only behavior and adds context about specific data returned, enhancing transparency beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence plus 'Read-only,' front-loading the core action and scope without extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides example outputs (new photos, downloads, views), which is adequate given the tool's simplicity and lack of output schema. It covers the essential behavioral context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, and schema coverage is 100%. The description appropriately omits parameter details, as none are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves Unsplash-wide totals for the past 30 days, listing example metrics (new photos, downloads, views). This distinguishes it from siblings like unsplash_total_stats, which likely provides all-time data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description indicates read-only usage and implies temporal scope (past 30 days). While it doesn't explicitly contrast with unsplash_total_stats, the name and description are sufficient for an agent to infer when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_photo_statisticsUnsplash Photo StatisticsARead-only
Get download and view totals for a photo over the last N days (default 30). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash photo ID or slug. | |
| quantity | No | Number of days of statistics to return (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description's 'read-only' adds little. It does add context about the default 30-day window and aggregate counts, but it does not disclose response shape or clarifies clamping behavior. No contradictions exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The key operation, data granularity, and default window are all front-loaded in the first sentence, and 'read-only' is a useful one-word safety signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two documented parameters and no output schema, the description is largely complete. It could say a bit more about expected return values, but the purpose and call context are clear enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Parameter schema coverage is 100%, so id and quantity are already documented. The description's phrase 'last N days (default 30)' adds minimal value beyond the schema, and it does not resolve the schema's confusing maximum/clamp mismatch.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('get'), a specific resource ('download and view totals for a photo'), and a clear time window ('over the last N days'). This distinguishes it from siblings like user statistics or collection/topic tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly implies when to use the tool, but it does not explicitly exclude alternatives or name related tools such as unsplash_user_statistics or unsplash_total_stats. The guidance is implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_random_photoRandom Unsplash PhotoARead-only
Fetch a single random photo from Unsplash. Optionally filter by search term, orientation, collections, topics, or user. Returns photo URLs, dimensions, color, and ready-to-use attribution (text + HTML). Content is filtered to "high" safety by default. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Limit the random selection to photos matching this search term. | |
| topics | No | Comma-separated topic ID(s)/slug(s) to narrow the selection. | |
| username | No | Limit the selection to photos by this Unsplash username. | |
| collections | No | Comma-separated public collection ID(s) to narrow the selection. | |
| orientation | No | Filter by photo orientation. | |
| content_filter | No | Content safety filter. Defaults to "high" to exclude potentially unsafe content. | high |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses valuable behavior: content safety defaults to 'high', returned data includes ready-to-use attribution, and a raw imgix base URL is provided for custom resizing/formatting. This gives an agent operational expectations beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense: it front-loads the core behavior, lists filters in one short sentence, summarizes the response shape, and explains a key URL recipe in a single example. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates well by explaining exactly what the agent will receive: URLs, dimensions, color, attribution, and fixed/raw image size options. Optional parameters are clear, and the tool's random selection purpose is fully specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented. The description restates the filter dimensions but adds no new semantic meaning about the parameters that is not already in the schema. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Fetch a single random photo'), the resource (Unsplash), and optional refinement dimensions (search term, orientation, collections, topics, user). This clearly distinguishes it from sibling tools like unsplash_list_photos or unsplash_search_photos, which do not return a single random photo.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the use case obvious: you need one random photo, optionally filtered by criteria. It does not explicitly name alternative tools or exclusion conditions, but the 'random' framing and mention of optional narrowing filters are a clear context for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_remove_photo_from_collectionRemove Photo from Unsplash CollectionA
Remove a photo from a collection owned by the authenticated user. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. | |
| photo_id | Yes | The Unsplash photo ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds authentication requirements and ownership constraints beyond the annotations, telling the agent that OAuth sign-in is required and that only collections owned by the user are affected. It also explicitly confirms the operation is not read-only, which aligns with readOnlyHint=true. It does not describe reverse effects or error cases, but the annotations already cover the basic safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short, front-loaded with the action, and every sentence adds useful context: what the tool does, the OAuth prerequisite, and the non-read-only nature. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple two-parameter mutation with no nested objects and no output schema. The schema fully explains both parameters, and the description covers the operational prerequisites and ownership constraint. The agent has enough to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both 'id' and 'photo_id' clearly documented in the schema. The description does not need to explain parameters further. It reaches the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Remove'), the resource ('photo from a collection'), and the ownership scope ('owned by the authenticated user'). This clearly distinguishes it from related operations like adding a photo to a collection or deleting a collection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: it is for authenticated users removing photos from their own collections, and it explicitly states the OAuth prerequisite with a concrete login command. It does not explicitly name alternatives or when-not-to-use scenarios, so it falls slightly short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_search_collectionsSearch Unsplash CollectionsARead-only
Search Unsplash collections by keyword. Returns paginated compact collections (title, description, cover photo, curator). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| query | Yes | Search terms (required). | |
| per_page | No | Results per page (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description augments the readOnlyHint by specifying paginated output and the compact field set, which is valuable because there is no output schema. It repeats 'read-only,' but the return representation and pagination behavior add meaningful transparency beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, dense sentences with no filler. The purpose is front-loaded and the return behavior is stated immediately afterward, making it easy for an agent to scan and use.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only search tool, this description provides a clear contract: keyword input, paginated output, and the returned fields. Combined with fully documented parameters and readOnlyHint, an agent has enough context to call it correctly without extra inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter meaning is already fully documented in the input schema. The description's phrases 'keyword' and 'paginated' loosely correspond to query and page/per_page, but they do not add significant semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Search Unsplash collections by keyword.' It also says exactly what is returned (paginated compact collections with title, description, cover photo, curator), which distinguishes it from plain collection listing and other search variants.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Search by keyword' gives clear context for when to use the tool, especially against the backdrop of sibling tools like list collections or fetching single collections. It does not explicitly name an alternative or say when not to use it, but the intended usage is easy to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_search_photosSearch Unsplash PhotosARead-only
Search Unsplash photos by keyword, with optional filters (orientation, color, order, collections, language). Returns paginated compact photos with URLs and ready-to-use attribution. Content is filtered to "high" safety by default. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | ISO language code for the query, e.g. "en", "es", "fr". | |
| page | No | Page number, 1-based. | |
| color | No | Filter by dominant color. | |
| query | Yes | Search terms (required). | |
| order_by | No | Sort order (Unsplash defaults to relevant). | |
| per_page | No | Results per page (clamped to a max of 30). | |
| collections | No | Comma-separated collection ID(s) to limit results to. | |
| orientation | No | Filter by photo orientation. | |
| content_filter | No | Content safety filter. Defaults to "high" to exclude potentially unsafe content. | high |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses useful behavioral details: output is paginated; photos include compact URLs and attribution; content_filter defaults to 'high' safety; and each photo has a raw imgix base URL with appendable parameters plus fixed sizes. This is meaningful context that helps an agent understand what will happen and what to pass on.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief, front-loaded with the core action, and uses every sentence to add value: the keyword search, the filter list, the return shape, the default safety behavior, the read-only nature, and the imgix URL detail. There is no filler or repetition beyond the mention of the content filter default.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema (100% coverage) and the absence of an output schema, the description sufficiently fills the gap by describing the output: paginated compact photos, URLs, attribution, imgix URL customization, and fixed sizes. An agent has enough information to select the tool, set required and optional parameters, and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter semantics are already fully documented. The description adds a general overview of filters and reiterates the high content-filter default, but does not provide additional meaning for individual parameters beyond what the input schema contains.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Search Unsplash photos by keyword.' It then lists the optional filters and return format, which distinguishes it clearly from sibling search tools like unsplash_search_collections and unsplash_search_users. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes the tool's use case: searching photos by keyword with optional filters. It provides enough context an agent needs to choose this tool, though it does not explicitly name alternatives or state when not to use it. The context is clear, but exclusions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_search_usersSearch Unsplash UsersARead-only
Search Unsplash users by keyword. Returns paginated compact user profiles (name, username, bio, profile link, photo/collection counts). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| query | Yes | Search terms (required). | |
| per_page | No | Results per page (clamped to a max of 30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. The description reinforces 'Read-only' and adds details about the returned data (name, username, bio, etc.), which provides useful behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words; the key action and result are front-loaded and clearly stated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description provides sufficient detail about return contents. It could include error or pagination specifics, but is adequate for a simple read-only search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description adds no substantial meaning beyond what the schema already provides for each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches Unsplash users by keyword and returns paginated compact user profiles, distinguishing it from siblings like unsplash_user_photos which focus on a specific user's content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for searching users but does not explicitly state when to use or not use this tool versus alternatives, nor does it provide exclusions or context about when it is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_topic_photosUnsplash Topic PhotosARead-only
List the photos in a topic (paginated), with URLs and ready-to-use attribution. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash topic ID or slug. | |
| page | No | Page number, 1-based. | |
| order_by | No | Sort order for the photos. | |
| per_page | No | Items per page (clamped to a max of 30). | |
| orientation | No | Filter by photo orientation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds details on the response structure (imgix URLs, fixed sizes, ready-to-use attribution) and pagination, giving a clear picture of the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the core purpose and adding key details without any wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the output content but does not mention the overall response format (e.g., array, pagination metadata). Given no output schema, more detail on the return structure would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 5 parameters with 100% coverage. The description does not add extra meaning beyond stating the output structure, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists photos in a topic with URLs and attribution. It distinguishes from sibling tools like unsplash_get_topic (topic info) and unsplash_user_photos (user photos).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does but does not provide explicit guidance on when to use it versus alternative tools, nor does it mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_total_statsUnsplash Total StatsARead-only
Get Unsplash-wide totals: photos, downloads, views, photographers, and more. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. Description adds 'Read-only' which is redundant but not contradictory. No further behavioral details (e.g., rate limiting, caching). Description carries minimal extra value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise (two sentences), front-loaded with primary action, no filler. Every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool, description lists main returned items but omits return format (JSON object with specific fields). With no output schema, description could be more explicit about what 'and more' includes. Adequate for simple stat but could be slightly improved.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters (empty schema, 100% coverage). Description adds no parameter info, but none needed. Baseline 4 applies as schema covers all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it retrieves Unsplash-wide totals (photos, downloads, views, photographers), with a specific verb 'Get' and resource 'Unsplash-wide totals'. Description distinguishes tool from sibling tools that focus on specific users, topics, or photos.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for aggregate statistics, but does not explicitly state when to use versus alternatives. However, the sibling tools are clearly different (user-specific, topic-specific), so context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_track_downloadTrack Unsplash Photo DownloadA
Register a download for a photo when it is actually used/displayed, as required by Unsplash's API guidelines. Pass the download_location URL from a prior photo result. Returns a fresh, usable image download URL. This has a side effect (it counts toward the photographer's download stats), so it is NOT read-only — call it only on real use.
| Name | Required | Description | Default |
|---|---|---|---|
| download_location | Yes | The `download_location` URL from a photo result. Call this when a photo is actually used/displayed to comply with the Unsplash download-tracking guideline. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clearly discloses the side effect (downloads are counted toward the photographer's stats) and explicitly warns it is NOT read-only, which aligns with annotations readOnlyHint=false. It also adds non-obvious behavior: it returns a fresh, usable image download URL. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tight and well-structured: it states the purpose, the required input, the return value, and the critical side-effect warning in four purposeful sentences. Nothing is redundant or unnecessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter side-effectful operation, this is complete. It explains why it exists, when and how to call it, what it returns, and what the consequences are. No important contextual gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully describes the single parameter with clear guidance at 100% coverage. The description repeats the same instruction about passing the download_location URL, adding no substantial new semantic information beyond the schema, so a baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action ('Register a download'), the exact resource (a photo download), and the triggering condition (actually used/displayed). This distinguishes it from all sibling tools, which cover listing, searching, and modifying photos or collections, not tracking downloads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly explains when to call the tool — on actual use/display per Unsplash API guidelines — and when not to call it: only on real use, because it is not read-only. It also tells the agent to pass the download_location from a prior photo result, fully specifying the required context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_update_collectionUpdate Unsplash CollectionA
Update a collection owned by the authenticated user. Only the fields you pass are changed. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash collection ID. | |
| title | No | New title. | |
| private | No | New private/public visibility. | |
| description | No | New description. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, and the description is consistent with them, adding real behavioral value beyond the annotations: the partial-update semantics 'Only the fields you pass are changed' informs the agent this is PATCH-like behavior rather than replace-all, and the explicit OAuth login prerequisite surfaces a likely failure mode. The redundant fragment 'Not read-only.' restates what readOnlyHint=false already conveys, which prevents this from reaching a 5. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficient and front-loaded: the main purpose comes first, the critical partial-update semantics second, and the auth prerequisite last. Every clause earns its place except the final 'Not read-only.' fragment, which duplicates the information already carried by readOnlyHint=false in the annotations — a minor redundancy. The login command with an example adds legitimate practical value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with 4 simple parameters, one required, and a full schema, the description covers everything an dimension agent needs to call it correctly: the purpose, the ownership scope, the partial-update field-behavior, and the only prerequisite (OAuth login). No output schema exists, but none is strictly necessary for a straightforward update tool whose success is simply the persisted changes. No equivalent gaps like on boarding the no-op failure modes that the auth hint already covers.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 — each parameter (id, title, private, description) is already documented in the schema. The description adds meaningful semantic context beyond that: by stating 'Only the param fields you pass are changed,' it tells the agent that title, private, and description are optional partial updates and that omitting them is safe, which is not explicitly stated in the schema itself. This enrichment raises it one rung above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource combination: 'Update a collection owned by the authenticated user.' The ownership constraint differentiates it from sibling tools like unsplash_create_collection, unsplash_delete_collection, and other update tools (unsplash_update_photo, unsplash_update_my_profile) with no ambiguity. The scope qualifier 'owned by the authenticated user' also tells an agent this only applies to the user's own collections, which is a meaningful restriction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use it: editing a user's own existing collection, including the explicit prerequisite 'Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first.' The ownership wording implies the exclusion (you cannot update collections you don't own), but it doesn't explicitly name a sibling alternative or state a when-not-to-use case. A clear operational trigger with prerequisites is present, so this falls short of the full 5 which requires explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_update_my_profileUpdate My Unsplash ProfileA
Update the authenticated user's own Unsplash profile. Only the fields you pass are changed. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| bio | No | New bio text. | |
| url | No | New portfolio/website URL on the user's profile. | |
| No | New account email. | ||
| location | No | New location text. | |
| username | No | New Unsplash username. | |
| last_name | No | New last name. | |
| first_name | No | New first name. | |
| instagram_username | No | New Instagram username. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, destructiveHint=false, and the description adds behavior beyond annotations: 'Only the fields you pass are changed' clarifies partial-update semantics, and the OAuth prerequisite explains the invocation flow. The phrase 'Not read-only' restates the annotation rather than adding new information, but there is no contradiction, and the added context helps an agent act correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short, purposeful sentences with the core function front-loaded ('Update the authenticated user's own profile…'), followed by carefully chosen behavioral and prerequisite details. It is tight and scannable; only the final 'Not read-only' redirects content also present in annotations, and that redundancy is minor.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 8 optional parameters, full schema coverage, and valid annotations, the description together with the schema covers the essential needs: what is mutated, the partial-update contract, and the setup requirement. There is no output schema, so the rubric does not require return-value documentation here; the only real gap is lack of an explicit note on what the response contains (e.g., the updated profile object), which is modest for this scenario.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — every parameter has a per-property description ('New bio text.', 'New Instagram username.' etc.) — so the baseline is 3. The description's 'Only the fields you pass are changed' reinforces the all-parameters-optional nature, but it doesn't layer new semantic detail on any individual parameter beyond what the schema already gives.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource ('Update the authenticated user's own Unsplash profile'). The scope is crystallized by 'own' and 'authenticated', which unambiguously separates it from the read sibling unsplash_get_my_profile and from the photo/collection update tools, so an agent doesn't need to open the schema to understand which object is being mutated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use context and an explicit prerequisite ('Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first'), which conventionally stands in for the supported 'when' guidance. It does not explicitly name alternatives or state when-not-to-use (e.g., a pointer to get_my_profile for reads), so it stops short of top-tier with no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_update_photoUpdate Unsplash PhotoA
Update metadata on a photo owned by the authenticated user (description, tags, location, EXIF, profile visibility). Only the fields you pass are changed. Requires OAuth sign-in — run npx @hanoak/unsplash-mcp-server login first. Not read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The Unsplash photo ID or slug. | |
| exif | No | New EXIF metadata. | |
| tags | No | Comma-separated list of tags for the photo (replaces the existing tags). | |
| location | No | New location metadata. | |
| description | No | New photo description. | |
| show_on_profile | No | Whether the photo shows on the owner's profile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It adds valuable behavioral information beyond the annotations: only the fields passed are modified, the operation requires an authenticated owner, and the tool is not read-only. These side effects are more specific than the provided readOnlyHint/destructiveHint annotations, and there is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and action-first, placing the core purpose before the auth prerequisite and safety note. Each sentence carries meaningful weight without excessive paraphrasing. The only slight redundancy is the final 'Not read-only' because the annotations already communicate this.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides the main operational context: who owns the photo, what can be changed, partial-update semantics, and a concrete login command. The lack of an output response shape prevents a perfect score, and the owner-only constraint could be stated even more explicitly, but the tool is callable with the given guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 6 parameters thoroughly, so per-parameter detail is already handled. The description contributes the partial-update semantics and a short field list, but it repeats field names rather than adding new meaning to individual parameters. With 100% coverage, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies an update action on a specific resource type ('photo owned by the authenticated user') and enumerates the exact metadata areas involved. It distinguishes itself from the many read/list/search sibling tools, though it does not name the other update_* tools as near alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear prerequisite: the user must have OAuth sign-in and provides the concrete command to run first. It conveys that this is a write operation and should not be considered read-only. It stops short of explicitly contrasting with unsplash_update_collection or unsplash_update_my_profile, so it does not reach a five.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_user_collectionsUnsplash User CollectionsBRead-only
List a user's collections (paginated). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| per_page | No | Items per page (clamped to a max of 30). | |
| username | Yes | The Unsplash username (without the @). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation already declares readOnlyHint=true, so the 'Read-only' phrase in the description is redundant. However, the description does clarify the paginated nature and the user-scoped resource, which adds modest behavioral context beyond the annotations. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exceptionally compact: two short phrases front-load the core action and scope with no fluff. The only slight redundancy is 'Read-only', which duplicates annotation data, but the overall structure is still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list with fully documented parameters, the description is minimally viable. However, there is no output schema and the description doesn't describe what a returned collection object looks like or direct the agent on how to compare with the broader sibling list tool, leaving moderate gaps for an agent deciding whether this tool is the right one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so username, page, and per_page are each fully documented with types, defaults, and constraints. The description adds no extra parameter-level meaning; it just says 'a user's collections', which largely reflects the username parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear specific action ('List') and resource ('a user's collections'), and adds 'paginated' to convey the operation's shape. It is distinguishable from other user-level tools like unsplash_user_photos, though it doesn't explicitly name an alternative or contrast with the more general list_collections.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to prefer this over unsplash_list_collections, unsplash_search_collections, or unsplash_user_photos. Saying 'a user's collections' implies user-scoped listing, but no explicit conditions, exclusions, or sibling routing are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_user_photosUnsplash User PhotosARead-only
List a user's photos (paginated), with URLs and ready-to-use attribution. Read-only. Each photo includes a raw imgix base URL — append params for a custom size/format, e.g. ?w=800&h=600&q=80&fm=webp&fit=crop — plus fixed full/regular/small/thumb sizes.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-based. | |
| order_by | No | Sort order for the photos. | |
| per_page | No | Items per page (clamped to a max of 30). | |
| username | Yes | The Unsplash username (without the @). | |
| orientation | No | Filter by photo orientation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial detail beyond readOnlyHint=true: it explains pagination, availability of raw imgix URL with customization example, and fixed image sizes. This fully informs the agent about the tool's behavior and output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences. First sentence captures purpose; second sentence delivers key behavioral detail. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately covers the return type (image URLs with sizes) and provides a customization hint. However, it could briefly mention pagination handling. Still, overall complete for the tool's scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters with descriptions. The description only adds value for the output format, not for parameter usage. Baseline of 3 is appropriate since schema already explains parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and resource 'user's photos' with pagination and attribution, distinguishing it from sibling tools focused on search, topics, or stats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for retrieving a user's photo collection, but does not explicitly compare to alternatives like unsplash_topic_photos or unsplash_search_users. The read-only hint and attribution advice provide some context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsplash_user_statisticsUnsplash User StatisticsARead-only
Get a user's download and view totals over the last N days (default 30). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| quantity | No | Number of days of statistics to return (clamped to a max of 30). | |
| username | Yes | The Unsplash username (without the @). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description simply repeats 'Read-only' without adding anything beyond the schema. The description does not mention clamping of quantity to a max of 30, which the schema notes, nor any response behavior. Since annotations cover the safety profile, this is acceptable but adds no extra value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence followed by 'Read-only'. Every token contributes to communicating the core purpose, and there is no fluff or repetition beyond the harmless echo of the annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity, read-only operation with two well-documented parameters, the description is nearly complete. It does not mention the clamp behavior or implicit maximum of 30 days, but the schema covers that, so nothing critical is missing for a safe and correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both properties thoroughly documented, including defaults, limits, and the '@' instruction. The description only adds 'default N days (default 30)' which mirrors the schema, so it does not meaningfully increase understanding beyond the structured data.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Get') and a specific resource ('a user's download and view totals'), and clarifies the time window with a default. It distinguishes itself from related tools like photo statistics or total stats by focusing on per-user totals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance or comparison against sibling tools such as unsplash_photo_statistics, unsplash_total_stats, or unsplash_month_stats. The context is implied by 'a user's' as opposed to 'photo' or 'total', but an agent is given no explicit instruction on when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
22 tool updates
v1.2.1- Added
unsplash_add_photo_to_collection - Added
unsplash_create_collection - Added
unsplash_delete_collection - Added
unsplash_get_collection - Added
unsplash_get_my_profile - Added
unsplash_get_photo - Added
unsplash_get_user - Added
unsplash_list_collections - Added
unsplash_list_photos - Added
unsplash_list_topics - Added
unsplash_photo_statistics - Added
unsplash_random_photo - Added
unsplash_related_collections - Added
unsplash_remove_photo_from_collection - Added
unsplash_search_collections - Added
unsplash_search_photos - Added
unsplash_track_download - Added
unsplash_update_collection - Added
unsplash_update_my_profile - Added
unsplash_update_photo - Added
unsplash_user_collections - Added
unsplash_user_statistics
7 tool updates
v1.0.1- First observed
unsplash_collection_photos - First observed
unsplash_get_topic - First observed
unsplash_month_stats - First observed
unsplash_search_users - First observed
unsplash_topic_photos - First observed
unsplash_total_stats - First observed
unsplash_user_photos
TDQS
Each tool targets a distinct resource: users, topics, collections, and stats. Even though three tools list photos, they are clearly differentiated by source (user, collection, topic).
All tools follow the 'unsplash_<resource>_<action>' pattern consistently. Verbs like search, get, and implicit list (user_photos) are clear and predictable.
7 tools is well-scoped for an Unsplash integration. It covers the main resources without being overwhelming.
Core functionality is missing: no photo search, no single photo details, no user profile details (only search), no collection listing for a user, and no topic listing. The set feels incomplete for typical image discovery workflows.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
Microlink MCP — wraps Microlink API (free tier, no auth required)
Product Hunt MCP — wraps the Product Hunt GraphQL API v2 (api.producthunt.com)
Official PicSee MCP server for short links, link management, click analytics, and optional OAuth.
Related MCP Servers
- AlicenseAqualityDmaintenanceA lightweight server that enables seamless integration with Unsplash's image library, allowing developers to search for high-quality photos with various filters directly from the Cursor editor.1235MIT
- AlicenseBqualityDmaintenanceMCP server to search and download stock images from Pexels, Unsplash, and Pixabay24103MIT
- AlicenseAqualityDmaintenanceAn MCP server for searching and retrieving photos from Unsplash with proper attribution, designed for LLMs building content pages.324MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for the Unsplash API that enables searching, downloading, and inserting high-quality images with automatic photographer attribution into local projects.321MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hanoak/unsplash-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server