FSearch:Rust 写的 macOS 全盘搜索,毫秒级找文件、自带 MCP 给编码 Agent 用

在 macOS 上找文件,Spotlight 平时够用,但一旦你要的是「这个仓库里哪个文件定义了 apply_dir」「上周改过的、大于 5MB 的图片在哪」,它就力不从心了。10 月初,GitHub 上冒出一个用 Rust 写的项目 FSearch(仓库 noahdunnagan/fsearch),专门解决这件事:把整块磁盘的文件名与文件内容都做成索引,让查询变成毫秒级操作,并且顺带给编码 Agent 留了一个 MCP 接口。

它 10 月 8 日建仓,一周多就攒到 2070 star,10 月 12 日连发两个版本。下面按「是什么、怎么这么快、怎么用、哪些坑」讲清楚。

一句话说清它是什么

FSearch 是 macOS 专用的全盘文件搜索工具,形态有三种,共用同一份索引:

  • CLI + 常驻守护进程:命令行敲查询,后台有一个 daemon 维护索引;
  • Rust crate:把搜索引擎链进你自己的程序;
  • MCP 服务:fsearch mcp 在 stdio 上起一个 MCP server,给编码 Agent 用。

仓库自己的描述是「Whole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep」。许可证是 MIT,语言 Rust,当前版本 0.2.1。

为什么值得看:三件事

一、名字搜索是毫秒级,而且容忍错字

README 首行写的是「names in about 0.1 ms」。它的模糊匹配不是简单子串:词的任意位置容忍 1 个错字,8 个字母以上的词容忍 2 个,所以 mian.rs 能找到 main.rs;多个词可以拼出同一个文件名;带重音的字符按存储时的写法匹配。

这个「容错」不只是噱头。作者公布的基准里最能说明问题的一行,是「打错两个字母时第一个就命中的比例」,从上一版的 11% / 15%(Linux 树 / Chromium 树)提升到了 74% / 93%。

二、文件一改,马上能 grep 到

内容搜索(grep: / regex:)走的是三元组(trigram)索引。但更实用的一点是索引的实时性:改完一个文件到它能被 grep 到,上一版要 2.1 秒,现在是 1.3 毫秒;文件改名或删除反映到索引里,从 45 / 47 毫秒降到 18 / 15 毫秒。

做法是「索引只负责筛选、内容现读」:查询时只用索引找出可能命中的文件,真正匹配的文本从磁盘现读,改动过的文件直接读盘。所以它不怕「索引落后于文件」。

三、它不只是个命令行工具

除了 CLI,它对外有三个口子:本机 Unix socket 上的 JSON-lines API(~/Library/Application Support/FSearch/fsearch.sock,或 fsearch stdio)、可以直接链接的 Rust crate,以及 MCP 服务。一份索引同时服务 CLI 和任何链接了 crate 的应用——第一个启动的进程持有索引,其余的跟随它。

它是怎么做到的

  • 首次爬盘用 getattrlistbulk,之后跟着 FSEvents 走:文件的创建、改动、删除由系统推事件(README 说约 15 毫秒反映到索引),重启时只重放变化的部分,不重新扫盘。
  • 文件名存在一个 mmap 文件里,按文件夹依次排布,所以 in:~/Developer 这样的目录过滤是一次范围查找而不是扫描;打分之前,先用每个名字的字母 bitmap 排除掉大部分候选。
  • 内容搜索 = trigram 索引 + 每文件一个 3-bit 过滤器:只读「有可能命中」的文件;内容相同的文件只索引一次;被删文件的条目会被压实掉。
  • daemon 用 malloc 的省内存模式,空闲时把内存还给系统。

从这份清单还能看出一个信号:它的直接依赖只有 8 个(libc、rayon、memchr、memmap2、regex、regex-syntax、serde、serde_json)——没有引入现成的全文索引库,索引是自己写的。

上手:装、授权、搜

有 Rust 工具链的话:

cargo build --release && ./target/release/fsearch install   # -> ~/.local/bin/fsearch

没有工具链、又是 Apple Silicon 芯片,可以直接下预编译包:

