内容
<p align="center">
<img src="docs/assets/hero.png" alt="Vellum — AI 资产生成的出处凭证" width="900" />
</p>
<h1 align="center">Vellum</h1>
<p align="center">
<strong>与供应商无关的生产结构 + AI 资产生成出处凭证,作为 MCP 工具呈现。</strong><br/>
<em>工作空间 → 项目 → 序列 → 镜头 → 版本。仅追加出处凭证。可以重现任何内容。</em>
</p>
<p align="center">
<a href="#license"><img alt="许可证:MIT" src="https://img.shields.io/badge/License-MIT-ff6b5a?style=flat-square" /></a>
<img alt="Node 20+" src="https://img.shields.io/badge/Node-20%2B-0c2a3a?style=flat-square" />
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5.9-0c2a3a?style=flat-square" />
<img alt="MCP SDK 1.29" src="https://img.shields.io/badge/MCP%20SDK-1.29-ff6b5a?style=flat-square" />
<img alt="测试通过" src="https://img.shields.io/badge/tests-1956%20passing-0c2a3a?style=flat-square" />
<img alt="v1.0" src="https://img.shields.io/badge/release-v1.0-ff6b5a?style=flat-square" />
</p>
---
## 为什么存在
AI 资产生成不会停留在单一工具中。生产过程会从 ComfyUI、Replicate、FAL、Scenario 和定制代理工作流中获取 - 而当它这样做时,**资产图谱就会崩溃**。文件会散布在各个服务中,种子会丢失,模型版本会漂移,而“哪个运行生成了这个帧?”变成了半天的考古挖掘。Vellum 是一个中立层,位于任何生成器和任何下游工作流之间:它为生产提供了所需的结构 - 项目、序列、镜头、版本、不可变出处凭证和 lineage - 无论哪个后端生成像素。
> *"我们不仅关心最终图像 - 我们关心它是如何精确**生成**的。*
> — 在每次工作室对话中反复出现的主题
## 它做什么
**一个 Node.js 进程。两个传输通道。一个连贯的界面。**
Vellum 是一个 [MCP](https://modelcontextprotocol.io) 服务器,暴露七种粗粒度工具(在 12 工具 MCP 限制下),同时运行在 **stdio** 和 **Streamable HTTP** 上,并附带一个 Preact 仪表板。任何 MCP 兼容的 AI 代理 - Claude Desktop、Claude Code、Cursor、MCP Inspector - 都具有相同的工具界面,并且可以从自描述的 `vellum://capabilities` 和 `vellum://output-contract` 资源中学习它。生成可以 **输出**(提交并轮询任何配置的提供者 - ComfyUI、Replicate、…)或 **输入**(任何代理或提供者 webhook 通过 URL 注册完成资产)。无论哪种方式,它都会自动创建一个不可变、版本化的记录,您可以 diff、重现或迭代。
### 七种工具
| 工具 | 目的 | 操作 |
| ------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------- |
| `workspace` | 顶级容器(一个工作室,一个客户端,一个项目组) | `create`, `list`, `get` |
| `project` | 工作空间内的电影、剧集、广告或活动 | `create`, `list`, `get` |
| `sequence` | 项目内的场景或镜头组 | `create`, `list`, `get` |
| `shot` | 单个镜头 — 零填充版本命名(`v001`,下划线分隔) | `create`, `list`, `get` |
| `generation` | 提交/轮询任何提供者(ComfyUI、Replicate、…);重现/迭代;或 **注册** 外部生成的输出 | `submit`, `status`, `reproduce`, `iterate`, `register` |
| `version` | 读取版本、完整出处凭证和任意两个版本之间的结构化 diff | `get`, `list`, `provenance`, `diff` |
| `asset` | 为版本添加标签、附加任意元数据并查询层次结构 | `add_tag`, `remove_tag`, `set_metadata`, `remove_metadata`, `query`, `list_tags`, `list_metadata_keys` |
每个响应都带有完整的层次结构 breadcrumb(`workspace > project > sequence > shot`),每个工具输入都经过 Zod 验证,每个错误都带有人类可读的 actionable 指导。
## 架构
<p align="center">
<img src="docs/assets/architecture.svg" alt="四层架构:MCP 工具 → 引擎 facade → 提供者适配器(ComfyUI、Replicate、…)→ SQLite WAL 追加存储" width="780" />
</p>
四层,每层可独立测试:
- **MCP 工具** (`src/tools/*-tool.ts`) — 薄 Zod 验证入口点。`action` 上的区分联合。零业务逻辑。
- **引擎 facade** (`src/engine/`) — 纯 TypeScript,**零 MCP 依赖**。`HierarchyRepo`、`VersionRepo`、`ProvenanceRepo`、`AssetsEngine`。架构纯度测试在每个提交时在类型级别强制执行此边界。
- **提供者适配器** (`src/providers/`、`src/comfyui/`) — 每个生成后端实现一个 `GenerationProvider` 接口(提交 / 状态 / 下载 / 验证)。ComfyUI Cloud 和 Replicate 今天发货;添加后端是一个类 + 注册表条目,引擎永远不会更改。SSRF 安全重定向门、主机允许列表、大小上限和原子流下载。
- **SQLite + WAL** (`drizzle/`) — Drizzle ORM,四个手动前缀迁移,`busy_timeout=5000`。追加出处凭证在结构上强制执行(存储库没有 `update` 或 `delete` 方法 - 没有路径可以改变事实)。
## 出处凭证 - 差异化因素
<p align="center">
<img src="docs/assets/provenance.png" alt="出处凭证 lineage 树:v001 分支到 reproduce 和 iterate 子项,递归" width="640" />
</p>
每次生成都捕获完整出处凭证:
- `workflow_json` / `prompt_json` — 用于图后端(ComfyUI):提交的工作流 + 解析的提示,包含种子和模型路径
- `generation_request_json` / `generation_result_json` — 中立的、与提供者无关的记录(参数、模型、输出哈希)用于 URL 后端(Replicate、…)和外部注册输出
- `provider`、`seed`、`model_names`、`timestamp`、lineage 链接、附加校验和 + C2PA 清单
您可以:
- **`版本差异`** 任意两个版本并获取更改的结构化比较(参数、种子、模型、工作流形状、元数据)
- **`生成重现`** 任意版本逐字逐句 - 重新提交存储的 `prompt_json`,创建具有 `lineage_type='reproduce'` 和父指针的新版本
- **`生成迭代`** 从任意版本开始,带有节点范围的重叠 + 可选的新种子,创建具有 `lineage_type='iterate'` 和跟踪父项的新版本
出处凭证记录在**构造上不可变**。`ProvenanceRepo` 仅暴露 `insertEvent`、`getEventsForVersion`、`getLatestCompletedEvent` 和 `getSubmitEvent`。没有 setter。原型断言测试如果有人添加 setter,则会失败构建。
## 快速入门
### 1. 安装
```bash
git clone https://github.com/alvdansen/vellum.git
cd vellum
npm install
```
需要 Node 20+。SQLite 数据库(`vellum.db`)在第一次服务器启动时自动创建。
### 2. 配置提供者
```bash
cp .env.example .env
# ComfyUI Cloud: COMFYUI_API_KEY (from https://platform.comfy.org)
# Replicate: REPLICATE_API_TOKEN
# 选择默认提供者(如果设置了多个提供者,则 ComfyUI 优先)。
```
Vellum 会发现存在的提供者凭证并选择默认后端。ComfyUI 端点锁定在 `https://cloud.comfy.org`,健康检查路径为 `/api/system_stats` - 截至 v1.0 版本已审计为唯一有效的组合,理由由只读探测矩阵 `scripts/probe-comfy-endpoint.mts` 捕获。层次结构、出处凭证和 `generation register`(输入)在没有提供者凭证的情况下也适用。
### 3. 烟雾测试(~5 秒,无需人工观看)
```bash
npm run smoke
```
这驱动实时 MCP SDK 客户端 (`scripts/inspector-smoke.mjs`) 通过 stdio 并运行 **56 个线级断言** - 完整的层次结构遍历、每个级别的 breadcrumb、错误信封、镜头格式验证、分页、按 ID 往返。如果绿色,则整个 MCP 传输 + 工具注册 + 引擎线路工作端到端。
### 4. 完整测试套件
```bash
npm test
```
预期:**760 of 763 通过**(3 个文档化的预先存在时间片在完整套件负载下)。套件涵盖层次结构 CRUD、ComfyUI 客户端 SSRF 防护、追加出处凭证不变性、资产查询/过滤组合、仪表板信号存储、SSE 线路形状和三个交叉回归防护(`architecture-purity`、`phase-attribution`、`validation-flags`)。
### 5. 实时、端到端与仪表板
```bash
# 终端 1 — 启动 HTTP 服务器(也提供仪表板)
npm run start:http
# 浏览器
open http://localhost:3000
```
```bash
# 终端 2 — 使用 MCP Inspector 驱动服务器
npm run inspect
```
现在创建工作空间 → 项目 → 序列 → 镜头,提交 `generation`,并在作业从 `submitted → running → completed` 移动时观察活动生成面板更新。当它完成时,时间线中出现具有完整出处凭证钻取的新版本卡。
## 连接 MCP 客户端
### Claude Code
```bash
claude mcp add vellum --scope user -- bash -c "cd $(pwd) && exec npx -y tsx src/server.ts"
```
然后在任何 Claude Code 会话中:`/mcp` 列出七种工具,或直接询问 Claude 使用 `vellum` 创建名为“demo”的工作空间。
### Claude Desktop
将以下内容添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows):
```json
{
"mcpServers": {
"vellum": {
"command": "npx",
"args": ["-y", "tsx", "/absolute/path/to/vellum/src/server.ts"]
}
}
}
```
### Streamable HTTP(网络代理,自定义客户端)
启动 HTTP 传输:
```bash
npm run start:http
```
MCP 端点是 `POST http://127.0.0.1:3000/mcp`(默认情况下仅限环回)。仪表板、REST API 和 SSE 馈送共享同一个 Hono 应用 - 相同的端口,没有单独的开发服务器。
## 项目结构
```
vellum/
├── src/
│ ├── server.ts # 双传输入口点(stdio + Streamable HTTP)
│ ├── tools/ # 7 个 MCP 工具 — Zod 验证,薄
│ ├── engine/ # 纯 TS facade,零 MCP 依赖
│ ├── comfyui/ # ComfyUI Cloud 客户端(SSRF 安全,健康检查)
│ ├── http/ # Hono REST 路由 + SSE 处理器 + 错误中间件
│ └── __tests__/ # 交叉回归不变性(纯度,归属,验证)
├── packages/
│ └── dashboard/ # Preact + Tailwind v4 + signals;构建到 dist/
├── drizzle/ # SQLite 迁移(4 个,手动前缀)
├── scripts/
│ ├── inspector-smoke.mjs # 56 检查程序编程 UAT — 规范的烟雾测试
│ └── probe-comfy-endpoint.mts # 只读矩阵探针,用于端点发现
└── docs/ # 图表 + 决策记录
```
## 质量标准
这是 v1.0 审计通过的里程碑,而不是冲刺演示。
- **审计:** 按 v1.0 里程碑重新审计通过。38 个 v1 要求得到验证,9 个阶段得到验证,5 个关键端到端流程绿色,4 个之前的技术债务类别通过审计驱动的差距封闭阶段存档。
- **交叉回归防护:**
- `architecture-purity.test.ts` — 没有外部 `src/tools/` 的 MCP 导入,没有引擎层 Zod,没有生产代码中的测试专用哨兵字符串
- `phase-attribution.test.ts` — 每个已发货阶段的 frontmatter `requirements-completed:` 是 ROADMAP 属性的超集
- `validation-flags.test.ts` — Nyquist Wave 0 状态标志在每个阶段保持
- **工具预算:** v1.0 使用 7 个 12 个 MCP 工具(`workspace`、`project`、`sequence`、`shot`、`generation`、`version`、`asset`)- 粗粒度 `action` 参数保持表面精简。
- **实时烟雾:** ComfyUI Cloud 往返(`generation submit` → `generation status` → completed → `version provenance`)连续两次通过,截至 2026-04-24。
## 路线图
### v1.0 — MVP *(已发货 2026-04-28)*
层次结构、异步 ComfyUI 生成、追加出处凭证与重现/迭代 lineage、资产标记和查询、Preact 仪表板、双传输 MCP 服务器。
### v1.1 — 出处凭证验证(C2PA) *(正在设计)*
由 **欧盟 AI 法案第 50 条**(2026 年 8 月生效)和 **加利福尼亚州 SB 942**(2026 年 1 月生效)驱动。v1.0 捕获私有出处凭证;v1.1 使其签名、可移植且监管可验证。
- 签名 C2PA 清单嵌入支持的输出格式(PNG、JPEG、MP4、WebP)
- 显式 AI 公告(`c2pa.created` 操作断言)
- 模型指纹 - 每个检查点、LoRA、VAE 的 SHA-256(在 `src/engine/provenance.ts:69` 处关闭 `model_hash: null` 漏洞)
- 成分图 — `parentOf`(lineage)、`componentOf`(控制/参考图像)、`inputTo`(提示 + 参数)断言
- 侧车 `.c2pa` 清单用于非原生嵌入格式(OpenEXR 等)
- 删减操作 — 在保留删减 *事实* 的同时剥离敏感值
- 新工具操作:`version export_manifest` / `version verify_manifest`
### v2.0 — 与提供者无关 *(已发货)*
与任何单个生成后端解耦,并从“VFX Familiar”重新命名为 **Vellum**。
- `GenerationProvider` 接口 - 每个后端都是适配器(`src/providers/`);引擎对后端依赖为零,通过架构纯度测试强制执行
- 第二个参考适配器:**Replicate**(原始 REST,无 SDK),与 ComfyUI Cloud 一起,通过提供者注册表和多凭证配置选择
- 中立的、与提供者无关的出处凭证 (`generation_request_json` / `generation_result_json`) 存储在 ComfyUI 图谱旁边
- **输入** `generation register` - 任意代理或提供者 webhook 通过 SSRF 防护的摄取边界(https + 主机允许列表 + 大小上限)报告完成资产的 URL
- 自描述 MCP **资源** (`vellum://manual`、`vellum://capabilities`、`vellum://output-contract`) 以便任何冷启动代理学习界面 + 如何报告输出
- 中立的参数差异重现模型用于非图谱后端
### 未来
- **多后端路由** - 基于能力的路由 + 跨配置提供者的故障转移(建立在 v2.0 注册表之上)
- **函数调用适配器** - OpenAI 兼容的 REST 端点,用于非 MCP 代理
- **高级操作** - 批量镜头队列、完成时的 Webhooks、层次结构导出、仪表板中的 lineage 图可视化
## 许可证
MIT — 见 [LICENSE](LICENSE)。
## 致谢
- **[Alvdansen Labs](https://github.com/alvdansen)** — 托管此版本并为生产级开源 AI 工具提供着陆点
- **[ComfyUI](https://www.comfy.org)** — 构建领域中最具扩展性的生成管道软件,并提供使此功能成为可能的 Cloud API
- **[Anthropic](https://www.anthropic.com)** 和 **[Model Context Protocol](https://modelcontextprotocol.io)** — 开放协议使此服务器可在客户端之间移植
<p align="center">
<em>故意为生产而构建。设计感觉必然。</em>
</p>