mcpField
T
TrendFlow

TrendFlow

リモート
trendflow.mory.devデータ・分析27 週間前に更新
リポジトリ公式サイト

TrendFlow について

TrendFlowは、Google Trendsのデータを取得・出力するJavaScript/TypeScriptライブラリで、トレンド調査向けのMCPサーバーも別途提供します。地域・期間別の関心度や関連クエリ、トピック、急上昇検索を扱えます。

主な機能

  1. 01期間別・地域別の関心度取得
  2. 02関連クエリとトピック候補の検索
  3. 03検索トレンドの成長率と規模の取得
  4. 04CSV・JSON出力
  5. 05プロキシプールのローテーション

活用シーン

  1. 01地域や期間ごとの検索関心度の比較
  2. 02トピックに関連するクエリの調査
  3. 03急上昇・高ボリューム検索の追跡

MCP 対応

別パッケージの `trendflow-mcp` は、トピック検索、関心度データ、関連クエリ、急上昇検索、トレンド調査向けの6つのツールと2つのリソースを提供します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://trendflow.mory.dev/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

8
パラメーター型必須説明
countryanyいいえ"US"、"GB"、"TH" などの国コード、"US-CA" などの下位地域コード、または "807" などの米国都市圏コード。空文字列は全世界を意味します。

詳細

Trendflow JS のロゴ

Trendflow JS

npm version CI docs trendflow-js MCP server

Google Trends データのクエリとエクスポートに対応した、型安全な JavaScript/TypeScript ライブラリです。 trendflow-py の JavaScript 版です。

📖 ドキュメント:trendflow.mory.dev/docs/js — 両方のライブラリのガイドに加え、 ChatGPT、Claude、Cursor 向けのホスト型 MCP サーバーも掲載しています。

インストール

npm install trendflow

Node.js 18 以降が必要です(グローバルな fetch を使用します)。型宣言をバンドルした ESM と CommonJS を提供しています。

使用方法

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");
エラー

リクエストに失敗すると ResponseError がスローされます。HTTP 429 の場合は、そのサブクラスである TooManyRequestsError がスローされます。 どちらにも .status と生の .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.
  }
}
トレンド取得バックエンド:RPC と RSS

Google はトレンド検索を 2 つの方法で公開しています。これらは互換性がないため、backend で 選択できます。

"rpc"(batchexecute)"rss"(フィード)
項目数5010
ペイロード約 2 KB の JSON約 21 KB の XML
増加率と検索ボリューム✅❌ — "2000+" のような区分
ニュース記事❌✅
window の選択✅Google に無視されます
全世界✅❌ 国のみ
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"(デフォルト)は RPC を試し、失敗した場合はフィードにフォールバックします。意図的に RPC を先に試します。 RPC は実際の増加率とともに 5 倍の項目を返すため、デフォルトを RSS にすると結果の質が知らないうちに低下します。記事が必要な場合は "rss" を選んでください。記事は RPC では取得できません。また、RPC の ID が古くなった場合に、別の情報源として使うこともできます。

フィードであっても、フィードは軽量な取得方法ではありません。また、Google はフィードでは hours、sort、count を無視し、常に同じ 10 件を返します。

トピックと検索候補

Google は検索語句(文字列そのもの)とトピック(あらゆる表記や言語におけるエンティティ)を区別しています。suggestions() でトピックを検索できます。各クエリメソッドはすでにトピックを受け取れるため、キーワードを渡す箇所に mid を渡してください。

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 }

この違いが重要です。トピックのスコアは 62 ですが、文字列そのもののスコアは 1 です。これは、実際に検索されるあらゆる言い回しや翻訳を集約するためです。

suggestions() に Cookie やプロキシは必要ありません。trendingNow() と同様に、widgetdata エンドポイントが 429 で拒否する IP からでも応答します。type を使うと同名のエンティティを区別できます("Nike" なら企業と女神の両方が返されます)。Google が値を省略した場合、type は null になります。

レート制限

