# ConvertFleet MCP — agent guide

ConvertFleet extracts live data from the public web: local business leads, contact details, live ad activity, search results and page content, social posts, product catalogues, YouTube data and transcripts, email validation and media links.

Endpoint `https://convertfleet.online/mcp` · 22 tools · registry v1, updated 2026-08-18.

## Categories
- **Local business & map data** — `google_maps_search`
- **Social platforms** — `facebook_page_scrape`, `facebook_ads_scrape`, `twitter_scrape`, `instagram_scrape`
- **Video, audio & downloads** — `youtube_extract`, `youtube_competitor`, `youtube_transcript`, `youtube_download`, `instagram_download`, `tiktok_download`, `facebook_download`, `snapchat_download`
- **E-commerce catalogues** — `product_scrape`
- **Email finding & verification** — `email_verify`, `disposable_email_check`, `website_email_find`
- **Web search & page reading** — `google_search`, `google_search_scrape`, `scrape_web_pages`
- **Ad intelligence** — `google_ads_transparency`, `ad_library_lead_finder`

## Helper tools (no quota cost)
- `convertfleet_guide` — this document, plus recipes, error handling and per-tool reference.
- `find_tool` — describe a job in plain English, get the right tool and example arguments.
- `account_status` — plan, monthly usage and the tools this credential may call.
- `get_job_result` / `list_jobs` — collect results from long-running jobs.

## The three rules
1. Long runs return `{status:"running", job_id}` — poll `get_job_result`, do not treat it as a failure.
2. Read each tool's **Not for** line before choosing between near-neighbours.
3. Empty results are usually real answers; `-32001` errors are auth/quota/scope and must not be retried.


---

# Tool reference

# Local business & map data

## google_maps_search — Google Maps Search

Scrape Google Maps business listings (name, address, phone, website, rating, reviews) for a search query and location. Returns B2B leads.

**When to use:** Building a B2B prospect list of physical/local businesses (name, phone, website, address, rating) for a niche in a city. The default starting point for 'find me leads / businesses / companies in <place>'.

**Not for:** Finding people or job titles, scraping one known website (use website_email_find), or checking who advertises (use ad_library_lead_finder).

**Returns:** One row per business.

**Result fields:** `store_name`, `category`, `phone`, `whatsapp`, `email`, `website`, `social_media`, `address`, `city`, `province`, `country`, `latitude`, `longitude`, `rating`, `review_count`, `hours_summary`, `permanently_closed`, `maps_url`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `query` | string | yes |  | What to search for, e.g. 'dentists', 'coffee shops'. Combined with location. |
| `location` | string | no |  | City / area to search in, e.g. 'Miami, FL'. |
| `limit` | integer | no | `20` | Max number of listings to return (clamped to the account tier ceiling). |
| `language` | string | no |  | Optional 2-letter UI language hint, e.g. 'en'. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "google_maps_search",
    "arguments": {
      "query": "dentists",
      "location": "Miami, FL",
      "limit": 25
    }
  }
}
```

**Related:** `ad_library_lead_finder`, `website_email_find`, `email_verify`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

# Social platforms

## facebook_page_scrape — Facebook Page Scraper

Pull public Facebook Page details (about, contact, category) from a page URL or ID.

**When to use:** Enriching one known Facebook Page with its public about/contact/category info.

**Not for:** Searching for pages by keyword, or reading ads (use facebook_ads_scrape).

**Returns:** One row of page metadata.

**Result fields:** `name`, `category`, `about`, `phone`, `email`, `website`, `address`, `likes`, `followers`, `page_url`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `page_url_or_id` | string | yes |  | Facebook Page URL or numeric/vanity ID. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "facebook_page_scrape",
    "arguments": {
      "page_url_or_id": "https://www.facebook.com/nike"
    }
  }
}
```

**Related:** `facebook_ads_scrape`, `website_email_find`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## facebook_ads_scrape — Meta Ad Library Search

Search Meta's Ad Library (Facebook + Instagram) for LIVE ads by brand, advertiser or keyword. Returns each ad's advertiser page, real ad copy, call-to-action, start date, media type and Ad Library link. An empty result means the library genuinely has no matching ads; a blocked run is reported as an error instead.

**When to use:** Seeing the actual creative a brand is running on Facebook/Instagram right now — ad copy, CTA, media type, start date. Competitor ad research and creative swipe files.

**Not for:** Google ads (use google_ads_transparency) or building a lead list (use ad_library_lead_finder).

**Returns:** One row per ad creative.

