MCP server exposing trendspyg as tools for AI agents. Lets any MCP client (Claude Desktop, Claude Code, Cursor, ...) query Google Trends through trendspyg — no Python required on the agent side.
This is a well-structured Google Trends MCP server with 11 tools covering trending, interest analysis, and historical data. Strengths: all tools have clear, detailed descriptions (100-500+ chars each); input schemas are fully specified with types; parameter descriptions are explicit and guide LLM behavior (geo codes, rate-limit warnings, browser requirements). Naming is consistently verb-first (get_*, list_*, compare_*) and unambiguous. Composition is strong, each tool does one thing, and output is designed for chaining (e.g., suggest_keywords returns mids for interest tools). Weaknesses: (1) No explicit output schemas documented, descriptions mention what's returned (e.g., 'normalized envelope with ~10-20 trends'), but formal schema definitions are absent from the code sample. (2) Error handling descriptions are minimal, tools mention rate limits and Chrome requirements but lack structured error classifications or recovery guidance (e.g., 'If rate-limited, wait 10+ minutes before retrying'). (3) Security baseline met (no credentials exposed, read-only risk), but no explicit scope/permission declarations. (4) STDIO transport caps this at a hard ceiling. Overall, this is a B-grade server, excellent domain design and descriptions, but missing output schema formalization and robust error guidance.
Compare 2-5 keywords on ONE shared 0-100 scale — the multi-keyword case. Single-keyword fetches each drive their own series independently (each keyword's own peak = 100), so fetching one at a time does NOT produce comparable numbers. A comparison call loads Google's own comparison view: one browser load, directly comparable values. SLOW on a fresh fetch: typically 10-90 seconds (one browser load, multiple keywords, widgets, and optional region tiles). Requires Chrome; rate-limited by Google — do NOT call it in a loop (roughly 8-10 fresh sessions in a short burst triggers a hard 429 block for this machine's IP). Repeating an IDENTICAL request is instant (cached up to 1h). Returns an envelope with: averages (keyword -> average relative interest), interest_over_time (array of comparable points), interest_by_region (who wins where), and schema/metadata.
Get current Google trends for several countries/states in one call. Fast (typically 0.2-2s per geo, no browser). Returns {geo: envelope} with the same normalized shape as get_trending_now. Accepts 1-20 geo codes, e.g. ["US", "GB", "DE"]. The full envelopes are large (about 15 KB per geo: news articles and images per trend) — pass compact=true to get only keyword, rank, volume_min and is_active per trend (about 1 KB per geo), which is enough to compare what is trending where. Pass archive=true from the first fetch to record fresh observations locally for get_trending_history. Cached reads do not add history; use get_trend_changes(archive=true) to record a fresh poll when needed.
Get 0-100 search interest for a keyword broken down by region (countries, US states, or cities). Answers 'who is searching for this?' by place. SLOW on a fresh fetch: drives Chrome, typically 10-90 seconds (more regions = longer). Requires Chrome; rate-limited by Google — do NOT call in a loop. Repeating an identical request is instant (cached up to 1h). Returns an array of regions with geo codes, names, and relative interest values. One keyword only (use compare_interest_over_time for multi-keyword comparison).
No explicit return/output schemas documented in tool definitions. Descriptions mention what is returned (e.g., 'normalized envelope', 'array of observations') but no formal JSON Schema for outputs.
Error handling lacks structured categorization and recovery guidance. Tools mention rate limits (429 blocking, 'stop for tens of minutes') and Chrome requirements but do not return error responses with actionable next steps (e.g., 'retryable', 'user_fixable', 'fatal').
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 75 | 2026-07-28+ | v2 |
Get Google's 0-100 relative search interest for a keyword over time. SLOW on a fresh fetch: drives a real Chrome browser against Google's Explore page — typically 10-40 seconds. Page loads and widget requests have timeouts, with a 44s browser-work budget between phases; driver setup/download and cleanup add time. Requires Chrome on this machine; Google rate-limits it aggressively — NEVER poll it or call it in a loop (roughly 8-10 fresh sessions in a short burst triggers Google's hard 429 block for this machine's IP); if it fails with a rate-limit error, stop for tens of minutes at least — do not retry. Repeating an IDENTICAL request is instant: results come from a local disk cache while fresh (up to 1h old for "now *" timeframes, 24h otherwise). Sessions reuse Google's cookies (a small file beside the cache) so this machine looks like one returning visitor — Google refuses new visitors first. Returns [{date, value, is_partial}, ...]; a keyword Google has no data for comes back as all zeros (Google's own answer). timeframe examples: "now 7-d", "today 12-m", "today 5-y", "all". gprop selects the Google property: "" (web search, default), "youtube" (YouTube search interest), "images", "news", or "froogle" (Google Shopping).
Get queries related to a keyword: 'top' (most popular) and 'rising' (fastest growing). Helpful for understanding what people search alongside a topic. SLOW on a fresh fetch: drives Chrome, typically 10-90 seconds. Requires Chrome; rate-limited by Google — do NOT call in a loop. Repeating an identical request is instant (cached up to 1h). Returns envelope with schema_version, source, keyword, timeframe, gprop, fetched_at, and related_queries dict with 'top' and 'rising' arrays.
Report what changed in Google trends for a geo since this tool was last called. Fast (typically 0.2-2s, no browser). The first call for a geo captures a baseline and reports no changes; each later call returns events diffed against the previous call: new, dropped, volume_up, volume_down, rank_change. Useful for monitoring a topic over a conversation or scheduled runs. Pass archive=true from the first fetch to record fresh observations locally for get_trending_history. Cached reads do not add history; use get_trend_changes(archive=true) to record a fresh poll when needed.
Export Google Trends' CSV data: full hourly trends (US only) with a 7-hour delay, searchable by category, hour window (0-168h = 0-7 days), and filters. Slow: drives Chrome, typically 10-15 seconds per call. Requires Chrome; rate-limited by Google — do NOT call in a loop. Repeating an identical request is instant (cached). US-only (this is Google's own limit). Returns dict with trend details: Trends (title), Trend breakdown (related search terms), Search volume, and more.
Query this machine's local archive: what WAS trending at any earlier observation? Instant (no network); only covers fetches recorded with archiving enabled (pass archive=true to Trending Now and related tools from the first call to build that history). Returns array of observations, newest first.
Get what is trending on Google right now for a country or US state. Fast (typically 0.2-2s, no browser). Returns a normalized envelope with ~10-20 trends: keyword, rank, search volume (text + numeric minimum), start time, related queries, news articles with sources, and an image. geo examples: "US", "GB", "JP", "US-CA". Use list_supported_options for the full list. Pass archive=true from the first fetch to record fresh observations locally for get_trending_history. Cached reads do not add history; use get_trend_changes(archive=true) to record a fresh poll when needed.
List every supported geo code plus the filters get_trending_full accepts. Instant (no network). Returns 125 country codes, 51 US state codes, the category keys and hour windows for get_trending_full, and timeframe examples for get_interest_over_time.
Resolve ambiguous text to topic IDs and metadata. Google Trends uses Topic IDs (mids) behind the scenes; the same text (e.g., 'Apple') can map to different entities (the fruit, the company, the record label, ...). This tool queries Google's suggestion service (instant, no Chrome) and returns ranked candidates: each with a mid, title, type, and description. Use the mid in interest tools; keep the ID-to-label mapping when explaining results to users. Suggestions are not a popularity ranking and empty suggestions do not mean zero interest.
STDIO-only transport. This server cannot be used by hosted MCP clients or remote agents. Consider adding HTTP/SSE support or Streamable HTTP.
Rate limit and resource constraints documented in descriptions but not as formal tool annotations (readOnlyHint, destructiveHint). All tools are read-only but lack explicit 'readOnlyHint' annotation.
Some parameters use string type for constrained sets (e.g., 'geo' codes, 'gprop' values). While descriptions are explicit, formal enum constraints would prevent LLM hallucination.