内容
# MVR — 我的视频资源
**一个自我托管的MCP服务器和本地仪表盘,用于构建可重复使用的AI视频参考库。**
MVR存储命名为 **元素** 的内容 — 角色、产品、地点、风格 — 作为结构化、版本化的参考图像(而不仅仅是文本提示),并通过 `@tags` 将上下文传递给任何与MCP兼容的代理。它是一个 **创意库和代理上下文层**,而不是视频生成模型:连接的代理仍然使用其自己的提供者集成执行实际生成。

---
## 目录
- [为什么是 MVR](#为什么是MVR)
- [工作原理](#工作原理)
- [核心概念](#核心概念)
- [快速入门](#快速入门)
- [MCP 工具](#MCP工具)
- [HTTP API](#HTTPAPI)
- [存储](#存储)
- [安全性和运维](#安全性和运维)
- [当前范围](#当前范围)
---
## 为什么是 MVR
AI视频提示不断重复相同的角色、产品和地点描述。场景之间的细微措辞差异往往足以使角色的面部或产品的形状发生变化。AI视频创作者的标准做法是为每个重复的资产创建 **参考表** — 锁定角色的特写、身体的前后转动、产品的多角度表 — 并在每个场景中重用这些确切的图像,而不是用语言重新描述它们。
MVR 将这种做法转变为一个小型、自我托管的服务:
- 参考图像存放在一个地方,按命名 **元素** 和 **槽位** (角度/视图)组织,而不是分散在聊天历史中。
- 每个元素 **类型** (角色、道具、地点、风格)都带有种子检查清单,列出基于实际保持AI视频输出一致性的角度。
- 任何与MCP兼容的代理 — Claude Desktop、Claude Code、Cursor或自定义代理 — 都可以查询同一个库,因此构建角色或产品表格的工作只做一次,并在所有地方重用。
---
## 工作原理
### 架构
```mermaid
flowchart TD
Creator(["🎬 创作者"])
UI["本地仪表盘\nlocalhost:8080"]
Agent["与MCP兼容的代理\nClaude · Cursor · 自定义"]
MVR["MVR 服务器\nMCP 工具 + REST API"]
DB[("SQLite 保险库\n元素 · 配置 · 提供者")]
Assets[("资产存储\n本地卷或 S3")]
Provider["外部 AI 提供者\n图像 / 视频生成"]
Output(["🎥 生成的视频 / 图像"])
Creator -->|管理库,密钥| UI
Creator -->|"聊天:使用 @hero + @headphones"| Agent
UI -->|REST,持有者令牌| MVR
Agent -->|MCP 工具,stdio 或 HTTP| MVR
MVR --> DB
MVR --> Assets
Agent -->|其自己的提供者集成| Provider
Provider --> Output
Output -.->|显示回| Creator
```
**关键边界:** MVR 绝不会直接调用生产生成 API。它将 `@tags` 解析为参考资产和保存的模型偏好,并将其返回给代理 — 代理执行实际调用给 Higgsfield、OpenAI 或其配置的任意提供者。
### 典型请求,逐步
```mermaid
sequenceDiagram
participant C as 创作者
participant A as AI 代理
participant M as MVR 服务器
participant P as 外部提供者
C->>A: "生成 @hero 戴上 @headphones 的镜头"
A->>M: resolve_prompt(text)
M-->>A: resolved_text, elements_used (with asset paths),<br/>completeness_warnings
A->>M: get_active_model("视频生成")
M-->>A: 提供者,模型,设置
A->>P: generate(resolved prompt, references, settings)
P-->>A: 生成的视频 / 图像
A-->>C: 结果,以及任何 "你缺少 @hero 的背面视图" 提醒
```
如果提示中引用的元素缺少必填参考角度,MVR 不会 **阻止** 请求 — 它会附加一个 `completeness_warnings` 条目,以便代理可以传递提醒,创作者可以决定现在修复它或接受风险。

### 元素结构
元素不是一个文本字段 — 它是一个命名记录和一组 **槽位**,其中每个槽位都是一个真实的、版本化的参考图像。必填槽位取决于元素的 `类型`:
```mermaid
flowchart LR
subgraph Element["元素:@hero(类型:角色)"]
direction LR
S1["面部特写\n✅ 已上传"]
S2["身体正面\n✅ 已上传"]
S3["身体背面\n⬜ 缺失"]
end
Element --> Check{"检查元素完整性"}
Check -->|缺少必填槽位| Warn["完整性警告\n返回给代理"]
Check -->|所有必填槽位存在| OK["元素准备好使用"]
```
| 类型 | 必填槽位 | 可选槽位 |
|---|---|---|
| `角色` | `面部特写`,`身体正面`,`身体背面` | 通过 `variantOf` 变体 |
| `道具` | `正面`,`三分之二` | `侧面`,`内侧`,`顶部`,`背面`,`底部` |
| `地点` | `建立_3_4` | `示意图_地图` |
| `风格` | — | `参考图像` |
| `音频`,`其他` | — | — |
这些配方在首次运行种子,可以通过 `get_kind_template` 在任何时候检查。
<!-- TODO: screenshot — 仪表盘的槽位上传器,用于单个元素,显示进度指示器(例如“2/3 槽位完成”) -->

---
## 核心概念
| 概念 | 它是什么 |
|---|---|
| **元素** | 可重用的角色、产品、地点、风格或其他创意资产,引用为 `@tag`。 |
| **元素资产** | 为元素的某个槽位存储的真实的、版本化的 PNG(例如 `面部特写`)。锁定资产可防止意外覆盖。 |
| **类型模板** | 给定 `类型` 的槽位配方和最佳实践的种子。 |
| **提示格式模板** | 已解析提示应遵循的模型特定结构(例如 Seedance 2.0 期望的 Style/Characters/Scene/CUT 块)。与元素配方分开,以便新模型只需要一个新的格式条目。 |
| **模型配置** | 为一项任务保存的提供者 + 模型 + 设置偏好,例如 `视频生成 → Seedance → 2.0`。 |
| **提供者** | 为未来评估功能存储的加密 API 密钥。今天不用于生产生成调用。 |
| **保险库** | 支持上述所有内容的本地 SQLite 数据库。 |
---
## 快速入门
### 本地
```bash
cp .env.example .env
# 将 MVR_ENCRYPTION_KEY 和 MVR_AUTH_TOKEN 替换为你自己的密钥。
npm install
npm run build
npm start
```
```bash
npm run dev # 监视模式
npm run build # TypeScript 构建
npm test # Vitest 套件
npm run stdio # 仅运行 stdio MCP 服务器
```
### Docker
```bash
cp .env.example .env
# 替换 MVR_ENCRYPTION_KEY 和 MVR_AUTH_TOKEN。
docker compose up --build
```
Docker Compose 在 `mvr-data` 卷中持久化数据库,并将 `./data/assets` 绑定挂载到 `/app/data/assets`,因此参考图像在主机上保持可检查。

### 连接 MCP 客户端
**stdio** (Claude Desktop,Claude Code,以及类似):
```json
{
"mcpServers": {
"mvr": {
"command": "node",
"args": ["/absolute/path/to/MVR/dist/index.js", "--stdio"],
"env": {
"MVR_DB_PATH": "/absolute/path/to/MVR/data/mvr.db",
"MVR_ASSET_PATH": "/absolute/path/to/MVR/data/assets",
"MVR_ENCRYPTION_KEY": "your-long-random-secret"
}
}
}
}
```
```text
Authorization: Bearer your-long-random-token
Accept: application/json, text/event-stream
```
<!-- TODO: screenshot — Claude Desktop 的 MCP 设置面板,显示 "mvr" 已连接 -->

---
## MCP 工具
| 工具 | 目的 |
|---|---|
| `list_elements` | 列出元素。 |
| `get_element` | 获取元素及其摘要版本历史。 |
| `create_element` | 创建元素(`tag`,`kind`,`displayName`,`summary`,`variantOf?`,`metadata?`)。 |
| `update_element` | 更新元素元数据或摘要。 |
| `delete_element` | 永久删除元素及其记录。 |
| `upload_element_asset` | 上传 PNG 到命名槽(`tag`,`slotName`,`image`,`sourcePrompt?`,`locked?`)。 |
| `list_element_assets` | 返回每个填充槽的当前版本。 |
| `check_element_completeness` | 返回 `{ complete, missing: [{ slot, required, rationale }] }`。 |
| `get_kind_template` | 获取类型的槽配方和最佳实践。 |
| `resolve_prompt` | 将 `@tags` 解析为引用和非阻塞完整性警告。 |
| `get_prompt_format` | 按提供者和模型获取模型特定提示格式。 |
| `list_model_configs` / `set_model_config` / `get_active_model` / `delete_model_config` | 管理每任务模型偏好。 |
| `list_providers` | 列出具有遮蔽 API 密钥的提供者。 |
---
## HTTP API
所有端点都在 `/api` 下,需要设置 `MVR_AUTH_TOKEN` 时的持有者令牌。
| 方法 | 端点 | 目的 |
|---|---|---|
| `GET`,`POST` | `/elements` | 列出或创建元素。 |
| `DELETE` | `/elements/:tagOrId` | 删除元素。 |
| `GET`,`POST` | `/elements/:tagOrId/assets` | 列出资产或上传 PNG。 |
| `GET` | `/elements/:tagOrId/completeness` | 检查必填槽。 |
| `GET` | `/kind-templates/:kind` | 获取种子类型模板。 |
| `GET` | `/prompt-formats?provider=Seedance&model=2.0` | 获取提示格式模板。 |
| `GET`,`POST` | `/providers` | 列出遮蔽提供者或保存密钥。 |
| `DELETE` | `/providers/:name` | 删除提供者。 |
| `GET`,`POST` | `/model-configs` | 列出或保存模型配置。 |
| `DELETE` | `/model-configs/:task` | 删除模型配置。 |
---
## 存储
**本地(默认):**
```dotenv
MVR_STORAGE_DRIVER=local
MVR_ASSET_PATH=/app/data/assets
MVR_ASSET_IMPORT_PATH=/app/data/imports
```
**S3 兼容:**
```dotenv
MVR_STORAGE_DRIVER=s3
MVR_S3_BUCKET=your-bucket
MVR_S3_REGION=us-east-1
MVR_S3_ACCESS_KEY_ID=...
MVR_S3_SECRET_ACCESS_KEY=...
MVR_S3_ENDPOINT=https://your-s3-compatible-endpoint # 可选
```
SQLite 数据库默认为 `data/mvr.db` 本地和 `/app/data/mvr.db` 在 Docker 中。启动时会自动迁移现有的第 1 阶段数据库,并为缺少的模板种子,而不触及现有的模板。
---
## 安全性和运维
| 领域 | 行为 | 操作员责任 |
|---|---|---|
| 提供者密钥 | 静止时使用 AES-256-GCM 加密;列表输出被屏蔽。 | 设置并保护 `MVR_ENCRYPTION_KEY` — 更改它会使现有密钥无法读取。 |
| 身份验证 | API 和 MCP 路由在配置时需要持有者令牌。 | 在将 MVR 暴露在受信任网络之外之前设置 `MVR_AUTH_TOKEN`。 |
| 资产 | 真实的参考 PNG 生活在配置的本地/S3 后端。 | 备份并控制文件系统/存储桶访问。 |
| 文件引用上传 | 路径在 `MVR_ASSET_IMPORT_PATH` 下受限。 | 将该目录视为仅受信任的本地输入。 |
| 生成 | MVR 绝不会直接调用生产图像/视频提供者。 | 连接的代理负责提供者调用及其安全性。 |
---
## 当前范围
**已实现**
- 具有真实、版本化、可以选择锁定的 PNG 资产的多槽元素
- 完整性检查和非阻塞提示解析警告
- 种子类型配方和种子 Seedance 2.0 提示格式
- 本地和 S3 兼容资产存储
- 通过 stdio 和身份验证的 Streamable HTTP 进行 MCP
- 本地仪表盘、加密提供者密钥存储、每任务模型配置
**尚未实现**
- 视频/图像生成编排
- 自动评估运行或评估驱动的模板更新
- 多用户身份验证和授权
参见 `ROADMAP.md` 了解下一步计划内容。
---
## 许可证