$npx -y skills add zilliztech/mfs --skill mfs-findSearch, grep, browse, and read across registered MFS data sources via the mfs CLI — codebases, docs, PDFs, web crawls, databases (postgres/mysql/mongo/snowflake/bigquery), issue trackers (jira/linear/github), CRMs (hubspot), chat (slack/discord/gmail/feishu), object stores (s3/
| 1 | # MFS — find / read across configured sources |
| 2 | |
| 3 | ## 1. What MFS is |
| 4 | |
| 5 | A retrieval layer that exposes many kinds of content as a unified path |
| 6 | tree and makes that tree searchable through one hybrid index: |
| 7 | |
| 8 | - **One CLI (`mfs`), one mental model.** Local dir, Postgres, GitHub repo, |
| 9 | Slack workspace, S3 bucket, BigQuery dataset — all addressed as paths |
| 10 | under their `<scheme>://` URI. Same verbs everywhere: `ls / tree / cat / |
| 11 | head / tail / grep / search / export`. |
| 12 | - **One hybrid index.** Dense vectors (semantic) + BM25 (keyword) fused |
| 13 | per query — covers conceptual recall and exact-token recall in one call. |
| 14 | - **POSIX-style locators.** Every search hit carries a `locator` that |
| 15 | reopens the exact unit: `{"lines":[s,e]}` for text/code, a PK dict for |
| 16 | rows/issues/threads. |
| 17 | |
| 18 | ## 2. When to use MFS — and when NOT to |
| 19 | |
| 20 | | Situation | Use MFS? | |
| 21 | |---|---| |
| 22 | | 1000+ files / rows / pages, you don't know where the answer is | ✅ | |
| 23 | | Cross-source question ("any past tickets / commits / RFCs about X") | ✅ `--all` | |
| 24 | | Concept-style query that won't match literally | ✅ `--mode semantic` | |
| 25 | | You already know the exact file + roughly where to look | ❌ plain `cat`/`grep` | |
| 26 | | Exact identifier / error code in 5 files you can list | ❌ plain `grep`/`rg` | |
| 27 | | Real-time tailing of a live log | ❌ index lags ingest | |
| 28 | | The source isn't in MFS yet | wrong skill, use `mfs-ingest` to register first | |
| 29 | |
| 30 | **Rule:** use the smallest tool that answers the question. MFS pays off |
| 31 | when the scope is too big for `rg`. |
| 32 | |
| 33 | **Borderline — ASK the user:** |
| 34 | |
| 35 | | Ask | Likely answer | Why | |
| 36 | |---|---|---| |
| 37 | | "Summarise these 10 PDFs" | ✅ `mfs search` + `cat --peek` per hit | each PDF gets a `converted_md` artifact + searchable chunks | |
| 38 | | "Find similar tickets to this one" | ✅ paste the ticket text as the search query | semantic over `row_text` does similarity matching | |
| 39 | | "Watch for new slack messages" | ❌ no `watch` capability; use Slack's API | index lags ingest | |
| 40 | | "Look up user 12345" | ❌ `mfs cat <source> --locator '{"id":12345}'` directly (skip search) | one-record-by-id doesn't need ranking | |
| 41 | |
| 42 | ## 3. Pre-flight — confirm the source is indexed |
| 43 | |
| 44 | Before running any query, especially on cross-source asks: |
| 45 | |
| 46 | ```bash |
| 47 | mfs status # server up? any connectors registered? |
| 48 | mfs connector inspect <uri> # this connector's object/job summary |
| 49 | mfs ls <uri> --json # per-entry capabilities + indexable / search_status |
| 50 | ``` |
| 51 | |
| 52 | - Server unreachable → tell user to start it (`mfs serve start` if |
| 53 | self-hosted), or this skill can't proceed. |
| 54 | - `connectors` empty → user hasn't ingested anything yet. **Redirect to |
| 55 | `mfs-ingest`** — don't try to search nothing. |
| 56 | - `search_status: unavailable` for the target URI → only `grep` / `ls` / |
| 57 | `cat` work; offer those or redirect to `mfs-ingest` for a re-sync. |
| 58 | - `building` → sync in flight; fall back to `mfs grep` (works without an |
| 59 | index) until done. |
| 60 | - `partial` → recall incomplete but usable; flag the caveat to the user. |
| 61 | |
| 62 | ## 4. The core workflow: search → locate → browse |
| 63 | |
| 64 | ``` |
| 65 | search locate browse |
| 66 | ┌──────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ |
| 67 | │ semantic + BM25 │ → │ result has lines │ → │ cat --range / cat │ |
| 68 | │ finds candidates│ │ or a locator │ │ --peek to confirm │ |
| 69 | └──────────────────┘ └──────────────────┘ └─────────────────────┘ |
| 70 | ``` |
| 71 | |
| 72 | On large corpora this loop is the whole point: read only the part that |
| 73 | matters. On small corpora it's still fine, just lighter. |
| 74 | |
| 75 | Concrete: |
| 76 | |
| 77 | 1. **Search:** |
| 78 | ```bash |
| 79 | mfs search "<what the user actually wants>" <path-or-uri> --top-k 10 |
| 80 | ``` |
| 81 | 2. **Locate** — every hit's envelope carries `locator`: |
| 82 | - text/code → `{"lines":[start,end]}` → `mfs cat <source> --range start:end` |
| 83 | - structured (row/issue/thread) → PK dict → `mfs cat <source> --locator '{...}'` |
| 84 | - once-per-object (dir/schema summary, image VLM) → `null` → `mfs cat <source>` |
| 85 | 3. **Browse** — verify only what's needed: |
| 86 | ```bash |
| 87 | mfs cat --peek <file> # outline (headings / function signatures) |
| 88 | mfs cat --ski |