diff --git a/README.md b/README.md index ddf5bfb7..441f5ef2 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,10 @@ Agent 碰到视频通常只能看标题和封面。装了 MoonDigest,agent 能 不装 skill 也行,把这段提示词粘给 agent(用 MCP 时把第 1、2 步换成 get_video、get_frame): ```text -需要了解 B站 或 YouTube 视频的内容时,用浏览器打开视频页,不要只看标题和封面,也不要下载视频。浏览器里装了 MoonDigest 扩展,按 https://github.com/PathGao/MoonDigest/blob/main/skills/moondigest/SKILL.md 的步骤做: +需要了解 B站 或 YouTube 视频的内容时,包括查资料时搜到的视频,用浏览器打开视频页,不要只看标题和封面,也不要下载视频。浏览器里装了 MoonDigest 扩展,按 https://github.com/PathGao/MoonDigest/blob/main/skills/moondigest/SKILL.md 的步骤做: 1. 在视频页执行文档里的 JS,用 moondigest-get 拿字幕、章节、简介和评论。 2. 按章节读字幕。要核对画面(图表、代码、屏幕上的文字)时,用 moondigest-frame 跳到对应秒数截一帧,图片别直接打印进上下文。 -3. 结论带上时间戳(mm:ss)和能跳到那一刻的链接。 +3. 查资料搜到多个视频时,挑最相关的几个读,只引用或推荐真正讲了我要的内容的。结论带上时间戳(mm:ss)和能跳到那一刻的链接。 4. 没字幕、没登录 B站 或被限流时,告诉我原因,不要反复重试,一次只读一个视频。 ``` diff --git a/mcp/server.js b/mcp/server.js index a2e82c6d..57877303 100755 --- a/mcp/server.js +++ b/mcp/server.js @@ -171,7 +171,7 @@ const URL_DOC = "A Bilibili video page (www.bilibili.com/video/…, /bangumi/pla const TOOLS = [ { name: "get_video", - description: "Read a Bilibili or YouTube video through the user's own browser: title, author, date, duration, chapters, the full timestamped transcript and hot comments. Call this first for any video. Work on one video at a time. If the result says THROTTLED, stop calling MoonDigest and tell the user; do not retry soon.", + description: "Read a Bilibili or YouTube video through the user's own browser: title, author, date, duration, chapters, the full timestamped transcript and hot comments. Call this first for any video: one the user links, and one that turns up in your search results or recommendations, to check what it actually says before you cite or recommend it. Work on one video at a time. If the result says THROTTLED, stop calling MoonDigest and tell the user; do not retry soon.", inputSchema: { type: "object", properties: { @@ -196,6 +196,13 @@ const TOOLS = [ }, ]; +// What MCP clients put in the model's prompt about this server: when to reach for it, not how each tool works. +export const INSTRUCTIONS = [ + "MoonDigest reads Bilibili and YouTube videos through the user's own browser and login: the full timestamped transcript, chapters, description and hot comments (get_video), and a frame at any second (get_frame).", + "Use it whenever a video matters to the answer, not only when the user links one. When you research a topic, look for tutorials or compare sources and your search turns up Bilibili or YouTube videos, do not judge them by title, thumbnail or view count: read the most promising ones with get_video, check that they really cover what the user asked, and say what each one says, citing mm:ss timestamps and links that open at that moment. Drop the ones that do not match.", + "Read a few candidates, one at a time, not dozens: Bilibili and YouTube rate-limit bursts. If a result says THROTTLED, stop and tell the user. MoonDigest cannot search; find the videos with your own search tools first.", +].join("\n\n"); + function errorResult(err) { const code = err.code ? `${err.code}: ` : ""; const tail = err.code === "THROTTLED" ? " Stop calling MoonDigest for now and tell the user; do not retry soon." : ""; @@ -203,7 +210,7 @@ function errorResult(err) { } export function createMcpServer(bridge) { - const server = new Server({ name: "moondigest", version: "0.1.0" }, { capabilities: { tools: {} } }); + const server = new Server({ name: "moondigest", version: "0.1.0" }, { capabilities: { tools: {} }, instructions: INSTRUCTIONS }); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); server.setRequestHandler(CallToolRequestSchema, async ({ params }) => { const args = params.arguments || {}; diff --git a/mcp/test/server.test.mjs b/mcp/test/server.test.mjs index 1570fde0..8f42dc31 100644 --- a/mcp/test/server.test.mjs +++ b/mcp/test/server.test.mjs @@ -179,6 +179,9 @@ test("stdio binary lists the two tools", async () => { await client.connect(transport); const { tools } = await client.listTools(); assert.deepEqual(tools.map((t) => t.name), ["get_video", "get_frame"]); + // The server tells the model to check videos that turn up in its own searches, not only linked ones. + assert.match(client.getInstructions() || "", /search turns up Bilibili or YouTube videos/); + assert.match(tools[0].description, /search results/); await client.close(); }); diff --git a/skills/moondigest/SKILL.md b/skills/moondigest/SKILL.md index d5b7ea95..d9f49be4 100644 --- a/skills/moondigest/SKILL.md +++ b/skills/moondigest/SKILL.md @@ -1,12 +1,17 @@ --- name: moondigest -description: Read and watch a Bilibili or YouTube video through the user's own browser. Open the video page in a browser that has the MoonDigest extension, get title, description, chapters, timestamped transcript and hot comments in one call, then grab frames at the moments worth seeing. Use when the user gives a bilibili.com / b23.tv / youtube.com / youtu.be link, or asks to summarize, check or quote a video. No download, no local transcription. +description: Read and watch a Bilibili or YouTube video through the user's own browser. Open the video page in a browser that has the MoonDigest extension, get title, description, chapters, timestamped transcript and hot comments in one call, then grab frames at the moments worth seeing. Use when the user gives a bilibili.com / b23.tv / youtube.com / youtu.be link, asks to summarize, check or quote a video, or when you research a topic and your search results include Bilibili or YouTube videos: read them to check they really cover what the user asked before citing or recommending them. No download, no local transcription. --- # MoonDigest: read a video in the browser The MoonDigest extension answers JS running in a Bilibili or YouTube video page. It reads the video the way the page does, with the user's login, so Bilibili's login-only subtitles work and there is no 429 / 412 from a server IP. It is read-only: no AI quota, no access to the user's notes or keys. The full contract is in [docs/AGENT.md](../../docs/AGENT.md). +## When to use it + +- The user links a video or asks about one. +- You are researching, looking for tutorials or comparing sources, and your search turns up Bilibili or YouTube videos. Do not judge them by title, thumbnail or view count. Read the most promising few, keep the ones that really cover what the user asked, and say what each one says with timestamps. MoonDigest cannot search: find the videos with your own search tools first. + ## Before you start - The browser you drive (ego, Claude in Chrome, Playwright with the user's profile, …) has MoonDigest installed and enabled.