**Result fields:** `advertiser`, `page_url`, `ad_text`, `cta`, `media_type`, `start_date`, `ad_library_url`, `platforms`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `query` | string | yes |  | Keyword or advertiser/page name to search the Ad Library for. |
| `country` | string | no | `"US"` | ISO country code to scope ads to, e.g. 'US', 'GB', 'PK'. |
| `status` | string | no | `"active"` | Ad delivery status. One of: `active`, `inactive`, `all`. |
| `limit` | integer | no | `20` | Max ads to return. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "facebook_ads_scrape",
    "arguments": {
      "query": "Athletic Greens",
      "country": "US",
      "status": "active",
      "limit": 20
    }
  }
}
```

**Related:** `google_ads_transparency`, `ad_library_lead_finder`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

## twitter_scrape — Twitter / X Scraper

Scrape X/Twitter by search query, username, or tweet URLs. Returns tweets with engagement.

**When to use:** Pulling tweets for a topic (mode=search), a person's timeline (mode=profile) or specific tweet URLs (mode=url), with engagement numbers.

**Not for:** Follower lists, or DMs. Private/protected accounts return nothing.

**Returns:** One row per tweet.

**Result fields:** `tweet_id`, `url`, `author`, `author_handle`, `text`, `created_at`, `likes`, `retweets`, `replies`, `views`, `is_retweet`, `is_reply`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `mode` | string | no | `"search"` | What to scrape. One of: `search`, `profile`, `url`. |
| `queries` | string[] | no |  | Run several searches in one call. Use instead of `query` for multiple angles on a topic. Capped by plan: Starter 2, Pro 10, Gold 25 — extra queries are dropped, not rejected. |
| `usernames` | string[] | no |  | Usernames without '@' (mode=profile). |
| `urls` | string[] | no |  | Direct tweet URLs (mode=url). |
| `max_tweets` | integer | no | `25` | Max tweets to return. |
| `include_replies` | boolean | no | `false` | Include reply tweets. |
| `include_retweets` | boolean | no | `true` | Include retweets. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "twitter_scrape",
    "arguments": {
      "mode": "search",
      "queries": [
        "ai agents saas"
      ],
      "max_tweets": 25
    }
  }
}
```

**Related:** `instagram_scrape`, `google_search`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

## instagram_scrape — Instagram Followers Scraper

Scrape an Instagram account's followers or following list. Returns username, full name, user id, verified/private flags and avatar per account. Follower lists need a server-side IG session (IG_SESSIONID); without one it returns the target profile's public metadata only.

**When to use:** Exporting who follows (or is followed by) an Instagram account — audience research and influencer-overlap work.

**Not for:** Posts, reels or comments. Without a server-side IG session it degrades to public profile metadata only, so treat an empty follower list as 'not configured', not 'no followers'.

**Returns:** One row per follower/following account (or profile metadata in degraded mode).

**Result fields:** `username`, `full_name`, `user_id`, `is_verified`, `is_private`, `profile_pic_url`, `source_account`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `usernames` | string[] | yes |  | Instagram handles (without '@') or profile URLs, one or more. |
| `data_to_scrape` | string | no | `"followers"` | Scrape the account's followers or the accounts it is following. One of: `followers`, `following`. |
| `max_results` | integer | no | `500` | How many result links this run may keep, SHARED across all queries (they do not multiply it). Clamped to the account's plan: Starter 10, Pro 50, Gold 200. Send 0 for 'as many as my plan allows'. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "instagram_scrape",
    "arguments": {
      "usernames": [
        "natgeo"
      ],
      "data_to_scrape": "followers",
      "max_results": 200
    }
  }
}
```

**Related:** `instagram_download`, `twitter_scrape`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

# Video, audio & downloads

## youtube_extract — YouTube Extractor

Extract metadata and stats for a YouTube video OR channel. Pass a video URL for one video, or a channel URL to list recent videos. Auto-detects which.

**When to use:** Getting stats/metadata for a YouTube video, or listing a channel's recent uploads. Auto-detects video vs channel from the URL.

**Not for:** Captions (use youtube_transcript) or download links (use youtube_download).

**Returns:** Video metadata, or a channel row plus its recent videos.

**Result fields:** `title`, `channel`, `channel_url`, `published_at`, `views`, `likes`, `comments`, `duration`, `description`, `thumbnail`, `video_url`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | A YouTube video URL (watch?v=, youtu.be, /shorts/) or channel URL (/@handle, /channel/, /c/, /user/). |
| `max_videos` | integer | no | `20` | For channel URLs: how many recent videos to list. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "youtube_extract",
    "arguments": {
      "url": "https://www.youtube.com/@MrBeast",
      "max_videos": 20
    }
  }
}
```

**Related:** `youtube_transcript`, `youtube_competitor`, `youtube_download`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## youtube_competitor — YouTube Competitor Analyzer

Compare 1-5 YouTube channels side by side (subscriber counts, upload cadence, recent performance).

**When to use:** Benchmarking 2-5 YouTube channels against each other (subs, upload cadence, recent performance) for a content or competitor report.

**Not for:** A single channel (use youtube_extract).

**Returns:** One row per channel plus comparative stats.

