saas-recon — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited saas-recon (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are the Lead Investigator. Your mission: discover every website, app, and platform that embeds, links to, redirects to, or references the target company's technology.
Current date: !date +%Y-%m-%d
This is a read-only investigation. You do NOT modify any external systems. All data comes from publicly accessible sources: CT logs, DNS, web archives, search engines, public code repositories, and regulatory filings.
Every finding MUST include the source (URL, API endpoint, or tool) and the date accessed. No uncited claims.
Every client finding is assigned a confidence tier per classification-rules.md:
| Tier | Required Evidence |
|---|---|
| CONFIRMED | Live embed verified (custom element + network request), OR 2+ independent source types (e.g., CT cert + investor filing), OR active production + UAT subdomain pair |
| STRONG | CT certificate + DNS CNAME resolves to client-specific deployment, OR named in investor filing, OR found in decompiled mobile app |
| MODERATE | Single CT certificate with client-branded production subdomain, OR single CDN archive with client folder, OR single GitHub code reference |
| WEAK | Demo subdomain only, OR expired cert only, OR single press mention / job listing |
Execute ALL 9 research phases + report compilation. Do not skip phases. If a phase yields no results, document that it was attempted and returned empty.
Generate target_slug by lowercasing the company name, replacing spaces/special chars with hyphens, stripping trailing hyphens (e.g., "Acme Corp." becomes acme-corp). All output goes to _recon/{target_slug}/ under the current working directory:
_recon/{target_slug}/
├── profile.json # Phase 1: structured company profile
├── findings/ # Per-phase findings
│ ├── 01-company-profile.md
│ ├── 02-certificates.md
│ ├── 03-infrastructure.md
│ ├── 04-archives.md
│ ├── 05-code-search.md
│ ├── 06-embeds.md
│ ├── 07-web-mentions.md
│ ├── 08-analytics-correlation.md
│ └── 09-business-intel.md
├── report.md # Final compiled report
└── report.html # Rendered HTML reportBefore executing, read these reference files for detailed rules and templates:
{PLACEHOLDER} values with actual data)Run this check FIRST before starting any phase. Detect available tools and MCP servers to maximize coverage:
echo "=== CLI Tool Availability ==="
for cmd in curl dig jq pandoc gau subfinder dnsx httpx nuclei katana waymore shodan uncover amass; do
printf "%-15s " "$cmd:"
if command -v $cmd &>/dev/null; then echo "AVAILABLE"; else echo "MISSING"; fi
doneRecord the results internally. For each phase, use ALL available tools — not just the minimum. The skill instructions include primary tools AND alternatives for every operation. Use every tool that is installed.
If RECOMMENDED tools are missing, output one suggestion line to the user before proceeding:
⚠ Install recommended tools for deeper coverage: brew install subfinder dnsx nuclei katana; go install github.com/projectdiscovery/httpx/cmd/httpx@latest| Tool | Category | Phase(s) | Priority | Fallback |
|---|---|---|---|---|
| MCP: google-researcher-mcp | Web search | 1, 7, 8, 9 | PRIMARY | WebSearch + WebFetch |
| MCP: playwright | Browser automation | 1, 6 | PRIMARY | WebFetch + source grep |
| MCP: github | Code search | 5 | PRIMARY | WebFetch on github.com/search |
| MCP: browser-tools | DevTools inspection | 6 | OPTIONAL | Playwright fallback |
| MCP: fetch | Web content | 1, 7 | OPTIONAL | WebFetch |
| MCP: sequential-thinking | Analysis | All | OPTIONAL | Direct reasoning |
Bash: curl | API calls | 2, 3, 4 | REQUIRED | No fallback |
Bash: dig | DNS resolution | 1, 3 | REQUIRED | No fallback |
Bash: jq | JSON parsing | All | REQUIRED | Python one-liner |
Bash: pandoc | HTML rendering | 10 | PRIMARY | Write HTML directly |
Bash: gau | URL collection | 4 | PRIMARY | Wayback CDX + CC CDX only |
Bash: subfinder | Subdomain discovery | 1, 2 | RECOMMENDED | crt.sh only |
Bash: dnsx | Bulk DNS resolution | 3 | RECOMMENDED | dig loop |
Bash: httpx (ProjectDiscovery) | Batch URL probing | 6 | RECOMMENDED | WebFetch per-URL |
Bash: nuclei | Template scanning | 6 | OPTIONAL | httpx match-string |
Bash: katana | JS site crawling | 6 | OPTIONAL | Playwright crawl |
Bash: waymore | Extended URL collection | 4 | OPTIONAL | gau covers most sources |
Bash: shodan | Server search | 3, 5 | OPTIONAL | Web-based Shodan search |
Bash: uncover | Multi-engine search | 5 | OPTIONAL | Individual searches |
Bash: amass | Asset discovery | 1 | OPTIONAL | subfinder + crt.sh |
Goal: Build a complete picture of the target — all names, brands, subsidiaries, products, and domains. This phase determines the scope for all subsequent phases.
Parse $ARGUMENTS:
. → treat as primary domain; research the owning company. → treat as company name; discover its domainsUse mcp__google-researcher-mcp__search_and_scrape (or fallback) to research:
"company name" site OR domain OR websitedig — most won't resolve)If `subfinder` is available:
subfinder -d DOMAIN1 -d DOMAIN2 -silent -o _recon/{target_slug}/subdomains_subfinder.txtThis queries 40+ passive sources (SecurityTrails, Censys, VirusTotal, Shodan, etc.) — far more comprehensive than crt.sh alone.
If `amass` is available:
amass enum -passive -d DOMAIN1,DOMAIN2 -o _recon/{target_slug}/subdomains_amass.txtAlways: Merge results with crt.sh output in Phase 2 for maximum coverage.
If Playwright MCP is available, load each product domain and extract:
// Navigate
mcp__playwright__browser_navigate({ url: "https://PRODUCT_DOMAIN" })
// All external scripts
mcp__playwright__browser_evaluate({
expression: "Array.from(document.querySelectorAll('script[src]')).map(s=>s.src).filter(u=>!u.includes(window.location.hostname))"
})
// Custom HTML elements
mcp__playwright__browser_evaluate({
expression: "[...new Set(Array.from(document.querySelectorAll('*')).map(e=>e.tagName.toLowerCase()).filter(t=>t.includes('-')))]"
})
// Branded JS globals (last 50 — browser built-ins are first)
mcp__playwright__browser_evaluate({
expression: "Object.keys(window).slice(-50)"
})
// Analytics IDs (GA4, GTM, UA, HubSpot, Facebook Pixel, LinkedIn)
mcp__playwright__browser_evaluate({
expression: "document.documentElement.innerHTML.match(/G-[A-Z0-9]+|GTM-[A-Z0-9]+|UA-\\d+-\\d+|hs-scripts\\.com\\/(\\d+)|fbq\\('init',\\s*'(\\d+)'|_linkedin_partner_id\\s*=\\s*\"(\\d+)\"/g)"
})If Playwright is NOT available, use WebFetch to fetch the page source and grep for script tags, data attributes, and analytics IDs. Note the fingerprinting gap in the report.
For each domain, extract TXT records to identify the company's SaaS stack:
dig DOMAIN TXT +short 2>/dev/nullParse: SPF includes (email provider), DMARC, Microsoft 365 (MS=), Google Workspace, Atlassian, HubSpot, Bitwarden, DocuSign, Stripe, Dropbox, Palo Alto, Wiz, etc.
Write _recon/{target_slug}/profile.json with the structure from section 0e. Every field must have an actual value or explicit null. Include:
target — corporate identitysubsidiaries[] — all discovered subsidiariesproducts[] — all products with domainsdomains — categorized as corporate/product/subsidiary/redirectssignatures — all detection fingerprints (html_elements, js_globals, cdn_domains, tracking_endpoints, script_urls, data_attributes, file_extensions, embed_patterns)analytics_ids — GA4, GTM, HubSpot, LinkedIn, Facebook, Pendoinfrastructure — DNS provider, cloud, CDN, WAF, emailnamed_customers[] — from investor filings (if found)named_partners[] — from marketing materials (if found)Write _recon/{target_slug}/findings/01-company-profile.md with human-readable summary.
If product domains found but signatures empty (e.g., SPA that renders nothing in source, or Playwright unavailable): proceed but log a warning that embed detection in Phase 6 will be limited.
Goal: Query CT logs for every certificate issued to any target domain. Client-branded subdomains reveal the customer base.
Read classification-rules.md now for subdomain classification rules.
For EVERY domain in profile.json (corporate + product + subsidiary), run:
curl -s "https://crt.sh/?q=%25.DOMAIN&output=json" 2>/dev/nullError handling:
&limit=1000[], that's valid — just means no certs found for that domainjq if available: jq -r '.[].name_value' | tr ',' '\n' | sort -ujq unavailable: python3 -c "import sys,json; [print(x) for e in json.load(sys.stdin) for x in e.get('name_value','').split('\n')]"Deduplicate results across all domain queries into a single sorted list.
If subfinder or amass ran in Phase 1, merge those subdomains with crt.sh results:
cat _recon/{target_slug}/subdomains_subfinder.txt _recon/{target_slug}/crt_domains.txt 2>/dev/null | sort -u > _recon/{target_slug}/all_subdomains.txtThis ensures maximum subdomain coverage — crt.sh catches certs, subfinder catches DNS records, zone transfers, and passive sources.
Apply rules from classification-rules.md:
clientname-uat.company.com) ARE client indicatorsFor each client-branded subdomain:
For each domain queried, record: issuer, SAN list, validity dates. Note:
CN=imperva.com or CN=cloudflare* → WAF providerWrite _recon/{target_slug}/findings/02-certificates.md.
If crt.sh reveals NO client-branded subdomains, the target may use:
In this case: document that CT logs did not reveal client-specific infrastructure, and rely more heavily on Phases 4-6 (archives, code search, embed detection) for client discovery.
Goal: Resolve key subdomains, follow CNAME chains, map cloud providers, identify client deployments.
If `dnsx` is available (PREFERRED — much faster for bulk):
dnsx -l _recon/{target_slug}/all_subdomains.txt -resp -cname -a -o _recon/{target_slug}/dns_results.txtOtherwise, use batched `dig`:
Priority 1 — Always resolve (main infrastructure):
for sub in DOMAIN www.DOMAIN cdn.DOMAIN portal.DOMAIN api.DOMAIN auth.DOMAIN track.DOMAIN; do
echo "=== $sub ==="
dig +short $sub A 2>/dev/null
dig +short $sub CNAME 2>/dev/null
donePriority 2 — Resolve all client-branded subdomains from Phase 2:
# Batch all client subdomains into one loop
for sub in CLIENT1.DOMAIN CLIENT2.DOMAIN CLIENT3.DOMAIN; do
cname=$(dig +short $sub CNAME 2>/dev/null | head -1)
a=$(dig +short $sub A 2>/dev/null | head -1)
echo "$sub|$cname|$a"
doneRun in a single Bash call with all subdomains in one loop. If there are 50+ client subdomains, sample the 20 most important (largest/newest certs) and note the rest as unresolved.
Priority 3 — Environment/other subdomains: Skip unless specifically relevant.
Follow every CNAME from 3a. Identify cloud services per this table:
| CNAME Pattern | Provider | Service |
|---|---|---|
*.elb.*.amazonaws.com | AWS | Load Balancer |
*.cloudfront.net | AWS | CloudFront |
*.s3.amazonaws.com | AWS | S3 |
*.azurewebsites.net | Azure | App Service |
*.cloudapp.azure.com | Azure | Cloud Service |
*.herokuapp.com | Heroku | Platform |
*.netlify.app | Netlify | Static hosting |
*.vercel-dns.com | Vercel | Edge |
*.hscoscdn*.net | HubSpot | CMS |
*.wpengine.com | WP Engine | WordPress |
*.firebaseapp.com | Firebase | |
*.run.app | Cloud Run |
Key finding: Client-specific CNAMEs like clientname.azurewebsites.net confirm a dedicated deployment and upgrade that client's confidence tier.
IP=$(dig +short MAIN_DOMAIN A | head -1)
shodan host $IP 2>/dev/nullThis reveals other domains on the same IP, open ports, and server software/versions.
Create an ASCII architecture diagram showing: Internet → WAF/CDN → Load Balancer → App Servers, with CDN, client deployments, and email branching off.
Write _recon/{target_slug}/findings/03-infrastructure.md.
Goal: Search web archives for historical evidence — CDN directory listings, client folder names, embed code, and pages that no longer exist.
If `gau` is available (RECOMMENDED — queries 4 sources simultaneously):
# Collect URLs from Wayback Machine, Common Crawl, OTX, and URLScan
for domain in DOMAIN1 DOMAIN2 DOMAIN3; do
gau --providers wayback,commoncrawl,otx,urlscan "$domain" 2>/dev/null
done | sort -u > _recon/{target_slug}/gau_urls.txt
# Count results
echo "Total URLs collected: $(wc -l < _recon/{target_slug}/gau_urls.txt)"If `waymore` is also available (most comprehensive):
waymore -i PRODUCT_DOMAIN -mode U -oU _recon/{target_slug}/waymore_urls.txtEven if gau ran, query CDX directly for CDN subdomains — these are highest priority for client discovery:
# CDN subdomain (highest priority — may expose directory listings)
curl -s "https://web.archive.org/cdx/search/cdx?url=cdn.DOMAIN/*&output=json&collapse=urlkey&fl=timestamp,original,statuscode,mimetype&limit=500"
# Client CDN
curl -s "https://web.archive.org/cdx/search/cdx?url=clients-cdn.DOMAIN/*&output=json&collapse=urlkey&limit=500"
curl -s "https://web.archive.org/cdx/search/cdx?url=clients.DOMAIN/*&output=json&collapse=urlkey&limit=500"
# All subdomains (domain match — broad sweep)
curl -s "https://web.archive.org/cdx/search/cdx?url=*.DOMAIN/*&output=json&matchType=domain&collapse=urlkey&limit=1000"Query at least the 3 most recent indices:
# Get latest 3 index IDs
INDICES=$(curl -s "https://index.commoncrawl.org/collinfo.json" | jq -r '.[0:3] | .[].id')
# Query each
for idx in $INDICES; do
curl -s "https://index.commoncrawl.org/${idx}-index?url=*.DOMAIN&output=json" 2>/dev/null
doneMany SaaS platforms use S3 or similar with directory listings. Even if disabled now, archives often captured them:
# Check if CDN had directory listing
curl -s "https://web.archive.org/web/2024/https://cdn.DOMAIN/" | head -100
# Look for client folder names in XML listings (S3 style)
curl -s "https://web.archive.org/web/2024/https://cdn.DOMAIN/" | \
grep -oE '<Key>[^<]+</Key>' | sed 's/<[^>]*>//g' | sort -uFrom gau/waymore output, extract client indicators:
# Extract unique paths with potential client names
grep -oP '(?<=://)[^/]+/[^/]+' _recon/{target_slug}/gau_urls.txt | sort | uniq -c | sort -rn | head -50
# Find partner IDs, account IDs, client folder names
grep -oE '/p/[0-9]+/' _recon/{target_slug}/gau_urls.txt | sort -u
grep -oE '/accounts?/[^/]+' _recon/{target_slug}/gau_urls.txt | sort -u
grep -oE '/clients?/[^/]+' _recon/{target_slug}/gau_urls.txt | sort -u
# Look for embed code patterns
grep -i 'embed\|widget\|player\|uiconf' _recon/{target_slug}/gau_urls.txt | head -50For the most interesting archived URLs (client references, CDN listings, embed code):
# Access a specific archived page
curl -s "https://web.archive.org/web/TIMESTAMP/https://DOMAIN/path"Write _recon/{target_slug}/findings/04-archives.md.
Goal: Find the target's domains, scripts, and brand names in public code repositories, source code indexes, and tracker databases.
Use mcp__github__search_code for each signature from profile.json. Execute ALL of these:
Primary searches (always execute):
"{PROD_DOMAIN}"
"{CDN_DOMAIN}"
"{SCRIPT_URL}" (if embed script URL known)
"{CUSTOM_ELEMENT}" (if custom HTML element known)
"{JS_GLOBAL}" (if JS global known)Secondary searches (execute if primaries yield results):
"{PROD_DOMAIN}" filename:*.html
"{PROD_DOMAIN}" filename:package.json
"{PROD_DOMAIN}" filename:*.jsx OR filename:*.tsx
"{COMPANY}" filename:config.json OR filename:config.yamlRepository searches:
mcp__github__search_repositories("{COMPANY}")
mcp__github__search_repositories("{PRODUCT}")What to look for in results:
PublicWWW indexes the raw HTML source of millions of websites. Search via Google:
mcp__google-researcher-mcp__google_search('site:publicwww.com "{CDN_DOMAIN}"')
mcp__google-researcher-mcp__google_search('site:publicwww.com "{CUSTOM_ELEMENT}"')Or fetch results directly:
WebFetch("https://publicwww.com/websites/%22{CDN_DOMAIN}%22/", "List all websites found containing this code")
WebFetch("https://publicwww.com/websites/%22{SCRIPT_URL}%22/", "List all websites found")If `shodan` CLI is available:
shodan search 'http.html:"{PROD_DOMAIN}"' --limit 100
shodan search 'http.html:"{JS_GLOBAL}"' --limit 100
shodan search 'ssl:"{COMPANY_NAME}"' --limit 100
shodan search 'ssl.cert.subject.cn:"{PROD_DOMAIN}"' --limit 100If neither CLI nor MCP, search via web:
mcp__google-researcher-mcp__google_search('site:shodan.io "{PROD_DOMAIN}"')uncover -q 'http.body:"{PROD_DOMAIN}"' -e shodan,publicwww,fofa -silentSearch for the target in privacy/tracker databases:
mcp__github__search_code("{PROD_DOMAIN} path:tracker-radar/domains")
mcp__github__search_code("{PROD_DOMAIN} path:APackets/yellowlist")
mcp__github__search_code("{PROD_DOMAIN} easylist OR easyprivacy")
mcp__github__search_code("{PROD_DOMAIN} path:hosts OR path:blocklist OR path:dns-blocklists")Tracker databases are valuable because they reveal:
Write _recon/{target_slug}/findings/05-code-search.md.
Goal: For suspected client sites (from Phases 2-5), verify embeds using live browser inspection and batch scanning.
IMPORTANT: Playwright MCP is only available in the main context, NOT in background agents. This phase MUST run in the main context.
From Phases 2-5, gather all suspected client URLs:
Limit to the 20 most promising candidates.
For each candidate URL (if Playwright MCP available):
// Navigate
mcp__playwright__browser_navigate({ url: "https://CANDIDATE_URL" })
// Check for custom elements
mcp__playwright__browser_evaluate({
expression: "document.querySelector('{CUSTOM_ELEMENT}') !== null"
})
// Check for JS globals
mcp__playwright__browser_evaluate({
expression: "typeof window.{JS_GLOBAL} !== 'undefined'"
})
// Capture all network requests
mcp__playwright__browser_network_requests()
// Filter for: product domain, CDN domain, tracking endpoints
// Extract all external script sources
mcp__playwright__browser_evaluate({
expression: "Array.from(document.querySelectorAll('script[src]')).map(s=>s.src).filter(u=>!u.includes(window.location.hostname))"
})
// Extract all iframe sources
mcp__playwright__browser_evaluate({
expression: "Array.from(document.querySelectorAll('iframe[src]')).map(f=>f.src)"
})# Create URL list from candidates
echo "URL1\nURL2\n..." > _recon/{target_slug}/candidate_urls.txt
# Scan for target signatures in responses
cat _recon/{target_slug}/candidate_urls.txt | httpx \
-match-string "{CDN_DOMAIN}" \
-match-string "{CUSTOM_ELEMENT}" \
-match-string "{JS_GLOBAL}" \
-status-code -title -tech-detect -follow-redirects \
-json -o _recon/{target_slug}/httpx_results.jsonCreate a custom detection template:
id: {target_slug}-embed-detect
info:
name: {COMPANY} Embed Detection
author: saas-recon
severity: info
http:
- method: GET
path:
- "{{BaseURL}}"
matchers-condition: or
matchers:
- type: word
words:
- "{CUSTOM_ELEMENT}"
- "{CDN_DOMAIN}"
- "{JS_GLOBAL}"
- "{SCRIPT_URL}"
condition: orSave to _recon/{target_slug}/detect.yaml and run:
nuclei -l _recon/{target_slug}/candidate_urls.txt -t _recon/{target_slug}/detect.yaml -o _recon/{target_slug}/nuclei_results.txtFor the top 5 most promising client sites:
katana -u https://CLIENT_SITE -js-crawl -d 3 -ef css,png,jpg,gif -f qurl 2>/dev/null | grep -i "{PROD_DOMAIN}"If Playwright, httpx, nuclei, and katana are all unavailable, use WebFetch to fetch page source and search for signature strings manually.
Write _recon/{target_slug}/findings/06-embeds.md.
Goal: Find third-party mentions, partner relationships, and customer evidence through web search.
Read search-patterns.md now. Map profile.json fields to placeholders:
{COMPANY} ← profile.target.name{PRODUCT} ← profile.products[0].name (repeat for each product){CORP_DOMAIN} ← profile.domains.corporate[0]{PROD_DOMAIN} ← profile.domains.product[0]{CDN_DOMAIN} ← profile.signatures.cdn_domains[0]{ELEMENT} ← profile.signatures.html_elements[0]{SCRIPT} ← first entry from profile.signatures.script_urls[]{JS_GLOBAL} ← profile.signatures.js_globals[0]{GA_ID} ← profile.analytics_ids.ga4From search-patterns.md, run all of these:
"{PRODUCT}" -site:{CORP_DOMAIN} -site:{PROD_DOMAIN} — third-party mentions"{COMPANY}" -site:{CORP_DOMAIN} — brand mentions"{COMPANY}" customer OR client OR "case study" -site:{CORP_DOMAIN} — customer evidence"{PRODUCT}" "powered by" OR "built with" OR "using" -site:{CORP_DOMAIN} — embed references"{COMPANY}" partner OR integration OR marketplace -site:{CORP_DOMAIN} — partner pages"{SCRIPT}" -site:{PROD_DOMAIN} — embed artifact (if script name known)"{CDN_DOMAIN}" -site:{PROD_DOMAIN} — CDN references on third-party sitessite:linkedin.com "{COMPANY}" AND ("we use" OR "experience with") — professional mentionssite:linkedin.com/jobs "{PRODUCT}" OR "{COMPANY}" — job postingsfiletype:pdf "{COMPANY}" customer OR client — PDF documentssite:stackoverflow.com "{PRODUCT}" OR "{PROD_DOMAIN}" — developer discussionssite:reddit.com "{COMPANY}" OR "{PRODUCT}" — community mentions"{COMPANY}" conference OR summit OR webinar speaker 2025 2026 — event mentions"{PRODUCT}" testimonial OR review -site:{CORP_DOMAIN} -site:g2.com -site:capterra.com — organic reviewsmcp__google-researcher-mcp__google_news_search("{COMPANY_NAME}")
mcp__google-researcher-mcp__google_news_search("{COMPANY_NAME} partnership OR acquisition OR customer")Search for the target on at least 5 of:
mcp__google-researcher-mcp__patent_search(assignee="{COMPANY_NAME}")
mcp__google-researcher-mcp__academic_search("{PRODUCT} {key_technology_term}")Search for companies OTHER than the target that mention the target's product in job postings — this confirms them as clients:
mcp__google-researcher-mcp__search_and_scrape('"{PRODUCT}" experience OR knowledge site:linkedin.com/jobs -{CORP_DOMAIN}')
mcp__google-researcher-mcp__google_search('site:indeed.com "{PRODUCT}" developer OR engineer')mcp__google-researcher-mcp__google_search('"{COMPANY}" conference OR summit OR webinar speaker 2025 2026')
mcp__google-researcher-mcp__google_search('"{PRODUCT}" demo OR presentation site:youtube.com')Write _recon/{target_slug}/findings/07-web-mentions.md.
Goal: Find all websites sharing the target's analytics IDs, technology fingerprints, and tracker classification data. This phase reveals sister sites, client portals, and shared infrastructure that other techniques miss.
For EACH analytics ID found in profile.json:
Google Analytics / GTM IDs:
mcp__google-researcher-mcp__google_search('"{GA4_ID}" -site:{CORP_DOMAIN} -site:{PROD_DOMAIN}')
mcp__google-researcher-mcp__google_search('"{GTM_ID}" -site:{CORP_DOMAIN} -site:{PROD_DOMAIN}')HubSpot Portal ID:
mcp__google-researcher-mcp__google_search('"hs-scripts.com/{HUBSPOT_ID}" -site:{CORP_DOMAIN}')Facebook Pixel / LinkedIn Partner ID:
mcp__google-researcher-mcp__google_search('"fbq(\'init\', \'{FB_PIXEL_ID}\')" -site:{CORP_DOMAIN}')
mcp__google-researcher-mcp__google_search('"_linkedin_partner_id" "{LINKEDIN_ID}" -site:{CORP_DOMAIN}')Marketo / Marketing Automation IDs:
mcp__google-researcher-mcp__google_search('"{MARKETO_MUNCHKIN_ID}" -site:{CORP_DOMAIN}')If available (can be cloned and run):
if [ ! -d /tmp/AnalyticsRelationships ]; then
git clone https://github.com/Josue87/AnalyticsRelationships /tmp/AnalyticsRelationships 2>/dev/null
fi
cd /tmp/AnalyticsRelationships && python3 analyticsrelationships.py -u {CORP_DOMAIN} 2>/dev/nullThis finds ALL domains sharing the same GA/GTM ID automatically by querying multiple sources.
Via web search:
mcp__google-researcher-mcp__search_and_scrape("site:builtwith.com {PROD_DOMAIN}")Or via direct fetch:
WebFetch("https://builtwith.com/{PROD_DOMAIN}", "List all technologies detected on this site and any 'sites also using' data")BuiltWith reveals: all technologies on the target's site, other sites using the same tech stack, and historical technology changes.
Check if the target's domains are classified in tracker databases:
mcp__github__search_code("{PROD_DOMAIN} path:APackets/APackets")
mcp__github__search_code("{PROD_DOMAIN} path:APackets/yellowlist")
mcp__github__search_code("{PROD_DOMAIN} path:APackets/yellowlist.txt")Also search directly:
mcp__github__search_code("{PROD_DOMAIN} tracker-radar")If found, extract: tracker classification, prevalence data, fingerprinting score, cookie usage, related domains.
mcp__github__search_code("{PROD_DOMAIN} easyprivacy OR easylist")
mcp__github__search_code("{PROD_DOMAIN} path:hosts OR path:blocklist")DNS blocklists categorize domains by purpose and often group domains by owner — revealing additional infrastructure and product domains.
If analytics ID correlation finds other domains sharing the same IDs, those domains are either:
Investigate each shared-ID domain to classify it.
Write _recon/{target_slug}/findings/08-analytics-correlation.md.
Goal: Discover named customers, revenue data, partner relationships, and market intelligence from business sources.
| Source | What You Find |
|---|---|
| SEC EDGAR (US) | 10-K, 10-Q, proxy statements with customer names |
| SEDAR+ (Canada) | Canadian public company filings |
| Companies House (UK) | UK company registrations |
| Investor presentations | Named customers, ARR data, growth metrics |
| Earnings call transcripts | Customer names mentioned verbally |
Search investor relations:
mcp__google-researcher-mcp__search_and_scrape("{COMPANY_NAME} investor relations earnings Q4 2025")
mcp__google-researcher-mcp__search_and_scrape("site:seekingalpha.com {COMPANY_NAME} earnings call transcript")
mcp__google-researcher-mcp__google_search("{COMPANY_NAME} 10-K annual report site:sec.gov")From the target's own marketing materials:
mcp__google-researcher-mcp__search_and_scrape("site:{CORP_DOMAIN} case study OR customer story")
mcp__google-researcher-mcp__search_and_scrape("site:{CORP_DOMAIN} resources case-studies")
mcp__google-researcher-mcp__search_and_scrape("site:{CORP_DOMAIN} customers OR clients")Scrape the case studies/customers page to extract ALL named customers, not just the first page.
mcp__google-researcher-mcp__google_search('"{COMPANY}" conference OR summit OR webinar speaker 2025 2026')
mcp__google-researcher-mcp__google_search('"{PRODUCT}" demo OR presentation site:youtube.com')
mcp__google-researcher-mcp__google_search('"{COMPANY}" exhibitor OR sponsor')mcp__google-researcher-mcp__google_search('"{COMPANY}" vs OR versus OR alternative OR competitor')For public companies:
mcp__google-researcher-mcp__search_and_scrape("{COMPANY_NAME} annual revenue ARR customers 2025")
mcp__google-researcher-mcp__google_news_search("{COMPANY_NAME} funding OR acquisition OR partnership 2025 2026")mcp__google-researcher-mcp__google_news_search("{COMPANY_NAME} acquisition OR merger OR partnership")
mcp__google-researcher-mcp__search_and_scrape("{COMPANY_NAME} strategic partner OR reseller OR OEM")Write _recon/{target_slug}/findings/09-business-intel.md.
Goal: Compile all findings, cross-reference, generate report.
Read ALL findings files (01 through 09). For each unique client found across ALL phases, build a row:
| Client | Industry | CT Cert | DNS | CDN | Code | Embed | Analytics | Filing | Press | Confidence |
|---|
Mark each cell with X if evidence exists from that source. Apply confidence tier per classification-rules.md rules (NOT by simple column count — use the specific evidence-type rules defined there).
Deduplicate clients per the deduplication rules in classification-rules.md. Merge aliases.
Read report-template.md. Create _recon/{target_slug}/report.md following that structure exactly:
{PLACEHOLDER} with actual computed values{COUNT} → actual numeric count{CLIENT}, {INDUSTRY}, etc. → expand to as many rows as there are entries{DATE} → the date captured at the top of this skill{PLACEHOLDER} text in the final reportThe report MUST include ALL 13 sections from the template:
pandoc _recon/{target_slug}/report.md -f markdown -t html5 --standalone \
--metadata title="{COMPANY_NAME} Technology Reconnaissance Report" \
-o _recon/{target_slug}/report.htmlIf pandoc unavailable, write the HTML directly by wrapping the markdown content in a basic HTML template with the CSS from html-styles.md.
After generating HTML, inject the CSS from html-styles.md:
max-width: 36em with max-width: 980px</style>Open in browser:
open _recon/{target_slug}/report.htmlYou are DONE only when ALL checks pass:
Completeness (1-9):
Quality (10-14):
{PLACEHOLDER} text remains in report.mdOutput (15-17):
If ANY check fails, fix it before declaring completion.
$ARGUMENTS — determine if company name or domaintarget_slug per section 0e rulesmkdir -p _recon/{target_slug}/findingsSpawn Agent A — Archives (background): Include in prompt: full domain list from profile.json, exact curl commands from api-endpoints.md, gau instructions (if available), CDN subdomain list, CDN directory mining technique, output path _recon/{target_slug}/findings/04-archives.md.
Spawn Agent B — Code Search (background): Include in prompt: all signatures from profile.json, all GitHub search queries from search-patterns.md, PublicWWW search instructions, Shodan queries (if CLI available), tracker database search queries, output path _recon/{target_slug}/findings/05-code-search.md.
Spawn Agent C — Web + Analytics + Business Intel (background): Include in prompt: all search pattern queries with placeholders filled from profile.json, analytics IDs, marketplace list, patent/academic search, investor filing search, output paths for 07-web-mentions.md, 08-analytics-correlation.md, 09-business-intel.md.
Main context — Live Embed Detection:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.