mcpField
F
framefetch

framefetch

远程服务
framefetch.net媒体与设计013 周前更新

关于 framefetch

framefetch 是将社交视频 URL 转为字幕、元数据、抽样帧、OCR 等结构化结果的 API 和 MCP 服务,面向需要搜索或分析多个平台视频的 Agent 与应用。

主要功能

  1. 01提取字幕、元数据和视频帧
  2. 02基于视频内容回答问题
  3. 03通过 OCR 识别画面文字
  4. 04按关键词搜索并批量处理最多 10 个 URL
  5. 05生成摘要、结构化数据和评论分析

适用场景

  1. 01回答有关社交视频的问题
  2. 02提取前按关键词查找视频
  3. 03分析视频画面和屏幕文字
  4. 04一次批量处理多个视频 URL

MCP 相关

通过 Streamable HTTP 提供 MCP 服务,包含 `framefetch_extract`、`framefetch_platform_capabilities`、`framefetch_search` 和 `framefetch_account` 工具。另有本地 stdio 桥接程序,将调用转发至托管服务。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://framefetch.net/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 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

4
参数类型必填说明
askstring否关于视频的问题(3–500 个字符);答案最多 500 个 token,包含带时间戳的引文,并以转录文本为依据(自动提取)。绝不缓存;如果不可用则降级处理(不收费)。对于较长的视频,答案取自按相关性选择/抽样的部分,而不只是开头——参见响应中的 `ask.coverage`。没有转录文本(例如 Pinterest)时,改用帧,并设置 `based_on`:["frames"]。
urlstring是受支持平台上的公开视频 URL。
cacheboolean否设为 false 可强制重新提取并收费。
voiceenum否"audio_digest" 的语音:OpenAI 语音(alloy/echo/fable/onyx/nova/shimmer)以及 Groq "Fritz-PlayAI";默认值为 "alloy"。alloy | echo | fable | onyx | nova | shimmer | Fritz-PlayAI
fieldsarray否要返回的数据;默认值为 ["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。
framesobject否帧采样规格;请求 "frames" 或 "text_overlay" 时必填。
frames.nnumber否every_n:每隔 N 个源帧采样一帧
frames.tonumber否range:结束秒数
frames.fpsnumber否fps/range:每秒帧数(最多 60)
frames.fromnumber否range:开始秒数
frames.modeenum是all | every_n | fps | range
frames.widthnumber否缩放后的宽度,单位为 px(16–7680)
frames.formatenum否jpg | png | webp
translatestring否ISO-639-1 目标语言(例如 "es");添加 `transcript_translated`(保留时间信息)。需要 "transcript"(或 "digest")。按音频分钟计费。
comments_capinteger否顶层评论的最大数量(1–200,默认值为 30);仅与 "comments" 一起使用。
subtitle_formatenum否将转录文本渲染为 `subtitles` 字幕(srt/vtt)。需要 "transcript"(或 "digest");如果设置了 "translate",则使用翻译后的字幕条目。srt | vtt

详细介绍

FrameFetch 标志

FrameFetch

任意社交视频 URL → 答案、转录文本、元数据、洞察、帧和屏幕文字(OCR)。
面向 Agent 的优先视频数据 API + MCP 服务。按次付费,或使用 x402(USDC)付款——无需账户。

npm 网站 状态 MIT


FrameFetch 可将一个 YouTube、YouTube Shorts、TikTok、Instagram Reels、Pinterest 或 Reddit 视频 URL 转换为单个 JSON 响应,其中包含:对视频问题的直接回答、元数据、互动洞察、转录文本(字幕或 Whisper)、大模型摘要(文本或语音 mp3)、结构化 JSON(章节/实体/产品/声明)、评论 + 情感分析、按参数采样的帧(每 N 帧/每秒 1 帧/指定时间范围,可设任意宽度),以及这些帧中嵌入的屏幕文字(OCR——字幕、价格标签、标牌)。此外,还提供关键词搜索(尚无 URL 时使用)和批量处理(单次调用最多处理 10 个 URL)。专为 AI Agent 打造,API 和 MCP 优先。

此仓库包含开源客户端 + 文档。服务本身运行于 framefetch.net——你只需准备一个免费的 API 密钥(或通过 x402 按次付费);后端由服务托管。

原因

大模型无法观看视频。若要对视频进行推理,必须先将其转换为文本和图像——包括答案、转录文本、元数据和若干帧。FrameFetch 可通过统一的架构,从六个平台的 URL 获取所有这些内容。

安装

npm install framefetch

Node 18+(使用内置的 fetch)。获取免费密钥:framefetch.net。

版本说明。 此仓库的版本为 0.4.0。目前 npm 上的最新版本是 0.3.0——npm install framefetch 安装的仍是该版本,且仅支持 extract/metadata/transcript/frames/platforms/status/demo/createKey。下文记录的其他功能现已在 API 上提供,也可通过此仓库使用;使用 npm 0.3.0 时,可通过 extract({ fields: [...] }) 获取相同数据。

提问——获取答案,而不是一大段转录文本

针对视频提问,可获得简短且有依据的回答,并附带时间戳引用;无需自行解析 25,000-token 的转录文本。

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

注意两种拼写: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);
}

单个 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 Agent 中使用

FrameFetch 附带一个 MCP 服务(Streamable HTTP),包含四个工具:framefetch_extract、 framefetch_platform_capabilities、framefetch_search 和 framefetch_account。将其添加到 Claude、 Cursor 或任何 MCP 客户端中:

{
  "mcpServers": {
    "framefetch": {
      "url": "https://framefetch.net/mcp",
      "headers": { "Authorization": "<YOUR_FRAMEFETCH_KEY>" }
    }
  }
}

也可以用一行命令:

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": "…"})。混淆两者是首次调用时最常见的错误,因此两个接口都会明确回应: 将 REST 请求体 POST 到 /mcp 会返回 JSON-RPC 解析错误;将 JSON-RPC 请求体 POST 到 /v1/extract 则会返回 400 WRONG_ENDPOINT,并指出客户端应使用的正确 URL。

本地 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)

自主 Agent 可通过 Base 上的 x402 按次使用 USDC 付费,无需注册,也无需人工介入。可在 x402 Bazaar 和 /.well-known/x402.json 中发现。个人用户可使用免费额度、预付费点数或 Stripe 卡付款。

错误

调用失败时会抛出 FrameFetchError,包含 .status、.code 和 .hint:

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

链接

网站 · 文档 · 定价 · 状态 · 指南:为 Agent 提供视频数据 · 与替代方案比较

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。