**Result fields:** `channel`, `channel_url`, `subscribers`, `total_views`, `video_count`, `uploads_per_week`, `avg_views`, `top_video`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `urls` | string[] | yes |  | 1-5 YouTube channel URLs to compare. |
| `max_videos` | integer | no | `30` | Recent videos to sample per channel. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "youtube_competitor",
    "arguments": {
      "urls": [
        "https://www.youtube.com/@veritasium",
        "https://www.youtube.com/@kurzgesagt"
      ],
      "max_videos": 30
    }
  }
}
```

**Related:** `youtube_extract`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

## youtube_transcript — YouTube Transcript Extractor

Get the transcript / closed captions for one or many YouTube videos. Returns, per video, the full plain-text transcript, timestamped segments, and an .srt subtitle string. Works with manual and auto-generated captions; can target a language or auto-translate.

**When to use:** Reading what was actually SAID in videos — summarising talks, mining podcasts/webinars, repurposing content, answering questions about a video's contents.

**Not for:** Videos with captions disabled (returns an error row for those) or non-YouTube video.

**Returns:** Per video: full plain text, timestamped segments and an .srt string.

**Result fields:** `video_id`, `url`, `title`, `language`, `is_generated`, `text`, `segments`, `srt`, `word_count`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `urls` | string[] | yes |  | 1-50 YouTube video URLs (watch?v=, youtu.be, /shorts/) to transcribe. |
| `languages` | string[] | no |  | Preferred caption language codes in priority order, e.g. ['en','es']. Defaults to English then any available. |
| `prefer_manual` | boolean | no | `true` | Prefer human-written captions, falling back to auto-generated. Set false to prefer auto captions. |
| `translate_to` | string | no |  | Optional target language code to auto-translate the transcript into (e.g. 'en'). |
| `include_timestamps` | boolean | no | `true` | Include the timestamped segment list and .srt string in each row. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "youtube_transcript",
    "arguments": {
      "urls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
      ],
      "languages": [
        "en"
      ]
    }
  }
}
```

**Related:** `youtube_extract`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## youtube_download — YouTube Downloader

Get downloadable media URLs and available formats/metadata for a YouTube video.

**When to use:** Getting direct media URLs and the available format/quality list for a YouTube video.

**Not for:** Transcripts (use youtube_transcript) or stats (use youtube_extract).

**Returns:** Media URLs plus a formats list.

**Result fields:** `title`, `duration`, `thumbnail`, `formats`, `download_url`, `quality`, `ext`, `filesize`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | YouTube video URL. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "youtube_download",
    "arguments": {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  }
}
```

**Related:** `youtube_extract`, `youtube_transcript`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## instagram_download — Instagram Downloader

Get downloadable media URLs and metadata for an Instagram post or reel.

**When to use:** Getting the media URL for a public Instagram post or reel.

**Not for:** Private posts or bulk profile exports.

**Returns:** Media URLs plus post metadata.

**Result fields:** `title`, `caption`, `author`, `thumbnail`, `download_url`, `media_type`, `ext`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | Instagram post/reel URL. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "instagram_download",
    "arguments": {
      "url": "https://www.instagram.com/p/CxAmPlE/"
    }
  }
}
```

**Related:** `instagram_scrape`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## tiktok_download — TikTok Downloader

Get downloadable (watermark-free) media URLs and metadata for a TikTok video.

**When to use:** Getting a watermark-free media URL for a public TikTok video.

**Not for:** Searching TikTok or listing a creator's videos — that scraper is retired.

**Returns:** Media URLs plus video metadata.

**Result fields:** `title`, `author`, `thumbnail`, `download_url`, `media_type`, `ext`, `duration`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | TikTok video URL. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "tiktok_download",
    "arguments": {
      "url": "https://www.tiktok.com/@user/video/1234567890"
    }
  }
}
```

**Related:** `youtube_download`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## facebook_download — Facebook Downloader

Get downloadable media URLs and metadata for a Facebook video.

**When to use:** Getting the media URL for a public Facebook video.

**Not for:** Private/friends-only videos.

**Returns:** Media URLs plus video metadata.

**Result fields:** `title`, `author`, `thumbnail`, `download_url`, `media_type`, `ext`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | Facebook video URL. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "facebook_download",
    "arguments": {
      "url": "https://www.facebook.com/watch/?v=1234567890"
    }
  }
}
```

**Related:** `facebook_page_scrape`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## snapchat_download — Snapchat Downloader

Get downloadable media URLs and metadata for a Snapchat spotlight/story video.

**When to use:** Getting the media URL for a public Snapchat Spotlight or story video.

**Not for:** Private snaps.

**Returns:** Media URLs plus metadata.

**Result fields:** `title`, `author`, `thumbnail`, `download_url`, `media_type`, `ext`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | Snapchat video URL. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "snapchat_download",
    "arguments": {
      "url": "https://www.snapchat.com/spotlight/abc123"
    }
  }
}
```

**Related:** `tiktok_download`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

# E-commerce catalogues

## product_scrape — Product Scraper

Scrape an e-commerce store's product catalogue (WooCommerce, Shopify, or generic) including variations, paid add-ons (each add-on option returns the combined parent+add-on total), descriptions, and reviews. Supports price/category/stock filters.

**When to use:** Exporting a store's catalogue for price comparison, competitor pricing, feed building or catalogue migration. Handles WooCommerce, Shopify and generic stores.

**Not for:** Marketplaces like Amazon/eBay listings pages, or a single product page you can read with scrape_web_pages.

**Returns:** One row per product (or per variant/add-on when expanded).

**Result fields:** `name`, `url`, `price`, `sale_price`, `currency`, `sku`, `in_stock`, `categories`, `variant`, `addon`, `description`, `rating`, `review_count`, `image`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `url` | string | yes |  | Store homepage or shop URL. |
| `max_products` | integer | no | `50` | Max products (0 = whole catalogue). |
| `include_variations` | boolean | no | `true` | Expand variable products into per-variant rows. |
| `include_addons` | boolean | no | `true` | Capture paid product add-ons (e.g. a battery bank on a UPS). Each add-on option becomes a row whose price is the combined parent+add-on total. |
| `include_descriptions` | boolean | no | `true` | Include product descriptions. |
| `include_reviews` | boolean | no | `true` | Include product reviews. |
| `max_reviews` | integer | no | `20` | Max reviews per product. |
| `search` | string | no |  | Filter: only products whose name contains this text. |
| `category` | string | no |  | Filter: only products whose category contains this text. |
| `min_price` | number | no |  | Filter: minimum base price. |
| `max_price` | number | no |  | Filter: maximum price (uses the add-on-inclusive total). |
| `in_stock_only` | boolean | no | `false` | Filter: only in-stock products. |
| `on_sale_only` | boolean | no | `false` | Filter: only on-sale products. |
| `platform` | string | no | `"auto"` | Force a platform or auto-detect. One of: `auto`, `woocommerce`, `shopify`, `generic`. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "product_scrape",
    "arguments": {
      "url": "https://examplestore.com",
      "max_products": 50,
      "in_stock_only": true
    }
  }
}
```

