Install
openclaw skills install osint-investigatorClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
Deep OSINT (Open Source Intelligence) investigations. Use when the user wants to research, find, or investigate any person, place, organisation, username, domain, IP address, phone number, image, vehicle, or object using publicly available information. Triggers on phrases like "find information on", "investigate", "look up", "who is", "trace this", "dig into", "OSINT search", "background check", or any request to gather open-source intelligence about a target. Performs deep multi-source analysis across web search, social media, DNS/WHOIS, image search, maps, public records, and more — returning a structured intelligence report.
openclaw skills install osint-investigatorMulti-source open-source intelligence gathering. Identify target type, run all applicable modules, then produce a structured report.
Before running any module, classify the target:
Run ALL applicable modules in parallel. Never stop after one source.
web_search tool)Run at minimum 5–8 targeted queries per target. Vary operators:
"full name" site:linkedin.com
"username" -site:twitter.com
target filetype:pdf
target inurl:profile
"target" "email" OR "contact" OR "phone"
target site:reddit.com
target site:github.com
Follow top URLs with web_fetch to extract full content.
whois <domain>
dig <domain> ANY
dig <domain> MX
dig <domain> TXT
nslookup <domain>
host <domain>
Also fetch: https://rdap.org/domain/<domain> via web_fetch
curl -s https://ipinfo.io/<ip>/json
curl -s https://ip-api.com/json/<ip>
Also check: https://www.shodan.io/host/<ip> via web_fetch
Check all platforms via web_fetch (just check HTTP status + page title — don't need to load full content for existence checks):
https://github.com/<username>https://twitter.com/<username>https://instagram.com/<username>https://reddit.com/user/<username>https://tiktok.com/@<username>https://youtube.com/@<username>https://linkedin.com/in/<username>https://medium.com/@<username>https://pinterest.com/<username>https://twitch.tv/<username>https://steamcommunity.com/id/<username>https://keybase.io/<username>https://t.me/<username> (Telegram)For each confirmed platform profile, use web_fetch to extract:
For Twitter/X: also search web_search for site:twitter.com "<target>" and nitter mirrors.
# Use web_fetch or browser for:
# Google Maps search
https://maps.googleapis.com/maps/api/geocode/json?address=<address>&key=<key>
# Or use goplaces skill if available
# Streetview metadata check
https://maps.googleapis.com/maps/api/streetview/metadata?location=<lat,lng>&key=<key>
Also search: web_search for "<target location>" site:maps.google.com OR site:wikimapia.org OR site:openstreetmap.org
Finding images of a person (no image provided):
web_search for "<name>" site:linkedin.com — LinkedIn og:image often returns profile photo URL directlyhttps://www.gravatar.com/<md5>.jsonweb_search for "<name>" filetype:jpg OR filetype:pngweb_fetch to pull og:image from any confirmed profile pagesReverse image search (image URL or local file provided):
# Direct URL-based reverse search (use web_fetch):
https://yandex.com/images/search?rpt=imageview&url=<image_url>
https://tineye.com/search?url=<image_url>
# Google Lens (requires browser tool):
https://lens.google.com/uploadbyurl?url=<image_url>
# For avatars and profile images — extract URL then feed into:
# 1. Yandex (best for face matching, indexes more than Google)
# 2. TinEye (exact match/copy detection)
# 3. Google Lens via browser tool
EXIF / Metadata extraction (if file is available locally):
exiftool <image> # full metadata dump
exiftool -gps:all <image> # GPS coordinates only
exiftool -DateTimeOriginal <image> # when photo was taken
Online tools: web_fetch https://www.metadata2go.com or https://www.pic2map.com
Photo geolocation (no EXIF GPS):
web_search to identify regionhttps://www.suncalc.org to estimate time & locationbrowser toolWhen searching for a person by image from social media:
web_fetch the profile page and look for og:image or <img> src in the rendered HTML# Breach/exposure check
curl -s "https://haveibeenpwned.com/api/v3/breachedaccount/<email>" -H "hibp-api-key: <key>"
# Format validation + domain MX check
dig $(echo <email> | cut -d@ -f2) MX
# Gravatar (hashed MD5 of email)
curl -s "https://www.gravatar.com/<md5_hash>.json"
Also: web_search for "<email>" site:pastebin.com OR site:ghostbin.com
# Carrier / region lookup
curl -s "https://phonevalidation.abstractapi.com/v1/?api_key=<key>&phone=<number>"
Also: web_search for "<phone_number>" and check site:truecaller.com, site:whitepages.com
Use web_fetch on:
https://opencorporates.com/companies?q=<name>https://find-and-update.company-information.service.gov.uk/search?q=<name>https://linkedin.com/company/<slug>web_search for site:crunchbase.com "<company>"web_search queries:
"<target>" filetype:pdf OR filetype:xlsx OR filetype:docx
"<target>" site:pastebin.com
"<target>" site:github.com password OR secret OR key
"<target>" site:trello.com OR site:notion.so
# Wayback Machine
curl -s "https://archive.org/wayback/available?url=<url>"
web_fetch "https://web.archive.org/web/*/<url>" for snapshots
# Google Cache via web_search: cache:<url>
Always produce a structured report. Adapt sections to what was found:
# OSINT Report: <Target>
**Date:** <UTC timestamp>
**Target Type:** <classification>
**Query:** <original user request>
## Identity Summary
[Key identifying information — name, aliases, age, location, nationality]
## Online Presence
[Confirmed profiles with URLs, follower counts, activity level]
## Contact & Technical
[Email addresses, phone numbers, domains, IPs]
## Location Intelligence
[Known locations, addresses, coordinates, map links]
## Corporate / Organisational Links
[Companies, roles, affiliations]
## Historical Data
[Archived content, old usernames, past locations]
## Document & Data Exposure
[Public documents, paste sites, leak mentions]
## Image Intelligence
[Profile photos, reverse image results, photo metadata]
## Confidence & Gaps
[Confidence level per finding — High/Medium/Low; list gaps]
## Sources
[All URLs consulted]
Config is stored at: <skill_dir>/config/osint_config.json (chmod 600, auto-created on first save).
The agent configures everything conversationally — no terminal script needed. When the user says they want to add credentials, configure PDF output, or set up an API key, follow the flow below.
When the user wants to configure the skill, ask them questions directly in chat and write the answers to the config file yourself using the write tool.
Step 1 — Ask what they want to configure:
"What would you like to set up? I can configure:
- Platform credentials (Instagram, Twitter/X, LinkedIn, Facebook)
- API keys (Google Maps, Shodan, HaveIBeenPwned, Hunter.io, AbstractAPI Phone)
- PDF report output (on/off, save location)"
Step 2 — Collect the values (ask one platform at a time):
Step 3 — Write the config:
# Read existing config (or start fresh)
import json, os
cfg_path = "<skill_dir>/config/osint_config.json"
os.makedirs(os.path.dirname(cfg_path), exist_ok=True)
cfg = json.load(open(cfg_path)) if os.path.exists(cfg_path) else {"platforms": {}, "output": {}}
# Example: save Twitter bearer token
cfg["platforms"]["twitter"] = {"configured": True, "method": "api_key", "bearer_token": "<VALUE>"}
# Example: enable PDF
cfg["output"]["pdf_enabled"] = True
cfg["output"]["pdf_output_dir"] = "~/Desktop"
# Write back
with open(cfg_path, "w") as f:
json.dump(cfg, f, indent=2)
os.chmod(cfg_path, 0o600)
Use the write tool directly — no need to run Python.
| Platform | Fields | What It Unlocks |
|---|---|---|
username, password | Profile content behind login wall — use a burner account | |
| Twitter/X | bearer_token (+ optional api_key, api_secret) | Full tweet/profile/search via API v2 (free tier works) |
username (email), password | Profile scraping — use sparingly, heavily rate-limited | |
email, password | Public profile/group content | |
| Google Maps | api_key | Geocoding, Place Search, Street View metadata |
| Shodan | api_key | Deep IP/host intelligence |
| HaveIBeenPwned | api_key | Email breach lookups ($3.95/mo at haveibeenpwned.com/API/Key) |
| Hunter.io | api_key | Email discovery by domain (free: 25 req/mo at hunter.io/api-keys) |
| AbstractAPI Phone | api_key | Phone carrier/region lookup (app.abstractapi.com/api/phone-validation) |
# Read config and extract a value in one line:
BEARER=$(python3 -c "import json; c=json.load(open('<skill_dir>/config/osint_config.json')); print(c['platforms']['twitter']['bearer_token'])")
# Then use it:
curl -s -H "Authorization: Bearer $BEARER" \
"https://api.twitter.com/2/users/by/username/<handle>?user.fields=description,location,created_at,public_metrics"
# Profile lookup
curl -s -H "Authorization: Bearer $BEARER" \
"https://api.twitter.com/2/users/by/username/<handle>?user.fields=description,location,created_at,public_metrics,entities"
# Recent tweets
curl -s -H "Authorization: Bearer $BEARER" \
"https://api.twitter.com/2/users/<user_id>/tweets?max_results=10&tweet.fields=created_at,geo,entities"
# Search recent tweets
curl -s -H "Authorization: Bearer $BEARER" \
"https://api.twitter.com/2/tweets/search/recent?query=<query>&max_results=10"
curl -s "https://api.shodan.io/shodan/host/<ip>?key=$SHODAN_KEY"
curl -s "https://api.shodan.io/dns/resolve?hostnames=<domain>&key=$SHODAN_KEY"
curl -s "https://api.hunter.io/v2/domain-search?domain=<domain>&api_key=$HUNTER_KEY"
curl -s "https://api.hunter.io/v2/email-verifier?email=<email>&api_key=$HUNTER_KEY"
curl -s "https://haveibeenpwned.com/api/v3/breachedaccount/<email>" \
-H "hibp-api-key: $HIBP_KEY" -H "User-Agent: osint-investigator"
curl -s "https://maps.googleapis.com/maps/api/geocode/json?address=<address>&key=$GMAPS_KEY"
curl -s "https://maps.googleapis.com/maps/api/place/textsearch/json?query=<query>&key=$GMAPS_KEY"
curl -s "https://maps.googleapis.com/maps/api/streetview/metadata?location=<lat,lng>&key=$GMAPS_KEY"
python3 -c "import json; c=json.load(open('<skill_dir>/config/osint_config.json')); print(c.get('output',{}).get('pdf_enabled', False))"
Write the markdown report to a temp file, then run the shell wrapper (self-installs fpdf2 if missing):
cat > /tmp/osint_report.md << 'ENDREPORT'
<full markdown report>
ENDREPORT
bash <skill_dir>/scripts/generate_pdf.sh \
--input /tmp/osint_report.md \
--target "Target Name" \
--output ~/Desktop
The wrapper (generate_pdf.sh) will:
fpdf2 is installed — install it automatically if notgenerate_pdf.py with the same argumentsPDF saved: /path/to/OSINT_Name_20260225_1035.pdfNo setup needed by the user — works on any machine with Python 3 + pip.
Confidence is detected automatically from the text of each section/paragraph/table row — just include the word in your report and the PDF will colour-code it:
[HIGH] — verified from multiple reliable sources[MED] — likely correct, single or unverified source[LOW] — possible match, little corroborating evidence[UNVERIFIED] — user-provided context, not independently confirmedWhen the user says "turn on PDF reports" or "disable PDF output":
cfg["output"]["pdf_enabled"] to true or falsereferences/osint-sources.md — curated OSINT databases, APIs, and search operators by categoryreferences/social-platforms.md — platform-specific extraction tips and URL patternsscripts/generate_pdf.py — PDF generator (requires fpdf2, auto-installed via shell wrapper)scripts/generate_pdf.sh — shell wrapper; self-installs fpdf2, then calls generate_pdf.pyconfig/osint_config.json — live config (auto-created on first write, chmod 600)