google-image-search — Claude Code skill: what it does, how to install
Searches and downloads images using the Google Custom Search API, scoring candidates with heuristics and LLM selection.
npx skills add glebis/claude-skills --skill google-image-search -a claude-codeWhat google-image-search does
The skill queries Google Custom Search API and ranks retrieved images. It applies scoring based on required terms, excluded words, MIME type, and preferred hosts. Then it passes top candidates to an LLM via OpenRouter to evaluate clarity and relevance for technical readers.
It handles single queries, batch runs from JSON configs, and Obsidian vault enrichment. When pointed at a Markdown note, the script extracts visual terms, downloads matching images into the vault attachments folder, and embeds them directly under headings. A backup copy is created before editing the note.
Setup requires Google Custom Search credentials and an OpenRouter API key in .env. You also need the llm CLI installed at /opt/homebrew/bin/llm. If the llm-openrouter plugin fails to find OPENROUTER_KEY, image selection falls back silently to keyword scoring.
What it helps with
- find technical illustrations for articles and slide decks
- enrich Obsidian markdown notes with images placed below headings
- generate batch search JSON configs from plain term lists
- filter out clipart and low-quality hosts using scoring rules
Example prompts for the agent
- Find and download 5 images for query "neural interface wearable device" into ./images
- Generate an image search config from terms "AlterEgo wearable", "sEMG electrodes", and "BCI headset"
- Enrich my Obsidian note at research/neural-interfaces.md with relevant images
How to install google-image-search
1Skills CLI (Vercel)
npx skills add glebis/claude-skills --skill google-image-search -a claude-code2Manually: put the files in place
~/.claude/skills/google-image-search/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/google-image-search/
1Skills CLI (Vercel)
npx skills add glebis/claude-skills --skill google-image-search -a codex2Manually: put the files in place
.agents/skills/google-image-search/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add glebis/claude-skills --skill google-image-search -a cursor2Manually: put the files in place
.cursor/skills/google-image-search/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install glebis/claude-skills google-image-search2Manually: put the files in place
.github/skills/google-image-search/SKILL.md1Skills CLI (Vercel)
npx skills add glebis/claude-skills --skill google-image-search -a gemini-cli2Platform CLI
gemini skills install https://github.com/glebis/claude-skills --path google-image-searchManually: put the files in place
.devin/skills/google-image-search/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add glebis/claude-skills --skill google-image-search -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about google-image-search
How to install google-image-search in Claude Code?
Run npx skills add glebis/claude-skills --skill google-image-search -a claude-code in your terminal.
What does google-image-search do?
It queries the Google Custom Search API, scores images using heuristics and LLM evaluation, and downloads selected files. It can also insert downloaded visuals directly into Obsidian notes.
What prerequisites are needed to run image selection?
You need Google Custom Search credentials and an OpenRouter key in .env, plus the llm CLI at /opt/homebrew/bin/llm. Without OpenRouter, the tool relies strictly on keyword scoring.
Source text
SKILL.md · MIT
---
name: google-image-search
description: Search and download images via Google Custom Search API with LLM-powered selection. This skill should be used when finding images for articles, presentations, research documents, or enriching Obsidian notes with relevant visuals. Supports simple queries, batch processing from JSON config, automatic config generation from terms, and full note enrichment with automatic image insertion below headings.
---
# Google Image Search Skill
Search for images using Google Custom Search API with intelligent scoring and LLM-based selection.
## When to Use
- Finding images to illustrate technical articles or research
- Adding visuals to presentations
- Enriching Obsidian notes with relevant images
- Batch image search for multiple topics
- Generating image search configs from plain text lists
## Requirements
- Google Custom Search API key and Search Engine ID
- OpenRouter API key (for LLM selection)
- llm CLI installed at `/opt/homebrew/bin/llm`
Store credentials in `.env`:
```
Google-Custom-Search-JSON-API-KEY=your_key
Google-Custom-Search-CX=your_cx
OPENROUTER-API-KEY=your_openrouter_key
```
(The `OPENROUTER_API_KEY=...` spelling works too — see the plugin note below.)
### OpenRouter / llm-openrouter caveat
The `llm-openrouter` plugin only registers its models when it can read a key named
`OPENROUTER_KEY` (env var or `llm keys set openrouter`). With only
`OPENROUTER_API_KEY` set, `llm models list` shows **zero** OpenRouter models and every
`openrouter/...` name fails with `Unknown model` — the script then silently falls back to
keyword scoring. `llm_select.py` sets both names for the subprocess, so this is handled;
if selection ever regresses, check `OPENROUTER_KEY` first:
```bash
llm models list | grep -c openrouter # 458+ means the plugin registered its models
```
## Modes of Operation
### 1. Simple Query
Search for a single term:
```bash
python3 ~/.claude/skills/google-image-search/scripts/google_image_search.py \
--query "neural interface wearable device" \
--output-dir ./images \
--num-results 5
```
### 2. Batch Processing
Process multiple queries from JSON config:
```bash
python3 ~/.claude/skills/google-image-search/scripts/google_image_search.py \
--config image_queries.json \
--output-dir ./images \
--llm-select
```
### 3. Generate Config from Terms
Create JSON config from a list of terms using LLM:
```bash
python3 ~/.claude/skills/google-image-search/scripts/google_image_search.py \
--generate-config \
--terms "AlterEgo wearable" "sEMG electrodes" "BCI headset" \
--output my_queries.json
```
### 4. Enrich Obsidian Note
Extract visual terms from note, find images, and insert below headings:
```bash
python3 ~/.claude/skills/google-image-search/scripts/google_image_search.py \
--enrich-note ~/Brains/brain/Research/neural-interfaces.md
```
This mode:
1. Detects Obsidian vault and attachments folder
2. Uses LLM to extract visual-worthy terms from note
3. Searches for images for each term
4. Downloads best images to attachments folder
5. Inserts image embeds below relevant headings
6. Creates backup before modifying note
## Key Options
| Option | Description |
|--------|-------------|
| `--query TEXT` | Simple single query |
| `--config FILE` | JSON config for batch |
| `--generate-config` | Generate config from `--terms` |
| `--enrich-note FILE` | Enrich Obsidian note |
| `--output-dir DIR` | Where to save images |
| `--urls-only` | Return URLs only, no download |
| `--llm-select` | Use LLM to pick best image (default: on) |
| `--no-llm-select` | Disable LLM selection |
| `--num-results N` | Results per query (default: 5) |
| `--dry-run` | Show what would be done |
## JSON Config Format
Each entry supports:
```json
{
"id": "unique-id",
"heading": "Display Heading",
"description": "Context for what image to find",
"query": "Google search query",
"numResults": 5,
"selectionCriteria": "What makes a good image",
"requiredTerms": ["must", "have"],
"optionalTerms": ["bonus", "terms"],
"excludeTerms": ["stock", "clipart"],
"preferredHosts": ["official-site.com"],
"selectionCount": 2
}
```
See `references/api_config_reference.md` for full documentation.
## Scoring System
Images are scored based on:
- **Required terms**: -80 if missing, +30 if all present
- **Optional terms**: +5 per match
- **Exclude terms**: -50 per match
- **Preferred hosts**: +25 if trusted, -5 if unknown
- **MIME type**: +5 for PNG/JPEG, -10 for GIF
- **Resolution**: +10 for high res, -10 for low res
- **File size**: -5 if very small
## LLM Selection
After scoring, LLM picks the best image from top candidates based on:
- Title and URL metadata
- Scoring reasons
- Selection criteria
The LLM evaluates authenticity, clarity, and relevance for technical audiences.
## Obsidian Integration
When in an Obsidian vault:
- Auto-detects vault root via `.obsidian` folder
- Uses configured attachments folder (default: `Attachments`)
- Generates Obsidian-style embeds: `![[image.png|alt text]]`
- Creates backup before modifying notes
## Script Files
| File | Purpose |
|------|---------|
| `google_image_search.py` | Main entry point |
| `api.py` | Google Custom Search API |
| `config.py` | Credentials and config handling |
| `download.py` | Image download with magic bytes |
| `evaluate.py` | Keyword-based scoring |
| `llm_select.py` | LLM selection and term extraction |
| `obsidian.py` | Vault detection and enrichment |
| `output.py` | Markdown output generation |
© glebis · MIT · glebis/claude-skills