**Related:** `scrape_web_pages`, `google_search_scrape`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

# Email finding & verification

## email_verify — Email Verifier

Verify deliverability of one or many email addresses (syntax, MX, SMTP).

**When to use:** Checking whether addresses will actually deliver before a send — syntax, MX and live SMTP probe. Run it on any list you scraped or were given.

**Not for:** Finding addresses (use website_email_find) or only spotting throwaways (use disposable_email_check — it is much cheaper).

**Returns:** One row per address with a verdict.

**Result fields:** `email`, `verdict`, `syntax_valid`, `domain`, `mx_found`, `smtp_ok`, `is_catch_all`, `is_disposable`, `is_role`, `score`, `reason`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `emails` | string[] | yes |  | Email addresses to verify (max 100). |
| `do_smtp` | boolean | no | `true` | Perform live SMTP mailbox checks. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "email_verify",
    "arguments": {
      "emails": [
        "hello@example.com",
        "sales@example.com"
      ],
      "do_smtp": true
    }
  }
}
```

**Related:** `disposable_email_check`, `website_email_find`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## disposable_email_check — Disposable Email Checker

Flag disposable / temporary / throwaway email addresses or domains.

**When to use:** Fast signup-fraud / list-hygiene screening: is this address or domain a temporary/throwaway mailbox? Cheap and quick.

**Not for:** Proving an address exists — that needs email_verify's SMTP probe.

**Returns:** One row per address/domain.

**Result fields:** `input`, `domain`, `is_disposable`, `mx_found`, `source`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `emails` | string[] | yes |  | Emails or domains to check (max 200). |
| `do_mx` | boolean | no | `true` | Also verify the domain has MX records. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "disposable_email_check",
    "arguments": {
      "emails": [
        "test@mailinator.com",
        "ceo@acme.com"
      ],
      "do_mx": true
    }
  }
}
```

**Related:** `email_verify`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## website_email_find — Website Email Finder

Crawl a website/domain and find public contact emails, phones, and social links.

**When to use:** Turning a company domain into contact details — crawls the site for public emails, phones and social profiles. The standard enrichment step after a lead list.

**Not for:** Verifying deliverability (chain into email_verify) or guessing personal addresses.

**Returns:** Contacts found across the crawled pages.

**Result fields:** `website`, `emails`, `phones`, `socials`, `pages_crawled`, `source_page`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `website` | string | yes |  | Website URL or domain to crawl. |
| `max_pages` | integer | no | `12` | Cap on how many result pages get fetched. Defaults to max_results and can never exceed it plus any explicit `urls`. Plan ceiling: Starter 10, Pro 50, Gold 200. |
| `include_phones` | boolean | no | `true` | Also extract phone numbers. |
| `include_socials` | boolean | no | `true` | Also extract social profile links. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "website_email_find",
    "arguments": {
      "website": "acme.com",
      "max_pages": 12
    }
  }
}
```

**Related:** `email_verify`, `google_maps_search`, `scrape_web_pages`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

# Web search & page reading

## google_search — Google Web Search

Search the web and return the ranked result links (title, URL, domain, snippet, position) plus related searches and any answer box. Fast — it does NOT open the pages; use google_search_scrape when you need what the pages actually say. The payload reports `engine_used` and `google_used`: google.com refuses plain datacenter IPs, so unless a Google provider key (SERPER_API_KEY / SERPAPI_KEY / GOOGLE_CSE_KEY+CX) or a residential proxy is configured, results come from a clearly labelled fallback engine (Bing, DuckDuckGo, Brave, Mojeek, Yahoo) — never presented as Google's ranking. If no engine answers, the run fails with the reason instead of returning an empty success.

**When to use:** You need the RANKED LINKS ONLY — SERP position tracking, finding candidate URLs to feed another tool, or a quick 'who ranks for this'. Fastest search option.

**Not for:** Answering a question from page content — that needs google_search_scrape, which opens each page.

**Returns:** Ranked links plus related searches and any answer box.

**Result fields:** `title`, `url`, `domain`, `snippet`, `position`, `engine`, `engine_used`, `google_used`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `query` | string | no |  | The search query, e.g. 'best crm software for real estate'. Required unless you pass `queries`. |
| `queries` | string[] | no |  | Run several searches in one call. Use instead of `query` for multiple angles on a topic. Capped by plan: Starter 2, Pro 10, Gold 25 — extra queries are dropped, not rejected. |
| `max_results` | integer | no | `10` | How many result links this run may keep, SHARED across all queries (they do not multiply it). Clamped to the account's plan: Starter 10, Pro 50, Gold 200. Send 0 for 'as many as my plan allows'. |
| `site` | string | no |  | Restrict results to one domain, e.g. 'techcrunch.com'. Enforced server-side even when the answering engine ignores the site: operator. |
| `time_range` | string | no |  | Freshness filter. One of: ``, `day`, `week`, `month`, `year`. |
| `country` | string | no | `"us"` | Two-letter country for result localisation, e.g. 'us', 'uk', 'de'. |
| `language` | string | no | `"en"` | Two-letter UI language, e.g. 'en'. |
| `engine` | string | no | `"auto"` | Which engine to use. 'auto' tries the Google providers first, then a labelled fallback engine. 'google' means Google only. One of: `auto`, `google`, `serper`, `serpapi`, `google_cse`, `google_html`, `google_browser`, `bing`, `duckduckgo`, `brave`, `mojeek`, `yahoo`, `startpage`. |
| `allow_fallback` | boolean | no | `true` | When false, the run fails with an explicit error rather than falling back to a non-Google engine. Only applies when engine='auto'; naming an engine (including 'google') already means that engine or an honest failure. |
| `scrape_pages` | boolean | no | `false` | Kept false for this tool — use google_search_scrape to fetch page content. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "google_search",
    "arguments": {
      "query": "best crm for real estate agents",
      "max_results": 10,
      "country": "us"
    }
  }
}
```

