keyword_generator
Generate keyword ideas for SEO content by analyzing search trends and related terms to improve backlink strategies.
Instructions
Get keyword ideas for the specified keyword
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | Yes | ||
| country | No | us | |
| search_engine | No |
Implementation Reference
- src/seo_mcp/server.py:100-109 (handler)Handler function for 'keyword_generator' tool. Registers the tool via @mcp.tool(), handles captcha solving, and delegates to get_keyword_ideas for core logic.@mcp.tool() def keyword_generator(keyword: str, country: str = "us", search_engine: str = "Google") -> Optional[List[str]]: """ Get keyword ideas for the specified keyword """ site_url = f"https://ahrefs.com/keyword-generator/?country={country}&input={urllib.parse.quote(keyword)}" token = get_capsolver_token(site_url) if not token: raise Exception(f"Failed to get verification token for keyword: {keyword}") return get_keyword_ideas(token, keyword, country, search_engine)
- src/seo_mcp/keywords.py:54-77 (helper)Core helper function that makes API request to Ahrefs for keyword ideas and formats the response.def get_keyword_ideas(token: str, keyword: str, country: str = "us", search_engine: str = "Google") -> Optional[List[str]]: if not token: return None url = "https://ahrefs.com/v4/stGetFreeKeywordIdeas" payload = { "withQuestionIdeas": True, "captcha": token, "searchEngine": search_engine, "country": country, "keyword": ["Some", keyword] } 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_keyword_ideas(data)
- src/seo_mcp/keywords.py:6-51 (helper)Helper function to parse and format the raw keyword ideas data from Ahrefs API into a structured list.def format_keyword_ideas(keyword_data: Optional[List[Any]]) -> List[str]: if not keyword_data or len(keyword_data) < 2: return ["\n❌ No valid keyword ideas retrieved"] data = keyword_data[1] result = [] # 处理常规关键词推荐 if "allIdeas" in data and "results" in data["allIdeas"]: all_ideas = data["allIdeas"]["results"] # total = data["allIdeas"].get("total", 0) for idea in all_ideas: simplified_idea = { "keyword": idea.get('keyword', 'No keyword'), "country": idea.get('country', '-'), "difficulty": idea.get('difficultyLabel', 'Unknown'), "volume": idea.get('volumeLabel', 'Unknown'), "updatedAt": idea.get('updatedAt', '-') } result.append({ "label": "keyword ideas", "value": simplified_idea }) # 处理问题类关键词推荐 if "questionIdeas" in data and "results" in data["questionIdeas"]: question_ideas = data["questionIdeas"]["results"] # total = data["questionIdeas"].get("total", 0) for idea in question_ideas: simplified_idea = { "keyword": idea.get('keyword', 'No keyword'), "country": idea.get('country', '-'), "difficulty": idea.get('difficultyLabel', 'Unknown'), "volume": idea.get('volumeLabel', 'Unknown'), "updatedAt": idea.get('updatedAt', '-') } result.append({ "label": "question ideas", "value": simplified_idea }) if not result: return ["\n❌ No valid keyword ideas retrieved"] return result
- src/seo_mcp/server.py:24-65 (helper)Shared helper to obtain Cloudflare Turnstile token using CapSolver for bypassing Ahrefs captcha.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