Google Trends search interest over time with growth metrics. Free key at trendsapi.ai
ai.trendsapi/google-trends (MCP) — Model Context Protocol Server
This MCP server provides access to Google Trends search interest over time, including normalized 0–100 scores, history, and growth metrics. It exposes a REST API–style workflow for trend-data and keyword-research, with a stated free key option via trendsapi.ai. The readme describes it as a Python client “Not a scraper.”
🛠️ Key Features
Search interest over time with normalized 0–100 scores
History and growth metrics
Integration oriented around REST API access
Tool count: 3
🚀 Use Cases
Time-series trend-data for market-research
SEO-oriented keyword research using search-interest/search-volume signals
Alternative-data workflows focused on Google Trends
⚡ Developer Benefits
Model Context Protocol support (topics include mcp/mcp-server)
Developer-focused data types: JSON API and REST API terminology
Point-to-point growth for a keyword on one or more sources. Each window is a preset string (12M, 3M, YTD, and the other listed periods). Values are on a 0-100 scale, plus absolute volume when available. Prefer this over get_time_series for growth questions. app downloads and app rankings are keyword sources (Android bundle ID). They are not the App Store / Google Play live boards on get_top_trends. If the request is rate limited or the monthly quota is used up, tell the user their plan limit is reached.
What to look up. The string format is required by source. Standard sources (google search, google images, google news, google shopping, youtube, wikipedia, tiktok, reddit, amazon, news sentiment, news volume): any name or phrase, e.g. 'nike'. npm: exact npmjs.com package name, case-sensitive. Right: 'react', '@babel/core'. Wrong: 'React', 'React.js'. python: exact PyPI project name. Right: 'pandas', 'requests'. Wrong: 'Pandas'. steam: game display name in plain English, not a Steam App ID. Right: 'Elden Ring', 'CS2'. First Steam store search result wins, so use an unambiguous name. app downloads and app rankings: Android bundle ID only (the id= value on Google Play). Right: 'com.openai.chatgpt', 'com.whatsapp'. Wrong: 'ChatGPT', 'WhatsApp', an iOS App Store ID, or a bundle ID that is not Android. Find it at play.google.com/store/apps/details?id=THIS_PART. If the request includes app downloads or app rankings with other sources, keyword must still be the Android bundle ID.
percent_growth
array
optional
Growth windows. Default if omitted: ['12M']. Each item must be a preset string: '7D', '1W', '14D', '2W', '30D', '1M', '2M', '3M', '6M', '9M', '12M', '1Y', '18M', '24M', '2Y', '36M', '3Y', '48M', '4Y', '60M', '5Y', 'MTD', 'QTD', 'YTD'. Every preset is a two-date comparison.
Raw schema
{
"type": "object",
"properties": {
"source": {
"description": "One source, or comma-separated sources (e.g. 'amazon, tiktok, youtube'). Valid: 'google search', 'google images', 'google news', 'google shopping', 'youtube', 'wikipedia', 'tiktok', 'reddit', 'amazon', 'news sentiment', 'news volume', 'npm', 'python', 'steam', 'app downloads', 'app rankings'.",
"type": "string"
},
"keyword": {
"description": "What to look up. The string format is required by source. Standard sources (google search, google images, google news, google shopping, youtube, wikipedia, tiktok, reddit, amazon, news sentiment, news volume): any name or phrase, e.g. 'nike'. npm: exact npmjs.com package name, case-sensitive. Right: 'react', '@babel/core'. Wrong: 'React', 'React.js'. python: exact PyPI project name. Right: 'pandas', 'requests'. Wrong: 'Pandas'. steam: game display name in plain English, not a Steam App ID. Right: 'Elden Ring', 'CS2'. First Steam store search result wins, so use an unambiguous name. app downloads and app rankings: Android bundle ID only (the id= value on Google Play). Right: 'com.openai.chatgpt', 'com.whatsapp'. Wrong: 'ChatGPT', 'WhatsApp', an iOS App Store ID, or a bundle ID that is not Android. Find it at play.google.com/store/apps/details?id=THIS_PART. If the request includes app downloads or app rankings with other sources, keyword must still be the Android bundle ID.",
"type": "string"
},
"percent_growth": {
"description": "Growth windows. Default if omitted: ['12M']. Each item must be a preset string: '7D', '1W', '14D', '2W', '30D', '1M', '2M', '3M', '6M', '9M', '12M', '1Y', '18M', '24M', '2Y', '36M', '3Y', '48M', '4Y', '60M', '5Y', 'MTD', 'QTD', 'YTD'. Every preset is a two-date comparison.",
"type": "array",
"items": {
"description": "A preset period such as '12M', '3M', or 'YTD'.",
"type": "string"
}
}
},
"required": [
"keyword",
"source"
]
}
trends___get_time_series
Full historical series for one keyword and one source (0-100 values, plus volume when available). Use for charting or custom math. Not for live 'what's trending now' boards (use get_top_trends). For most growth questions, use get_growth. If the request is rate limited or the monthly quota is used up, tell the user their plan limit is reached.
What to look up. The string format is required by source. Standard sources (google search, google images, google news, google shopping, youtube, wikipedia, tiktok, reddit, amazon, news sentiment, news volume): any name or phrase, e.g. 'tesla'. npm: exact npmjs.com package name, case-sensitive. Right: 'react', '@babel/core'. Wrong: 'React', 'React.js'. python: exact PyPI project name. Right: 'pandas', 'requests'. Wrong: 'Pandas'. steam: game display name in plain English, not a Steam App ID. Right: 'Elden Ring', 'CS2'. First Steam store search result wins, so use an unambiguous name. app downloads and app rankings: Android bundle ID only (the id= value on Google Play). Right: 'com.openai.chatgpt', 'com.whatsapp'. Wrong: 'ChatGPT', 'WhatsApp', an iOS App Store ID, or a bundle ID that is not Android. Find it at play.google.com/store/apps/details?id=THIS_PART.
Raw schema
{
"type": "object",
"properties": {
"source": {
"description": "Exactly one source per request. Valid: 'google search', 'google images', 'google news', 'google shopping', 'youtube', 'wikipedia', 'tiktok', 'reddit', 'amazon', 'news sentiment', 'news volume', 'npm', 'python', 'steam', 'app downloads', 'app rankings'.",
"type": "string"
},
"keyword": {
"description": "What to look up. The string format is required by source. Standard sources (google search, google images, google news, google shopping, youtube, wikipedia, tiktok, reddit, amazon, news sentiment, news volume): any name or phrase, e.g. 'tesla'. npm: exact npmjs.com package name, case-sensitive. Right: 'react', '@babel/core'. Wrong: 'React', 'React.js'. python: exact PyPI project name. Right: 'pandas', 'requests'. Wrong: 'Pandas'. steam: game display name in plain English, not a Steam App ID. Right: 'Elden Ring', 'CS2'. First Steam store search result wins, so use an unambiguous name. app downloads and app rankings: Android bundle ID only (the id= value on Google Play). Right: 'com.openai.chatgpt', 'com.whatsapp'. Wrong: 'ChatGPT', 'WhatsApp', an iOS App Store ID, or a bundle ID that is not Android. Find it at play.google.com/store/apps/details?id=THIS_PART.",
"type": "string"
}
},
"required": [
"keyword",
"source"
]
}
trends___get_top_trends
Live top-trending board for exactly one feed type. No keyword. For 'Amazon Best Sellers by Category', 'Google Trends by Category', 'Top Websites', 'Substack by Category', and 'TikTok Trending Hashtags by Category', always pass category. Default sort is current rank. Use sort='rank_change' for climbers vs a prior snapshot (window 1d, 3d, 7d, 14d, or 30d). App Store Top Free, App Store Top Paid, and Google Play are live store boards, not keyword lookups. For an app's history use get_growth or get_time_series with source app downloads or app rankings and an Android bundle ID. Do not use get_time_series for live boards. If the request is rate limited or the monthly quota is used up, tell the user their plan limit is reached.
Parameters6
offset
integer
optional
Rows to skip for pagination. Default 0.
limit
integer
optional
Max rows to return. Default 25, min 1, max 200.
sort
string
optional
How to rank the board. 'rank' (default): current leaders. 'rank_change': biggest climbers vs a prior snapshot. Mover rows include rank, keyword, prev_rank, and rank_change.
window
string
optional
Lookback used only when sort is 'rank_change'. One of '1d', '3d', '7d', '14d', '30d'. Default '30d'. Short windows only work on daily feeds; weekly and monthly feeds return a note pointing to a longer window.
type
string
required
Exactly one live feed. Valid: 'Amazon Best Sellers Top Rated', 'Amazon Best Sellers by Category', 'App Store Top Free', 'App Store Top Paid', 'GitHub', 'Google News Top News', 'Google Play', 'Google Trends', 'Google Trends by Category', 'IMDb MOVIEmeter', 'Open Library Trending Books', 'Reddit Hot Posts', 'Reddit World News', 'Top Websites', 'Spotify Top Podcasts', 'Steam Most Played', 'Substack', 'Substack by Category', 'TikTok Trending Hashtags', 'TikTok Trending Hashtags by Category', 'TikTok Trending Searches', 'Wikipedia Trending', 'X (Twitter) Trending', 'YouTube Trending'.
category
string
optional
Pass this whenever type is 'Amazon Best Sellers by Category', 'Google Trends by Category', 'Top Websites', 'Substack by Category', or 'TikTok Trending Hashtags by Category'. Use the official name. Without it those feeds mix every board. Only omit on a first pull to learn the official names.
Raw schema
{
"type": "object",
"properties": {
"offset": {
"description": "Rows to skip for pagination. Default 0.",
"type": "integer"
},
"limit": {
"description": "Max rows to return. Default 25, min 1, max 200.",
"type": "integer"
},
"sort": {
"description": "How to rank the board. 'rank' (default): current leaders. 'rank_change': biggest climbers vs a prior snapshot. Mover rows include rank, keyword, prev_rank, and rank_change.",
"type": "string"
},
"window": {
"description": "Lookback used only when sort is 'rank_change'. One of '1d', '3d', '7d', '14d', '30d'. Default '30d'. Short windows only work on daily feeds; weekly and monthly feeds return a note pointing to a longer window.",
"type": "string"
},
"type": {
"description": "Exactly one live feed. Valid: 'Amazon Best Sellers Top Rated', 'Amazon Best Sellers by Category', 'App Store Top Free', 'App Store Top Paid', 'GitHub', 'Google News Top News', 'Google Play', 'Google Trends', 'Google Trends by Category', 'IMDb MOVIEmeter', 'Open Library Trending Books', 'Reddit Hot Posts', 'Reddit World News', 'Top Websites', 'Spotify Top Podcasts', 'Steam Most Played', 'Substack', 'Substack by Category', 'TikTok Trending Hashtags', 'TikTok Trending Hashtags by Category', 'TikTok Trending Searches', 'Wikipedia Trending', 'X (Twitter) Trending', 'YouTube Trending'.",
"type": "string"
},
"category": {
"description": "Pass this whenever type is 'Amazon Best Sellers by Category', 'Google Trends by Category', 'Top Websites', 'Substack by Category', or 'TikTok Trending Hashtags by Category'. Use the official name. Without it those feeds mix every board. Only omit on a first pull to learn the official names.",
"type": "string"
}
},
"required": [
"type"
]
}
Keyword helpers default to source: "google search". Pass source= to hit any other platform with the same client. Official full client (every source, no preset): trendsapi.
One object per window (period, growth, direction, dates, values)
metadata
Counts / success flag
Several windows still count as one request. Python: growth.results[0].growth. JS: growth.results[0].growth.
get_live
python
hot = client.get_live(limit=10)
Field
Meaning
as_of_ts
Snapshot time
type
Feed name
limit, offset, count
Pagination
data
[rank, label] rows
Python: hot.data. JS: hot.data. Optional offset= and category= (Amazon Best Sellers by Category, Top Websites only).
Async
python
import asyncio
from google_trends_client import AsyncTrendsAPI
asyncdefmain():
c = AsyncTrendsAPI()
returnawait asyncio.gather(
c.get_time_series("heat pump"),
)
asyncio.run(main())
Each 200 is one billed request.
Pandas
python
from dataclasses import asdict
import pandas as pd
from google_trends_client import TrendsAPI
df = pd.DataFrame(asdict(p) for p in TrendsAPI().get_time_series("heat pump"))
df["date"] = pd.to_datetime(df["date"])
print(df.set_index("date")["value"].resample("ME").mean().tail())
JavaScript / TypeScript
bash
npm install google-trends-js
Node 18+, Deno, Bun, Workers. Same API key. Field tables above apply.