**Related:** `google_search_scrape`, `scrape_web_pages`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## google_search_scrape — Google Web Search + Page Scrape

Search the web AND read every result page in one call. Returns the ranked links plus, for each one, the scraped page: final URL, HTTP status, title, meta description, canonical, language, H1/H2 headings, readable body text, word count, emails, phones, social profiles, Open Graph/Twitter cards and JSON-LD. This is the tool to use for research, fact-finding, competitor/lead analysis or answering a question from live web content. The payload reports `engine_used` and `google_used`: google.com refuses plain datacenter IPs, so unless a Google provider key (SERPER_API_KEY / SERPAPI_KEY / GOOGLE_CSE_KEY+CX) or a residential proxy is configured, results come from a clearly labelled fallback engine (Bing, DuckDuckGo, Brave, Mojeek, Yahoo) — never presented as Google's ranking. If no engine answers, the run fails with the reason instead of returning an empty success.

**When to use:** Research and fact-finding from live web content: search, then READ every result page. Use this when the answer lives inside the pages — competitor analysis, company research, 'what does the web say about X'.

**Not for:** URLs you already have (use scrape_web_pages — it skips the search step and costs less).

**Returns:** Ranked links, each with the parsed page attached.

**Result fields:** `title`, `url`, `domain`, `snippet`, `position`, `final_url`, `http_status`, `meta_description`, `canonical`, `language`, `headings`, `text`, `word_count`, `emails`, `phones`, `socials`, `open_graph`, `jsonld`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `query` | string | no |  | The search query, e.g. 'best crm software for real estate'. Required unless you pass `queries`. |
| `queries` | string[] | no |  | Run several searches in one call. Use instead of `query` for multiple angles on a topic. Capped by plan: Starter 2, Pro 10, Gold 25 — extra queries are dropped, not rejected. |
| `max_results` | integer | no | `10` | How many result links this run may keep, SHARED across all queries (they do not multiply it). Clamped to the account's plan: Starter 10, Pro 50, Gold 200. Send 0 for 'as many as my plan allows'. |
| `site` | string | no |  | Restrict results to one domain, e.g. 'techcrunch.com'. Enforced server-side even when the answering engine ignores the site: operator. |
| `time_range` | string | no |  | Freshness filter. One of: ``, `day`, `week`, `month`, `year`. |
| `country` | string | no | `"us"` | Two-letter country for result localisation, e.g. 'us', 'uk', 'de'. |
| `language` | string | no | `"en"` | Two-letter UI language, e.g. 'en'. |
| `engine` | string | no | `"auto"` | Which engine to use. 'auto' tries the Google providers first, then a labelled fallback engine. 'google' means Google only. One of: `auto`, `google`, `serper`, `serpapi`, `google_cse`, `google_html`, `google_browser`, `bing`, `duckduckgo`, `brave`, `mojeek`, `yahoo`, `startpage`. |
| `allow_fallback` | boolean | no | `true` | When false, the run fails with an explicit error rather than falling back to a non-Google engine. Only applies when engine='auto'; naming an engine (including 'google') already means that engine or an honest failure. |
| `scrape_pages` | boolean | no | `true` | Fetch and parse each result page. |
| `max_pages` | integer | no |  | Cap on how many result pages get fetched. Defaults to max_results and can never exceed it plus any explicit `urls`. Plan ceiling: Starter 10, Pro 50, Gold 200. |
| `text_chars` | integer | no | `5000` | Characters of readable body text per page. Clamped by plan: Starter 5,000, Pro 50,000, Gold 200,000 (full page). |
| `include_contacts` | boolean | no | `true` | Extract emails, phone numbers and social profiles from each page. |
| `include_structured` | boolean | no | `true` | Extract JSON-LD, Open Graph and Twitter-card data from each page. |
| `include_links` | boolean | no | `false` | Return the internal/external links found on each page. |
| `include_images` | boolean | no | `false` | Return the images (src + alt) found on each page. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "google_search_scrape",
    "arguments": {
      "query": "top project management saas 2026",
      "max_results": 5,
      "text_chars": 5000
    }
  }
}
```

**Related:** `google_search`, `scrape_web_pages`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.

## scrape_web_pages — Web Page Scraper

Fetch specific URLs you already know and extract their content — title, meta description, canonical, language, H1/H2 headings, readable body text, word count, emails, phones, social profiles, Open Graph and JSON-LD structured data. No search step. Blocked or non-HTML URLs come back with the reason in their status instead of failing the whole run.

**When to use:** You already have the URLs and want their content — reading a docs page, a pricing page, an article, or enriching links another tool returned.

**Not for:** Discovering URLs (search first with google_search) or JS-only app screens behind a login.

**Returns:** One row per URL with parsed content; blocked pages report the reason in-row instead of failing the run.

**Result fields:** `url`, `final_url`, `http_status`, `title`, `meta_description`, `canonical`, `language`, `headings`, `text`, `word_count`, `emails`, `phones`, `socials`, `open_graph`, `jsonld`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `urls` | string[] | yes |  | The page URLs to scrape (http/https). Private and internal addresses are rejected. |
| `text_chars` | integer | no | `5000` | Characters of readable body text per page. Clamped by plan: Starter 5,000, Pro 50,000, Gold 200,000 (full page). |
| `include_contacts` | boolean | no | `true` | Extract emails, phone numbers and social profiles from each page. |
| `include_structured` | boolean | no | `true` | Extract JSON-LD, Open Graph and Twitter-card data from each page. |
| `include_links` | boolean | no | `false` | Return the internal/external links found on each page. |
| `include_images` | boolean | no | `false` | Return the images (src + alt) found on each page. |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "scrape_web_pages",
    "arguments": {
      "urls": [
        "https://example.com/pricing"
      ],
      "text_chars": 8000
    }
  }
}
```

