内容
<div align="center">
<img src="web/public/assets/logo.png" alt="Disk" width="96" height="96" />
# 磁盘
**您和您的代理的个人云存储。**
任意文件,任意大小 · 范围 API 密钥 · 完整审计追踪 · 代理就绪
(REST + OpenAPI + MCP)
[**disk.zaynjarvis.com**](https://disk.zaynjarvis.com) · 基于 Cloudflare
Workers · R2 · D1
</div>
---
<div align="center">
<img src="docs/screenshots/files.png" alt="Disk 文件浏览器" width="820" />
</div>
## 它是什么
Disk 是 **R2** (文件字节)前面的一个 Cloudflare Worker,**D1** (密钥,共享,审计),以及一个 **React** 单页应用。它是一个您完全拥有的 Dropbox 精简版 —— 并且每个功能都可以通过干净的 API 同样适用于您的代理,作为他们的临时存储,工件存储或共享驱动。
## 功能
- 🔑 **基于 API 密钥的身份验证和角色** — 一个 `ROOT_KEY` 环境密钥,一个可撤销的根等效 **管理员** 密钥,和范围 **用户** 密钥(路径前缀,只读/读写,每个文件上传上限,过期时间)。
- 🗂️ **每个密钥的虚拟根目录** — 一个范围密钥将其前缀视为根目录,并且永远不会感知或逃离它。给代理一个范围限定在 `agents/zouk/` 的密钥,并且对该代理来说,其世界直接从 `/` 开始。
- 📤 **任意文件,任意大小** — 拖放和文件夹上传,多部分上传适用于数 GB 大小的文件,范围下载,预览(图像 / 视频 / 音频 / PDF / Markdown / 代码)。
- 👀 **四种浏览方式** — 列表,网格,**树形**,和 Finder 样式的 **列** 视图,在右侧的窗格中预览所选文件,充分利用宽屏幕。
- 🔗 **共享** — 可撤销的,过期时间有限的公共链接(`/s/<token>`),下载次数统计。
- 📜 **完整审计** — 每个请求都记录(操作者,操作,路径,字节,状态,IP,用户代理);可筛选的 UI + CSV 导出功能适用于管理员。
- 🤖 **代理就绪** — `/api/v1` 处的 REST,`/openapi.json` 处的 OpenAPI 3.1,`/llms.txt` 处的代理指南,以及 `POST /mcp` 处的 **MCP 服务器** —— 包括管理员工具,以便代理可以自行管理密钥。
## 截图
| 登录 | 预览任意文件 |
|---|---|
| <img src="docs/screenshots/login.png" width="400" /> | <img src="docs/screenshots/preview.png" width="400" /> |
| API 密钥 — 角色,范围,上传上限 | 存储使用情况 |
|---|---|
| <img src="docs/screenshots/keys.png" width="400" /> | <img src="docs/screenshots/usage.png" width="400" /> |
**列视图** — Finder 样式的 Miller 列,右侧带有实时预览窗格;以及 **树形** 视图,用于鸟瞰图。不同视图适用于不同受众。
| 列视图 + 预览窗格 | 树形视图 |
|---|---|
| <img src="docs/screenshots/column.png" width="400" /> | <img src="docs/screenshots/tree.png" width="400" /> |
**虚拟根目录** — 通过限定在 `agents/zouk/` 的密钥查看同一个磁盘。没有前缀,没有其他文件夹,没有管理员视图:其范围 *是* 根目录。
<div align="center">
<img src="docs/screenshots/scoped.png" alt="限定密钥的虚拟根目录" width="700" />
</div>
## 如何使用它
### 作为用户
1. 打开 [disk.zaynjarvis.com](https://disk.zaynjarvis.com)。
2. 粘贴一个 API 密钥(您的 `ROOT_KEY`,或您创建的任意密钥)并登录。
3. 拖入文件,预览它们,共享链接, — 作为根管理员 — 创建密钥并读取审计日志。
### 作为代理
在 **密钥** 标签页(或通过 API)为代理创建密钥,然后指向它到 Disk。给它一个 **范围限定** 的密钥,以便它只能访问它自己的部分:
```sh
# (管理员)创建一个范围限定的读写密钥,每个文件上传上限为 10 MB
curl -s -X POST https://disk.zaynjarvis.com/api/v1/keys \
-H "Authorization: Bearer $ROOT_KEY" -H 'Content-Type: application/json' \
-d '{"name":"zouk-agent","prefix":"agents/zouk/","permission":"rw","maxUploadBytes":10485760}'
# → 返回 {"key":"dk_…"} (仅显示一次)
```
代理然后使用 **范围相对** 的路径 — 它永远不会看到 `agents/zouk/`:
```sh
export DISK_KEY=dk_...
# 上传 (存储在 agents/zouk/notes/todo.md,但代理只看到 notes/todo.md)
curl -s -X PUT "https://disk.zaynjarvis.com/api/v1/files/blob?path=notes/todo.md" \
-H "Authorization: Bearer $DISK_KEY" --data-binary @todo.md
# 列出其根目录
curl -s "https://disk.zaynjarvis.com/api/v1/files" -H "Authorization: Bearer $DISK_KEY"
# 共享文件
curl -s -X POST https://disk.zaynjarvis.com/api/v1/shares \
-H "Authorization: Bearer $DISK_KEY" -H 'Content-Type: application/json' \
-d '{"path":"notes/todo.md","ttlSeconds":3600}'
```
每个操作的完整 curl 参考: **[/llms.txt](https://disk.zaynjarvis.com/llms.txt)**。
### 通过 MCP
连接任意 MCP 客户端(Claude Code,Claude Desktop,Cursor,…)。代理获得原生工具 — `disk_list`,`disk_read`,`disk_write`,`disk_delete`,`disk_move`,`disk_share`,以及(对于管理员密钥)`disk_key_create` / `disk_key_list` / `disk_key_revoke`:
```json
{ "mcpServers": { "disk": {
"type": "http",
"url": "https://disk.zaynjarvis.com/mcp",
"headers": { "Authorization": "Bearer dk_..." }
} } }
```
给代理一个 **管理员** 密钥,它可以通过 MCP 管理整个磁盘 — 包括创建和撤销其他密钥 — 完全。
## 技术栈
Cloudflare Workers 上的 Hono · R2 · D1 · React 19 + Vite + Tailwind v4 · vitest(`@cloudflare/vitest-pool-workers`)。一次 `wrangler deploy` 部署 API,MCP 服务器和单页应用。
## 贡献和部署
- **[DEV.md](DEV.md)** — 本地设置,合约优先规则,安全核心不变性,配方和陷阱。
- **[DEPLOY.md](DEPLOY.md)** — 架构,资源配置,重新部署,迁移,灾难恢复启动。
- **[API.md](API.md)** — 绑定 API 合同。
上面的截图使用 `node scripts/screenshots.mjs` 在本地开发服务器上生成。