geo-sleuth skill
A skill that finds where a photo without GPS was taken from terrain, OpenStreetMap, satellite and street view, and shows the files behind each claim
- 4,480 ★ on the repository
- Last commit
- MIT
Broad access
Why this level
- Runs about twenty Python scripts through uv and drives Chrome or Chromium, and ML packages and model weights are downloaded on first run
- Reverse image search hands the photo to Baidu and Yandex, and the other scripts call OpenStreetMap and panorama services
- A dual-use tool: it locates a place from a photo, including someone else's, so personal photos and frames with people require permission
Install
- Works in
Manual install
npx skills add Oldcircle/geo-sleuthPick agents in the prompt. Requires Python 3.10 or newer, uv, curl and Chrome or Playwright Chromium.
Access and checks
How we reviewBroad accessThe tool can change data, run commands or handle secrets.
- Runs about twenty Python scripts through uv and drives Chrome or Chromium, and ML packages and model weights are downloaded on first run
- Reverse image search hands the photo to Baidu and Yandex, and the other scripts call OpenStreetMap and panorama services
- A dual-use tool: it locates a place from a photo, including someone else's, so personal photos and frames with people require permission
This is third-party code. Review the repository files before installing.
What it does
geo-sleuth works out where a photo was taken from the frame itself, when it has no signs, plates or famous buildings. One `intake.py` run reads the EXIF metadata, recognizes text, cuts out the frame edges and starts a reverse image search on Baidu and Yandex. The results go to a candidate board kept by `board.py`: it stores clues, scores each hypothesis, refuses to exclude a candidate without a computed file and suggests the next step. The agent then picks a branch by what the photo shows. `sun.py` handles shadows and lit faces, `terrain.py` matches the horizon and mountain line against elevation data, and `osm.py` finds power lines, railways and bridges in OpenStreetMap. The CLIP model in `sat_scan.py` ranks satellite tiles against a description. To confirm a spot, `gsv.py` and `baidu_pano.py` find street panoramas and `match.py` compares them with the photo using DINOv2 and SIFT. The skill has about twenty scripts, one job each: scripts rank and the model chooses among the best few. `evidence.py` assembles the result: coordinates with an error radius, the camera heading, a satellite image with the field-of-view fan and a graded confidence. Every claim in the report has to point at a command run in that session and the file it produced. Without such a link the skill requires writing "unverified". Fame and population do not count as evidence.
Who it is for. For journalists, open-source researchers and geo-guessing hobbyists who want Claude Code, Codex or Cursor to locate a place verifiably on their own photos or on photos they have permission to analyze.
Good fit when
- You need to find where your own frame without GPS metadata was shot and attach a satellite evidence image to the answer
- The photo shows a mountain range, a power line or a railway bridge but no text
- The frame has a row of identical piers or spans whose spacing can fix the shooting point
- You want a report rather than a guess, where every conclusion has a command and a file, so you can see where the reasoning turned wrong
- You solve location puzzles and want terrain, shadows and street panoramas wired into the search
Not a fit when
- The photo is not yours and you lack permission to analyze it: the author asks not to look for people who have not agreed to be found
- The photo shows a private home or minors: the skill itself asks you for the purpose, and without a lawful reason it is better not to run it
- You need a quick answer with no setup: the scripts require Python 3.10 or newer, uv, curl and Chrome or Chromium
- You only want to read geotags from EXIF: an ordinary metadata viewer is enough and the skill is much heavier
Example request
Find where this photo was taken: no metadata, no text, a mountain in the distance and a railway bridgeLimitations
- Use the skill only on photos you have permission to analyze. The author asks not to use it to find people who have not agreed to be found, and when a private home or children appear in the photo the skill asks once about the purpose.
- The README gives accuracy for three worked cases: from 2 to 100 meters. The author calls the end-to-end re-runs regression checks, because both photos were solved before and the lessons already went into the skill. Accuracy on unseen photos is not measured, and a public test set is still on the roadmap.
- A result is recorded for one model in one run. The model decides which queries to write and how many top options to inspect, so another model may not reproduce the answer.
- The scripts query OpenStreetMap and panorama services over the network, and no OSM data ships in the repository. Reverse search goes through a browser, and on a 403, a 429 or a CAPTCHA the author advises checking the saved screenshot and retrying later or working by hand.
- The first run pulls dependencies through uv, and `match.py` and `sat_scan.py` download model weights, so it takes time and disk space. Instructions, help and reports in the skill are in English, and source text from the frame stays in its original language.
How to disable. Delete the `geo-sleuth` folder from the agent's skills directory: `~/.agents/skills/` for Codex, Cursor, Gemini CLI, OpenCode and GitHub Copilot, `~/.claude/skills/` for Claude Code. If you installed it with `npx skills add`, the same tool can remove it. Delete the `intake` and `rev` working folders the scripts created next to the photo by hand.
FAQ
How do I find where a photo was taken with no GPS and no signs?
The skill builds the search from the geometry of the frame. The spacing of identical bridge piers gives a ruler, a shadow sets a bearing, and the ridge line works as a fingerprint matched against elevation data. `terrain.py` uses them to select points and one is left. In the worked example with a rice paddy and a viaduct this fixed the camera to about 2 meters.
How is geo-sleuth different from reading EXIF?
`exif.py` reads EXIF, but only as one clue: the skill treats metadata and hints as hypotheses and trusts the frame when they conflict. The main work starts where there are no geotags and consists of reading the frame, searching the map and matching panoramas.
Does geo-sleuth need a key or an account?
The documentation asks for no keys or accounts. You need Python 3.10 or newer, uv, curl and Chrome or Playwright Chromium. Data comes from OpenStreetMap, AWS Terrain elevation tiles and satellite tiles, and panoramas come from Google Street View and Baidu.
What if reverse image search returns a 403 or a CAPTCHA?
Open the saved screenshot, retry later or search by hand in a browser. `intake.py` with the `--no-rev` flag runs without reverse search and checks only metadata, image preparation and text recognition. The author does not treat a failed search as proof that no matching image exists.
Why did the skill write "unverified" instead of coordinates?
An error radius of up to 100 meters is allowed only with the intersection of two independent constraints or a match of three invariant features at ground level. If the required commands were not run in the session, the skill requires marking the conclusion unverified and giving a range with the missing information.
Discussion
No questions or reviews yet.
Related
SkillsA skill for web search, X search and page fetching for models without web access: no signup or key, the answer is JSON with source links
A web research skill: SearXNG searches, Camofox reads pages and CloakBrowser opens sites that check their visitors
A skill for collecting business data from Google Maps: the agent plans queries, runs a local scraper and helps with the results
The news-extractor skill pulls the title, text, images and metadata from a link on 12 news platforms and returns JSON or Markdown, with no browser
A skill that routes a question to the right AI platform and, via browser automation, collects the answer from its native search
Ozon shopper skill
Ozon Shopper
A skill for searching Ozon products with seller checks, spec validation and scam detection against a red-flag checklist
README in short
The repository holds the skill itself: a SKILL.md file, about twenty Python scripts, reference notes on clues, geometry, sky and search, lookup tables of calling codes, driving side and territories, and region packs. The front page walks through three cases with answers in meters, a table of scripts and per-operation measurements. Installation for six agents, requirements and a troubleshooting table are described separately. The examples folder has scripts for two of the solved photos, and issue templates cover reports of wrong results.