**Related:** `google_search`, `google_search_scrape`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

# Ad intelligence

## google_ads_transparency — Google Ads Transparency Search

Check whether a business or brand is running GOOGLE ads right now. Reads Google's public Ads Transparency Center and returns each matching advertiser with its verified name, advertiser ID, region and live ad count. No match is a REAL answer meaning nobody advertises under that name in that region — not a failure. Keyless and fast (about a second).

**When to use:** Answering 'is this business running Google ads?' for one named advertiser, in about a second. Keyless.

**Not for:** Facebook/Instagram ads (use facebook_ads_scrape) or scanning a whole niche (use ad_library_lead_finder).

**Returns:** One row per matching verified advertiser. Zero matches is a real answer: nobody advertises under that name in that region.

**Result fields:** `advertiser_name`, `advertiser_id`, `region`, `ad_count`, `transparency_url`, `verified`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `query` | string | yes |  | Advertiser, business or brand name to look up, e.g. "Joe's 2 Sons Plumbing". |
| `country` | string | no | `"US"` | ISO country code of the market to check, e.g. 'US', 'GB', 'DE'. Advertisers are verified per region. |
| `limit` | integer | no | `20` | Max advertisers to return (1-50). |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "google_ads_transparency",
    "arguments": {
      "query": "Joe's 2 Sons Plumbing",
      "country": "US",
      "limit": 20
    }
  }
}
```

**Related:** `facebook_ads_scrape`, `ad_library_lead_finder`

**Runtime:** asynchronous job. Counts as 1 run against the monthly quota.

## ad_library_lead_finder — Ad Library Lead Finder

Find local businesses in a niche + city and report which ones are running ads. For every business it checks BOTH Google's Ads Transparency Center and Meta's Ad Library, then returns a scored, ranked sales-lead list with phone, website, rating, reviews, live ad counts, a verdict and a suggested opening line. Ad status is tristate: 'advertising', 'not_advertising' or 'unknown' — a check that could not be completed is NEVER reported as 'not advertising'. Use mode='cold' to rank businesses running nothing highest, or mode='spending' to rank current advertisers highest.

**When to use:** Prospecting for an agency: find businesses in a niche+city, check BOTH Google and Meta ad libraries, and get a scored, ranked lead list with a suggested opening line. mode='cold' for businesses running nothing, mode='spending' for active advertisers.

**Not for:** A single known business (use google_ads_transparency) or a plain lead list with no ad check (use google_maps_search — much faster).

**Returns:** One scored lead per business, ranked. Ad status is tristate — 'unknown' means the check could not complete, never 'not advertising'.

**Result fields:** `name`, `verdict`, `lead_score`, `phone`, `website`, `google_ads_status`, `google_ads_count`, `meta_ads_status`, `meta_ads_count`, `rating`, `review_count`, `address`, `pitch`

**Parameters**

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| `niche` | string | yes |  | Business type to search for, e.g. 'dentists', 'roofers', 'gyms'. |
| `city` | string | no |  | City or area to search in, e.g. 'Miami, FL'. |
| `mode` | string | no | `"cold"` | 'cold' ranks businesses running NO ads highest (pitch: you're invisible); 'spending' ranks current advertisers highest (pitch: we'll beat your agency); 'all' ranks on business quality only. One of: `cold`, `spending`, `all`. |
| `country` | string | no | `"US"` | ISO country code for both ad libraries, e.g. 'US', 'GB'. |
| `limit` | integer | no | `20` | How many businesses to build the list from and check (clamped to the account tier ceiling). |
| `check_google` | boolean | no | `true` | Check Google Ads Transparency. Fast. |
| `check_meta` | boolean | no | `true` | Check the Meta Ad Library. Needs a browser per business, so it is the slow half — set false for a quick Google-only sweep. |
| `min_score` | integer | no | `0` | Drop leads scoring below this (0-100). 0 keeps everything. |
| `only_verified` | boolean | no | `false` | Return only rows where BOTH ad checks completed (no 'unknown'). |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "ad_library_lead_finder",
    "arguments": {
      "niche": "roofers",
      "city": "Austin, TX",
      "mode": "cold",
      "limit": 20,
      "check_meta": false
    }
  }
}
```

