google_trends_server.py•2.6 kB
from typing import Annotated
from fastmcp import FastMCP
from datetime import datetime, timedelta, timezone
import serpapi
import os
from dotenv import load_dotenv
mcp = FastMCP(
name="google-trends",
instructions="Provides Google Trends search interest data for queries over 30-day periods before a cutoff date. Use this to understand search popularity trends for topics, events, or entities."
)
@mcp.tool(exclude_args=["cutoff_date"])
async def get_google_trends(
query: Annotated[str, "The search query to analyze trends for"],
cutoff_date: Annotated[str, "ISO format date (YYYY-MM-DD) - retrieve trends data ending at this date"] = datetime.now().strftime("%Y-%m-%d")
) -> str:
"""Get Google Trends data for a query over the past 30 days before cutoff date.
Args:
query: Search query string
cutoff_date: End date for trends data in YYYY-MM-DD format
Returns:
Formatted string with interest over time data (0-100 scale)
"""
try:
load_dotenv()
# Parse cutoff date
cutoff_date_dt = datetime.fromisoformat(cutoff_date).replace(tzinfo=timezone.utc)
cutoff_date_str = cutoff_date_dt.strftime("%Y-%m-%d")
start_date_str = (cutoff_date_dt - timedelta(days=30)).strftime("%Y-%m-%d")
# Call SerpAPI
search = serpapi.search({
"api_key": os.getenv("SERPAPI_API_KEY"),
"engine": "google_trends",
"data_type": "TIMESERIES",
"geo": "US",
"tz": 0,
"q": query,
"date": f"{start_date_str} {cutoff_date_str}",
})
result = search.get_dict()["interest_over_time"]["timeline_data"]
if not result:
return f"No Google Trends data found for query: {query}"
# Format output
formatted_lines = [
f"--- Google Trends for '{query}' ---",
f"Period: {start_date_str} to {cutoff_date_str}",
f"Region: US",
"",
"Interest over time (0-100 scale, where 100 = peak popularity):"
]
for item in result:
date = item["date"]
value = item["values"][0]["extracted_value"]
partial = " (partial data)" if item.get("partial_data") else ""
formatted_lines.append(f" {date}: {value}{partial}")
return "\n".join(formatted_lines)
except ValueError as e:
return f"Error parsing date '{cutoff_date}'. Please use ISO format (YYYY-MM-DD): {str(e)}"
except Exception as e:
return f"Error retrieving Google Trends data: {str(e)}"