Skip to main content
Glama
Pexafy

Pexafy MCP Server

Official

Search photos by example image

search_photos_by_image
Read-onlyIdempotent

Search royalty-free stock photos by providing an example image. Refine visual similarity with a natural-language description, such as 'same scene but at night' or 'with hands raised'.

Instructions

Find visually similar stock photos from an EXAMPLE IMAGE, optionally TWEAKED with words. This is the right tool for 'find photos LIKE THIS but ' (e.g. 'like this but with their hands raised', 'the same scene but at night'). Give the reference image one of three ways: (1) image_url — a public http(s) link: a photo from a PREVIOUS search result (reuse its image_url/urls.regular), or any public URL the user provides; (2) image_file — auto-filled by the host when the user UPLOADS an image (e.g. ChatGPT) — it is populated by the host, not by the caller; (3) image_base64 — raw base64 image bytes, for a programmatic client that already holds the file. A chat assistant has no access to the exact bytes of an image it was shown, so image_base64 is not available to it. Put any change in q; raise text_alpha to weight the text more. If the reference image has no URL and the host did not auto-provide image_file (e.g. a file pasted into a chat that can't be forwarded), you cannot send it — describe what you see and use search_photos instead. Every result carries an attribution you show.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qNoYour search query as a full natural-language sentence describing the scene you want — Pexafy is semantic, so sentences beat keywords. Up to 500 characters. Optional if you provide at least one filter instead. Example: 'an old man sitting at a café table he has visited every morning for thirty years'.
cursorNoToken to fetch the next page. Take `pagination.next_cursor` from a previous response and pass it back here — no need to re-upload the image. See the Pagination guide.
sourceNoKeep only photos from these providers: Unsplash, Pexels, Pixabay, Kaboompics, Burst, StockSnap, Picjumbo, Skitterphoto, NegativeSpace. Repeat the parameter to pass several.
image_urlNoPublic http(s) URL of the reference image. Reuse the `image_url` of a photo from a previous search result, or any public URL the user provides.
after_dateNoOnly return photos published on or after this date, formatted YYYY-MM-DD.
color_nameNoKeep only photos whose dominant color matches one of: red, orange, yellow, green, blue, purple, pink, brown, black, white, gray, teal, beige, gold, navy. Cannot be combined with color_hex.
image_fileNoFilled in by the host when the user uploads an image, not by the caller. Carries the upload's `download_url` and `file_id`.
text_alphaNoBalance between your text and the image when both are provided, from `0` to `10`. `0` ignores the text (pure visual search), `1.7` (the default) is balanced, and higher values give your words more weight. Has no effect without `q`.
orientationNoKeep only photos with these shapes: landscape, portrait, square. Repeat the parameter to pass several.
image_base64NoThe reference image as base64 bytes, optionally as a `data:` URL. For a client that already holds the bytes; prefer `image_url` when a link exists.
license_typeNoKeep only photos with these license types: free, cc0. 'free' means the photo can be used freely and attribution is appreciated. Repeat the parameter to pass several.
photographerNoOnly return photos from this photographer's exact username.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataNo
metaNo
errorNo
successNo
paginationNo

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed19 schema fields changedv0.4.9
    • addedInput schema / properties / after_date / description
      Added value: +"Only return photos published on or after this date, formatted YYYY-MM-DD."
    • addedInput schema / properties / color_name / description
      Added value: +"Keep only photos whose dominant color matches one of: red, orange, yellow, green, blue, purple, pink, brown, black, white, gray, teal, beige, gold, navy. Cannot be combined with color_hex."
    • addedInput schema / properties / cursor / description
      Added value: +"Token to fetch the next page. Take `pagination.next_cursor` from a previous response and pass it back here — no need to re-upload the image. See the Pagination guide."
    • addedInput schema / properties / image_base64 / description
      Added value: +"The reference image as base64 bytes, optionally as a `data:` URL. For a client that already holds the bytes; prefer `image_url` when a link exists."
    • addedInput schema / properties / image_file / additionalProperties
      Added value: +false
    • removedInput schema / properties / image_file / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / image_file / default
      Removed value: -null
    • addedInput schema / properties / image_file / description
      Added value: +"Filled in by the host when the user uploads an image, not by the caller. Carries the upload's `download_url` and `file_id`."
    • addedInput schema / properties / image_file / properties
      Added value: +{
      +  "download_url": {
      +    "type": "string"
      +  },
      +  "file_id": {
      +    "type": "string"
      +  },
      +  "file_name": {
      +    "type": "string"
      +  },
      +  "mime_type": {
      +    "type": "string"
      +  }
      +}
    • addedInput schema / properties / image_file / required
      Added value: +[
      +  "download_url",
      +  "file_id"
      +]
    • addedInput schema / properties / image_file / type
      Added value: +"object"
    • addedInput schema / properties / image_url / description
      Added value: +"Public http(s) URL of the reference image. Reuse the `image_url` of a photo from a previous search result, or any public URL the user provides."
    • addedInput schema / properties / license_type / description
      Added value: +"Keep only photos with these license types: free, cc0. 'free' means the photo can be used freely and attribution is appreciated. Repeat the parameter to pass several."
    • addedInput schema / properties / orientation / description
      Added value: +"Keep only photos with these shapes: landscape, portrait, square. Repeat the parameter to pass several."
    • addedInput schema / properties / photographer / description
      Added value: +"Only return photos from this photographer's exact username."
    • addedInput schema / properties / q / description
      Added value: +"Your search query as a full natural-language sentence describing the scene you want — Pexafy is semantic, so sentences beat keywords. Up to 500 characters. Optional if you provide at least one filter instead. Example: 'an old man sitting at a café table he has visited every morning for thirty years'."
    • addedInput schema / properties / source / description
      Added value: +"Keep only photos from these providers: Unsplash, Pexels, Pixabay, Kaboompics, Burst, StockSnap, Picjumbo, Skitterphoto, NegativeSpace. Repeat the parameter to pass several."
    • addedInput schema / properties / text_alpha / description
      Added value: +"Balance between your text and the image when both are provided, from `0` to `10`. `0` ignores the text (pure visual search), `1.7` (the default) is balanced, and higher values give your words more weight. Has no effect without `q`."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "data": {
      +      "items": {
      +        "description": "A photo result. Fields returned can be narrowed with the `fields` parameter and may depend on your plan.",
      +        "properties": {
      +          "alt_description": {
      +            "description": "Accessibility-friendly text.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "attribution": {
      +            "description": "Ready-to-display credit for the photographer/source.",
      +            "properties": {
      +              "html": {
      +                "description": "HTML attribution snippet.",
      +                "type": "string"
      +              },
      +              "plain": {
      +                "description": "Plain-text attribution.",
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "blur_hash": {
      +            "description": "BlurHash placeholder string.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "color_hex": {
      +            "description": "Dominant color hex code.",
      +            "type": "string"
      +          },
      +          "color_name": {
      +            "description": "Dominant color name.",
      +            "type": "string"
      +          },
      +          "description": {
      +            "description": "AI-generated caption.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "height": {
      +            "type": [
      +              "integer",
      +              "null"
      +            ]
      +          },
      +          "image_url": {
      +            "description": "Canonical source image URL.",
      +            "format": "uri",
      +            "type": "string"
      +          },
      +          "license_type": {
      +            "description": "License type (e.g. `free`).",
      +            "type": "string"
      +          },
      +          "orientation": {
      +            "enum": [
      +              "landscape",
      +              "portrait",
      +              "square"
      +            ],
      +            "type": "string"
      +          },
      +          "photo_id": {
      +            "description": "Unique Pexafy identifier (UUID).",
      +            "type": "string"
      +          },
      +          "photographer_full_name": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "photographer_url": {
      +            "format": "uri",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "photographer_username": {
      +            "type": "string"
      +          },
      +          "relevance_score": {
      +            "description": "Match score 0–1 (higher is better). Only on search results.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "source": {
      +            "description": "Provider (e.g. `Pexels`, `Unsplash`, `Pixabay`).",
      +            "type": "string"
      +          },
      +          "source_description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "source_image_url": {
      +            "description": "URL of the photo's page on the provider.",
      +            "format": "uri",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "uploaded_on": {
      +            "description": "Publication date (YYYY-MM-DD).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "urls": {
      +            "description": "Ready-to-use image links in five sizes.",
      +            "properties": {
      +              "full": {
      +                "format": "uri",
      +                "type": "string"
      +              },
      +              "large": {
      +                "format": "uri",
      +                "type": "string"
      +              },
      +              "regular": {
      +                "format": "uri",
      +                "type": "string"
      +              },
      +              "small": {
      +                "format": "uri",
      +                "type": "string"
      +              },
      +              "thumb": {
      +                "format": "uri",
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "width": {
      +            "type": [
      +              "integer",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "error": {
      +      "anyOf": [
      +        {
      +          "properties": {
      +            "code": {
      +              "description": "Machine-readable error code (e.g. `MISSING_PARAMS`, `PHOTO_NOT_FOUND`).",
      +              "type": "string"
      +            },
      +            "message": {
      +              "description": "Human-readable error message.",
      +              "type": "string"
      +            },
      +            "request_id": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "code",
      +            "message"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "meta": {
      +      "properties": {
      +        "request_id": {
      +          "description": "Unique id for this request (quote it in support tickets).",
      +          "type": "string"
      +        },
      +        "took_ms": {
      +          "description": "Server processing time in milliseconds.",
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "pagination": {
      +      "anyOf": [
      +        {
      +          "properties": {
      +            "has_more": {
      +              "description": "Whether another page exists.",
      +              "type": "boolean"
      +            },
      +            "next_cursor": {
      +              "description": "Pass back as `cursor` for the next page; `null` when `has_more` is false.",
      +              "type": [
      +                "string",
      +                "null"
      +              ]
      +            },
      +            "per_page": {
      +              "description": "Number of items per page.",
      +              "type": "integer"
      +            }
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "success": {
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object",
      +  "x-fastmcp-top-level-schema": "PhotoListResponse"
      +}
  2. First observedv0.2.0

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly and idempotent, so the description doesn't need to repeat that. It adds meaningful context beyond annotations: the image_file is host-populated rather than caller-set, image_base64 is unavailable to chat assistants, and every result carries an attribution to display. 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every section earns its place—it covers usage, input methods, edge cases, and attribution. The numbered list of image-providing options is clear and well-structured. It could be slightly trimmed, but the density is justified by the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the 12 parameters, 100% schema coverage, and an output schema, the description provides all necessary behavioral context: how to provide the reference image, the host-filling behavior of image_file, the text weighting mechanism, and the fallback to search_photos. It also mentions the attribution requirement from results, which is not in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents each parameter. The description adds practical nuance beyond the schema, such as how text_alpha weights text against image, and the guidance to put any modification in q. This exceeds the baseline for fully covered schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool finds visually similar stock photos from an example image, optionally tweaked with words. It explicitly distinguishes from siblings by providing a usage scenario ('find photos LIKE THIS but <change>') and names the alternative (search_photos) when the image can't be sent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance with examples and a concrete fallback: when the image has no URL and no auto-provided file, use search_photos instead. It also explains the three ways to supply the reference image and which is appropriate for different clients.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Latest Blog Posts

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/Pexafy/pexafy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server