Understand your images. Locally. No uploads. No API keys.
Semantic search · Perceptual hashing · Metadata analysis · Safe trash · Extensible agent runtime
Every image tool does one thing.
- dupeGuru finds duplicates but can't search by content.
- exiftool reads metadata but can't compare images.
- CLIP-as-service needs a cloud account.
- ImageMagick compares pixels but knows nothing about semantics.
To organize a photo library you need four different tools, each with its own CLI, its own config, and its own way of doing things.
Imago is the one tool that does all of it — and is built to grow.
search-text "a photo of a strawberry" dir=~/Photos
search-img reference.jpg dir=~/Photos
diff photo1.jpg photo2.jpg
meta image.jpg
find-similar ~/Photos threshold=8
trash unwanted.jpg
Everything runs locally. Nothing leaves your machine. No API costs. No privacy violations.
pip install imago
imago view ~/PicturesOr from source:
git clone https://github.com/your-org/imago
cd imago
pip install -e .
imago --help| Capability | Imago | dupeGuru | exiftool | CLIP-as-a-service | ImageMagick |
|---|---|---|---|---|---|
| Semantic search (text → image) | ✅ | ❌ | ❌ | ✅ | ❌ |
| Perceptual hash search | ✅ | ✅ | ❌ | ❌ | ❌ |
| Metadata reading + search | ✅ | ❌ | ✅ | ❌ | ✅ |
| Pixel-level diff heatmap | ✅ | ❌ | ❌ | ❌ | ✅ |
| Near-duplicate grouping | ✅ | ✅ | ❌ | ❌ | ❌ |
| Safe trash (undo delete) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Fully local, zero cloud | ✅ | ✅ | ✅ | ❌ | ✅ |
| Extensible tool architecture | ✅ | ❌ | ❌ | ❌ | ❌ |
| Interactive CLI | ✅ | ✅ | ❌ | ❌ | ❌ |
| LLM planner ready | ✅ | ❌ | ❌ | ❌ | ❌ |
Imago uses a layered agent architecture that separates concerns cleanly:
- CLI parses commands (
view,search-text,diff, …) and routes them through the runtime. - Runtime maintains a registry of all available tools. The executor invokes the right tool with parsed arguments. A
Plannerstub is already in place for future LLM-driven multi-step workflows. - Tools are tiny self-contained modules. Each implements
Tool.execute()and registers itself on import. Adding a new capability means writing one file — no CLI changes, no config, no wiring. - Core algorithms (CLIP embedding, perceptual hashing, metadata parsing, image differencing, similarity grouping, trash management) live in
image_agent/core/. These are pure functions with no dependency on the runtime or CLI. - Infrastructure (config, logging, cache) provides shared services to everything above.
The result: a CLI that grows by addition, not by modification.
graph TB
subgraph CLI["CLI — imago"]
DP[Command Dispatcher]
end
subgraph Runtime["Runtime Layer"]
REG[ToolRegistry]
EXEC[Executor]
PLAN[Planner<br/><i>coming soon</i>]
end
subgraph Tools["Tool Layer — 11 tools"]
T1[search-text / search-img / search-meta]
T2[view / meta / diff]
T3[find-similar]
T4[trash · trash-list · trash-restore · trash-empty]
end
subgraph Core["Core Algorithms"]
C1[CLIP Engine]
C2[phash Engine]
C3[Metadata Reader / Searcher]
C4[Image Differ]
C5[Similarity Grouper]
C6[Trash Manager]
end
subgraph Infra["Infrastructure"]
I1[Config]
I2[Logging]
I3[Cache]
end
DP --> REG
REG --> EXEC
EXEC --> Tools
PLAN --> EXEC
Tools --> Core
Core --> Infra
| Command | Description |
|---|---|
view [dir] |
List all images in a directory with dimensions, format, size |
meta <path> |
Show full EXIF / image metadata |
search-text <query> |
Semantic search by text description using CLIP |
search-meta <key> <value> |
Search images by EXIF metadata field |
search-img <image> |
Find visually similar images using perceptual hashing |
diff <img1> <img2> |
Pixel-level difference heatmap with MSE + phash distance |
find-similar [dir] |
Group near-duplicates in a directory |
trash <path> |
Move to ~/.opencode-trash (safe delete) |
trash-list |
List trashed files |
trash-restore <file> |
Restore from trash |
trash-empty |
Permanently delete all trash |
# Browse a directory
imago view ~/Downloads
# Semantic search — CLIP understands content, not just filenames
imago search-text "a person standing on a beach" dir=~/vacation
# Find images visually similar to a reference
imago search-img reference_product.jpg dir=~/catalog
# Compare two near-identical images
imago diff original.jpg edited.jpg
# Deep metadata dive
imago meta photo.jpg
# Find and group near-duplicates
imago find-similar ~/Pictures threshold=8
# Safe delete with undo
imago trash unwanted.jpg
imago trash-list
imago trash-restore unwanted.jpgAdd a new capability in one file. No CLI changes. No wiring.
# imago/tools/ocr.py
from ..runtime.tool import Tool, ToolParameter
from ..runtime.registry import ToolRegistry
class OcrTool(Tool):
name = "ocr"
description = "Extract text from images"
parameters = [ToolParameter(name="path", type="string")]
def execute(self, path: str = "") -> dict:
# Your OCR logic here
return {"text": "..."}
ToolRegistry.register(OcrTool())Add from .ocr import OcrTool to image_agent/tools/__init__.py. Done.
This architecture makes it trivial to add:
- OCR (Tesseract wrapper)
- Face detection / recognition
- Object detection (YOLO, DETR)
- Reverse image search
- AI captioning
- Video keyframe extraction + analysis
- Web UI (gradio, streamlit)
- Semantic text → image search (CLIP)
- Perceptual hash image search
- EXIF metadata reading + search
- Pixel-level diff with heatmap
- Near-duplicate grouping
- Safe trash management
- OCR tool (Tesseract wrapper)
- Face detection & recognition
- Object detection (YOLO / DETR)
- CLIP-based reverse image search
- AI captioning (BLIP / GIT)
- Video keyframe analysis
- Web UI (gradio)
- LLM planner (multi-step workflows via natural language)
imago/
├── image_agent/
│ ├── cli.py # CLI entry point + command dispatch
│ ├── tools/ # 11 auto-registered tools
│ │ ├── view.py
│ │ ├── metadata.py
│ │ ├── search_image.py
│ │ ├── search_text.py
│ │ ├── compare.py
│ │ ├── similarity.py
│ │ └── trash.py
│ ├── core/ # Algorithm implementations
│ │ ├── clip_engine.py
│ │ ├── phash_engine.py
│ │ ├── image_differ.py
│ │ ├── image_viewer.py
│ │ ├── metadata_reader.py
│ │ ├── metadata_searcher.py
│ │ ├── similarity_grouper.py
│ │ └── trash_manager.py
│ ├── runtime/ # Agent runtime
│ │ ├── tool.py # Tool ABC + ToolParameter
│ │ ├── registry.py # ToolRegistry
│ │ ├── executor.py # Executor
│ │ └── planner.py # Planner stub
│ └── infrastructure/ # Shared services
│ ├── config.py
│ ├── logging.py
│ └── cache.py
├── tests/ # pytest suite (17 tests)
│ ├── test_registry.py
│ ├── test_executor.py
│ └── test_tools.py
├── pyproject.toml
└── README.md
MIT. See LICENSE.
Contributions welcome — see CONTRIBUTING.md and the architecture checklist before opening a PR.