curl -L https://github.com/noahdunnagan/fsearch/releases/latest/download/fsearch-aarch64-apple-darwin.tar.gz | tar xz && ./fsearch install

装完有一步必须做,否则等于没用:给它和终端完全磁盘访问权限(系统设置 → 隐私与安全性)。用终端跑,就给终端授权;注册成登录项(fsearch install --login)则要给 ~/.local/bin/fsearch 这个二进制单独授权——而且每次重新编译后都要再授权一次。没有权限时,它会跳过受保护目录,而不是弹窗提示你。

然后就可以搜了:

fsearch fsearch main             # 按名字找文件
fsearch 'ext:rs grep:apply_dir'  # 在 rs 文件里搜内容
fsearch 'sym:apply_dir'          # 找符号定义在哪

查询语法速查

筛选器(内联写在查询里):ext: type: kind: in: size: mtime: re: path: grep: regex: sym: limit: git:。其中 git: 支持 modified / staged / untracked / clean / tracked / ignored / conflict。

另有精确与排除写法:'exact(精确)、^prefix、suffix$、!exclude,以及 glob(src/**/*.{c,h})。几个官方例子:

fsearch 'readme in:~/Developer'           # 限定在某个文件夹内
fsearch 'type:image size:>5mb mtime:<7d'  # 最近 7 天改过、大于 5MB 的图片
fsearch 'ext:rs regex:fn\s+\w+_dir'       # 在文件内容里跑正则
fsearch 'src/**/*.{c,h} !test/ init'      # glob 包含与排除
fsearch 'git:modified in:~/Developer/app'

给编码 Agent 用:MCP 三个工具

这是它对 AI 场景最有价值的部分。fsearch mcp 在 stdio 上起一个 MCP server,暴露三个工具:

  • find_files——按名字找文件,模糊且容错,作用于整个路径。官方工具描述里直接写明:「找文件位置用它,找内容用 grep」,并要求所有词都匹配;
  • grep——按单个模式搜索文件内容;
  • multi_grep——多个字面量模式按 OR 匹配。官方举的例子很实际:搜索一个人名或变量的「各种拼法」,比如 ['PrepareUpload', 'prepare_upload']。注意它明确说明「模式是字面量,永远不要转义」。

对做编码 Agent 的人来说,这等于把「找文件 + 搜内容」从一个每次都要遍历目录、每次都要重新扫仓库的低效动作,换成一个常驻索引上的毫秒级查询——而且这个索引是全局的,不只覆盖当前项目。

性能数字怎么读

README 里那张表是作者在 M4 Mac mini 上自测的「上一版 vs 现在」对比(Linux 源码树 / Chromium 源码树):

  • 按名字找文件:0.054 / 0.12 毫秒(上一版 0.045 / 0.10,这一项基本持平);
  • 改过的文件变得可 grep:2.1 秒 → 1.3 毫秒;
  • 首次运行时「在文件夹里找一个名字」:7.8 秒 → 0.18 / 1.2 秒;
  • grep 能覆盖到的文件比例(以 ripgrep 自己的文件集合为分母):96% / 92% → 99.9% / 99.8%;
  • 索引落盘体积:503 / 893 MB → 309 / 600 MB(索引小了三分之一,装下的文本多了三分之一);
  • daemon 常驻内存:19 / 100 MB → 21 / 35 MB。

三点提醒:

  • 全部是作者自测,没有第三方复现,且强依赖具体机器(M4 Mac mini);
  • 官方口径本身有三处:README 首行说「约 0.1 毫秒」,GitHub 仓库简介说「8M 文件下约 1 毫秒」,基准表给的是具体源码树上的 0.054 / 0.12 毫秒——它们对应不同数据集,别混着引用;
  • 目前的基准表是相对上一版的自我对比。网上一些报道引用的「与 fff 工具对比、1.1ms vs 13.8ms」那组数字,在当前 README 里已经找不到了——引用前建议自己去看一眼仓库。

