Skip to main content
Glama

Wharf

面向 AI 的网盘 + 工作区,单一物理文件的双视图存储。 网盘是仓库,工作区是 AI 的操作台。两个视图指向同一份磁盘数据,所以「看起来两份,实际只有一份」。

  • 单容器 Docker,ARM64 / AMD64 均可

  • 自带 MCP(16 个工具)、ACP(JSON-RPC fs/* + REST agents/runs)与 REST 文件 API

  • Web 界面把 AI 的操作翻译成人话卡片,而不是日志流


1. 它解决什么问题

大多数「AI 网盘」把读写权限一股脑交给模型:删了就是删了,改了也不知道改了哪儿。Wharf 的做法是分权 + 可回溯:

区域

定位

AI 权限

网盘 drive

长期仓库

只读(可下载、可预览、可搜索)

工作区 workspace

AI 施工台

可新建、可改写、可批量改名、可删除

要改网盘里的文件,必须先把条目 移到工作区(move_to_workspace)。这一步在磁盘上是一次 link() 系统调用——两个目录出现同名条目,但 inode 相同、nlink = 2,实际只有一份数据。

三个条目状态

状态

含义

磁盘事实

shared 共用

两边都有,且是同一个文件

同 inode

only 单区

只在当前区域出现

一份

diverged 已分叉

两边都有,但内容不同

两份,需要 sync_to_drive

正常操作永远停留在 shared。只有用外部工具绕过 Wharf 直接写盘、或跨文件系统(硬链接不支持)时才会出现 diverged / 副本,并通过 sync_to_drive 重新合并回一份。


Related MCP server: Python MCP Server Starter

2. 快速开始

Docker(推荐)

docker compose up -d --build

默认映射宿主机 8686 → 容器内 8787(宿主机 8787 常被其他服务占用),数据落在 ./data。首次启动会在日志里打印带令牌的入口地址:

Web 界面    : http://localhost:8686
带令牌入口  : http://localhost:8686/?token=wharf_xxxxxxxx

打开带令牌链接即可,令牌会存进浏览器 localStorage,地址栏随即被清理。

本地开发

npm install
npm start          # 或 npm run dev(node --watch)

需要 Node.js 18+(推荐 22/24)。

预构建镜像(GHCR)

仓库内置 .github/workflows/docker.yml,每次推送 main 会自动构建 linux/amd64 + linux/arm64 双架构镜像:

docker login ghcr.io                     # 包默认私有,用自己的 GitHub 账号登录
docker pull ghcr.io/xkx121029/wharf:latest

在 NAS 上本地构建

docker buildx build --platform linux/arm64 -t wharf:arm64 --load .
# 或直接构建到目标机器
docker buildx build --platform linux/arm64 -t wharf:arm64 --push .

NAS 上运行:

docker run -d --name wharf \
  -p 8686:8787 \
  -v /volume1/docker/wharf/data:/data \
  -e TZ=Asia/Shanghai \
  -e PUBLIC_URL=http://192.168.2.x:8686 \
  --restart unless-stopped \
  wharf:arm64

PUBLIC_URL 只影响日志里打印的入口地址和 download_link 工具生成的链接,不影响监听。


3. 配置

环境变量

默认值

说明

PORT

8787

监听端口

DATA_DIR

./data

数据根目录(容器内 /data)

AUTH_TOKEN

自动生成

访问令牌;留空则读取/生成 <DATA_DIR>/.token

PUBLIC_URL

空

对外地址,用于生成下载链接

MAX_TEXT_BYTES

2 MiB

单次读取文本上限,超出截断

MAX_UPLOAD_BYTES

512 MiB

单文件上传上限

MAX_IMPORT_BYTES

64 MiB

import_url 抓取上限

TZ

容器默认

建议 Asia/Shanghai

数据目录结构:

data/
├── drive/          # 网盘
├── workspace/      # 工作区
├── tmp/            # 上传中转,自动清理
├── activity.jsonl  # 活动事件流(超过 8 MiB 自动轮转)
└── .token          # 自动生成的访问令牌

4. 把 AI 接进来

所有端点在 http://<host>:8787,认证统一使用:

Authorization: Bearer <令牌>

详细的请求/响应示例见 docs/API.md;可直接粘给 AI 的接入提示词见 docs/AGENT_PROMPT.md,Web 界面「接入信息」里也有一键复制。

MCP

Streamable HTTP,无状态,POST /mcp,协议版本 2025-06-18 / 2025-03-26 / 2024-11-05。

{
  "mcpServers": {
    "wharf": {
      "type": "http",
      "url": "http://192.168.2.x:8787/mcp",
      "headers": { "Authorization": "Bearer wharf_xxxx" }
    }
  }
}

16 个工具:vault_overview、list_items、search_items、stat_item、read_file、write_file、create_folder、move_to_workspace、publish_to_drive、sync_to_drive、release_to_drive、rename_items、delete_items、copy_item、import_url、download_link。

ACP

两种形态都提供:

  • JSON-RPC(Agent Client Protocol 风格):POST /acp,方法 fs/read_text_file、fs/write_text_file、fs/list_directory、fs/stat_item、fs/search、fs/create_folder、fs/rename_items、fs/delete_items、fs/move_to_workspace、fs/publish_to_drive、fs/sync_to_drive、fs/release_to_drive。路径默认相对工作区,也接受 /data/workspace/... 绝对写法。

  • REST(Agent Communication Protocol 风格):GET /acp/agents、POST /acp/agents/wharf-workspace/runs、GET /acp/runs、GET /acp/runs/:id。

curl -s http://192.168.2.x:8787/acp \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"fs/list_directory","params":{"path":"/"}}'

规划中的典型工作流

AI 收到任务
  ├─ list_items (drive)          看一眼网盘有什么
  ├─ move_to_workspace           把要改的文件硬链接进工作区
  ├─ read_file / write_file      在工作区里读写
  ├─ rename_items / delete_items 批量整理
  └─ publish_to_drive 或 sync_to_drive
                                 收工,把成果写回网盘

5. 界面

四个区域:左侧区域切换与占用统计、中间文件表、右侧「AI 动态」、底部统一抽屉。

  • AI 动态不是日志流:服务端把事件合并成人类可读的句子,例如「把 3 个文件移到了工作区」「删除了 2 个条目(只删除了网盘的视图,文件内容仍在工作区)」,点击卡片里的文件名可直接跳到对应位置。

  • 所有弹窗都是页面内的底部抽屉,不使用系统 alert / confirm。

  • 上传支持拖拽与进度条;下载走 /api/fs/download,链接自带令牌,可直接粘到浏览器或下载器。


6. 安全

  • 除 /api/health 与静态页面外,所有接口都需要 Bearer 令牌;比较使用 timingSafeEqual。

  • 路径统一规范化,拒绝 .. 与越界。

  • import_url 拒绝 localhost、127.*、10.*、172.16-31.*、192.168.*、169.254.* 等内网与保留地址,防 SSRF。

  • 下载令牌可以出现在 URL query 中,方便直接下载;因此不要把这个链接发给不受信任的人。

  • 容器以非 root 用户 node 运行。


7. 已知边界

  • 硬链接依赖同一文件系统。drive 与 workspace 若被挂到不同卷,会自动降级为复制副本,状态显示为 diverged,需要 sync_to_drive 合并。

  • 目录的「共用」是逐文件判断的:目录本身是两边各自创建的同名目录,内部文件才是硬链接。

  • ACP REST 的 runs 保存在内存中(上限 200 条),容器重启即清空。

  • 活动流保存在内存环形缓冲 + activity.jsonl,最多回溯 2500 条。


8. 开发

server/
  config.js    环境与目录
  store.js     双视图存储核心(硬链接、分叉合并、批量改名)
  activity.js  事件缓冲、中文标题、SSE
  api.js       REST 文件接口
  tools.js     MCP 工具定义与调度
  mcp.js       MCP JSON-RPC 传输
  acp.js       ACP JSON-RPC 与 REST
  index.js     入口
public/
  index.html / app.css / app.js
docs/
  API.md       全部接口的独立文档
  AGENT_PROMPT.md  复制给 agent 的接入提示词

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Hosted filesystem MCP server over HTTP with auth. Enables reading, writing, editing, searching, and listing files via MCP tools like grep, glob, and tree.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    It enables developers to run a Streamable HTTP MCP endpoint with example tools, a README resource, and a REST API route as a customizable foundation for MCP server projects.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to browse selected folders, search filenames, inspect metadata, and read bounded UTF-8 text files through a read-only, token-authenticated interface.
    1
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to manage files in an isolated workspace and perform lightweight Git operations through a protected Streamable HTTP endpoint, including listing, reading, writing, searching, replacing, and deleting files plus checking status and diffs.
    1
    -