Stocky is a Model Context Protocol (MCP)-based server that lets AI assistants search, view, and download royalty-free stock photos from Pexels and Unsplash. It is invoked through natural language, with no need to manually operate the API.
Purpose: Stocky is intended for AI assistant scenarios where high-quality royalty-free images are needed for projects. Users can describe their needs in natural language, for example "search for photos of misty pine forests at dawn" or "find 30 landscape-oriented mountain photos from Pexels," and the AI client will call the tools provided by Stocky to complete the search and download.
Main capabilities:
- Concurrent search across multiple providers: queries Pexels and Unsplash at the same time, returns results grouped by provider, and includes total_results; if a provider fails, an errors mapping is returned explaining the reason.
- Rich metadata: each image includes dimensions, photographer, tags, and all available sizes.
- Licensing and attribution: generates attribution information according to each provider's requirements. Pexels requires a prominent link to Pexels when displaying API results, and attribution to the photographer whenever possible; Unsplash requires attribution to both the photographer and Unsplash, links must include UTM parameters, and images should be hotlinked using the URLs returned by the API rather than re-hosted. When ENABLE_ATTRIBUTION_LINKS=true is set, each result includes a properly formatted attribution block (text and HTML).
- Search caching: a short TTL cache avoids consuming quota on repeated queries.
- Honest errors: failed providers are clearly reported rather than silently returning "no results."
- Filtering: supports orientation, color, and sorting, validated per provider. Invalid orientation or color is discarded rather than forwarded, because Pexels silently ignores invalid filters and returns 200, while Unsplash directly returns HTTP 400.
Usage:
- Obtain API keys: only one provider needs to be configured to run.
- Add to an MCP client: the recommended configuration requires no installation, and it can also be installed via pip or uv, or run from a source checkout. Stocky reads configuration from the environment in which the client launches it and does not load its own .env file, so keys must be placed in the env block of the client configuration.
- Configuration: it is recommended to set STOCKY_DOWNLOAD_ROOT, restricting the download path to a single directory. Stocky always rejects non-image extensions and verifies before fetching that the image URL returned by the provider is a public HTTP(S) address.
Stocky exposes three MCP tools, which the client invokes when the user makes a natural language request:
- search_stock_images: returns results grouped by provider, along with total_results and errors (if any failed).
- get_image_details: fetches image details; if the provider does not offer the requested size, the closest available size is used.
- download_image: downloads an image; downloading an Unsplash image triggers the mandatory download report endpoint. It also provides the stock-images://help resource, for the assistant to read usage guidance on demand.
Use cases: suitable for AI assistant workflows that need to quickly obtain royalty-free images for tasks such as design, content creation, and presentations.
Limitations and notes:
- Requires at least one provider's API key, and the key must be passed in via the env block configured by the client, with names case-sensitive.
- Version 2.0 requires Python 3.10+, no longer uses pycurl, and installation is changed to uv sync or pip install -e ., with requirements.txt and setup.py removed.
- Downloading Unsplash images to disk or returning base64 conflicts with Unsplash's hotlinking requirement; if displaying images in an application, use the hotlink URL from the search results rather than downloading.
- Pexels also returns 200 for a malformed key, so a misspelled key may appear to work fine, and the key should be verified directly.
- Startup timeouts are usually caused by a minimized PATH in a GUI client, making uvx or the virtual environment python unfindable; use absolute paths or a system-level installed uvx.
- All log output goes to stderr, while stdout is used for protocol communication.