**Related:** `google_ads_transparency`, `facebook_ads_scrape`, `google_maps_search`

**Runtime:** asynchronous job — usually exceeds the inline wait, so expect `{status:"running", job_id}` and poll `get_job_result`. Counts as 1 run against the monthly quota.


---

# ConvertFleet recipes — multi-tool workflows

## Build an enriched local lead list

_Goal:_ A contactable, verified B2B prospect list for one niche in one city.

_Tools:_ `google_maps_search` → `website_email_find` → `email_verify`

1. google_maps_search { query: <niche>, location: <city>, limit: 25 } — the businesses, with phone/website/rating.
2. For each row that has a website: website_email_find { website: <that domain> } — public emails, phones, socials.
3. email_verify { emails: [...collected addresses] } — drop anything that is not 'deliverable' before you hand the list over.
4. Report per lead: name, phone, website, best verified email, rating/review count.

## Find businesses that are NOT advertising (agency prospecting)

_Goal:_ A ranked list of local businesses running no ads, with an opening line for each.

_Tools:_ `ad_library_lead_finder` → `google_ads_transparency` → `website_email_find`

1. ad_library_lead_finder { niche, city, mode: 'cold', limit: 20 } — one call does the Maps search AND both ad-library checks.
2. Set check_meta:false for a fast Google-only sweep; leave it true for the full picture (slower — expect a job handle back).
3. Treat google_ads_status/meta_ads_status = 'unknown' as 'not checked', never as 'not advertising'.
4. Optionally website_email_find on the top-scoring rows to get a contact address.

## Audit a competitor's live advertising

_Goal:_ What a named brand is running right now, on Google and on Meta.

_Tools:_ `google_ads_transparency` → `facebook_ads_scrape`

1. google_ads_transparency { query: <brand>, country } — is there a verified advertiser, and how many live ads?
2. facebook_ads_scrape { query: <brand>, country, status: 'active' } — the actual creatives, copy and CTAs.
3. Zero results from either is a real finding (not advertising there), not a failure.

## Answer a question from live web content

_Goal:_ A sourced answer built from pages that exist today, not from memory.

_Tools:_ `google_search_scrape` → `google_search` → `scrape_web_pages`

1. google_search_scrape { query, max_results: 5, text_chars: 5000 } — searches AND reads each page in one call.
2. If you already have the URLs, skip the search: scrape_web_pages { urls: [...] }.
3. If you only need to know who ranks (no page content), google_search is much faster and cheaper.
4. Cite the final_url of each page you used; check engine_used before calling results 'Google's ranking'.

## Summarise or mine a YouTube channel

_Goal:_ What a channel publishes and what was actually said in it.

_Tools:_ `youtube_extract` → `youtube_transcript` → `youtube_competitor`

1. youtube_extract { url: <channel url>, max_videos: 20 } — the recent uploads with view counts.
2. youtube_transcript { urls: [...the video URLs you care about] } — full text + timestamps to quote from.
3. youtube_competitor { urls: [2-5 channels] } when the question is comparative.

## Clean an email list before a send

_Goal:_ Only addresses that will deliver, with throwaways removed.

_Tools:_ `disposable_email_check` → `email_verify`

1. disposable_email_check { emails: [...] } first — it is fast and removes the obvious junk cheaply.
2. email_verify { emails: [...survivors], do_smtp: true } — syntax, MX and a live mailbox probe.
3. Keep verdict = 'deliverable'; treat catch-all domains as risky, not safe.

## Export a competitor's catalogue and prices

_Goal:_ Every product, variant and price from a store.

_Tools:_ `product_scrape` → `scrape_web_pages`

1. product_scrape { url: <store homepage>, max_products: 0 } for the whole catalogue (use a number to cap it).
2. Filter server-side with min_price/max_price/category/in_stock_only instead of pulling everything and filtering yourself.
3. For a single product page you already have, scrape_web_pages is lighter.


---

