OSINT Investigator
Multi-source open-source intelligence gathering. Identify target type, run all applicable modules, then produce a structured report.
Target Classification
Before running any module, classify the target:
- - Person (real name, alias, face) → modules: social, web, image, username
- Username / Handle → modules: username, social, web
- Domain / Website → modules: dns, whois, web, social
- IP Address → modules: ip, dns, web
- Organisation / Company → modules: web, social, dns, maps, corporate
- Phone Number → modules: phone, web, social
- Email Address → modules: email, web, social
- Location / Address → modules: maps, web, social, geo
- Image / Photo → modules: image, reverse
- Object / Asset → modules: web, image, social
Run ALL applicable modules in parallel. Never stop after one source.
Module Playbook
🌐 Web Search (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.
🔗 DNS / WHOIS
whois <domain>
dig <domain> ANY
dig <domain> MX
dig <domain> TXT
nslookup <domain>
host <domain>
Also fetch:
https://rdap.org/domain/<domain> via INLINECODE3
🌍 IP Intelligence
curl -s https://ipinfo.io/<ip>/json
curl -s https://ip-api.com/json/<ip>
Also check:
https://www.shodan.io/host/<ip> via INLINECODE5
📱 Username Search
Check all platforms via
web_fetch (just check HTTP status + page title — don't need to load full content for existence checks):
- - INLINECODE7
- INLINECODE8
- INLINECODE9
- INLINECODE10
- INLINECODE11
- INLINECODE12
- INLINECODE13
- INLINECODE14
- INLINECODE15
- INLINECODE16
- INLINECODE17
- INLINECODE18
- INLINECODE19 (Telegram)
🐦 Social Media Deep Dive
For each confirmed platform profile, use
web_fetch to extract:
- - Bio / description
- Profile photo URL
- Follower/following counts
- Join date
- Location (if listed)
- Links in bio
- Pinned posts / recent activity
For Twitter/X: also search web_search for site:twitter.com "<target>" and nitter mirrors.
🗺️ Maps & Location
# 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 INLINECODE24
🖼️ Image Search & Reverse Image Search
Finding images of a person (no image provided):
- 1. Search for profile photos on all confirmed social profiles — extract direct image URLs from page source or og:image meta tags
- Run
web_search for "<name>" site:linkedin.com — LinkedIn og:image often returns profile photo URL directly - Check Gravatar: compute MD5 of likely email addresses → INLINECODE27
- Search news/press:
web_search for INLINECODE29 - Use
web_fetch to pull og:image from any confirmed profile pages
Reverse image search (image URL or local file provided):
CODEBLOCK4
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 INLINECODE33
Photo geolocation (no EXIF GPS):
- - Street signs, shop names, vehicle plates →
web_search to identify region - Architecture / vegetation / road markings → narrow country/region
- Sun angle + shadow direction →
https://www.suncalc.org to estimate time & location - Cross-reference with Google Street View via
browser tool
When searching for a person by image from social media:
- 1.
web_fetch the profile page and look for og:image or <img> src in the rendered HTML - Extract the full CDN image URL
- Feed to Yandex imageview and TinEye
- Note: Instagram/Facebook CDN URLs expire — use Yandex cache or download first
📧 Email Intelligence
# 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 INLINECODE41
📞 Phone Intelligence
# 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, INLINECODE45
🏢 Corporate / Organisation
Use
web_fetch on:
- - INLINECODE47
- Companies House (UK): INLINECODE48
- LinkedIn company page: INLINECODE49
- Crunchbase:
web_search for INLINECODE51
📄 Document & Data Leaks
CODEBLOCK8
🔍 Cache & Archive
CODEBLOCK9
Investigation Workflow
- 1. Classify the target type
- Plan — list all modules to run
- Execute all modules (parallelise where possible using multiple tool calls)
- Correlate — cross-reference findings across sources, note consistencies and conflicts
- Report — structured output (see below)
Report Format
Always produce a structured report. Adapt sections to what was found:
CODEBLOCK10
Configuration & Authentication
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.
Conversational Config Flow
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):
- - For API keys: ask them to paste the key directly in chat
- For passwords: warn them the value will be stored in a local JSON file, then ask
- For output settings: ask yes/no / provide a path
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.
Supported Platform Integrations
| Platform | Fields | What It Unlocks |
|---|
| Instagram | INLINECODE55 , INLINECODE56 | 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) |
| LinkedIn |
username (email),
password | Profile scraping — use sparingly, heavily rate-limited |
| Facebook |
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) |
Reading Credentials During a Search
CODEBLOCK12
Twitter/X API v2 (when configured)
CODEBLOCK13
Shodan API (when configured)
CODEBLOCK14
Hunter.io API (when configured)
CODEBLOCK15
HaveIBeenPwned API (when configured)
CODEBLOCK16
Google Maps API (when configured)
CODEBLOCK17
PDF Report Generation
Check if PDF is enabled
CODEBLOCK18
Generate a PDF
Write the markdown report to a temp file, then run the shell wrapper (self-installs
fpdf2 if missing):
CODEBLOCK19
The wrapper (generate_pdf.sh) will:
- 1. Check if
fpdf2 is installed — install it automatically if not - Call
generate_pdf.py with the same arguments - Print the output path: INLINECODE73
No setup needed by the user — works on any machine with Python 3 + pip.
PDF confidence colour coding
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:
- - 🟢 GREEN
[HIGH] — verified from multiple reliable sources - 🟠 ORANGE
[MED] — likely correct, single or unverified source - 🔴 RED
[LOW] — possible match, little corroborating evidence - ⚪ GREY
[UNVERIFIED] — user-provided context, not independently confirmed
Toggling PDF output via conversation
When the user says "turn on PDF reports" or "disable PDF output":
- 1. Read the config file
- Update
cfg["output"]["pdf_enabled"] to true or INLINECODE80 - Write it back
- Confirm to the user
Ethics & Legality
- - Only use publicly available data — never attempt to access private systems
- Do not aggregate data in ways designed to facilitate stalking or harassment
- Respect robots.txt in spirit; use cached/archive versions where direct scraping is blocked
- If the target is clearly a private individual being investigated without consent, flag this before proceeding
- Instagram/LinkedIn/Facebook credentials: always recommend a burner/alt account — never the user's personal accounts
Reference Files
- -
references/osint-sources.md — curated OSINT databases, APIs, and search operators by category - INLINECODE82 — platform-specific extraction tips and URL patterns
- INLINECODE83 — PDF generator (requires fpdf2, auto-installed via shell wrapper)
- INLINECODE84 — shell wrapper; self-installs fpdf2, then calls generate_pdf.py
- INLINECODE85 — live config (auto-created on first write, chmod 600)