边界与坑(读完再装)

  • 只有 macOS,而且预编译包只有 Apple Silicon(aarch64-apple-darwin),Intel Mac 和 Linux 都得自己编译。有人提过 Windows 支持(NTFS MFT 爬取)和 Linux 支持的 PR,都没被合并。
  • 没有 GUI,而且官方明确不做。issue #15 里有人建议加界面,维护者 10 月 12 日的回复是「Not planned: fsearch stays a CLI and daemon.」。它给自己的定位就是给开发者用的 CLI + daemon。
  • 需要完全磁盘访问权限,重新编译后要重新授权;没权限时会静默跳过受保护目录。
  • 内容搜索有明确的覆盖范围:文本文件最大 1 MB,在 git 仓库内最大 10 MB,并会排除 lockfile、100 KB 以上的 JSON、压缩或打包产物、被 git 忽略的内容、链接的 git worktree,以及仓库之外的构建输出目录。想再排除更多,可以往 ~/Library/Application Support/FSearch/content-skip.txt 里一行一个目录地加。文件名则始终全量索引。
  • 维护者对改动很挑:仓库里 28 个 PR,只有 8 个被合并,18 个被关闭未合并——大功能(Windows、Linux、Swift 绑定、整套测试)基本都被婉拒,说明「只做 macOS 上的 CLI + daemon」这条线守得很紧。

同名提醒:别下错

GitHub 上叫 fsearch 的仓库有 153 个。其中最容易混的是 cboxdoerfer/fsearch——那是另一个项目:C 语言写的 Linux / Unix 图形文件搜索工具(GTK3),GPL-2.0 许可,2016 年建仓,至今仍在维护,star 数(4477)比这个 macOS 版还高。两者除了名字和「都在做文件搜索」之外没有任何关系。

本文介绍的 macOS 版地址是 github.com/noahdunnagan/fsearch,MIT 许可,用 Rust 写的。

第三方已经在补 GUI 和生态

官方不做 GUI,社区就自己来,目前至少有两个:

  • domfahey/fsearch-app(Swift,MIT)——菜单栏启动器,默认 ⌥Space 呼出,边输入边出结果,也能搜索文件内容、查找符号定义。它自己不做索引,全部走 fsearch 的 daemon;会捆绑一个固定版本的 fsearch,并用 SMAppService 注册登录项,如果已有 daemon 在跑就直接用现成的。作者在做这个前端的过程中发现了一个 daemon 的安全问题,选择私下报告(维护者随后开启了私密漏洞报告通道)。
  • huangy7/lokii(Rust,MIT)——另一个独立的 macOS 原生搜索应用,用 Rust + AppKit,自称「给 Mac 的 Everything」,是在上面那个「要 GUI」的 issue 里被推荐出来的。

一句话总结

FSearch 代表了一类很实用的开源项目:不追热点,只把一件事做到极致——用 Rust 把 macOS 的全盘索引做成毫秒级查询,同时把接口留干净(CLI、socket、crate、MCP),让别人去接 GUI、接 Agent。如果你在 macOS 上做开发,又经常要「先找到文件再开始干活」,它值得装一个;如果你在做编码 Agent,那个 MCP 入口更值得研究,因为它示范了「给 Agent 提供一个常驻的本地检索层」应该长什么样。

参考来源

  • 项目仓库与 README:github.com/noahdunnagan/fsearch(star 数、版本、依赖、基准表、查询语法、实现说明均核对自此处,数据核对于 2026-10-15)
  • Release 页:github.com/noahdunnagan/fsearch/releases(v0.2.1 发布于 2026-10-12)
  • issue #15「加个界面吧」与维护者回复 Not planned: fsearch stays a CLI and daemon.
  • issue #18:第三方 macOS 前端 fsearch-app 的公告与安全漏洞私下报告
  • 同名项目对比:cboxdoerfer/fsearch(Linux GTK3 版,GPL-2.0)

本文为项目介绍与解读,未在真机上安装实测;文中所有数字、版本、许可证与 issue 内容均直接核对自上述官方来源。引用的性能数据均为项目作者自测,尚无第三方独立复现。

腾讯云精选福利

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注