Find broken outbound links on websites and discover contact emails for outreach. Usable as a CLI, library, or MCP server for Claude Code.
Project description
broken-link-finder
Find broken outbound links on any website and discover contact emails for outreach. Works as a CLI tool, Python library, or MCP server for Claude Code.
Install
pip install broken-link-finder
Usage
CLI
# Check a CSV of target URLs for broken links
broken-link-finder --input targets.csv --output results.csv
# Limit to 5 pages for a test run
broken-link-finder --input targets.csv --limit 5
# Custom delay between requests (default: 1 second)
broken-link-finder --input targets.csv --delay 2.0
# Re-process already-crawled URLs
broken-link-finder --input targets.csv --force
Input CSV format:
| University | Tier | Category | Target URL | Notes |
|---|---|---|---|---|
| Example University | 1 | Career Center | https://example.edu/careers |
MCP Server (Claude Code)
Add to your project's .mcp.json or ~/.claude/settings.json:
{
"mcpServers": {
"broken-links": {
"command": "uvx",
"args": ["broken-link-finder-mcp"]
}
}
}
This gives Claude three tools:
| Tool | Description |
|---|---|
find_broken_links |
Crawl a page, check all outbound links, return broken ones with contact emails |
check_url |
Quick check if a single URL is reachable |
find_contact_emails |
Find contact emails for any website |
Python Library
import asyncio
from broken_link_finder import BrokenLinkFinder, ContactFinder
async def main():
async with BrokenLinkFinder(delay=1.0) as finder:
result = await finder.crawl_page("https://example.com/resources")
for broken in result.broken_links:
print(f"{broken.broken_url} -> {broken.status_code}")
cf = ContactFinder()
emails = await cf.find_emails("https://example.com")
print(emails)
asyncio.run(main())
Contact Email Discovery
The ContactFinder uses three strategies to find the right person to contact:
- Page scraping — extracts
mailto:links and email patterns from the crawled page - Contact page discovery — checks common paths (
/contact,/about,/contact-us, etc.) - Hunter.io API — optional domain-level email lookup
Set HUNTER_API_KEY as an environment variable to enable Hunter.io lookups.
Emails are scored by outreach relevance: career/webmaster/editor emails rank highest, named-person emails rank next, generic addresses lower, and free providers (gmail, etc.) rank lowest.
Incremental Processing
The CLI tracks processed URLs in output/processed-urls.json. On subsequent runs, already-processed URLs are automatically skipped. Use --force to re-process everything.
Docker
docker compose run --rm broken-link-finder python main.py --limit 5
docker compose up # full run
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file broken_link_finder-0.1.1.tar.gz.
File metadata
- Download URL: broken_link_finder-0.1.1.tar.gz
- Upload date:
- Size: 20.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.5 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b436eacf8b821f48f6d9b710da4a9b99075cb9f15ee8efee4367d09d48121ca
|
|
| MD5 |
55de86de32d95219240c0859649afef7
|
|
| BLAKE2b-256 |
f22ed7fea533f3dfdd588b863d89adf088192b317a7340e16298b38e55b91a8b
|
File details
Details for the file broken_link_finder-0.1.1-py3-none-any.whl.
File metadata
- Download URL: broken_link_finder-0.1.1-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.5 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ae5666fe0fe9ee9435e26becd3df3c9293fa9dc47073f86ade6abc9418d2910
|
|
| MD5 |
dc401ddbd74aab6075d6073b7bfe4c9c
|
|
| BLAKE2b-256 |
15740559dd7730899398f1a3e82085e805d15eba8f4cd568ba8956d3c094f7b7
|