📦dmtrKovalenko / fff
← 返回首页
The fastest and the most accurate file search SDK for AI agents, Neovim, Rust, C, Python, Bun and NodeJS
⚖️ MIT#filesearch#lua#neovim#neovim-plugin#rust🌐 fff.dmtrkovalenko.dev📅 创建于 2025-07-31🔄 更新于 2026-10-28

📄 仓库 README

在 GitHub 查看 ↗
来自 GitHub 仓库自述文件 · 版权归原作者所有

FFF

A file search toolkit for humans and AI agents. Really fast.

Typo-resistant path and content search, frequency-ranked file access, a background watcher, and a lightweight in-memory content index. Way faster than CLIs like ripgrep and fzf in any long-running process that searches more than once.

Powers file search in opencode, nushell, and many more amazing projects!

Originally started as Neovim plugin people loved, but it turned out that plenty of AI harnesses and code editors need the same thing: accurate, fast file search as a library. That is what fff is.

dmtrKovalenko%2Ffff | Trendshift


Sponsors

fff is MIT and open source forever. Development is supported by these companies:

💎
DIAMOND
Anomaly Anomaly
The team behind opencode.
🥇
GOLD
Mango Proxy Mango Proxy
Fast, secure proxies for all the needs.
🥈
SILVER
RapidProxy RapidProxy
Residential proxies built for scraping at scale.

Use and enjoy fff? Become a sponsor to get your features/fixes the highest priority.


Pick what you are interested in:

MCP server