Google Trends はデータセンターの IP や共有 IP に対して厳しいレート制限を設けているため、その日の最初のリクエストでも 429 がよく発生します。重要な点は次の 2 つです。

  1. User-Agent。 Google は、Node の HTTP クライアントが送信するデフォルトのエージェント文字列に対し、リクエスト数がどれほど少なくても 429 を返します。そのため、このライブラリはデフォルトでブラウザーの User-Agent を送信します。headers を上書きする場合は、現実的な値を指定してください。
  2. IP の評価。 IP が一度フラグ付けされると、ヘッダーに関係なくすべてのリクエストに 429 が返されます。復旧するには、住宅用プロキシ経由で接続してください。
プロキシプールの使用

プロキシ URL のリストを渡すと、クライアントは自動的にローテーションし、クエリが拒否されるたびに次のプロキシに切り替えます。

import { Client, Region, Timeframe } from "trendflow";

const tf = new Client({
  proxies: [
    "http://user:[email protected]:7000",
    "http://user:[email protected]: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 answered

プロキシをサポートするには、オプションのピア依存関係である undici が必要です。npm install undici を実行してください。エントリーには URL のみを指定するため、プール内でプロバイダーを混在させることもできます。同じローテーションゲートウェイを繰り返し指定する方法も使えます。各エントリーは個別の接続を使うため、新しい出口 IP が割り当てられます。

ローテーションはリクエストごとではなく、クエリごとに行われます。これは重要です。 Google は NID Cookie とウィジェットトークンを、それらをリクエストした IP に紐付けます。そのため、1 つのクエリは同じ出口 IP で完了する必要があります。後続の widgetdata 呼び出しを別の IP から送信すると、即座に 429 が返されます。プールはクエリ全体で 1 つのプロキシを固定し、失敗時にのみ切り替え、そのたびに Cookie jar を再初期化します。同じ理由から、プロバイダーで選択できる場合は、リクエストごとにローテーションするエンドポイントではなく、スティッキーセッションをプールに指定してください。

別の IP でも解決できないエラー(404 や、Google が batchexecute RPC ID の名前を変更したときに発生する UnknownRpcError など)の場合、ローテーションはスキップされます。

プロキシの入手先

Google の 429 を実際に解消できるのは住宅用プロキシです。このライブラリで検証済みです。

Decodo

プロバイダー備考エンドポイント形式
Decodo(旧 Smartproxy)最も安価なエントリーティアです。従量課金も利用できます。このライブラリのライブテストの検証に使用しました。http://user:[email protected]:7000
const tf = new Client({
  proxies: ["http://user:[email protected]:7000"],
});

登録時にスティッキーセッションを選択してください。リクエストごとにローテーションするエンドポイントでは、前述の Cookie とトークンの紐付けが崩れます。共有の住宅用プロキシプールは、Google Trends に対して使い切られる場合があります。その場合、有効なプロキシでも 429 が返されます。このために maxProxyAttempts が用意されています。

独自のクライアントを使用する

ロギング、キャッシュ、カスタムルーティングを行う場合は、代わりに fetch を渡してください(proxies との併用はできません。両方を渡すとライブラリが通知します)。

import { ProxyAgent, fetch as undiciFetch } from "undici";

const agent = new ProxyAgent("http://user:[email protected]:7000");
const tf = new Client({
  fetch: ((input, init = {}) =>
    undiciFetch(input, { ...init, dispatcher: agent })) as typeof globalThis.fetch,
});
ブラウザー/Next.js

export() を除くすべてのメソッドは、fetch が使える場所ならどこでも動作します。ただし、Google Trends は CORS ヘッダーを送信しないため、ブラウザーの JavaScript からの呼び出しはブロックされます。このライブラリはサーバー側(Route Handlers、Server Actions、API routes)で使用し、結果をクライアントに渡してください。

MCP サーバー

エージェントが Google Trends に直接クエリできるよう、ライブラリとともに MCP サーバー trendflow-mcp が提供されています。これは独立したパッケージです。ライブラリのランタイム依存関係はゼロのままです。

claude mcp add trendflow -- npx -y trendflow-mcp

6 つのツール(search_topics、get_interest_over_time、get_interest_by_region、get_related_queries、get_trending_now、research_trend)と 2 つのリソースがあります。詳しくは mcp/README.md を参照してください。

機能の同等性

現在:trendflow-py 0.2.0 · trendflow 0.1.0。バージョンは独立しており、それぞれの変更履歴で対応するもう一方のリリースを相互に参照しています。

機能Python — trendflow-pyJS — trendflow
時系列の検索インタレスト✅✅
地域別の検索インタレスト✅✅
現在のトレンド✅✅
トレンドの成長率とボリューム✅✅
任意の国コードのトレンド✅✅
トレンド関連ニュース記事(RSS)✅✅
トレンドバックエンドの選択✅✅
関連クエリ✅✅
検索候補✅ suggestions()✅ suggestions()
トピック(エンティティの mid)によるクエリ✅✅
CSV / JSON エクスポート✅✅
ローテーションプロキシプール✅✅
デフォルトのブラウザー User-Agent✅✅
完全な地域階層✅ geo_list()✅ geoList()
RPC ID の上書き✅✅
pandas DataFrame✅ to_dataframe()❌ 該当なし
プレーンオブジェクトの行❌ 該当なし✅ toArray()
ESM + CommonJS + 型定義❌ 該当なし✅
MCP サーバー🔜 予定✅ trendflow-mcp
CLI✅🔜 予定
現在のトレンド

Google は hottrends/visualize/internal/data エンドポイントを廃止し、api/dailytrends と api/realtimetrends も廃止しました。3 つとも HTTP 404 を返すようになっています。このライブラリは、代わりに trends.google.com 自身が使用している batchexecute RPC を呼び出します。0.2.0 以降の trendflow-py も同様です。この RPC は、旧エンドポイントより多くのデータを返します。

const trending = await tf.trendingNow(Region.US);
// { title: "fifa world cup 2026", growth: 3650, volume: 6, traffic: "+3,650%", articles: [] }

旧エンドポイントと比べて、実用上の利点は 3 つあります。

  • タイトルだけでなく、成長率とボリュームも取得できます。 growth は期間内の上昇率、volume は相対的な検索ボリュームのインデックスです。
  • 旧エンドポイントで必要だった 16 個のハードコードされた名前に限らず、任意の国コードを指定できます。 以前は拒否されていた全世界も指定できます。
  • Cookie が不要で、レート制限も大幅に緩やかです。 この RPC は、widgetdata エンドポイントから 429 を受ける IP にも応答するため、trendingNow() はプロキシなしでも機能することがよくあります。

このバックエンドでは articles は空です。RPC に記事へのリンクが含まれていないためです。各トレンドに関連するニュース記事を取得するには、{ backend: "rss" } を渡してください。

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-volume

window は Google の非公開パラメーターです。名前を付けて説明する価値のある動作をするのは、この 2 つの値だけです。4 から 12 までのほかの整数を指定しても、さまざまな直近期間のデータが返されます。また、数値をそのまま渡すこともできます。

未実装:CAPTCHA が必要な RPC

同じ batchexecute エンドポイントでは、より高精度な時系列(公開 API が返す丸められた 0~100 の値ではなく、浮動小数点値)と、キーワードを指定した関連クエリも公開されています。どちらも reCAPTCHA Enterprise トークンが必要で、トークンなしでは空のペイロードが返されるため、このライブラリでは実装していません。これらのデータは、ドキュメント化された widgetdata エンドポイントを使う interestOverTime() と relatedQueries() から引き続き取得できます。

API の対応関係
PythonJavaScript
interest_over_time()interestOverTime()
interest_by_region()interestByRegion()
trending_now()trendingNow()
related_queries()relatedQueries()
to_dataframe()toArray()
export(fmt, path)export(fmt, path) — Node のみ。さらに toCSV() / toJSON()

主な違い:

  • すべて非同期です。 4 つのクエリメソッドはすべて Promise を返します。
  • timeout の単位はミリ秒です(JS の慣例)。秒ではありません。
  • 列挙型は as const オブジェクトです。 そのため、Region.US は文字列 "US" であり、型が求められる箇所には有効な文字列リテラルを指定できます。
  • 結果は型付きのプレーンオブジェクトです。 変換メソッドを備えているため、InterestOverTimeResult のみクラスで、それ以外はインターフェースです。

開発

git clone [email protected]: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 + build

ユニットテストではネットワークに接続しません。実際のエンドポイントを確認するには:

npm run build && npm run smoke
TRENDFLOW_PROXY_URL=http://user:pass@host:7000 npm run smoke   # via a proxy

作者

Trendflow JS は、2026 年に Dario Mory によって作成されました。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。