开发者与 AI Agent 的上传工具

一条命令
一个 URL

把文件和静态站点传到你自己的 Cloudflare R2。默认输出是 JSON —— 带 ok、失败原因和可以直接执行的下一步,agent 不用从提示文字里把链接抠出来。想要那一个裸 URL,加 --plain。

curl -LsSf https://ferry.longye.dev/install.sh | sh

单个静态二进制 · macOS · Linux · Windows · 无运行时依赖

zsh — ferry
图 1 · 默认输出是 JSON,--plain 换回裸 URL
运行时依赖
0
指向自己的 R2
永久免费
命令总数
5
Agent 接入
MCP
01

它怎么工作

R2 的自定义域名绑定单个桶且不做路径重写,所以泛解析子域名必须靠一个 Worker。ferry init 会把它部署进你自己的 Cloudflare 账号 —— 那是 Ferry 唯一持续运行的部分。不需要你自备域名:默认走 Cloudflare 免费的 workers.dev 地址,有域名时再换成好看的形式。

  1. 1 ./dist 本地目录
  2. 2 sha256 由内容派生 deploy id
  3. 3 your R2 只上传缺的对象
  4. 4 <id>.你的域名 Worker 负责路由
图 2 · deploy id 由内容派生,所以同一个目录永远得到同一个 URL

重新部署是免费的

目录没变,就不上传任何东西,并返回同一个 URL。放进 CI 循环里也不会产生垃圾。

失败也是一份 JSON

同一个信封里有 ok: false、失败原因、retryable(值不值得重试),以及 next —— 能执行的直接给命令。

不会卡住等输入

没有终端时直接以错误码退出,而不是挂在那里等一个不可能到来的回答。CI、容器和 agent 沙箱里都安全。

密钥不落盘

token 只进系统 keychain,配置文件里永远没有 secret。没有 keychain 的机器走环境变量。

表 1 · 退出码
0成功
1用户错误 —— 参数、文件、配置
2网络 —— 唯一值得重试的一类
3认证
4当前后端不支持
02

Agent 需要的是一个链接

一个 agent 产出了图表、报告或构建好的站点,通常没办法把它交到人手里。Ferry 用一次调用把路径变成 URL。

  • 三个工具:ferry_up、ferry_deploy、ferry_ls
  • 刻意没有 rm —— 不该让 agent 距离删掉线上站点只差一个记错的 id
  • 不走 MCP 也行:默认 JSON、retryable 与可执行的 next、稳定退出码、无交互提问
  • 静态 musl 二进制,沙箱里不需要 Node 或 Python
claude_desktop_config.json
{
  "mcpServers": {
    "ferry": {
      "command": "ferry",
      "args": ["mcp"]
    }
  }
}
图 3 · 加进任意 MCP 客户端
03

自托管永久免费

不是「免费额度」—— 是根本没有计量表。CLI 直连 R2,链路里没有任何 Ferry 的东西。下面那些空心圈不是被拿掉的功能,是结构上做不到:它们都需要有个东西挡在每次请求前面。

表 2 · 能力对照。支持 结构上做不到
能力 自托管今天 Cloud以后
文件上传、目录部署
自定义域名、泛解析子域名
列出与删除产物
链接过期、密码、访问上限
可吊销的 scoped 上传凭证
团队命名空间、访问日志
无需 Cloudflare 账号

任何在自托管下能用的能力,都不会为了制造付费理由而被移除。

两条命令就能开始

# 装上
curl -LsSf https://ferry.longye.dev/install.sh | sh

# 配好 Cloudflare:建桶、部署 Worker、接上地址
ferry init

# 然后就是它了
ferry deploy ./dist