Unsplash MCP Server

by hellokaton
Verified
# -*- coding: utf-8 -*- #!/usr/bin/env python3 import os from dataclasses import dataclass from typing import Optional, List, Dict import httpx from dotenv import load_dotenv from fastmcp import FastMCP # Load environment variables load_dotenv() # Create an MCP server mcp = FastMCP("Unsplash MCP Server") @dataclass class UnsplashPhoto: id: str description: Optional[str] urls: Dict[str, str] width: int height: int @mcp.tool() async def search_photos( query: str, page: int = 1, per_page: int = 10, order_by: str = "relevant", color: Optional[str] = None, orientation: Optional[str] = None ) -> List[UnsplashPhoto]: """ Search for Unsplash photos Args: query: Search keyword page: Page number (1-based) per_page: Results per page (1-30) order_by: Sort method (relevant or latest) color: Color filter (black_and_white, black, white, yellow, orange, red, purple, magenta, green, teal, blue) orientation: Orientation filter (landscape, portrait, squarish) Returns: List[UnsplashPhoto]: List of search results containing photo objects with the following properties: - id: Unique identifier for the photo - description: Optional text description of the photo - urls: Dictionary of available image URLs in different sizes - width: Original image width in pixels - height: Original image height in pixels """ access_key = os.getenv("UNSPLASH_ACCESS_KEY") if not access_key: raise ValueError("Missing UNSPLASH_ACCESS_KEY environment variable") params = { "query": query, "page": page, "per_page": min(per_page, 30), "order_by": order_by, } if color: params["color"] = color if orientation: params["orientation"] = orientation headers = { "Accept-Version": "v1", "Authorization": f"Client-ID {access_key}" } try: async with httpx.AsyncClient() as client: response = await client.get( "https://api.unsplash.com/search/photos", params=params, headers=headers ) response.raise_for_status() data = response.json() return [ UnsplashPhoto( id=photo["id"], description=photo.get("description"), urls=photo["urls"], width=photo["width"], height=photo["height"] ) for photo in data["results"] ] except httpx.HTTPStatusError as e: print(f"HTTP error: {e.response.status_code} - {e.response.text}") raise except Exception as e: print(f"Request error: {str(e)}") raise