image-fetcher
Use Cautionnpx machina-cli add skill sacredvoid/skillkit/image-fetcher --openclawImage Fetcher
Fetch relevant, free-to-use images from the web for any project context.
Config
Read config from ~/.claude/skills/image-fetcher/config.json:
{
"unsplash_key": "",
"pexels_key": "",
"pixabay_key": "",
"default_count": 5,
"output_dir": "assets/images"
}
All fields are optional. The skill works with zero configuration via the WebSearch fallback.
Load config silently at the start of every invocation:
cat ~/.claude/skills/image-fetcher/config.json 2>/dev/null || echo '{}'
Phase 1: Determine What to Search For
If the user provided input (argument after the skill name), use that directly as the search context. Skip to Phase 2.
If no input was provided, scan the current directory for context signals:
| Source | What to extract |
|---|---|
README.md / README | Project name, description, purpose |
package.json / Cargo.toml / pyproject.toml | Name, description, keywords |
CLAUDE.md | Project conventions, domain |
| HTML/CSS files (first 3) | Page titles, headings, color themes |
Existing images in assets/, public/, static/, images/ | What already exists (to avoid duplicates) |
Use Glob and Read to scan. Build a brief internal context summary:
CONTEXT:
project: [name or "unknown"]
domain: [web app / game / docs / CLI / etc.]
keywords: [extracted keywords]
existing_images: [list of what's already there]
If the directory scan yields nothing useful (empty dir, no descriptive files), use AskUserQuestion:
"What kind of images are you looking for?"
Options:
- Hero/banner images
- Product photos
- Abstract/background textures
- Icons/illustrations
- Other (describe)
Then ask a follow-up for specifics: subject, mood, color preference.
From the context, generate 1-3 concise search queries (e.g., "minimalist coffee shop interior", "abstract tech gradient background").
Present the queries to the user:
Based on your project context, I'll search for:
- "minimalist coffee shop interior"
- "coffee beans close-up warm tones"
- "cozy cafe atmosphere"
Want me to adjust any of these?
Proceed when the user confirms (or adjust if they give feedback).
Phase 2: Fetch Images
Use the first available source from this priority chain:
Source 1: Unsplash API (if unsplash_key is set and non-empty)
curl -s "https://api.unsplash.com/search/photos?query=QUERY&per_page=COUNT&orientation=landscape" \
-H "Authorization: Client-ID UNSPLASH_KEY"
Extract from JSON response:
results[].urls.regular— download URL (good quality, ~1080px wide)results[].alt_description— image descriptionresults[].width,results[].height— dimensionsresults[].user.name— photographer nameresults[].links.html— source page URL
Source 2: Pexels API (if pexels_key is set and non-empty)
curl -s "https://api.pexels.com/v1/search?query=QUERY&per_page=COUNT&orientation=landscape" \
-H "Authorization: PEXELS_KEY"
Extract from JSON response:
results[].src.large— download URLresults[].alt— image descriptionresults[].width,results[].height— dimensionsresults[].photographer— photographer nameresults[].url— source page URL
Source 3: Pixabay API (if pixabay_key is set and non-empty)
curl -s "https://pixabay.com/api/?key=PIXABAY_KEY&q=QUERY&per_page=COUNT&image_type=photo&orientation=horizontal"
Extract from JSON response:
hits[].largeImageURL— download URLhits[].tags— image descriptionhits[].imageWidth,hits[].imageHeight— dimensionshits[].user— photographer namehits[].pageURL— source page URL
Source 4: WebSearch Fallback (zero config, always available)
If no API keys are configured, use WebSearch:
WebSearch: "free stock photo {QUERY} site:unsplash.com OR site:pexels.com OR site:pixabay.com"
From the search results, extract individual photo page URLs (e.g., pexels.com/photo/TITLE-ID/).
Important: Stock sites block WebFetch scraping (return 403). Do NOT attempt to WebFetch individual photo pages. Instead, use known CDN URL patterns to construct direct download URLs:
Pexels CDN Pattern
Extract the numeric photo ID from the Pexels URL (e.g., 417074 from /photo/lake-and-mountain-417074/), then construct:
https://images.pexels.com/photos/{ID}/pexels-photo-{ID}.jpeg?auto=compress&cs=tinysrgb&w=1920
Unsplash CDN Pattern
Extract the photo slug from the Unsplash URL (e.g., abc123 from /photos/abc123), then construct:
https://images.unsplash.com/photo-{SLUG}?w=1920&q=80
Note: Unsplash slugs can be complex. If the direct CDN URL doesn't work, search for individual photo pages on Pexels instead — their CDN pattern is more reliable.
Pixabay
Pixabay CDN URLs are not predictable without the API. If only Pixabay results are found, suggest the user configure a free API key.
If no individual photo URLs are found, try a second search:
WebSearch: "pexels free stock photo {QUERY}"
Collect up to default_count (default 5) image candidates from whatever source was used.
Phase 3: Present Candidates
Present the fetched images to the user in a clear table:
Found 5 images for "minimalist coffee shop interior":
| # | Description | Size | Source | Photographer |
|---|-------------|------|--------|-------------|
| 1 | Cozy cafe with wooden tables and warm lighting | 1920x1280 | Unsplash | John Doe |
| 2 | Modern coffee bar with espresso machine | 1800x1200 | Unsplash | Jane Smith |
| 3 | Minimalist white cafe interior | 2000x1333 | Unsplash | Alex Chen |
| 4 | Coffee shop window seat with natural light | 1920x1080 | Unsplash | Maria Garcia |
| 5 | Rustic coffee house with brick walls | 1600x1067 | Unsplash | Sam Wilson |
Then ask:
AskUserQuestion: "Which images would you like to download?"
Options:
- All of them
- Pick specific ones (enter numbers like 1, 3, 5)
- None — search again with different terms
Phase 4: Download & Save
For each selected image:
- Create the output directory if it doesn't exist:
mkdir -p ./OUTPUT_DIR
-
Generate a descriptive filename from the image description:
- Lowercase, hyphenated, max 50 chars
- Append a number suffix if needed to avoid collisions
- Keep the original file extension (
.jpg,.png,.webp) - Example:
cozy-cafe-warm-lighting-01.jpg
-
Download with curl:
curl -sL "IMAGE_URL" -o "./OUTPUT_DIR/FILENAME"
- Verify the download:
file "./OUTPUT_DIR/FILENAME"
Confirm it's a valid image file (not an HTML error page).
- If the download fails or produces an invalid file, skip it and note the failure.
Phase 5: Summary
Print a final summary:
Downloaded 3 images to ./assets/images/:
1. assets/images/cozy-cafe-warm-lighting-01.jpg (1920x1280, 245 KB)
Source: unsplash.com/photos/abc123 | Photo by John Doe
2. assets/images/modern-coffee-bar-02.jpg (1800x1200, 198 KB)
Source: unsplash.com/photos/def456 | Photo by Jane Smith
3. assets/images/minimalist-white-cafe-03.jpg (2000x1333, 312 KB)
Source: unsplash.com/photos/ghi789 | Photo by Alex Chen
License: Free to use (Unsplash License)
If using Pexels or Pixabay, note attribution requirements:
Note: Pexels license requires attribution. Consider adding credit in your project.
Error Handling
- No API keys and WebSearch returns no usable results: Tell the user to configure at least one API key in
~/.claude/skills/image-fetcher/config.jsonfor better results. Offer to help them get a free key (link to signup pages). - API rate limit hit: Fall back to the next source in the chain.
- Download fails: Skip the image, note it in the summary, continue with others.
- All downloads fail: Report the issue, suggest trying different search terms.
Important Notes
- All image sources used by this skill (Unsplash, Pexels, Pixabay) provide free-to-use images with permissive licenses.
- Unsplash License: Free for commercial and non-commercial use, no attribution required (but appreciated).
- Pexels License: Free for commercial and non-commercial use, attribution not required but appreciated.
- Pixabay License: Free for commercial and non-commercial use, no attribution required.
- The WebSearch fallback specifically targets these three sites to ensure license compliance.
- Never download images from sources with unclear licensing.
Source
git clone https://github.com/sacredvoid/skillkit/blob/main/skills/image-fetcher/SKILL.mdView on GitHub Overview
Image Fetcher automatically finds relevant, free images for your project. It can search by your description or scan your project directory for context, then pull from Unsplash, Pexels, and Pixabay (if keys are configured) or fall back to a WebSearch. This speeds up asset creation while keeping licensing clear.
How This Skill Works
Phase 1 determines what to search for using your input or by analyzing project files for context. Phase 2 fetches images from the first available source in a priority chain (Unsplash, then Pexels, then Pixabay) with a zero-config WebSearch fallback if keys are not set. Outputs include download URLs, alt text, dimensions, photographer name, and source page URL, saved to assets/images.
When to Use It
- Need a hero image for a website or landing page
- Want illustrations or visuals to accompany a blog post
- Building marketing materials with free-to-use visuals
- Creating UI mocks or product visuals for a SaaS or app
- Generating placeholder or background images during design
Quick Start
- Step 1: Provide a description of the needed images, or let the skill scan your project for context
- Step 2: Ensure API keys are configured in ~/.claude/skills/image-fetcher/config.json, or rely on the WebSearch fallback
- Step 3: Run the skill and save results to assets/images (default_count = 5)
Best Practices
- Provide a clear description or let the skill scan project context for accurate results
- Prefer landscape orientation when targeting banners or wide layouts
- Respect licensing: attribute photographers when possible and verify usage rights
- Avoid duplicates by comparing against existing images in assets/ and related folders
- Check and save results to the recommended output_dir: assets/images
Example Use Cases
- Fetch a hero image for a cafe website
- Find abstract textures for a technology landing page
- Collect product photos for an e-commerce mockup
- Acquire landscape images for a travel blog
- Obtain app UI background imagery for a SaaS dashboard