Skip to content
Back to skills

Image Fetcher

ASecurity

Fetch relevant, high-quality, free-to-use images from the web. Accepts a description/query, or scans the current directory for context. Sources from Unsplash, Pexels, and Pixabay APIs (if keys configured) with a zero-config WebSearch fallback.

  • 10 stars
  • 0 votes
  • 1 copy
  • 2 views
  • Added May 26, 2026
toolsrustgobashapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add sacredvoid/skillkit --skill image-fetcher --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Image Fetcher?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Image Fetcher
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sacredvoid-image-fetcher/badge)](https://www.skillsdirectory.com/skills/sacredvoid-image-fetcher)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: image-fetcher
description: "Fetch relevant, high-quality, free-to-use images from the web. Accepts a description/query, or scans the current directory for context. Sources from Unsplash, Pexels, and Pixabay APIs (if keys configured) with a zero-config WebSearch fallback."
argument-hint: "[description of images needed, e.g. 'hero image for a coffee shop website']"
disable-model-invocation: true
allowed-tools: Bash, Read, Write, Glob, Grep, WebSearch, WebFetch, AskUserQuestion
---

# Image Fetcher

Fetch relevant, free-to-use images from the web for any project context.

## Config

Read config from `~/.claude/skills/image-fetcher/config.json`:

```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:

```bash
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:
> 1. "minimalist coffee shop interior"
> 2. "coffee beans close-up warm tones"
> 3. "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)

```bash
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 description
- `results[].width`, `results[].height` — dimensions
- `results[].user.name` — photographer name
- `results[].links.html` — source page URL

### Source 2: Pexels API (if `pexels_key` is set and non-empty)

```bash
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 URL
- `results[].alt` — image description
- `results[].width`, `results[].height` — dimensions
- `results[].photographer` — photographer name
- `results[].url` — source page URL

### Source 3: Pixabay API (if `pixabay_key` is set and non-empty)

```bash
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 URL
- `hits[].tags` — image description
- `hits[].imageWidth`, `hits[].imageHeight` — dimensions
- `hits[].user` — photographer name
- `hits[].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:

1. Create the output directory if it doesn't exist:
```bash
mkdir -p ./OUTPUT_DIR
```

2. 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`

3. Download with curl:
```bash
curl -sL "IMAGE_URL" -o "./OUTPUT_DIR/FILENAME"
```

4. Verify the download:
```bash
file "./OUTPUT_DIR/FILENAME"
```
Confirm it's a valid image file (not an HTML error page).

5. 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.json` for 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.

Files in this skill

  • SKILL.md8.8 KB
  • config.json121 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.