Skip to main content
Glama
cnych

Backlinks MCP

by cnych

get_backlinks_list

Retrieve a list of backlinks for any domain to analyze SEO performance, including title, URL, and domain rating data.

Instructions

Get backlinks list for the specified domain Args: domain (str): The domain to query Returns: List of backlinks for the domain, containing title, URL, domain rating, etc.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
domainYes

Implementation Reference

  • The primary handler function for the 'get_backlinks_list' tool. Decorated with @mcp.tool() for registration. Orchestrates caching, token acquisition, signature retrieval, and backlinks fetching.
    @mcp.tool() def get_backlinks_list(domain: str) -> Optional[Dict[str, Any]]: """ Get backlinks list for the specified domain Args: domain (str): The domain to query Returns: List of backlinks for the domain, containing title, URL, domain rating, etc. """ # Try to get signature from cache signature, valid_until, overview_data = load_signature_from_cache(domain) # If no valid signature in cache, get a new one if not signature or not valid_until: # Step 1: Get token site_url = f"https://ahrefs.com/backlink-checker/?input={domain}&mode=subdomains" token = get_capsolver_token(site_url) if not token: raise Exception(f"Failed to get verification token for domain: {domain}") # Step 2: Get signature and validUntil signature, valid_until, overview_data = get_signature_and_overview(token, domain) if not signature or not valid_until: raise Exception(f"Failed to get signature for domain: {domain}") # Step 3: Get backlinks list backlinks = get_backlinks(signature, valid_until, domain) return { "overview": overview_data, "backlinks": backlinks }
  • Core helper function that makes the API request to Ahrefs to retrieve the backlinks list using the provided signature and formats the results.
    def get_backlinks(signature: str, valid_until: str, domain: str) -> Optional[List[Any]]: if not signature or not valid_until: return None url = "https://ahrefs.com/v4/stGetFreeBacklinksList" payload = { "reportType": "TopBacklinks", "signedInput": { "signature": signature, "input": { "validUntil": valid_until, "mode": "subdomains", "url": f"{domain}/" } } } headers = { "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) if response.status_code != 200: return None data = response.json() return format_backlinks(data, domain)
  • Helper function to obtain the API signature, validUntil timestamp, and overview data from Ahrefs using the captcha token obtained from CapSolver.
    def get_signature_and_overview(token: str, domain: str) -> Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]: """ Get signature and validUntil parameters using the token Args: token: Verification token domain: Domain to query Returns: (signature, valid_until, overview_data) tuple, or (None, None, None) if failed """ url = "https://ahrefs.com/v4/stGetFreeBacklinksOverview" payload = { "captcha": token, "mode": "subdomains", "url": domain } headers = { "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) if response.status_code != 200: return None, None, None data = response.json() try: # Assuming data format is always ['Ok', {signature object}] if isinstance(data, list) and len(cast(List[Any], data)) > 1: second_element: Dict[str, Any] = cast(Dict[str, Any], data[1]) signature: str = cast(str, second_element['signedInput']['signature']) valid_until: str = cast(str, second_element['signedInput']['input']['validUntil']) overview_data: Dict[str, Any] = cast(Dict[str, Any], second_element['data']) # Save the new signature to cache save_signature_to_cache(signature, valid_until, overview_data, domain) return signature, valid_until, overview_data else: return None, None, None except Exception: return None, None, None
  • Helper function to load previously cached signature and overview data for a domain, checking if it's still valid (not expired).
    def load_signature_from_cache(domain: str) -> Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]: """ Load signature information for a specific domain from local cache file Returns the signature and valid_until if cache is valid, otherwise None Args: domain: Domain to query Returns: (signature, valid_until) tuple, or (None, None) if no valid cache """ if not os.path.exists(SIGNATURE_CACHE_FILE): return None, None, None try: with open(SIGNATURE_CACHE_FILE, 'r') as f: cache_data = json.load(f) # Check if cache exists for current domain if domain not in cache_data: return None, None, None domain_cache = cache_data[domain] # Check if signature is expired valid_until = domain_cache.get("valid_until") if valid_until: # Convert ISO date string to timestamp for comparison valid_until_timestamp = iso_to_timestamp(valid_until) current_time = time.time() if current_time < valid_until_timestamp: return domain_cache.get("signature"), valid_until, domain_cache.get("overview_data") else: return None, None, None else: return None, None, None except Exception: return None, None, None
  • Helper function to obtain captcha token from CapSolver service, required to bypass Ahrefs protections before getting signatures.
    def get_capsolver_token(site_url: str) -> Optional[str]: """ Use CapSolver to solve the captcha and get a token Args: site_url: Site URL to query Returns: Verification token or None if failed """ if not api_key: return None payload = { "clientKey": api_key, "task": { "type": 'AntiTurnstileTaskProxyLess', "websiteKey": "0x4AAAAAAAAzi9ITzSN9xKMi", # site key of your target site: ahrefs.com, "websiteURL": site_url, "metadata": { "action": "" # optional } } } res = requests.post("https://api.capsolver.com/createTask", json=payload) resp = res.json() task_id = resp.get("taskId") if not task_id: return None while True: time.sleep(1) # delay payload = {"clientKey": api_key, "taskId": task_id} res = requests.post("https://api.capsolver.com/getTaskResult", json=payload) resp = res.json() status = resp.get("status") if status == "ready": token = resp.get("solution", {}).get('token') return token if status == "failed" or resp.get("errorId"): return None

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cnych/backlinks-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server