关于 Cursio
Cursio 是用于可信个人设备的局域网网格,可在机器间共享输入、窗口、剪贴板、音频和文件,同时应用仍在原主机运行。它面向需要跨多台设备协作的人,不依赖中心服务器或枢纽。
主要功能
- 01跨设备共享鼠标和键盘
- 02传送应用窗口画面
- 03同步剪贴板与音频
- 04按需挂载对等设备磁盘
- 05共享 USB、屏幕及文件
- 06支持 Android 与 AirPlay 接入
适用场景
- 01在多台电脑间切换键鼠操作
- 02在另一台机器查看运行中的应用
- 03从对等设备挂载磁盘或 USB
- 04将设备窗口提供给 Discord 或 OBS
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Cursio
仅限局域网的可信个人设备网状网络,共享加密且可恢复的会话。
输入、音频、剪贴板、窗口传输和文件共享都是这些会话上的模块,而非独立产品。应用永远不会迁移;只有像素、采样数据、事件和文件请求会通过连接传输。
目标很简单:应用是在哪台机器上启动的,不应该有任何影响。
功能
- 在所有机器之间共享一套鼠标和键盘,通过将光标推过屏幕边缘在机器之间切换
- 将单个应用窗口串流到另一台机器,同时让应用继续在原主机上运行
- 在机器之间传递剪贴板内容,保留格式和图像
- 按应用路由音频,让每个远程应用在此处显示为独立的命名节点
- 按需在本地挂载对等设备的磁盘
- 像插在本机上一样使用对等设备的 USB 设备(USB/IP)
- 将对等设备的窗口和显示器提供给此处的 Discord、OBS 或浏览器通话,而不在此桌面上显示
- 将 iPhone/iPad 屏幕镜像接收到整个网状网络的 AirPlay 接收端
- 将 Android 手机作为完整的对等设备接入:无论你身在何处,都能看到它的通知;使用它的 SMS、通话(通过 Bluetooth,让 Cursio 充当免提设备)、声音和麦克风、存储和图库;还能在一个窗口中显示整个手机屏幕,并用鼠标操作——无需 ADB 的 scrcpy
- 自行更新:由你信任的机器提供的签名构建会并行安装;如果无法正常启动,则会回滚
不是什么
- 不是远程桌面——你通过将光标移到对等设备自己的屏幕上来操作它;窗口和屏幕只会以图像形式通过连接传输
- 不是应用或进程迁移——应用永远不会离开其主机
- 不是虚拟化
- 并非为互联网或 NAT 穿透而构建(v0.x 仅限局域网)
- 不是你的混音器的替代品——Cursio 替代的是网络传输环节,而非 VoiceMeeter 或 Carla
支持的平台
| 输入 | 剪贴板 | 窗口宿主 | 窗口视图 | 远程屏幕 | 音频 | 文件 | USB | AirPlay | |
|---|---|---|---|---|---|---|---|---|---|
| Linux(Wayland、X11) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Windows 11 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| macOS 13+ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | 仅提供 | ❌ | ✅ |
| Android(arm64) | 触控板 | 分享表单 | 自己的屏幕 | ❌ | ❌ | ✅ | 仅提供 | ❌ | ❌ |
- Linux:在 Wayland 上,通过
InputCapture门户 + libei 捕获输入;在 X11 上则通过 evdev。窗口捕获使用 ScreenCast 门户,因此具体效果取决于合成器;在 GNOME 上拖动传输需要随附的 Shell 扩展。音频需要 PipeWire,文件挂载需要 FUSE,USB 需要usbip-host。已在 Ubuntu 24.04 和 25.10 上测试:构建产物只能使用与其链接的 FFmpeg 运行,因此两个版本需分别构建(cargo xtask stage ubuntu24)。 - Windows:挂载需要 WinFsp,USB 需要
usbipd-win,音频端点需要随附的驱动程序(native/cursio-vad)。Cursio 启动时会请求 UAC,因为 Windows 会静默丢弃注入到提升权限窗口中的输入;拒绝后其他功能仍可正常使用。 - macOS:Mac 可以托管窗口,但目前无法显示对端的窗口,会拒绝对端的远程屏幕请求;可以提供自己的卷,但无法挂载对端的卷。输入需要“辅助功能”权限,窗口捕获需要“屏幕录制”权限。
- Android(API 28+):
app/中的应用内置链接好的节点,并以connectedDevice前台服务的形式保持运行。它会播放对端的声音,提供自己的音频和麦克风(AAudio),提供共享存储和图库,并在你选择的电脑上显示自己的屏幕——优先显示在你最后使用的电脑上——还可通过你启用一次的辅助功能服务从电脑控制。通知只会发送到你当前使用的电脑;短信可在电脑上读取和发送;来电会在电脑上响铃,在 Linux 上还可传输通话语音,此时 Cursio 会作为手机的蓝牙免提设备和扬声器(cursio bluetooth install)。网络中断时,它会通过蓝牙保持连接。它会报告电量和网络状态,但不能查看窗口、挂载磁盘或共享 USB。
核心概念
没有服务器,也没有中心节点。 每个节点既监听对端的拨入连接,也会主动拨号连接已知的离线对端。某个节点宕机不会让其他节点将其遗忘——它们会将其标记为离线,继续彼此通信,并在该节点恢复后重新连接。
机器按网格排列,而不是按方位命名。--at 1,0 表示一台机器位于 0,0 的右侧;四台机器排成一行时,坐标为 0,0 1,0 2,0 3,0。网格使用单元格而非像素,因此无需知道任何机器的屏幕有多宽。方位无法表达顺序,而指定中心节点会导致每台机器都依赖该节点在线;而避免这种依赖正是构建网状网络的目的。
一个会话,四条相互独立的传输通道。 每对对端会使用独立的加密 TCP 连接来传输交互流量、音频、视频和大容量数据。六个优先级类别依次为 Control > Input > Audio > Video > Metadata > Bulk;文件连接阻塞不会影响输入。队列设有字节预算和背压机制,大容量流量会根据交互 RTT 控速,视频编码器则共享自适应预算。无需重建模块即可替换连接。参见传输设计。
输入采用相对坐标。 鼠标移动以 dx/dy 的形式通过网络传输,绝不使用绝对位置——绝对定位会让光标瞬移,并破坏读取原始输入的游戏。按键也以相同方式传输,因此你控制对端时,对端会响应自己的快捷键(包括 Alt+Tab)。
只有拖动操作才能开始窗口传输。 没有可启用此功能的标志,因此不会意外传输任何内容。接收端保持被动:对端的窗口始终会显示。
快速开始
构建 CLI:
cargo build -p cursio-core
在两台机器上运行相同的命令,并使用相同的密码,即可配对:
cargo run -p cursio-core -- mesh --pair
然后运行网状网络,并启用所需的模块:
cursio mesh --at 0,0 --send-input --clipboard
配对
配对时会提示输入密码,输入内容不会回显。不存在单独的“监听”和“加入”端:网状网络节点会同时监听和拨号,两端会自行确定由哪一端发起连接。--pair 只会开启一个 10 分钟的窗口,在此期间,尚未相识的机器才允许被呼叫。
首次联系时,双方会以对称模式运行 SPAKE2 配对——密码不会通过网络传输——确认派生出的密钥、互相记住对方并建立会话。密码错误会产生两个不同的密钥,而不是报错,因此之后还会进行明确的密钥确认步骤;只有完成确认后,对等端才会被保存。之后运行时会跳过配对(peer already trusted),因此只需运行 mesh。
若已有节点在运行,cursio pair 无需密码即可配对:它会显示一次性代码;在另一台机器上运行 cursio pair <CODE>(或在应用中输入代码),并在 5 分钟内完成配对。
身份信息和受信任对等端会保存在平台配置目录下(Linux 上为 ~/.config/cursio,Windows 上为 %APPDATA%\cursio\cursio\config,macOS 上为 ~/Library/Application Support/dev.cursio.cursio)。
CLI
cursio mesh # run as a mesh node — this is how everything runs
cursio status # what the running node is doing: peers, modules, latency, problems
cursio pair [CODE] # pair through the running node with a one-time code
cursio forget <NAME> # remove a paired machine and its key
cursio wake <NAME> # wake a paired machine that is asleep (Wake-on-LAN)
cursio peers # list peers discovered on the LAN, then exit
cursio config # print the config `mesh` would run with, and where it lives
cursio update ... # install, switch and roll back versions
cursio portal install # (Linux) make Cursio the ScreenCast portal for --remote-screen
mesh 的运行内容来自 config.toml(运行 cursio config 可打印其路径);每个标志都会覆盖配置文件,但仅对本次运行生效,因此每个模块开关都成对出现(--audio / --no-audio)。节点运行期间更改的设置会在活动连接上重新协商;少数无法重新协商的设置会报告为等待下次重启生效。
| 标志 | 作用 |
|---|---|
--at X,Y | 此机器在网格上的位置。默认为 0,0,此处没有任何相邻位置,只有 Ctrl+Alt+G 可以切换。负数坐标也可以(--at -1,0)。 |
--send-input | 捕获此机器的鼠标和键盘输入,并与对等端共享 |
--clipboard | 共享剪贴板(文本、图像及其他格式) |
--audio | 按应用共享音频 |
--files | 双向共享磁盘;对等端的卷会显示在 ~/Cursio/<peer>/ 下 |
--files-share <PATH[:ro]> | 仅提供此根目录,而不是所有磁盘;可重复指定多个目录,:ro 表示拒绝更改 |
--usb | 共享此机器的 USB 设备,并使用对等端的 USB 设备 |
--remote-screen | 将对等端的窗口和显示器提供给此处的屏幕共享应用;--no-screen-host 则拒绝对等端对本机发起的请求 |
--pair | 开启配对窗口(在两台机器上运行) |
--pair-addr <HOST:PORT> | 指定要配对的机器,以便在无法使用 mDNS 时配对;同时表示由此端发起连接 |
--port <n> | 监听端口。默认为 46073,有意保持稳定——对等端会缓存最后使用的地址,以便在 mDNS 较慢时重新连接;如果每次重启端口都改变,缓存就会指向失效地址。传入 0 可使用临时端口。 |
--mac-modifiers <SPEC> | 设置 Mac 上修饰键的位置(见下文) |
--files 会以读写方式挂载,因此任一机器能够访问的内容,另一台机器也能更改。Linux 使用 FUSE 挂载,Windows 使用 WinFsp。
接管光标
将光标推过朝向对等端的一侧边缘,即可将其交给对方。若要从空闲机器取回光标,请按 Ctrl+Alt+G。
快捷键使用 wire 按键命名空间(Linux evdev),因此在 Mac 上会随 --mac-modifiers 改变:positional(默认值)对应 Control+Option+G,swapped 对应 Command+Option+G。启动日志会列出实际按下的物理按键,因为快捷键悄然移位后就很难找到了。
--mac-modifiers 接受预设值(positional、swapped)或 from=to 配对,例如 rightalt=globe。swapped 会让 PC 键盘上的 Ctrl+C 在 Mac 上执行复制。
AirPlay
cursio mesh 会为整个 mesh 参与一个 AirPlay 接收器,该接收器的名称简单明了:Cursio。打开控制中心 → 屏幕镜像并选择它。mesh 会选取一个控制端口空闲的主机,并优先选择配备硬件 H.264 解码器的主机;如果该主机离线,其余节点会重新计算部署位置并由其中一个接管。
| 标志 | 效果 |
|---|---|
--airplay <MODE> | on/control(默认)表示参与;如 1440p:30fps 这样的配置文件会提高 mesh 的画质请求;off 表示退出托管 |
--airplay-window | 即使接收器由另一台机器托管,也在此机器上显示镜像屏幕 |
--airplay-port <port> | 更改控制端口 |
--airplay-interface <addr> | 将 AirPlay 的 mDNS 固定到具有此地址的 LAN 接口 |
--share-airplay | 托管时,将镜像屏幕提供给每个节点,而不只是请求窗口的节点 |
画面会显示在启动镜像的机器上:托管节点会通过普通窗口路径原样转发 H.264,因此传输过程中不会重新编码。
当前范围:屏幕镜像、临时 AirPlay 配对、FairPlay 会话设置、加密 H.264 传输和硬件加速呈现。镜像伴随的音频尚未解码。任意文件传输并非 AirPlay 功能——Cursio 自己的加密文件通道才是用于此目的的路径。
平台视频要求
- macOS — 自带原生 AppKit/AVFoundation 助手和 Apple 硬件解码器;无需 GStreamer
- Linux — 需要 GStreamer 1.x、硬件 H.264 解码器(
vah264dec、nvh264dec或vaapih264dec)以及兼容的 Wayland/GL sink - Windows — 需要 GStreamer 1.x、
d3d11h264dec和d3d11videosink
如果只能使用软件解码,则会拒绝运行,而不会静默使用软件解码。启动时,CLI 会检查视频路径和端口可用性;检查结果会随 mesh 握手信息传递,因此每个节点都会计算出相同的部署位置。
构建与安装
项目自动化流程由 cargo xtask 提供,它会封装每次构建所需的环境变量和目标三元组:
cargo xtask build # release build of supported binaries for this host
cargo xtask install # build + copy cursio, clipd, cursio-app to ~/.local/bin
cargo xtask run # build and run `cursio mesh --send-input --clipboard`, restarting on crash
cargo xtask windows # cross-compile the .exe(s) from Linux (MSVC)
cargo xtask macos # build on a Mac
cargo xtask android # the phone app as an arm64 APK (needs ANDROID_HOME, ANDROID_NDK_HOME, bun)
cargo xtask stage ubuntu24 # an Ubuntu 24.04 build, in docker
cargo xtask publish # stage host + Windows + Ubuntu 24.04, sign, offer to the mesh
cargo xtask logs --follow # print the log dir and tail the current log
构建产物会安装到每用户独立的根目录下,并排存放,同时提供 current 指针和回滚功能(docs/update-design.md)。只有信任构建机器的机器才能从 mesh 获取构建产物(cursio update trust-builder),并根据 [update] policy = "auto" | "ask" | "never" 应用更新。
cargo xtask deploy 和 cargo xtask live-test 会通过 ssh 驱动一个真实的 Windows 节点(docs/live-test.md)。该节点的信息位于检出目录根部的 .env 文件中,git 会忽略此文件:复制 .env.example 并填写内容。
install 还会在 ~/.local/share/applications 下写入 .desktop 文件;如果 ~/.local/bin 尚未加入 PATH,请将其添加进去。clipd 仅支持 Linux,因此 macOS 构建的是 cursio 和 cursio-app。
将 cargo 的作用范围限定到某个包 —
--workspace在 macOS 上会失败,因为apps/clipd需要 GTK4/libadwaita,而gdk-pixbuf-sys未提供 macOS pkg-config。
原生 Linux 构建需要 OPUS_TARGET=ubuntu-24.04_x86_64;cargo xtask 会自动设置它,普通的 cargo build 则不会。Windows 交叉构建会从源代码编译 libopus,因此不需要此变量,但需要在构建主机上解压 GStreamer's MSVC development 软件包,并通过 GSTREAMER_WINDOWS_SYSROOT 指定其路径(即包含 lib/pkgconfig 的前缀,通常为 .../1.0/msvc_x86_64)。
运行测试:
cargo test -p cursio-protocol -p cursio-transport -p cursio-core
若干 crate 附带 examples/,用于探测真实硬件(capture_probe、wasapi_loopback_probe、grab_cycle、encode_bench)。这些示例之所以存在,是因为它们测试的功能需要合成器、GPU 或 iPhone:
cargo run -p <pkg> --example <name>
日志记录
每个二进制文件都会同时将日志写入控制台和轮转文件:
- 控制台(stderr):带颜色,默认级别为
info - 文件:纯文本,默认级别为
debug,每天轮转,位于平台数据 目录下 — Linux 上为~/.local/share/cursio/logs/, Windows 上为%APPDATA%\cursio\cursio\data\logs, macOS 上为~/Library/Application Support/dev.cursio.cursio/logs
覆盖日志级别:
RUST_LOG=debug— 同时提高两个输出目标的日志级别CURSIO_LOG_FILE=trace— 仅提高文件的日志级别,控制台保持安静
RUST_LOG=cursio_airplay=debug,info cargo run -p cursio-core -- mesh
cargo xtask logs --follow
项目结构
Cursio 是一个 Cargo 工作区,分层结构为 protocol → transport → core →
平台 crate → 二进制文件:
crates/protocol— 线协议词汇和长度前缀帧封装,不涉及 I/Ocrates/transport— 发现、密码配对(SPAKE2 + 密钥确认 + 信任存储)、Noise 和优先级调度crates/core— 身份、链路建立、网状网络监管、会话循环、 模块实现和cursioCLIcrates/input— 各平台的输入捕获和注入crates/window— 窗口捕获、编码和代理窗口crates/audio— PipeWire 和 WASAPI 后端crates/files— 提供卷服务并挂载对端的卷crates/usb— USB/IP 导出与导入,以及设备持有者管理crates/clipboard-core— 与clipd共用的剪贴板后端crates/android— 手机节点及其 JNI 入口,以及 Kotlin 服务、 插件和后端(plugin/)crates/bluetooth— Cursio 作为手机免提设备和 A2DP 扬声器,以及网状网络的蓝牙通道crates/airplay— AirPlay 接收器,刻意置于网状网络之外;vendored FairPlay C 位于native/playfaircrates/logging— 所有二进制文件共用的控制台 + 轮转文件日志记录crates/xtask— 构建/安装/交叉编译自动化app— Tauri UI:桌面窗口和托盘,以及完整的手机应用apps/clipd— 独立的 Linux 剪贴板历史弹出窗口(GTK4/libadwaita)native/— Windows 音频驱动和 GNOME 扩展(拖动检测和快速设置磁贴)
平台 crate 负责机制;core 中对应的 *_session.rs 负责策略。功能通过添加模块实现,绝不通过在 CLI 中添加分支实现。
docs/*.md 是对应子系统的权威文档:网状网络、
平台、输入、
音频、剪贴板、
窗口传输、USB、
消息、通话、
媒体、图库、
更新、实时测试。
限制(v0.x)
- DRM/受保护的画面可能无法捕获
- 全屏应用和游戏仍处于实验阶段
- Wayland 合成器会限制捕获和窗口控制;GNOME 上的拖动检测需要捆绑的 Shell 扩展
- 延迟取决于网络和硬件
路线图
已完成 — 加密网状网络、输入代理、拖动窗口到屏幕边缘以跨设备传输、按应用区分音频、剪贴板、文件共享、USB 共享、为屏幕共享应用提供远程屏幕、AirPlay 接收器、带签名的自动更新,以及将手机作为完整节点(音频、麦克风、存储、图库、通知、短信、通话、媒体控制、由电脑驱动手机屏幕、蓝牙回退)。
接下来 — 在 macOS 上显示节点的窗口、macOS 音频、以服务形式运行的 Windows 音频驱动、Windows 上的通话语音、后台同步手机剪贴板、VideoToolbox 编码、合成器集成。
在 macOS 上挂载节点的磁盘 — 通过 Cursio 内的 localhost NFSv3 服务,由系统自带的 NFS 客户端挂载,而不是使用 FUSE:无需安装任何内容、无需内核扩展,适用于所有 macOS 版本。如今 FUSE 方案都更差:fuser 未在 macOS 上测试过,并且在 macFUSE 5.3 中丢失了挂载路径;macFUSE 的 kext 要求在 Apple Silicon 上从 Recovery 设置 Reduced Security;它的无 kext FSKit 后端不提供 FUSE 设备 fd(只有仍在变化的 MFMount.framework),只能挂载到 /Volumes 下,而且速度更慢;FUSE-T 替代的是 libfuse,而不是提供 fd,并且仅供个人用途免费使用。非 root 用户通过 mount_nfs 挂载 localhost 导出,这正是 Hugging Face 的 hf-mount 和 rclone nfsmount 已采用的方案。服务端使用 nfs3_server(其 CI 覆盖 macOS arm64),但有两处缺陷需要修补:其中的 FSSTAT 和 PATHCONF 是常量(可用空间 1 TiB,区分大小写),因此要为两者分别添加钩子并贡献到上游,同时随项目 vendored 一份修补后的副本。NFS 没有 open/close 操作,因此适配器会按文件 id 保存节点句柄,并在删除或重命名前关闭句柄,否则 Windows 节点会拒绝操作。挂载选项:vers=3,tcp, noresvport,locallocks(nolocks 会导致 flock 失败并返回 ENOTSUP)、intr 和 deadtimeout,以免节点崩溃后调用方陷入阻塞;rsize/wsize 设为 1 MiB。
贡献
请参阅 CONTRIBUTING.md。安全问题请通过 SECURITY.md 报告,不要在公开议题中报告。
许可证
Cursio 是自由软件:您可以根据 GNU 通用公共许可证(第 3 版,或您选择的任何更高版本)的条款重新发布和/或修改它。发布该软件是希望它能发挥作用,但不提供任何担保。
采用 GPL 并非在代码之上另行声明的偏好:iPhone 所需的 FairPlay 实现和 Windows 挂载所需的 WinFsp 绑定都采用 GPL-3.0,因此每个桌面二进制文件本身都已受 GPL 约束。THIRD-PARTY.md 列出了 vendored 代码及其许可证——native/cursio-vad 中的 Windows 音频驱动仍采用 Microsoft 的 MS-PL,作为独立程序发布。
AirPlay 和 FairPlay 是 Apple Inc. 的商标。Cursio 与 Apple 无关联,也未获 Apple 背书;它实现了该协议的接收端,以实现互操作。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。