Works with Claude Code, Codex, OpenCode, Cursor, Cline, and any MCP-capable client. A resident Rust index supports file discovery and content search across tool calls. ![Measured search time and tokens for FFF MCP versus normal shell search](https://raw.githubusercontent.com/dmtrKovalenko/fff/HEAD/./chart.png) The chart compares warm FFF MCP with shell search in the small and big repos. Startup and indexing are excluded. Six additional tasks were held out from tuning in the small repo. The big repo appears in the main comparison above, but did not have a separate held-out run. | Held-out model | Shell time | FFF time | Shell tokens | FFF tokens | | --- | ---: | ---: | ---: | ---: | | Opus 5.5 | 10.7 s | 9.0 s | 58.3k | 49.2k | | GPT-6 Astra | 8.1 s | 9.0 s | 43.9k | 49.3k | [Held-out chart](https://github.com/dmtrKovalenko/fff/blob/HEAD/scripts/search-benchmark-heldout.png). Both models returned all six expected answers in each recorded search mode. Tokens include cached input. ### One-line install Linux / macOS:
curl -L https://dmtrkovalenko.dev/install-fff-mcp.sh | bash
Windows (PowerShell):
irm https://raw.githubusercontent.com/dmtrKovalenko/fff/main/install-mcp.ps1 | iex
The scripts live at [`install-mcp.sh`](https://github.com/dmtrKovalenko/fff/blob/HEAD/./install-mcp.sh) and [`install-mcp.ps1`](https://github.com/dmtrKovalenko/fff/blob/HEAD/./install-mcp.ps1) if you want to read them first. They print the exact wiring instructions for your client. ### Homebrew (macOS / Linux)
brew install dmtrKovalenko/fff/fff-mcp
brew upgrade fff-mcp   # after new stable releases
Formula lives in [`Formula/fff-mcp.rb`](https://github.com/dmtrKovalenko/fff/blob/HEAD/./Formula/fff-mcp.rb) in this repo and is **auto-bumped on every stable release** (see `bump-homebrew-formula` in [`.github/workflows/release.yaml`](https://github.com/dmtrKovalenko/fff/blob/HEAD/./.github/workflows/release.yaml)). Installs the prebuilt `fff-mcp` binary from [GitHub releases](https://github.com/dmtrKovalenko/fff/releases). ### Codex setup Register the installed binary using its absolute path, since Codex desktop sessions may not inherit your interactive shell's `PATH`. Homebrew:
codex mcp add fff -- "$(brew --prefix)/bin/fff-mcp"
One-line installer:
codex mcp add fff -- "$HOME/.local/bin/fff-mcp"
This creates an entry in `~/.codex/config.toml` similar to:
[mcp_servers.fff]
command = "/opt/homebrew/bin/fff-mcp"
Use the actual installed path for your system, then restart Codex or start a new task so it loads the server. On Codex versions that support `omit_tools_from`, add `omit_tools_from = ["deferred"]` to this server's configuration to expose FFF's tools immediately. This avoids a separate tool-discovery round trip. The measurements above use this setting. Once the server is connected, ask the agent to "use fff". The MCP tools are `grep`, `find_files`, and `multi_grep`. ### Recommended agent prompt Drop this into your project's `CLAUDE.md` or equivalent:
For any file search or grep in the current git-indexed directory, use fff tools.
Include the known directory or module in the first search. Use definitions_only
for declarations. Read more source only when the returned lines need context.
### Definition search MCP and Pi accept `definitions_only: true` to search declarations. MCP uses `{ "query": "AudioMap", "path": "src/audio", "definitions_only": true }`; Pi's `ffgrep` uses `pattern` instead of `query`. In MCP, use `path` for a known file or directory and `globs` for patterns. MCP's `path` also scopes `find_files`. Inline query constraints remain supported. An existing checkout-relative `path` anchors the search at the root; otherwise the name matches at any depth. Case or `-`/`_` differences use the indexed spelling with a notice. Missing paths also produce a notice. A definition query drops a filename constraint that matches no indexed file and reports that change. MCP also accepts ripgrep-style searches without putting scope tokens in the pattern:
{"query":"retry|backoff","mode":"regex","paths":["src","lib"],"globs":["*.rs","!**/tests/**"],"context":3}
`mode: "regex"` and `mode: "literal"` preserve the query, including whitespace, and default to case-sensitive matching. `case` also accepts `"insensitive"` and `"smart"`. Without a mode, smart-case and inline constraints remain available. Supplying `paths` or `globs` keeps the query verbatim, so inline constraint tokens become search text. Regex matches stay within one line unless the pattern contains `\n`. `paths` contains checkout-relative files or directories. Positive `globs` are alternatives; exclusions take priority. `hidden: false` skips hidden paths unless a path or glob explicitly includes them. Globs cannot restore files excluded by the index's ignore rules. Ripgrep-specific `.rgignore` files can also make its file inventory differ. Grep returns up to 100 matching lines per page by default, 30 with `definitions_only`, and at most 200. Use `maxResults` and the returned cursor to continue, including within a file. `max_matches_per_file` explicitly limits matches per file. Small content result sets include bounded surrounding source automatically. `context`, `before_context`, and `after_context` request explicit context; overlapping windows are merged. Set `context: 0` for matching lines only. `find_files` matches path fragments before approximate filenames. Its default mode treats hyphens and underscores alike. Set `mode: "glob"` or `mode: "regex"` for exact path filtering, with the same `paths`, `globs`, and `hidden` options. Its optional `filters` array applies additional path regexes, like `rg --files | rg pattern1 | rg pattern2`. Single-query definition search tries these stages in order: 1. Matching declarations. 2. Ordinary exact matches, with a notice that no matching declarations were found. 3. Fuzzy declarations, labeled "Maybe you meant these definitions". 4. Fuzzy ordinary matches, labeled "Maybe you meant these other matches". 5. If all four stages found nothing, suggest files from a broader search. Exclusions remain active. Filename-only suggestions are labeled as unverified. Exact stages advance only after a complete search returns no matches. Each fuzzy stage has a two-second budget and can advance with zero matches before scanning the full index. Cursors preserve the stage, and a stage that returned matches never broadens when pagination ends. The first four stages keep the original file constraints; the final suggestions can come from elsewhere in the indexed project and include a notice. The multi-pattern tools accept the same flag but use only the first two stages; their patterns remain literal. On each page, files that declare the query as a whole name come first, and that declaration leads its file. `Value` lists `enum Value` before `ArgValueCompletion` and `DebuggableValue(pub Value)`. MCP confirms the declared name with the definition classifier; Pi approximates it. This ordering does not add a search. MCP's broader suggestions can include up to eight matching source lines. MCP tries partial module names before searching the whole index. Pi returns suggested filenames. ### What changes - Frecency memory. Files you actually open rank higher next time. Warm-up from git touch history runs automatically. - Definition-first hinting. Lines that look like code definitions are classified on the Rust side, no regex overhead in your prompt. - Smart-case with auto-fuzzy fallback. `IsOffTheRecord` finds snake_case variants; zero-match queries retry as fuzzy and surface the best approximate hits. - Git-aware annotations. Modified, untracked, and staged files are tagged so the agent reaches for what you are actively changing. Source: [`crates/fff-mcp/`](https://github.com/dmtrKovalenko/fff/blob/HEAD/./crates/fff-mcp/).

📈 近 7 天 Star 趋势

每日新增 Star(柱)与累计 Star(线)· 数据来自 GitHub

🏆 排名变化趋势

在各榜单中的排名历史(数字越小越靠前)

📋 历史上榜记录

每次快照的详细数据
日期 榜单 排名 周期新增 总 STAR