传个文件,不必先交给别人的服务器。

无账号,无中央服务器。桌面、手机和浏览器都是真正的传输端;配一次对,之后一直有效。

SwarmDrop 桌面端的设备页:已配对设备网格,第一张卡显示对端在线、信任级别为协作者、经局域网连接,右侧是附近设备与配对入口。
macOSWindowsLinuxAndroid浏览器
开源 · MIT源码

文件走的哪条路,页面上写着

多数工具只告诉你「已发送」。SwarmDrop 把链路摊开:哪种传输、对端地址是什么、经不经中继。排查的时候可以整段复制进 issue。

  1. 01

    局域网直连

    mDNS 在同一网段里发现对方,数据不出这间屋子。浏览器走 WebTransport——它是浏览器上的 QUIC,回环实测是 WebRTC Direct 的 4.5 倍。

    TCP · QUIC · WebTransport · WebRTC Direct

  2. 02

    NAT 打洞

    两端同时朝对方发包,在中间会合(DCUtR)。跨网络的常态就落在这里。

    QUIC · WebRTC

  3. 03

    中继兜底

    前两条都不通才走。中继只转发密文,看不到内容,也不留副本。

    p2p-circuit

一台真实节点当前监听的地址

原样取自运行中的节点,中段已截断。三条分别对应上面三种路径。

局域网
/ip4/192.168.50.105/udp/61961/webrtc-direct/certhash/uEiD7XGPe…/p2p/12D3KooW…
公网中继
/ip4/47.115.172.218/udp/4001/quic-v1/p2p/12D3KooWCkaj…/p2p-circuit/p2p/12D3KooW…
浏览器入口
/ip4/47.115.172.218/udp/4003/webrtc-direct/certhash/uEiBuBPte…/p2p-circuit/p2p/12D3KooW…

浏览器有两条入口,各管一段。webrtc-direct 负责发现与打洞——它是唯一能穿透 NAT 的那条,引导节点在 4003 端口上为它开着。WebTransport 负责同网快通道,本质是浏览器上的 QUIC;它连的机器没有域名,靠地址里的证书哈希建立信任, 而那张自签证书的有效期被规范限死在 14 天,所以地址里总是带着两个哈希——当前这张,和下一张。

三端,同一个内核

桌面端与移动端共用同一份 Rust 核心,浏览器端把它编成 wasm——不是「网页版精简功能」,而是完整的节点、协议和配对握手,只少了 mDNS。

SwarmDrop 浏览器端的设备页:左侧持久侧边栏,主区是已配对设备与配对面板,设备卡显示在线状态、信任级别与局域网连接延迟。
浏览器端 —— 零安装。打开网页就是一个节点,配对、收发、断点续传都在这一页里。
SwarmDrop 桌面端的配对页:中间是邀请二维码与 24 小时倒计时,左侧列出已发出的邀请及其状态,每条都可撤销。
桌面端 —— 邀请是一次性的,发出去的每一条都能在这里撤销。

安全模型写在这里,不写在标语里

下面每一条都能在源码里对上号。没有「军工级」,也没有「银行级」——那些词不携带任何可核对的信息。

设备身份
Ed25519 密钥对。移动端交给系统安全存储(iOS Keychain / Android EncryptedSharedPreferences);桌面端存在应用数据目录下仅本人可读的文件里(unix 权限 0600),形态与无口令的 SSH 私钥一致。
传输加密
Noise 与 QUIC-TLS,在传输层完成。中继节点全程只经手密文。
逐块校验
BLAKE3 + bao-tree。每收到一块立刻可验,不必等整个文件收完才发现它被动过;续传也因此不需要「信任对端」。
配对
一次性签名邀请:Ed25519 签名 + 128 位凭证,24 小时有效,用掉即作废。没有可被猜到的短码。
遥测
没有。不连任何分析后台,也不加载外部字体或脚本。
源码
MIT,全部公开。引导节点也可以自建,连发现层都不必依赖别人。

我们删掉过一层加密

早期版本在传输层之上又套了一层 XChaCha20-Poly1305,后来整块删了。它是自引用的冗余—— 密钥经同一条 Noise 信道分发,能读密文的攻击者必然也能读密钥;更要命的是它和逐块校验 不能共存,加密之后校验和会变成密文的哈希,「根哈希 == 明文 BLAKE3」这条不变量当场就塌。 宁可少一层,也不要一层看起来很安全的装饰。

完整推导在文档里

agent 也是一台设备

桌面端内置一个本地 MCP server,20 个工具。agent 用的是和你完全相同的那条通道——发文件、查收件箱、看传输状态。

  • send_files
  • list_paired_devices
  • search_inbox
  • get_transfer_status
  • accept_transfer
  • export_inbox_item
  • 共 20 个

每台已配对设备单独控制允不允许 MCP 向它发送,默认关闭。没开的时候 agent 收到的是一句明确的拒绝,而不是一次静默的发送。

claude_desktop_config.json
{
  "mcpServers": {
    "swarmdrop": {
      "url": "http://127.0.0.1:19527"
    }
  }
}

端口在设置页里可改;服务只监听 127.0.0.1,不对外暴露。

配一次对,之后它就一直在那儿。

没有「发送模式」和「接收模式」——配过对的设备发来东西,后台就收下了。

项目现状:核心功能已经完成并稳定跑了一段时间——跨网络传输、配对、断点续传、三端客户端、MCP。 当前的工作是收尾打磨:三端交互对齐、边界状态的文案、真机链路的收敛(尤其是跨网络那条)。 用起来有别扭或看不懂的地方,开一个 issue是这个阶段最有价值的反馈。