dsh-video-evidence
Allows searching Bilibili public videos for a query and locating the specific video segments that answer it, with timestamps and direct playback links.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dsh-video-evidence在B站搜‘Transformer原理’,并告诉我视频中讲到Self-Attention的时间点"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dsh-video-evidence
兼容的 Harness 版本
已验证支持:DeepSeek Harness
0.1.0-rc.6(通过@deepseek-ai/dsh-mcp-client,跨 profile 可用)。最新版
0.1.2-alpha.3:适配计划进行中,暂无确切完成时间。升级前请先备份你的 DSH 安装。
给 DeepSeek Harness (dsh) 的 MCP 插件:按问题检索 B 站视频,并定位到真正讲到该内容的片段(带时间戳、可直接回跳)。
不是"搜到视频"就结束,而是回答"这个问题的答案在视频的第几分钟"。
用户:Spring Boot 项目怎么创建?
→ 1. https://www.bilibili.com/video/BV17m411d7Ny?t=0
环境准备、JDK 版本选择 …
→ 2. https://www.bilibili.com/video/BV17m411d7Ny?t=60
打开 IDEA,新建 Project,选择 Spring Initializr …
→ 3. https://www.bilibili.com/video/BV17m411d7Ny?t=90
填写 Group / Artifact,勾选依赖,Finish …Related MCP server: vid-agent-mcp
为什么做这个
市面上的"跨模态检索 / 智能搜索"插件,绝大多数做的是网页和文本这一层:给一段查询,返回一堆链接和摘要。这一层已经很挤了,重复造轮子没有意义。
真正还没有被好好解决的,是视频内部的片段级定位:
搜索引擎只能告诉你"这个视频可能相关",不会告诉你相关的是哪 30 秒;
视频平台自带的字幕搜索依赖 UP 主上传字幕,覆盖率和质量都靠运气;
对教程、课程录像、会议发言这类内容,用户真正要的从来不是"整片",而是"讲到 X 的那一小段"。
本插件补的就是这一段:公开视频 → 本地转写 → 片段级检索 → 可回跳的时间戳证据。全部本地完成,不依赖任何付费 API 或第三方检索服务。
工作流程
┌──────────────────────── dsh (MCP client) ────────────────────────┐
│ mcp__video_evidence__video_search / __video_cache_stats │
└───────────────────────────────┬──────────────────────────────────┘
│ stdio / JSON-RPC
┌───────────────────────────────▼──────────────────────────────────┐
│ server.js (Node 常驻进程,只做协议转发) │
│ · 双分帧解析:NDJSON ⇄ Content-Length │
│ · 收到 tools/call 才 spawn Python worker │
└───────────────────────────────┬──────────────────────────────────┘
│ spawn(按需,用完即退)
┌───────────────────────────────▼──────────────────────────────────┐
│ worker.py → server.py │
│ 1. bili.py B 站 wbi 签名搜索 → 取 cid → 取 360P 流地址 │
│ 2. asr.py ffmpeg 拉流转 16k 单声道 wav │
│ faster-whisper (base/int8, CPU) 转写 │
│ 3. cache.py SQLite 按 BV 号缓存转写结果(TTL 30 天) │
│ 4. evidence.py 中文 BM25(单字 + 二元组)打分 │
│ 45s 滑窗 / 30s 步长切块 → 排序取 top-k │
└──────────────────────────────────────────────────────────────────┘为什么是 Node 常驻 + Python worker: dsh 的 dsh-mcp-client spawn 之后会立刻发 initialize,跟 Python 常驻进程握手不稳定(实测 4 次启动、0 条消息收到)。Node 冷启动足够快,而真正的检索/ASR 留在 Python 侧,只在工具被真正调用时才拉起,空闲时不占资源。
安装
前置依赖
依赖 | 说明 |
Node.js | 18+,只用到内置模块,无需 |
Python | 3.9+ |
ffmpeg | 必须在 PATH 中,或用 |
faster-whisper |
|
git clone https://github.com/wjxn13/dsh-video-evidence.git
cd dsh-video-evidence
# Windows
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
# macOS / Linux
python3 -m venv .venv
# 注意:server.js 里写死了 .venv/Scripts/python.exe(Windows 布局)。
# 非 Windows 需要把 server.js 中 PY 的路径改成 .venv/bin/python。
.venv/bin/pip install -r requirements.txt首次调用 video_search 时,faster-whisper 会自动下载 base 模型到 models/base/(约 145MB)。也可以手动放置,或用 ASR_MODEL_DIR 指向已有模型目录。
接入 dsh
在用户级 ~/.dsh/cordis.patch.yml 里追加(路径改成你自己的):
- insert:
- id: mcp-video-evidence
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: video_evidence # ← 决定工具名前缀:mcp__video_evidence__*
transport: stdio
command: "C:/path/to/node.exe"
args:
- "C:/path/to/dsh-video-evidence/server.js"
cwd: "C:/path/to/dsh-video-evidence"
env:
PYTHONIOENCODING: "utf-8"
PYTHONUNBUFFERED: "1"
toolCallTimeoutMs: 240000几个关键点:
name要填@deepseek-ai/dsh-mcp-client,这是 dsh 的 MCP loader 包名,不是随便起的名字。serverName决定工具名前缀:mcp__<serverName>__<toolName>,所以这里是mcp__video_evidence__video_search。command用 node 的绝对路径。dsh 会清理子进程环境,不能依赖 PATH。cwd要指向插件目录,server.js依赖它定位.venv和worker.py。toolCallTimeoutMs给足(这里 240 秒)。首次查询要拉流 + 转写,默认的短超时会让工具在结果出来前被判失败。
然后重启 dsh——配置只在启动时加载。用 dsh --dump-config --profile web 可以确认条目有没有被正确合并进去。
⚠️
id不能和已有条目重复。 cordis loader 不允许同 id 覆盖,重复会直接让 dsh 启动崩溃(报 duplicate loader entry)。改配置前先备份cordis.patch.yml。
工具
video_search
参数 | 类型 | 默认值 | 说明 |
| string | 必填 | 要检索的问题或关键词 |
| integer | 3 | 最多处理几个候选视频(1–5) |
| integer | 5 | 返回几个最相关片段(1–10) |
| integer | 300 | 每个视频最多转写前多少秒(60–1800) |
| integer | 170 | 总时间预算,超时就返回已经拿到的结果 |
video_cache_stats
无参数。返回已缓存转写的视频数量。
性能实测
本机环境:Windows 11 / Ryzen 7 6800H / RTX 3050 Ti(纯 CPU 推理,不用显卡),faster-whisper base + int8:
项目 | 实测 |
转写速度 | 45 秒音频 ≈ 2.3 秒(约 20 倍实时) |
10 分钟视频 | ≈ 30 秒 |
命中缓存后 | 几乎瞬时(只查 SQLite + BM25) |
也就是说,一次交互式提问(转写前 90–180 秒)通常在几秒内返回。
环境变量
变量 | 默认值 | 说明 |
| PATH 里的 | ffmpeg 可执行文件路径。不设则自动从 PATH 查找,找不到才需要显式指定 |
|
| faster-whisper 模型目录 |
| 空 | B 站 SESSDATA Cookie。不填也能用(搜索/取流正常),填了可以尝试走官方字幕通道 |
|
| 转写缓存数据库路径 |
|
| 缓存有效期(秒) |
|
| 默认单视频转写时长上限 |
|
| 默认总时间预算 |
|
| 默认候选视频数 |
|
| 滑窗切块的窗口长度与步长(秒) |
|
| Python worker 超时(毫秒) |
已知限制
只覆盖 B 站公开视频,且只转写前
audio_seconds秒(默认 5 分钟)。长视频靠后的内容需要调大该参数,耗时线性增长。匿名状态下拿不到官方字幕(
subtitles接口返回 0 条),所以一律走本地 ASR,不依赖 UP 主有没有上传字幕。BM25 是词面匹配,不做语义向量检索。换个说法提问可能命中不到,这是有意的取舍——本地 CPU 上跑 embedding 模型会显著拖慢交互式响应。
server.js里 Python 路径写死为.venv/Scripts/python.exe(Windows 布局),非 Windows 需要手动改一处。
排错
工具注册不上去(dsh 里看不到 mcp__video_evidence__*)
这是最坑的一类问题,现象是:配置明明正确(dsh --dump-config --profile web 能看到条目),重启也没用,日志里反复刷 server ready → stdin closed → server ready。
根因:同一个 dsh 实例里存在两套 MCP 分帧格式。
dsh 自带的
dsh-mcp-client发的是 NDJSON(裸 JSON +\n,没有Content-Length头)argo / memorix 这类用标准 MCP SDK 的走的是
Content-Length: N\r\n\r\n{json}
只认 Content-Length 的解析器收 NDJSON 时永远凑不出一条完整消息 → 不回 initialize → dsh 超时关 stdin → 重拉,死循环。
本插件的 server.js 已经用 clientFraming 闩锁 + nextMessage() 做了双格式兼容,响应按客户端格式对称回写。如果你要 fork 改写协议层,这两段不要动。
配套的两个必要细节:
initialize必须回显客户端发来的protocolVersion,不能硬编码。MCP SDK 会校验服务端返回的版本是否在自身支持列表内,硬编码新版会让较老 SDK 判定协商失败并直接关闭 stdin。ping/resources/list/prompts/list要返回空结果而不是-32601。 客户端探测能力时收到 method not found 会判定连接不健康,进而断连重连。
怎么定位: 在 stdin 的 data 回调里打第一条原始数据:
if (!gotAny) {
gotAny = true;
log("FIRST stdin data: raw=" + JSON.stringify(d.toString("utf8").slice(0, 400)));
}看到 {"method":"initialize",...} 后面直接跟 \n、没有 Content-Length,就确认是 NDJSON。
B 站搜索返回空(HTTP 200、code:0、但结果为空)
wbi 签名的坑:urllib.parse.urlencode 默认用 quote_plus,空格编码成 +;B 站服务端按 %20 重算签名,校验不通过就静默拒绝。
# 必须用 quote(空格 -> %20),不能用默认的 quote_plus(空格 -> +)
q = urllib.parse.urlencode(p, quote_via=urllib.parse.quote)bili.py 里已经修好,并且加了非 wbi 的 legacy 接口作为兜底。
目录结构
dsh-video-evidence/
├── server.js # Node 常驻 MCP server(协议层:双分帧 + 方法分发)
├── worker.py # Python worker 入口(CLI,读 JSON 参数、打 JSON 结果)
├── server.py # 业务编排:搜索 → 取流 → 转写 → 检索
├── bili.py # B 站 API 客户端(wbi 签名、搜索、cid、playurl)
├── asr.py # ffmpeg 拉流 + faster-whisper 转写
├── evidence.py # 中文 BM25 打分 + 滑窗切块
├── cache.py # SQLite 转写缓存(按 BV 号,TTL 30 天)
└── requirements.txtLicense
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Extract YouTube transcripts, search what was said, and read on-screen frames with cited timestamps.
YouTube video search with transcript extraction as first-class output.
Video knowledge base for agents: search your library's transcripts, keyframes and on-screen text.
Transcribe YouTube via Whisper. Summaries, chapters, semantic-search across your corpus.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables interaction with Bilibili (B站) platform through API and web scraping. Supports video search, article search, video info retrieval, comment fetching, danmaku extraction, and article content access.4
- AlicenseNot gradedqualityCmaintenanceEnables Claude to transcribe Bilibili videos, search by intent, and analyze local video files, returning structured summaries with key points and verdicts.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables probing, ingesting, transcribing, and searching Bilibili videos with timestamped evidence and frame extraction, without reading browser cookies.2MIT
- AlicenseNot gradedqualityCmaintenanceEnables transcribing public Douyin videos to text using a local AI model, providing read-only tools for transcription, search, and listing.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/wjxn13/dsh-video-evidence'
If you have feedback or need assistance with the MCP directory API, please join our Discord server