framefetch について
framefetchは、ソーシャル動画のURLから字幕、メタデータ、サンプルフレーム、OCRなどを取得するAPI兼MCPサーバーです。複数の対応プラットフォームの動画を検索・分析するエージェントやアプリ向けです。
主な機能
- 01字幕、メタデータ、動画フレームの抽出
- 02動画内容に基づく質問への回答
- 03OCRによる画面内テキストの認識
- 04キーワード検索と最大10件のURLの一括処理
- 05要約、構造化データ、コメント分析の生成
活用シーン
- 01ソーシャル動画に関する質問への回答
- 02抽出前のキーワードによる動画検索
- 03フレームと画面内テキストの分析
- 04複数の動画URLの一括処理
MCP 対応
Streamable HTTPのMCPサーバーとして、`framefetch_extract`、`framefetch_platform_capabilities`、`framefetch_search`、`framefetch_account`ツールを提供します。ローカルstdioブリッジもあり、ホスト型サービスへ呼び出しを転送します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://framefetch.net/mcpclaude mcp add --transport http marvinrey7879-framefetch https://framefetch.net/mcp{"mcpServers":{"marvinrey7879-framefetch":{"type":"http","url":"https://framefetch.net/mcp"}}}Cursor で開く{"servers":{"marvinrey7879-framefetch":{"type":"http","url":"https://framefetch.net/mcp"}}}VS Code で開く{"mcpServers":{"marvinrey7879-framefetch":{"type":"http","url":"https://framefetch.net/mcp"}}}{"mcpServers":{"marvinrey7879-framefetch":{"serverUrl":"https://framefetch.net/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
4| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| ask | string | いいえ | 動画に関する質問(3~500 文字)。タイムスタンプ付き引用を含む、最大 500 トークンの回答を文字起こし(自動取得)に基づいて返します。キャッシュは行いません。利用できない場合は機能を縮退します(課金なし)。長い動画では、冒頭だけでなく、関連性に基づいて選択/サンプリングした部分から回答します。レスポンスの `ask.coverage` を参照してください。文字起こしがない場合(例:Pinterest)はフレームにフォールバックし、`based_on`:["frames"] を設定します。 |
| url | string | はい | サポート対象プラットフォームの公開動画 URL。 |
| cache | boolean | いいえ | false にすると、抽出を強制的に再実行し、課金されます。 |
| voice | enum | いいえ | "audio_digest" の音声:OpenAI の音声(alloy/echo/fable/onyx/nova/shimmer)および Groq "Fritz-PlayAI"。デフォルトは "alloy"。alloy | echo | fable | onyx | nova | shimmer | Fritz-PlayAI |
| fields | array | いいえ | 返すデータ。デフォルトは ["metadata"]。取得依存関係:digest→transcript;audio_digest→digest→transcript;structured→transcript;comment_sentiment→comments。digest/audio_digest/structured/comment_sentiment は、失敗時に警告へ縮退し、課金されません。digest:LLM による要約とトピック。audio_digest:digest の mp3(署名付き URL、有効期間 24 時間)。音声は `voice` で指定します。他言語の音声には +`translate` を指定します。structured:ビジョン LLM によるチャプター/エンティティ/表示された製品/主張/重要な場面。comments:最大 comments_cap 件。YouTube のみ(それ以外は警告。GET /v1/platforms を参照)。comment_sentiment:視聴者の感情を集計(positive_pct/neutral_pct/negative_pct/summary/top_themes)。コメントが 5 件以上必要です。同じく YouTube のみです。text_overlay:フレームごとの OCR。「frames」が必要です。200 フレームを超える場合はスキップします。delta:前回の取得と比較した変化速度。初回呼び出しで基準値を設定します。ドキュメント:https://framefetch.net/docs。 |
| frames | object | いいえ | フレームのサンプリング仕様。「frames」または「text_overlay」を要求する場合は必須です。 |
| frames.n | number | いいえ | every_n:ソースフレームを N フレームごとにサンプリング |
| frames.to | number | いいえ | range:終了秒 |
| frames.fps | number | いいえ | fps/range:フレームレート(最大 60) |
| frames.from | number | いいえ | range:開始秒 |
| frames.mode | enum | はい | all | every_n | fps | range |
| frames.width | number | いいえ | 縮小後の幅(px、16~7680) |
| frames.format | enum | いいえ | jpg | png | webp |
| translate | string | いいえ | ISO-639-1 の翻訳先言語(例:"es")。`transcript_translated` を追加します(タイミングは保持)。「transcript」(または「digest」)が必要です。音声の分数単位で課金されます。 |
| comments_cap | integer | いいえ | トップレベルコメントの最大数(1~200、デフォルトは 30)。「comments」と併用する場合のみ使用します。 |
| subtitle_format | enum | いいえ | 文字起こしを字幕として `subtitles`(srt/vtt)にレンダリングします。「transcript」(または「digest」)が必要です。「translate」が設定されている場合は翻訳済みの字幕キューを使用します。srt | vtt |
詳細
FrameFetch
あらゆるソーシャル動画の URL → 回答、文字起こし、メタデータ、インサイト、フレーム、画面上のテキスト(OCR)。
エージェントファーストの動画データ API + MCP サーバー。呼び出しごとの支払い、または x402(USDC)での支払いに対応。アカウントは不要です。
FrameFetch は、YouTube、YouTube Shorts、TikTok、Instagram Reels、Pinterest、Reddit の動画 URL から、単一の JSON レスポンスを生成します。レスポンスには、動画に関する質問への直接的な回答、メタデータ、エンゲージメントのインサイト、文字起こし(字幕または Whisper)、LLM による要約(テキストまたは音声の mp3)、構造化 JSON(チャプター/エンティティ/商品/主張)、コメント+感情分析、パラメーター指定でサンプリングしたフレーム(N フレームごと/1 秒ごとに 1 フレーム/時間範囲、幅は任意)、さらにフレームに焼き込まれた画面上のテキスト(OCR — 字幕、価格タグ、看板)が含まれます。URL がまだない場合はキーワードで検索でき、1 回の呼び出しで最大 10 件の URL を処理するバッチにも対応しています。AI エージェント向けに、API と MCP を中心に設計されています。
このリポジトリはオープンソースのクライアント+ドキュメントです。サービス本体は framefetch.net で稼働しています。無料の API キーを使うか、x402 で呼び出しごとに支払います。バックエンドはホストされたままです。
理由
LLM は動画を見ることができません。動画について推論するには、まず動画をテキストと画像、つまり回答、文字起こし、メタデータ、いくつかのフレームに変換する必要があります。FrameFetch は、6 つのプラットフォームの URL から、単一のスキーマでそのすべてを返します。
インストール
npm install framefetch
Node 18 以降(組み込みの fetch を使用)。無料のキーを取得するには、framefetch.net をご覧ください。
バージョンに関する注意。 このリポジトリのバージョンは 0.4.0 です。現在 npm で公開されている最新バージョンは 0.3.0 です。
npm install framefetchでは引き続き 0.3.0 がインストールされ、利用できるのはextract/metadata/transcript/frames/platforms/status/demo/createKeyのみです。以下に記載されているその他の機能は、現在 API で利用でき、このリポジトリからも使用できます。npm 版 0.3.0 からは、extract({ fields: [...] })を通じて同じデータにアクセスできます。
質問をして、文字起こしの羅列ではなく回答を得る
動画について直接質問すると、自分で 25,000 トークンの文字起こしを解析する代わりに、タイムスタンプ付きの引用を含む、簡潔で根拠のある回答が返されます。
import { FrameFetch } from 'framefetch';
const ff = new FrameFetch({ apiKey: process.env.FRAMEFETCH_API_KEY });
const { ask } = await ff.ask(
'https://www.youtube.com/watch?v=jNQXAC9IVRw',
'What does the presenter say to do first?',
);
console.log(ask.answer); // short, direct answer
console.log(ask.confidence); // 'high' | 'medium' | 'low'
for (const q of ask.quotes) { // verbatim, timestamped supporting quotes
console.log(`[${q.t_sec}s] ${q.text}`);
}
console.log(ask.coverage); // which part of the transcript was analyzed
回答が実際に生成された場合にのみ課金されます。抽出済みの動画に同じ質問を繰り返すと、キャッシュされた文字起こしが再利用されるため、再ダウンロードや再文字起こしなしですばやく回答できます。ただし、回答自体は毎回新たに生成され、キャッシュから返されることはありません。
フレームベースの回答: 動画に文字起こしがない場合(Pinterest など)、または文字起こしに失敗した場合、サンプリングしたキーフレーム画像を根拠に回答します。この場合、coverage.mode は "frames"、quotes は [](引用できる文字起こしテキストがないため)、confidence は "medium" が上限になります。
クイックスタート
import { FrameFetch } from 'framefetch';
const ff = new FrameFetch({ apiKey: process.env.FRAMEFETCH_API_KEY });
const r = await ff.extract({
url: 'https://www.youtube.com/watch?v=jNQXAC9IVRw',
fields: ['metadata', 'transcript', 'frames', 'text_overlay'],
frames: { mode: 'fps', fps: 1, width: 480 },
});
console.log(r.metadata.title); // "Me at the zoo"
console.log(r.transcript.text); // "All right, so here we are, in front of the elephants…"
console.log(r.frames.length); // 19 — frames is an array
console.log(r.textOverlay?.[0]?.text); // on-screen text detected in the first frame, if any
名前の表記が 2 種類ある点に注意してください。text_overlay はリクエストのフィールド名で、textOverlay はレスポンスのキーです。
スコープ指定ヘルパー
await ff.metadata(url); // title, author, duration, views, likes…
await ff.transcript(url); // captions, else Whisper
await ff.frames(url, { mode: 'fps', fps: 1, width: 512 });
await ff.ask(url, 'What product is being reviewed?'); // grounded Q&A, see above
await ff.digest(url); // LLM summary of the transcript
await ff.audioDigest(url, { voice: 'nova' }); // spoken mp3 briefing (signed URL, 24h)
await ff.structured(url); // chapters/entities/products/claims/key_moments
await ff.comments(url, { comments_cap: 50 }); // top-level comments
await ff.commentSentiment(url); // aggregated audience-mood rollup (+ the comments)
await ff.platforms(); // capability matrix (no key)
await ff.status(); // live service health (no key)
// on-screen text (OCR) — requires "frames" alongside it, use extract() directly:
await ff.extract({ url, fields: ['frames', 'text_overlay'], frames: { mode: 'fps', fps: 1 } });
上記のヘルパーはすべて extract() の薄いラッパーです。そのため、extract() が受け付ける引数(translate、
format、追加の fields など)は、最後の引数として渡すことができ、そのまま転送されます。
動画を検索し、複数の動画を一度に抽出する
// Find something to extract when you don't have a URL yet
const s = await ff.search('how to make sourdough', { limit: 5 });
for (const hit of s.results) {
console.log(hit.title, hit.url, hit.durationSec);
}
// Then extract up to 10 of them in ONE call. Shared options apply to every url.
const b = await ff.batch(s.results.slice(0, 3).map((r) => r.url), {
fields: ['metadata', 'digest'],
});
for (const item of b.results) {
if (!item.ok) { console.error(item.url, item.error?.code); continue; }
console.log(item.metadata.title, '→', item.digest.gist);
}
1 つの URL が失敗してもバッチ全体が失敗することはありません。各エントリーには独自の ok フラグがあり、ok が false の場合は、code/message/hint を含む error が設定されます。URL ごとの frames 指定はバッチでは受け付けられません。その場合は extract() を使用してください。
トランスクリプトを翻訳して、字幕をエクスポートする
// translate the transcript into 1 of 25 languages (surfaced as transcript_translated)
const r = await ff.transcript(url, { translate: 'ja' });
console.log(r.transcript_translated.text);
// export subtitles directly — format is sent as a query param, response comes back as a string
const srt = await ff.transcript(url, { format: 'srt' }); // source-language subtitles
const vttJa = await ff.transcript(url, { translate: 'ja', format: 'vtt' }); // translated subtitles
サインアップ不要
const ff = new FrameFetch(); // no key
await ff.demo('https://youtu.be/jNQXAC9IVRw'); // instant metadata, rate-limited
const { key } = await ff.createKey('[email protected]'); // self-serve key + free credit
MCP エージェントから利用する
FrameFetch には、4 つのツール(framefetch_extract、
framefetch_platform_capabilities、framefetch_search、framefetch_account)を備えた MCP サーバー(Streamable HTTP)が付属しています。Claude、
Cursor、または任意の MCP クライアントに追加できます。
{
"mcpServers": {
"framefetch": {
"url": "https://framefetch.net/mcp",
"headers": { "Authorization": "<YOUR_FRAMEFETCH_KEY>" }
}
}
}
または、1 行で指定できます。
claude mcp add --transport http framefetch https://framefetch.net/mcp \
--header "Authorization: <YOUR_FRAMEFETCH_KEY>"
MCP は https://framefetch.net/mcp にあり、Streamable HTTP 経由で JSON-RPC を使用します。REST は
/v1/* 配下にあり、プレーンな JSON({"url": "…"})を受け取ります。この 2 つを取り違えるのは初回の呼び出しで最もよくある間違いです。そのため、どちらの方向でも明確なエラーが返されます。REST の本文を /mcp に POST すると JSON-RPC の解析エラーが返され、JSON-RPC の本文を /v1/extract に POST すると、クライアントが使うべき URL を示す 400 WRONG_ENDPOINT が返されます。
ローカル stdio ブリッジ
ローカルの stdio サーバー(Claude Desktop、サンドボックス、インバウンド HTTP なし)を使いたい場合、このパッケージには framefetch-mcp が付属しています。これは依存関係のない stdio↔HTTP ブリッジで、同じツールを提供し、呼び出しを framefetch.net に転送します。
{
"mcpServers": {
"framefetch": {
"command": "npx",
"args": ["-y", "framefetch-mcp"],
"env": { "FRAMEFETCH_API_KEY": "<YOUR_FRAMEFETCH_KEY>" }
}
}
}
tools/list はキーなしで動作します。ツールの呼び出しには FRAMEFETCH_API_KEY(または x402)を使います。エンドポイントは FRAMEFETCH_MCP_URL で上書きできます。
アカウントなしで支払う(x402)
自律型エージェントは、Base 上で x402 経由に USDC で呼び出しごとに支払えます。サインアップ不要で、人間の介在もありません。x402 Bazaar および /.well-known/x402.json から検出できます。人間は無料プラン、プリペイドクレジット、または Stripe カードを利用できます。
エラー
呼び出しが失敗すると、.status、.code、.hint を持つ FrameFetchError がスローされます。
import { FrameFetchError } from 'framefetch';
try {
await ff.transcript(url);
} catch (e) {
if (e instanceof FrameFetchError && e.status === 402) {
// out of credit — top up at framefetch.net or via x402
}
}
API の概要
| メソッド | エンドポイント | 認証 |
|---|---|---|
extract({ url, fields, frames, … }) | POST /v1/extract | キー |
ask(url, question) | POST /v1/extract(ask パラメーター) | キー |
metadata(url) | POST /v1/metadata | キー |
transcript(url, { translate, format }) | POST /v1/transcript | キー |
frames(url, spec) | POST /v1/frames | キー |
digest(url) | POST /v1/extract(digest) | キー |
audioDigest(url, { voice }) | POST /v1/extract(audio_digest) | キー |
structured(url) | POST /v1/extract(structured) | キー |
comments(url, { comments_cap }) | POST /v1/extract(comments) | キー |
commentSentiment(url) | POST /v1/extract(comment_sentiment) | キー |
search(query, { limit }) | POST /v1/search | キー |
batch(urls, { fields }) | POST /v1/batch | キー |
platforms() | GET /v1/platforms | — |
status() | GET /v1/status | — |
demo(url) | POST /v1/demo | — |
createKey(email) | POST /v1/keys | — |
extract() リクエストの完全な形式
ff.extract({
url: string,
fields?: Field[], // 'metadata' | 'insights' | 'transcript' | 'frames' | 'text_overlay'
// | 'digest' | 'audio_digest' | 'structured' | 'comments'
// | 'comment_sentiment' | 'delta'
frames?: { mode, n, fps, from, to, format, width },
translate?: string, // ISO-639-1 target language (25 supported)
voice?: string, // TTS voice for audio_digest
comments_cap?: number, // 1-200, default 100
ask?: string, // 3-500 char question — see ff.ask() above
publish?: boolean, // opt in to a public per-video SEO page
format?: 'md' | 'markdown' | 'srt' | 'vtt', // alternate egress rendering (returns a string, not JSON)
});
型定義を含むレスポンスの完全な形式(ExtractResult、Ask、
VideoStructured、VideoComments、CommentSentiment、AudioDigest、SearchResult、
BatchResult など)は index.d.ts を参照してください。
OpenAPI の全仕様:framefetch.net/openapi.json · ドキュメント:framefetch.net/docs
リンク
ウェブサイト · ドキュメント · 料金 · ステータス · ガイド:エージェントに動画データを提供する · 代替サービスとの比較
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。