# dsh-plugin-mcn MCN 短视频插件:在 DSH Web 左侧面板添加「MCN短视频」导航按钮, 点击进入抖音账号列表页面(数据来自 MCP 服务,本地 SQLite 缓存)。 参考实现:[deepseek-plugin-store](https://github.com/Ericwong5021/deepseek-plugin-store) ## 功能 - 左侧边栏底部新增「MCN短视频」按钮(图标 + 文字,窄栏模式显示图标) - 点击进入**抖音账号列表页**(非 iframe,内部 React 页面) - 账号数据:从 MCP `list_hot_accounts` 获取,**首次自动拉取存入本地 SQLite**(`~/.dsh/mcn-plugin.db`) - **分页**:每页 20 条,上一页/下一页 - **排序**:默认按序号(id)升序,点击表头可切换排序(序号/账号名/赛道) - **搜索**:按账号名 / 内容 / 赛道模糊搜索 - **筛选**:按赛道下拉筛选 - **更新**:点击弹窗确认后,从 MCP 重新拉取并覆盖本地缓存 - 页面左上角「← 返回」按钮;URL 路由 `/mcn` ## 架构 ``` 客户端(React,client.js) │ fetch /mcn/api/* 宿主端(Node,index.js) ├─ 本地 SQLite(node:sqlite,Node 24 内置,~/.dsh/mcn-plugin.db) ├─ MCP stdio 客户端(spawn npx -y myai-mcp → list_hot_accounts) └─ HTTP 路由:/mcn/api/accounts|tracks|refresh|status ``` ### 数据流 ``` 首次访问 /mcn 页面 → GET /mcn/api/accounts → 宿主端查 SQLite → 空 → 自动调 MCP list_hot_accounts → 写入 SQLite → 返回 → 有 → 直接返回缓存 点击「更新」(弹窗确认) → POST /mcn/api/refresh → 调 MCP → 覆盖 SQLite → 返回新数量 ``` ## 安装(本地开发) ```sh dsh plugin --profile web add file:D:/dshworkspace/plugin_package/dsh-plugin-mcn ``` 或通过 patch 直接挂载: ```yaml # cordis.patch.yml(profile 层) - insert: - id: mcn-nav name: '/绝对路径/dsh-plugin-mcn/lib/index.js' ``` ## 结构 ``` dsh-plugin-mcn/ ├── package.json ← dsh.bundle 声明 + client 入口 ├── cordis.patch.yml ← 挂载条目 ├── lib/ │ ├── index.js ← 宿主端(SQLite + MCP 拉取 + HTTP 路由) │ └── client.js ← 客户端 bundle(侧边栏按钮 + 账号列表页) └── README.md ``` ## API | 路由 | 方法 | 说明 | |------|------|------| | `/mcn/api/accounts?page=&pageSize=&search=&track=&sortBy=&order=` | GET | 分页查询账号列表 | | `/mcn/api/tracks` | GET | 赛道列表(筛选下拉) | | `/mcn/api/refresh` | POST | 从 MCP 重新拉取数据 | | `/mcn/api/status` | GET | 本地缓存数量 | ## 说明 - 外部账号导入(/mcn/api/external/*)的字段归一化与「定位/内容」提取规范见 [docs/外部账号导入处理规范.md](docs/外部账号导入处理规范.md),处理新账号时复用 - 客户端 bundle 使用 `window.__ModuleLoader__.load` 格式,与官方 client 插件一致 - 侧边栏注入点:`sidebar.footer.action`(与插件商店相同位置) - 修改 client.js / index.js 后需刷新页面生效;宿主端改动需重启 dsh 服务 - MCP 拉取依赖飞书登录态(复用 `~/.myai-mcp/credentials.json`)