# Photo Geolocation

Geolocates or dates a photo with metadata, OCR and reverse image search clues.

- Repository: https://github.com/Oldcircle/geo-sleuth (5249 stars)
- Category: AI and agents
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: yes, review before use

## Install

Claude Code: `npx skills add Oldcircle/geo-sleuth --skill geo-sleuth -g -a claude-code -y`
Codex: `npx skills add Oldcircle/geo-sleuth --skill geo-sleuth -g -a codex -y`
Cursor: `npx skills add Oldcircle/geo-sleuth --skill geo-sleuth -g -a cursor -y`
Gemini CLI: `npx skills add Oldcircle/geo-sleuth --skill geo-sleuth -g -a gemini-cli -y`

## Description

Geolocate or chronolocate a photo with tool-verified reasoning (where was this taken / when was it taken / photo geolocation / geo-guessing). Given one or more photos, intake.py does metadata, OCR and reverse image search (Baidu/Yandex) in one command; clues and candidates go on a candidate board (board.py) that ranks them and gives the next step; clues.py looks up calling codes, driving side, plates and area codes from region packs; for satellite and street view the machine ranks first and you look only at the top few (CLIP in sat_scan.py, DINOv2+SIFT in match.py); plus sun and shadow math, OSM Overpass and DEM skylines. Every conclusion is checked against real data; output is coordinates + error radius, evidence images and tiered confidence. Use when the user shares a photo and asks where was this taken / geolocate this / when was this taken / 这是哪 / 在哪拍的 / 帮我定位这张照片 / 网络迷踪 / 图寻 / 几点拍的.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# geo-sleuth (v2)

Goal: find a location that **holds up under checking**. Every conclusion must point to the clue it used, the command it ran and the file it produced.

> `${CLAUDE_SKILL_DIR}` in commands means the directory containing this SKILL.md (the same for commands in references). Claude Code substitutes it automatically; in other agents, first `export CLAUDE_SKILL_DIR=<absolute path of this directory>` before running (if the shell doesn't keep variables between commands, prefix every command with it), or replace it with that path directly.

The work is split into three layers. Remember this first, then read the flow:

| Layer | Who | Tools |
|---|---|---|
| Decision: which candidates exist, how evidence is scored, whether a candidate can be excluded, what to scan next | **Script** (candidate board) | `board.py` |
| Perception: reading text, table lookups, finding targets in satellite imagery, street-view matching | **Scripts compute and rank first; you look only at the top few** | `intake.py` `ocr.py` `clues.py` `sat_scan.py` `match.py` `geo.py bearings` |
| Judgment: pulling clues out of the image, proposing hypotheses when the tables have nothing, deciding among the machine's top few | **You** |, |

The method comes from breaking down 14 photo-geolocation (网络迷踪) creator videos and 22 puzzles, plus several rounds of blind-test comparisons; the breakdown notes are not published with the repo. The lesson of v1: rules written as prose don't get executed, and two runs of the same skill version gave very different results; so v2 puts every rule that can be written as code into `board.py`.

## Hard rules (always in force; ★ = enforced by board.py, just follow it)

The rest: https://github.com/Oldcircle/geo-sleuth/blob/HEAD/skills/geo-sleuth/SKILL.md
