Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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站 或被限流时,告诉我原因,不要反复重试,一次只读一个视频。
```

Expand Down
11 changes: 9 additions & 2 deletions mcp/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -196,14 +196,21 @@ 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." : "";
return { isError: true, content: [{ type: "text", text: `${code}${err.message}${tail}` }] };
}

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 || {};
Expand Down
3 changes: 3 additions & 0 deletions mcp/test/server.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand Down
7 changes: 6 additions & 1 deletion skills/moondigest/SKILL.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
Loading