# Errors, limits and job handling

## Asynchronous jobs
Every tool starts a job. If it completes within ~25 seconds the rows come back inline. Otherwise the call returns `{ "status": "running", "job_id": "...", "tool_flow": "tool-run" | "scrape" }`. That is a normal, successful response — wait a few seconds and call:

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_job_result",
    "arguments": {
      "job_id": "JOB_ID",
      "tool_flow": "tool-run"
    }
  }
}
```

Repeat until `status` is `done` (results attached) or `error`.

## JSON-RPC error codes

| code | meaning | what to do |
| --- | --- | --- |
| `-32001` | Authentication, quota or scope. Invalid key, monthly cap reached, or the tool is outside a scoped token's allow-list. | Do not retry. Call `account_status` and tell the user which of the three it is. |
| `-32602` | Invalid parameters. The message names the accepted arguments and gives an example. | Fix the arguments and call again. |
| `-32601` | Unknown tool. The message lists the closest real tool names. | Call one of the suggestions, or `find_tool`. |
| `-32000` | Upstream/site error — the target site blocked or failed the run. | One retry after a pause is reasonable. |

## Quotas and clamping
Runs are metered monthly per account and attributed to a source (web, api, mcp). Per-run row counts are clamped to the plan tier, so a request for more rows than the plan allows returns the ceiling rather than an error — always read `count` in the result. `account_status` reports the plan, the usage so far and the tools the current credential may call.

## Empty results
An empty result set is normally a real answer: no businesses match, or nobody is advertising under that name in that region. Tools that were blocked report an error instead, so an empty success can be reported to the user as a finding.


---

# Connect an agent to ConvertFleet MCP

Endpoint: `https://convertfleet.online/mcp` (Streamable HTTP, JSON-RPC 2.0)
Auth: `Authorization: Bearer <token>` — a scoped `cfm-` MCP token (recommended) or your account `sk-` key. OAuth 2.1 is also supported for clients that cannot send headers.
Get a token: https://convertfleet.online/dashboard → MCP / Agents.

## Hermes
```yaml
mcp_servers:
  convertfleet:
    url: "https://convertfleet.online/mcp"
    headers:
      Authorization: "Bearer YOUR_TOKEN"
```

## Claude Code / Claude Desktop
```json
{
  "mcpServers": {
    "convertfleet": {
      "type": "http",
      "url": "https://convertfleet.online/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

## OpenClaw
```json
{
  "mcpServers": {
    "convertfleet": {
      "type": "streamable-http",
      "url": "https://convertfleet.online/model_context_protocol/2025-03-26/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

## n8n / Zapier / Make
Add an MCP Client node/connection with server URL `https://convertfleet.online/mcp`, transport "HTTP Streamable", auth "Bearer" → your token.

## curl
```bash
curl -sN https://convertfleet.online/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```


---

# Documentation pages

- https://convertfleet.online/mcp
- https://convertfleet.online/mcp/docs
- https://convertfleet.online/mcp/quickstart
- https://convertfleet.online/mcp/quickstart/hermes
- https://convertfleet.online/mcp/quickstart/claude
- https://convertfleet.online/mcp/quickstart/cursor
- https://convertfleet.online/mcp/quickstart/openclaw
- https://convertfleet.online/mcp/quickstart/n8n
- https://convertfleet.online/mcp/quickstart/zapier
- https://convertfleet.online/mcp/quickstart/make
- https://convertfleet.online/mcp/quickstart/curl
- https://convertfleet.online/mcp/quickstart/python
- https://convertfleet.online/mcp/quickstart/typescript
- https://convertfleet.online/mcp/tools
- https://convertfleet.online/mcp/tools/google_maps_search
- https://convertfleet.online/mcp/tools/facebook_page_scrape
- https://convertfleet.online/mcp/tools/facebook_ads_scrape
- https://convertfleet.online/mcp/tools/youtube_extract
- https://convertfleet.online/mcp/tools/youtube_competitor
- https://convertfleet.online/mcp/tools/youtube_transcript
- https://convertfleet.online/mcp/tools/twitter_scrape
- https://convertfleet.online/mcp/tools/instagram_scrape
- https://convertfleet.online/mcp/tools/product_scrape
- https://convertfleet.online/mcp/tools/email_verify
- https://convertfleet.online/mcp/tools/disposable_email_check
- https://convertfleet.online/mcp/tools/website_email_find
- https://convertfleet.online/mcp/tools/youtube_download
- https://convertfleet.online/mcp/tools/instagram_download
- https://convertfleet.online/mcp/tools/tiktok_download
- https://convertfleet.online/mcp/tools/facebook_download
- https://convertfleet.online/mcp/tools/snapchat_download
- https://convertfleet.online/mcp/tools/google_search
- https://convertfleet.online/mcp/tools/google_search_scrape
- https://convertfleet.online/mcp/tools/scrape_web_pages
- https://convertfleet.online/mcp/tools/google_ads_transparency
- https://convertfleet.online/mcp/tools/ad_library_lead_finder
- https://convertfleet.online/mcp/recipes
- https://convertfleet.online/mcp/auth
- https://convertfleet.online/mcp/errors
- https://convertfleet.online/mcp/api
- https://convertfleet.online/mcp/faq