Identify website visitor companies from IPs
Take IP addresses from server logs, extract the unique IPv4 addresses, and look up which organisation owns each one with ip_to_company. The user gets a ranked list of companies that visited, with a clear note on what IP data cannot tell you.
One command.
Installs into ~/.claude/skills for Claude Code. In Claude, upload the downloaded file under Settings → Capabilities → Skills.
npx ravn skill install identify-website-visitors
When to use
- The user has access logs, CDN logs or an analytics export with visitor IPs.
- "Which companies looked at our pricing page this week?"
- Not for identifying individual people. IP lookups return organisations and networks, never a person.
Before you start
- Check the connection:
npx ravn whoami(free). - Costs:
ip_to_companyis 1 lookup per IP. Misses are free, and many IPs will miss. - Set expectations before you run anything: - Only IPv4 is supported. IPv6 addresses are skipped. - Big ISPs, mobile carriers and cloud hosts return
not_found. Someone working from home or on a phone shows up as their ISP, so most consumer traffic will not resolve. - A company that owns its own network range will resolve. Expect a minority of visits to match.
Steps
- Extract IPs locally. Parse the log for the client IP field, keep only IPv4 (four dot-separated numbers), and drop private and reserved ranges (10.x, 172.16-31.x, 192.168.x, 127.x).
- If the logs sit behind a proxy or CDN, use the forwarded client IP field, not the proxy's address. Ask the user if unsure.
- Remove known bots by user agent if the logs have it, and remove your own office IPs.
- Count hits and pages per unique IP, then write
ips.csvwith columnsIP,hits,pages. - Look them up. Dry run, sample, full:
npx ravn enrich ips.csv --tool ip_to_company --column IP --dry-run npx ravn enrich ips.csv --tool ip_to_company --column IP --limit 10 --out sample.csv npx ravn enrich ips.csv --tool ip_to_company --column IP --out ips.enriched.csv
Single IP over MCP: { "ip": "203.0.113.42" }. 6. Group rows with rw_status = ok by rw_organization. Sum hits and list the pages each company viewed. 7. Review the names. Some organisations are hosting providers, universities or VPNs that slipped through. Mark those as network_type: hosting/other rather than presenting them as prospects. 8. Optional: for a real company with a website, the user can run account-research-brief or find-decision-makers on its domain. Ask first.
Output
visitors.csv, one row per organisation:
organization,country,ips(count),hits,pages(list),network,range
The enriched IP file keeps IP, hits, pages plus rw_status (ok, not_found, error, dropped), rw_ip, rw_organization, rw_network, rw_range and rw_country.
Summary: unique IPs, IPv6 skipped, resolved to an organisation, not found (ISP, mobile or cloud), and the top 10 organisations by hits.
Rules
- Never claim an IP identifies a person, and never try to link a visit to an individual's email or phone.
- Say plainly that unresolved traffic is normal. Do not fill gaps with guesses.
- Logs may hold personal data. Process them locally and keep only what the user needs.
- No FCRA uses.
- On exit code 4 the 5-hour window is full; the CLI waits for the reset unless
--no-waitis set. On a 429fair_use_exhausted, stop and tell the human.
Example prompt
Here's last week's nginx access.log. Which companies have been reading our pricing and docs pages? Ignore bots.
More skills
Install them all with npx ravn skill install --all.