Facebook Ad Library MCP
by leyovco
README.md
# Facebook Ad Library MCP
A small MCP server that scrapes the public Facebook Ad Library for competitive ad research — from your MCP client, with no Facebook account and no API token.
## Install
```bash
git clone https://github.com/leyovco/facebook-ads-library-mcp.git
cd facebook-ads-library-mcp
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python -m playwright install chromium # crawl4ai needs a browser
```
### Register with your MCP client
Claude Code:
```bash
claude mcp add facebook-ads -- /abs/path/venv/bin/python /abs/path/facebook_ads_mcp_complete.py
```
Claude Desktop (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"facebook-ads": {
"command": "/abs/path/venv/bin/python",
"args": ["/abs/path/facebook_ads_mcp_complete.py"]
}
}
}
```
Restart the client.
## Usage
```
"Search the Mexico Ad Library for 'automatización con inteligencia artificial',
group by advertiser, and list the landing domains."
"Scrape https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=MX&q=nike&search_type=keyword_unordered
with scroll_rounds=15 and summarise the creative angles."
```
## Tools
Two tools:
- **`search_ad_library(query, country="MX", ...)`** — keyword search.
- **`scrape_ad_library_url(url, ...)`** — scrape any Ad Library URL you already have.
Both return structured records per ad:
| field | meaning |
|---|---|
| `advertiser`, `advertiser_handle` | Page name and its `facebook.com/<handle>` |
| `started_running` | first-seen date |
| `ads_using_creative` | how many creatives share this copy — a rough scale signal |
| `landing_url`, `landing_domain` | destination, unwrapped from the `l.facebook.com` redirect |
| `cta` | the button label (`Learn more`, `Sign up`, `Send message`, …) |
| `link_text` | the headline strip under the creative |
| `body` | full ad copy |
| `creative_image` | thumbnail URL |
| `ad_details_url` | deep link to that ad's detail view |
Plus an `advertisers` histogram and the `raw_markdown` of the page so the model can pull anything the parser missed.
## Configuration
- **`scroll_rounds`** (default 8)
- **`wait_seconds`** (default 8)
- **`country`** — ISO code (e.g., `MX`, `US`, `ES`)
- **`advertiser_page_id`** — target one Page's "all ads" view (less reliable than keyword search)
## How it works
`crawl4ai` (`AsyncWebCrawler`) opens the Ad Library URL in headless Chromium, waits for the React app to hydrate, runs a scroll loop to trigger lazy-loaded cards, serialises the DOM to markdown, and a regex parser (`_parse_ad_library_markdown`) splits it on `Library ID:` boundaries and pulls the fields above.
Facebook answers the headless browser with **HTTP 403** but still serves the rendered cards, so the tools judge success by whether cards parsed, not by status code.
## License
MIT — original by Ramses Aguirre (RamsesAguirre777). Adapted and hosted under leyovco.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues