trendflow
It is an MCP server for querying Google Trends data programmatically.
search_topics — resolve a named entity to a Google Trends topic id (
mid) for better coverage.get_interest_over_time — get normalized historical search interest for 1-5 terms, compare trends over time.
get_interest_by_region — break down interest by country, region, or city.
get_related_queries — discover top and rising related searches for a keyword.
get_trending_now — list currently trending searches by country, with optional RSS news articles.
research_trend — combine interest over time, regional popularity, and related queries in one call.
Provides tools for querying and exporting Google Trends data, including interest over time, interest by region, trending searches, related queries, and topics/search suggestions.
Trendflow JS
A type-safe JavaScript/TypeScript library for querying and exporting Google Trends data.
The JavaScript port of trendflow-py.
📖 Documentation: trendflow.mory.dev/docs/js — guides for both libraries, plus a hosted MCP server for ChatGPT, Claude, and Cursor.
npm package: https://www.npmjs.com/package/trendflow
API reference: https://dariomory.github.io/trendflow-js/
Python sibling: https://pypi.org/project/trendflow-py/
Created by: Dario Mory | GitHub https://github.com/dariomory
Free software: MIT License
Install
npm install trendflowRequires Node.js 18+ (uses the global fetch). Ships ESM and CommonJS with bundled type declarations.
Related MCP server: Google Trends MCP Server
Usage
import { Client, Region, Timeframe, Resolution, SearchProperty, ExportFormat } from "trendflow";
// Initialize client (optional config)
const tf = new Client({ language: "en", timeout: 10_000 });
// --- Const objects for type safety ---
// Region.US, Region.GB, Region.DE ... (or any code: "US-CA", "807")
// Timeframe.PAST_HOUR ... PAST_5_YEARS, ALL_TIME (or "2023-01-01 2023-06-30")
// Resolution.COUNTRY, Resolution.REGION, Resolution.CITY
// SearchProperty.WEB, IMAGES, NEWS, YOUTUBE, SHOPPING
// Fetch interest over time
const data = await tf.interestOverTime(
["Python", "JavaScript", "Rust"],
Timeframe.PAST_YEAR,
Region.US,
);
console.log(data.keywords); // ["Python", "JavaScript", "Rust"]
console.log(data.granularity); // "weekly"
console.log(data.points); // TrendPoint[] — { date: Date, scores: Record<string, number> }
// Regional breakdown (region defaults to Region.US)
const regional = await tf.interestByRegion("Python", Resolution.COUNTRY);
for (const row of regional.rows) {
console.log(row.label, row.value);
}
// Trending searches right now (any country code, or omit for worldwide)
const trending = await tf.trendingNow(Region.US);
for (const item of trending.results) {
console.log(item.title, item.growth, item.volume, item.traffic);
// "fifa world cup 2026" 3650 6 "+3,650%"
}
// Related queries (region defaults to worldwide)
const related = await tf.relatedQueries("machine learning", { region: Region.GB });
for (const query of related.top) console.log(query.term, query.value);
for (const query of related.rising) console.log(query.term, query.breakout);
// --- Narrowing a query ---
// Every query method takes an optional category and search property, and any of them
// accepts a custom date range and a sub-region or metro code in place of the named values.
// "jaguar" the car, on YouTube, in California, over the first half of 2023
const jaguar = await tf.interestOverTime(["jaguar"], "2023-01-01 2023-06-30", "US-CA", {
category: 47, // Autos & Vehicles — disambiguates without needing a topic id
searchProperty: SearchProperty.YOUTUBE,
});
// --- Exports ---
data.toArray(); // [{ date: Date, Python: 80, ... }] — plain objects, the JS answer to DataFrames
data.toJSON(); // same rows with ISO 8601 date strings (also drives JSON.stringify)
data.toCSV(); // CSV text
// Node.js only — writes UTF-8 to disk
await data.export(ExportFormat.CSV, "trends.csv");
await data.export(ExportFormat.JSON, "trends.json");Errors
Failed requests throw ResponseError, or TooManyRequestsError (a subclass) on HTTP 429.
Both carry .status and the raw .response.
import { TooManyRequestsError } from "trendflow";
try {
await tf.interestOverTime(["Python"], Timeframe.PAST_YEAR, Region.US);
} catch (error) {
if (error instanceof TooManyRequestsError) {
// Google is rate-limiting this IP — back off and retry later.
}
}Trending backends: RPC and RSS
Google exposes trending searches two ways. They are not interchangeable, so backend lets
you pick:
|
| |
items | 50 | 10 |
payload | ~2 KB JSON | ~21 KB XML |
growth % and volume | ✅ | ❌ — buckets like |
news articles | ❌ | ✅ |
| ✅ | ignored by Google |
worldwide | ✅ | ❌ country only |
const rss = await tf.trendingNow(Region.US, { backend: "rss" });
rss.source; // "rss"
rss.results[0].articles;
// [{ title: "...", url: "https://...", source: "Buffalo News", picture: "https://..." }]"auto" (the default) tries the RPC and falls back to the feed. The RPC comes first
deliberately: it returns five times the items with real growth figures, so defaulting to RSS
would quietly degrade results. Reach for "rss" when you want the articles — that is the
one thing the RPC cannot give you — or as a second opinion if the RPC id ever goes stale.
Note that the feed is not a lighter path despite being a feed, and Google ignores hours,
sort and count on it: it always returns the same 10 entries.
Topics and search suggestions
Google distinguishes a search term (the literal string) from a topic (the entity, in
every spelling and language). suggestions() finds the topic; every query method already
accepts one — pass the mid where you would pass a keyword.
const topics = await tf.suggestions("artificial intelligence");
// [{ mid: "/m/0mkz", title: "Artificial intelligence", type: "Professional field" }]
const data = await tf.interestOverTime(
[topics[0].mid, "artificial intelligence"],
Timeframe.PAST_YEAR,
Region.US,
);
// { "/m/0mkz": 62, "artificial intelligence": 1 }That gap is the point: the topic scores 62 where the literal phrase scores 1, because it aggregates every phrasing and translation people actually search.
suggestions() needs no cookie and no proxy — it answers on IPs the widgetdata endpoints
reject with 429, same as trendingNow(). type disambiguates same-name entities
("Nike" returns both the company and the goddess) and is null when Google omits it.
Rate limits
Google Trends aggressively rate-limits datacenter and shared IPs, so 429 is common even on
your first request of the day. Two things matter:
User-Agent. Google returns
429to the default agent strings Node HTTP clients send, no matter how few requests you have made. This library sends a browser User-Agent by default for exactly that reason — if you overrideheaders, keep a realistic one.IP reputation. Once an IP is flagged, every request gets
429regardless of headers. Route through a residential proxy to recover.
Using a proxy pool
Pass a list of proxy URLs and the client rotates through them automatically, moving to the next one whenever a query is refused:
import { Client, Region, Timeframe } from "trendflow";
const tf = new Client({
proxies: [
"http://user:pass@gate.decodo.com:7000",
"http://user:pass@gate.decodo.com:7000",
],
maxProxyAttempts: 3, // defaults to the pool size, capped at 5
onProxyRotate: ({ attempt, error }) => console.warn(`rotated after ${attempt}:`, error),
});
const data = await tf.interestOverTime(["Python"], Timeframe.PAST_YEAR, Region.US);
console.log(tf.currentProxy); // the proxy that answeredProxy support needs undici, an optional peer
dependency — npm install undici. Entries are just URLs, so a pool can mix providers. Repeating one rotating gateway also works: each entry gets its own connection, so it lands on a fresh exit IP.
Rotation happens per query, not per request — this matters. Google binds the NID
cookie and the widget token to the IP that requested them, so a single query must complete
on one exit IP; sending the follow-up widgetdata call from a different IP earns an instant
429. The pool pins one proxy for the whole query and advances only on failure, re-seeding
the cookie jar each time. For the same reason, point the pool at sticky sessions rather
than per-request rotating endpoints if your provider offers the choice.
Rotation is skipped for errors a different IP cannot fix, such as a 404 or the
UnknownRpcError raised when Google renames a batchexecute RPC id.
Where to get proxies
Residential proxies are what actually clears Google's 429. Verified against this library:
Provider | Notes | Endpoint format |
Decodo (formerly Smartproxy) | Cheapest entry tier; pay-as-you-go available. Used to verify this library's live tests. |
|
const tf = new Client({
proxies: ["http://user:pass@gate.decodo.com:7000"],
});Ask for sticky sessions when you sign up — per-request rotating endpoints break the
cookie/token binding described above. Note that a shared residential pool can be exhausted
for Google Trends specifically, in which case even a valid proxy returns 429; that is what
maxProxyAttempts is for.
Bringing your own client
For logging, caching, or custom routing, pass a fetch instead (mutually exclusive with
proxies — the library will tell you if you pass both):
import { ProxyAgent, fetch as undiciFetch } from "undici";
const agent = new ProxyAgent("http://user:pass@proxy.example.com:7000");
const tf = new Client({
fetch: ((input, init = {}) =>
undiciFetch(input, { ...init, dispatcher: agent })) as typeof globalThis.fetch,
});Browser / Next.js
Every method except export() works anywhere fetch does, but Google Trends sends no CORS
headers — calls from browser JavaScript will be blocked. Use this library server-side
(Route Handlers, Server Actions, API routes) and pass results to the client.
MCP server
An MCP server ships alongside the library as trendflow-mcp, so agents can query
Google Trends directly. It's a separate package — the library keeps its zero runtime
dependencies.
claude mcp add trendflow -- npx -y trendflow-mcpSix tools (search_topics, get_interest_over_time, get_interest_by_region,
get_related_queries, get_trending_now, research_trend) and two resources. See
mcp/README.md.
Feature Parity
Current: trendflow-py 0.2.0 · trendflow 0.1.0. Versions are independent; each changelog cross-references the sibling release.
Feature | Python — | JS — |
Interest over time | ✅ | ✅ |
Interest by region | ✅ | ✅ |
Trending now | ✅ | ✅ |
Trending growth % and volume | ✅ | ✅ |
Trending for any country code | ✅ | ✅ |
Trending news articles (RSS) | ✅ | ✅ |
Selectable trending backend | ✅ | ✅ |
Related queries | ✅ | ✅ |
Search suggestions | ✅ | ✅ |
Query by topic (entity mid) | ✅ | ✅ |
CSV / JSON export | ✅ | ✅ |
Rotating proxy pool | ✅ | ✅ |
Browser User-Agent by default | ✅ | ✅ |
Full geo hierarchy | ✅ | ✅ |
Overridable RPC ids | ✅ | ✅ |
pandas DataFrame | ✅ | ❌ N/A |
Plain-object rows | ❌ N/A | ✅ |
ESM + CommonJS + types | ❌ N/A | ✅ |
MCP server | 🔜 planned | |
CLI | ✅ | 🔜 planned |
Trending now
Google retired the hottrends/visualize/internal/data endpoint, along with
api/dailytrends and api/realtimetrends; all three now return HTTP 404. This library
calls the batchexecute RPC that trends.google.com itself uses instead — as does
trendflow-py from 0.2.0 — and it returns more
than the old endpoint did:
const trending = await tf.trendingNow(Region.US);
// { title: "fifa world cup 2026", growth: 3650, volume: 6, traffic: "+3,650%", articles: [] }Three practical wins over the old endpoint:
Growth and volume, not just titles.
growthis the percentage rise over the window,volumea relative search-volume index.Any country code, not the 16 hardcoded names the old endpoint required — and worldwide works, which it previously refused.
No cookie, and far looser rate limiting. This RPC answers on IPs that get a
429from the widgetdata endpoints, sotrendingNow()often works with no proxy at all.
articles is empty on this backend — the RPC carries no article links. Pass
{ backend: "rss" } to get the news articles behind each trend instead.
The window is selectable via TrendingWindow:
import { TrendingWindow } from "trendflow";
await tf.trendingNow(Region.US, { window: TrendingWindow.RISING }); // default: fastest-growing
await tf.trendingNow(Region.US, { window: TrendingWindow.TOP }); // highest-volumewindow is an undocumented Google parameter. Only these two values have behaviour worth
naming; other integers between 4 and 12 also return data over varying recency windows, and
you can pass one as a raw number.
Not implemented: captcha-gated RPCs
The same batchexecute endpoint exposes a higher-precision timeseries (floating-point
values rather than the rounded 0-100 the public API returns) and keyword-scoped related
queries. Both require a reCAPTCHA Enterprise token and return an empty payload without one,
so this library does not implement them — that data remains available through
interestOverTime() and relatedQueries(), which use the documented widgetdata endpoints.
API mapping
Python | JavaScript |
|
|
|
|
|
|
|
|
|
|
|
|
Notable differences:
Everything is async. All four query methods return promises.
timeoutis milliseconds (JS convention), not seconds.Enums are
as constobjects, soRegion.USis the string"US"and any valid string literal is accepted where the type is expected.Results are plain typed objects. Only
InterestOverTimeResultis a class, because it carries the conversion methods; the rest are interfaces.
Development
git clone git@github.com:dariomory/trendflow-js.git
cd trendflow-js
npm install
npm test # vitest — 60 tests, fully offline against a stubbed fetch
npm run qa # typecheck + test + buildThe unit tests never touch the network. To check the real endpoints:
npm run build && npm run smoke
TRENDFLOW_PROXY_URL=http://user:pass@host:7000 npm run smoke # via a proxyAuthor
Trendflow JS was created in 2026 by Dario Mory.
Available Tools
6 toolsget_interest_by_regionInterest by regionAInspect
Break down search interest for one term by geography. Use this when the user asks where something is popular, or wants a regional or city-level comparison. Values are Google's normalized relative interest (0-100 within the result set), not absolute search volume.
| Name | Required | Description | Default |
|---|---|---|---|
| region | No | Country code such as "US", "GB", "TH". Empty string means worldwide. | |
| keyword | Yes | A search term, or a topic id from search_topics (e.g. "/m/0mkz"). | |
| resolution | No | Geographic granularity of the breakdown. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It clarifies that values are normalized relative interest (0-100 within the result set) and not absolute search volume, which is important behavioral information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose and immediately followed by concrete use cases and output semantics. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides the essential output-value caveat and use cases, and the sibling context is clear. It does not describe the exact output format, but that is not required given the simple breakdown nature.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters already have descriptive schema text (100% coverage), and the description does not add meaning beyond what the schema provides. Baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Break down') and resource ('search interest') with a clear geographic scope, and explicitly distinguishes this tool from time-based or related-query siblings by mentioning regional/city-level comparisons.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool ('Use this when the user asks where something is popular'), but it does not explicitly state when not to use it or name alternative sibling tools for other cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_interest_over_timeInterest over timeAInspect
Get relative search interest for one or more terms over a historical period. Use this when the user asks how popular something is, whether it is rising or falling, or how several things compare — passing multiple keywords compares them against each other on one scale. Values are Google's normalized relative interest (0-100 within the result set), not absolute search volume.
| Name | Required | Description | Default |
|---|---|---|---|
| region | No | Country code such as "US", "GB", "TH". Empty string means worldwide. | |
| keywords | Yes | 1-5 search terms. Pass several to compare them against each other. Accepts topic ids from search_topics (e.g. "/m/0mkz") as well as literal phrases. | |
| timeframe | No | Time range for the series. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden. It discloses a key behavioral detail: values are normalized on a 0-100 scale and are not absolute search volume, which prevents misinterpretation. It also conveys the comparative behavior when multiple keywords are used. It does not mention any side effects or permissions, but for a read-only data retrieval tool this is acceptable. Some specifics like aggregation window or time-series granularity are omitted, hence a 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, tightly packed with purpose, usage, and a critical interpretative note. There is no fluff or redundancy; every word contributes to understanding. The structure is logical: function, then when to use, then key behavior. This is exemplary conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although there is no output schema, the description provides enough context about the return value ('normalized relative interest (0-100)') and its comparative nature to manage expectations. It also includes usage context that helps an agent decide between siblings, covering the 'when to use' aspect. The tool is simple (3 parameters, no nested objects), and the description addresses all necessary dimensions for effective selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 100% with descriptions for all parameters, and the tool description adds extra meaning beyond the schema. It explains that keywords can accept topic IDs from search_topics and that multiple keywords are compared against each other. It also clarifies that an empty region string means worldwide. This rich contextualization makes parameter usage clearer than the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the function: 'Get relative search interest for one or more terms over a historical period.' It explicitly differentiates the tool from siblings by emphasizing the time-series aspect and the comparative use case with multiple keywords ('whether it is rising or falling, or how several things compare'). This makes the tool's purpose unambiguous and distinct from region, related queries, or trending tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage triggers: 'Use this when the user asks how popular something is, whether it is rising or falling, or how several things compare.' It also clarifies that passing multiple keywords compares them on one scale and that values are relative (0-100), not absolute search volume. This provides direct guidance on when and how to invoke the tool, though it does not explicitly state when to prefer alternatives, the positive triggers are strong enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trending_nowTrending nowAInspect
List searches surging right now in a country. Use this for discovery — what is spiking without the user naming a term — and for news, monitoring, and real-time questions. Choose backend "rss" when the user wants to know why something is trending: it returns the news articles behind each entry, which the default source does not carry.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return. | |
| region | No | Country code such as "US", "GB", "TH". Empty string means worldwide. | |
| backend | No | Source to use. "rpc" returns ~50 items with growth percentages; "rss" returns 10 with the news articles behind each trend; "auto" tries rpc then falls back to rss. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description and parameter descriptions carry the full burden. They disclose that 'rpc' returns ~50 items with growth percentages, 'rss' returns 10 with news articles, and 'auto' falls back, but do not describe sorting order or potential failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct yet information-dense, using two well-structured sentences with a clear em-dash aside. Every clause adds functional value, avoiding redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description reasonably communicates what each backend returns (items, growth percentages, news articles). It does not specify exact response shape, but that is not essential for this simple list tool given the parameter descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters have descriptions with explicit meaning and constraints. 'limit' has min/max, 'region' explains empty string as worldwide and accepts ISO codes, and 'backend' details the behavior of each enum value, going beyond basic schema info.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists trending searches in a country, using specific verbs like 'List' and 'surging'. It also distinguishes its discovery purpose from user-named term queries, and explains the 'rss' backend's role in providing explanatory news articles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool: for discovery, news, monitoring, and real-time questions. It also provides specific guidance on choosing the 'rss' backend when the user wants to know why something is trending, and contrasts with default behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
research_trendResearch a trendAInspect
Full picture of one term in a single call: interest over time, where it is popular, and what people search alongside it. Use this when the user asks to "research", "analyse", or "look into" a topic rather than asking one narrow question — it saves three round trips.
Each section is fetched independently, so a partial result is normal: any section that fails carries an error instead of data, and the rest still returns. Pass a topic id from search_topics for materially better numbers.
| Name | Required | Description | Default |
|---|---|---|---|
| region | No | Country code such as "US", "GB", "TH". Empty string means worldwide. | |
| keyword | Yes | A search term, or a topic id from search_topics (e.g. "/m/0mkz"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It transparently discloses partial failure behavior and the error field in results, but it does not explicitly state whether the tool is read-only or whether any destructive side effects exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: the first sentence states the core value, the second gives the recommended usage, and the third sets expectations about partial results. No superfluous details are present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description sufficiently conveys what data categories to expect and how errors are handled. It does not enumerate exact output fields, but given the composite nature and the lack of output schema, the provided context is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers both parameters well, so the baseline is 3. The description adds valuable guidance by advising that passing a topic id from search_topics yields materially better numbers, which meaningfully supplements the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool returns a composite view (interest over time, popularity by region, related searches) in a single call, and differentiates it from narrow single-purpose sibling tools. The phrase 'Full picture of one term' succinctly captures the intended resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use this tool ('when the user asks to research, analyse, or look into a topic') and contrasts it with asking a narrow question. It also notes the efficiency benefit of saving three round trips, though it does not name the alternative sibling tools directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_topicsSearch topicsAInspect
Look up the Google Trends topic id for a thing. Call this FIRST whenever the user names an entity — a company, product, person, technology, concept — then pass the returned mid as a keyword to the other tools.
A topic aggregates every spelling and translation of the same concept, so it measures far more search activity than the literal phrase: querying the topic for "artificial intelligence" scores 62 where the literal string scores 1. The type field disambiguates same-name entities (Nike the company vs the goddess). Skip this only when the user explicitly wants a literal phrase.
Cheapest tool here: it needs no cookie and works on IPs that rate-limit the others.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | A search term, or a topic id from search_topics (e.g. "/m/0mkz"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, but the description discloses key behavioral aspects: it aggregates spellings/translations, returns a `mid` and `type` field for disambiguation, and requires no cookie while working on rate-limited IPs. This is transparent about access and output semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a clear primary statement, followed by clarifying examples and a practical note about cost. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that no output schema is provided, the description sufficiently explains what the tool returns and how it fits into the broader workflow with the sibling tools. It covers when to use, what to pass, and what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully describes the single parameter, and the description adds the crucial nuance that the parameter can be either a search term or an existing topic id. This enhances understanding beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: looking up a Google Trends topic id. It explains the primary use case (first step for entity queries) and distinguishes it from literal phrase searches. It also explicitly tells when to call it relative to the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use: call first whenever the user names an entity, and skip only when a literal phrase is intended. It also notes that this is the cheapest tool, helping the agent decide among alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
get_interest_by_region - First observed
get_interest_over_time - First observed
get_related_queries - First observed
get_trending_now - First observed
research_trend - First observed
search_topics
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: topic lookup, time-series interest, regional breakdown, related queries, trending searches, and a combined research call. The only potential overlap is research_trend, but its description explicitly frames it as a convenience wrapper, reducing ambiguity.
Most tools follow a consistent verb_noun snake_case pattern, such as search_topics and get_interest_over_time. research_trend deviates slightly from the get_ prefix pattern, but still fits the overall verb_noun style.
Six tools is a well-scoped set for a Google Trends server. Each tool covers a distinct aspect of the domain without redundant or unnecessary additions.
The surface covers the core Google Trends workflow: resolving topics, measuring interest over time and by region, exploring related queries, checking current trending searches, and a combined research endpoint. No obvious missing functionality for the stated purpose.
Maintenance
Related MCP Connectors
Google Trends interest over time, by region, and related queries and topics, as JSON.
Google Trends search interest over time with growth metrics. Free key at trendsapi.ai
Google Trends: Search, Images, News, Shopping over time, growth metrics. Free key at trendsmcp.ai
Google Trends trending searches, volume estimates & trend duration. Not affiliated with Google LLC.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables retrieval and analysis of Google Trends data for any search term over the last 12 months. Provides structured timeline data with relative interest scores that can be filtered by geography and category.-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to access Google Trends data for comparing keywords, discovering trending searches, and analyzing regional interest through natural language.2MIT
- FlicenseNot gradedqualityDmaintenanceProvides access to Google Trends data via SerpAPI for analyzing regional search interest patterns, comparing services across locations, and discovering related queries to support data-driven advertising and service decisions.-
- AlicenseBqualityDmaintenanceEnables Claude to query Google Trends data such as keyword interest, related queries, and regional popularity, with robust proxy rotation to bypass Google's anti-bot measures.526 npm1MIT