| name | fmm |
| description | MCP-first code navigation for this codebase. Use before any symbol lookup, file search, dependency trace, impact analysis, or codebase evaluation — replaces grep/glob/read with O(1) fmm_* tool calls. Trigger when: starting any task involving unfamiliar code, navigating code structure, finding where a symbol is defined, checking what imports a file, tracing blast radius before a rename, mapping test coverage, or evaluating/auditing a codebase.
|
FMM — MCP-First Code Navigation
This codebase has FMM metadata available via the fmm MCP server. All tools are prefixed fmm_*. Use them for instant, structured lookups instead of grep/read.
The index stays current throughout your session — a hook re-indexes any file you edit immediately after the write. You can trust fmm data at every point in your task.
Before You Touch Any Code
If you are about to call Read, Grep, or Glob on a source file — stop. Ask: does fmm answer this? It answers structural questions at O(1): file topology, symbol locations, export maps, dependency graphs, blast radius. Reading files to derive those answers costs 10-50x more tokens and is less complete.
Reserve Read for two cases only: editing a specific symbol, or understanding logic that fmm_read_symbol cannot provide.
MCP Tools (ALWAYS USE THESE FIRST)
| Tool | Use Case | Example |
|---|
fmm_list_files | Orient in an unknown codebase. sort_by: loc (heaviest), downstream (most-imported, best pre-refactoring), name, exports, modified | fmm_list_files(directory: "src/", sort_by: "downstream") |
fmm_file_outline | Full structural profile — exports, public/private (include_private) methods, line ranges | fmm_file_outline(file: "src/core/index.ts", include_private: true) |
fmm_lookup_export | O(1) exact lookup → file, line range, full file profile | fmm_lookup_export(name: "createPipeline") |
fmm_list_exports | Export search: substring or regex (auto-detected). ^handle, Service$, ^[A-Z] for regex; plain text for substring | fmm_list_exports(pattern: "^[A-Z]", directory: "packages/core/") |
fmm_read_symbol | Exact source for a named export or specific method | fmm_read_symbol(name: "Injector.loadInstance") |
fmm_search | Cross-cutting queries: imports, LOC range, depends_on, term | fmm_search(imports: "rxjs", min_loc: 500) |
fmm_dependency_graph | Upstream deps + downstream blast radius. filter: "source" strips test files, filter: "tests" shows only test coverage | fmm_dependency_graph(file: "src/core/index.ts", filter: "source") |
fmm_glossary | Symbol impact — call-site callers or test coverage by method | fmm_glossary(pattern: "Injector.loadInstance", mode: "source") |
CLI and MCP Command Mapping
CLI commands use short terminal names. Aliases mirror MCP tool names with the fmm_ prefix removed and underscores converted for the CLI.
| MCP Tool | CLI Command | CLI Alias |
|---|
fmm_lookup_export | fmm lookup | fmm lookup-export |
fmm_list_exports | fmm exports | fmm list-exports |
fmm_dependency_graph | fmm deps | fmm dependency-graph |
fmm_dependency_cycles | fmm cycles | fmm dependency-cycles |
fmm_read_symbol | fmm read | fmm read-symbol |
fmm_file_outline | fmm outline | fmm file-outline |
fmm_search | fmm search | none |
fmm_list_files | fmm ls | fmm list-files |
fmm_glossary | fmm glossary | none |
fmm_find_similar | fmm similar | none |
fmm_dupe_clusters | fmm dupes | none |
Navigation Workflow
- Orient —
fmm_list_files(sort_by: "downstream") — highest blast-radius files first. Start here before touching anything.
- Locate —
fmm_lookup_export("SymbolName") — O(1) file + line range. Replaces grep.
- Outline —
fmm_file_outline(file, include_private: true) — symbol inventory with line ranges, density fields, and private members.
- Read —
fmm_read_symbol("Class.method", line_numbers: true) — surgical extraction.
- Impact —
fmm_glossary("Class.method") — confirmed callers before renaming or changing a signature.
- Reuse check —
fmm_find_similar(name: "loadConfig") or fmm_find_similar(name: "loadConfig", signature: "(Path) -> Config", kind: "fn") — before authoring a new function or type, probe for an existing one. Reuse the match instead of duplicating.
Discovering Code Structure
fmm_list_files(sort_by: "downstream") → highest blast-radius first
fmm_list_files(group_by: "subdir") → directory topology in one call
fmm_list_files(filter: "source") → source files only (no tests)
fmm_list_files(filter: "tests") → test files by path/name; Rust inline #[cfg(test)] modules inside source files are excluded
fmm_list_files(pattern: "*.ts") → filter by filename glob
Finding a Symbol
fmm_lookup_export("SymbolName") → O(1) file + line range
fmm_list_exports(pattern: "auth") → fuzzy: validateAuth, authMiddleware
fmm_file_outline(file: "src/foo.ts") → symbols with line ranges, signature, visibility, kind
fmm_file_outline(..., include_private: true) → private members and non-exported top-level declarations too
Reading Code
fmm_read_symbol("ClassName") → full class source (capped at 10KB)
fmm_read_symbol("Class.member") → single method or indexed field; includes kind when known
fmm_read_symbol("module_name") → Rust `mod module_name;` declaration with kind: module
fmm_read_symbol("src/foo.ts:helperFn") → non-exported top-level function
fmm_read_symbol("Symbol", line_numbers: true) → with absolute line numbers
fmm_read_symbol("LargeClass", truncate: false) → bypass 10KB cap
Impact Analysis
fmm_glossary("loadInstance") → all callers (named-import precision)
fmm_glossary("Injector.loadInstance") → call-site precision
fmm_glossary("Symbol", truncate: false) → bypass 10KB cap for large caller lists
fmm_dependency_graph(file: "src/injector.ts") → upstream deps + downstream blast radius
fmm_dependency_graph(..., filter: "source") → production blast radius (no tests)
fmm_dependency_graph(..., depth: -1) → full transitive closure
fmm_dependency_graph(..., reverse: true, transitive: true) → reverse dependent closure
Searching
fmm_search(term: "store") → smart search: exports, files, imports, named-import call sites
fmm_search(imports: "lodash", min_loc: 100) → structured AND query
fmm_search(export: "createStore", min_loc: 50) → export + size filter
fmm_search(depends_on: "src/auth.ts") → full blast radius (transitive)
Navigation Protocol
"Orient me / What's in this directory?"
1. fmm_list_files(directory: "packages/core/", sort_by: "loc") → largest files first
2. Top entries = complexity anchors. Use fmm_file_outline on those first.
First tool to reach for in an unknown codebase. Default sort is loc (heaviest files first).
Sort modes: loc (default, heaviest files), downstream (most-imported — best before a refactor to see blast radius), exports (most exported symbols), name/path (alphabetical file path), modified (recently changed).
Pre-refactoring: use sort_by: "downstream" to find the files other files depend on most. Those are the highest-risk targets for changes.
"What's in this file?"
1. fmm_file_outline(file: "src/foo.ts") → symbols with line ranges, signature, visibility, and kind
2. Decide WHAT to read before reading anything
fmm_file_outline lists symbols and class members with exact line ranges and populated density fields. For a 1,000-line class, you see the full table of contents in one call.
"Where is X defined?"
1. fmm_lookup_export(name: "X") → file, line range, AND full file profile — DONE
2. Not found? → fmm_list_exports(pattern: "X") for fuzzy match
3. Still nothing? → fall back to Grep
fmm_lookup_export returns more than a location — the entire file's export map, imports, and dependency list come with it.
"Show me the code for X"
1. fmm_read_symbol(name: "ClassName.memberName") → exact method or indexed field source — DONE
Full class: fmm_read_symbol(name: "ClassName") — truncates at 10KB; add truncate: false for full source
Always use ClassName.member notation for large classes. It extracts exactly that method or indexed field — no class body noise. Reading a 1,000-line class to find an 80-line method wastes ~90% of your token budget.
"Find everything named like X"
1. fmm_list_exports(pattern: "X") → all matching exports with file + line range
2. Scope: fmm_list_exports(pattern: "X", directory: "packages/core/")
Results include class methods (e.g., Injector.loadInstance) as distinct entries. Use offset to paginate wide searches.
"Cross-cutting query: files using X with more than N lines"
1. fmm_search(imports: "rxjs", min_loc: 500) → files matching ALL criteria with full metadata
2. fmm_search(depends_on: "src/core/injector.ts") → all files in the transitive dependency chain
3. fmm_search(term: "Injector") → EXPORTS + FILES + NAMED IMPORTS grouped by type
depends_on uses transitive matching — it returns the full downstream closure, not just direct importers. For direct importers only, use fmm_dependency_graph(depth: 1) and read downstream.
term vs export: Use export: "SymbolName" for a known symbol — returns the file profile instantly with no noise. Use term: "name" for discovery — returns EXPORTS (fuzzy), FILES (path match), and NAMED IMPORTS (call sites). Generic terms produce noisy EXPORTS; the NAMED IMPORTS section is the valuable part for understanding usage.
"Who calls function X from an external package?"
fmm_search(term: "createServerFn") →
NAMED IMPORTS:
createServerFn from @tanstack/react-start
src/utils/docs.ts
src/utils/feed.functions.ts
... (all call sites)
term traces named imports across the entire codebase regardless of whether the symbol is local or external. Results group by import source path — multiple relative paths to the same module appear as separate groups, showing exactly which files import from which depth.
Use this instead of grep for "which files use X". A single call returns every import site with file paths, no regex required.
"What would break if I rename/change X?"
1. fmm_glossary(pattern: "ClassName.method") → actual method call sites only — surgical blast radius
fmm_glossary(pattern: "ClassName") → file-level: all files importing the class's file
2. Separate production vs test impact: mode: "source" | "tests" | "all"
The dotted pattern is the contract. fmm_glossary(pattern: "loadInstance") returns every file that imports injector.ts — a superset. fmm_glossary(pattern: "Injector.loadInstance") runs a tree-sitter second pass and returns only files with an actual call site. Use the dotted form for rename safety.
Dotted substring matching. Dotted glossary patterns narrow to call sites but still match symbols as substrings of the full dotted name. fmm_glossary(pattern: "Type.foo") may return both Type.foo and Type.foo_bar; pass exact: true when you need exactly one full symbol name.
Dotted fields. If the dotted member is an indexed field, fmm_glossary emits kind: field and explains that field access is not a method call site.
Re-export annotation. When a file re-exports a symbol without calling it, glossary marks it: # re-exports only (1 file — rename required but no call site). This means a rename must update the re-export chain, but no call-site edits are needed. Distinct from a true caller.
precision: named and precision: call-site may return identical results. This is correct — it means every named importer is also a real caller. The call-site pass confirmed all imports. Not a failure.
Known gaps — use fmm_dependency_graph instead:
- React JSX components.
<Navbar /> compiles to a createElement call that tree-sitter does not recognise as a named import. fmm_glossary returns used_by: [] for components used only via JSX. Use fmm_dependency_graph(file: "src/components/Navbar.tsx") to find all files that import the component file.
createServerFn wrappers. Server functions invoked through an RPC mechanism do not appear as named call sites. fmm_glossary returning used_by: [] on a server function export does not mean dead code — it means the caller is the framework runtime, not a direct import.
"What tests cover X?"
1. fmm_glossary(pattern: "ClassName.method", mode: "tests") → test files with actual call sites
fmm_glossary(pattern: "ClassName", mode: "tests") → all test files importing the class
"What depends on this file? What does it import?"
1. fmm_dependency_graph(file: "src/foo.ts")
- local_deps: intra-project imports, resolved to actual paths
- external: third-party packages
- downstream: files that import this file (complete and reliable)
2. Transitive: fmm_dependency_graph(file: "...", depth: 3) or depth: -1 for full closure
3. Reverse only: fmm_dependency_graph(file: "...", reverse: true, transitive: true)
"Evaluate or audit this codebase"
1. fmm_list_files(group_by: "subdir") → full topology, LOC per bucket
2. fmm_list_files(sort_by: "loc", limit: 20) → largest files = complexity anchors
3. fmm_list_files(sort_by: "downstream", limit: 15) → highest blast-radius files
4. fmm_file_outline on key files → structure without reading
5. fmm_search(imports: "package") → cross-cutting architecture patterns
A comprehensive evaluation in 5-8 calls and under 5k tokens — faster and more complete than reading files.
Parameter Reference
Auto-generated from tools.toml — all options for each tool.
fmm_lookup_export
Instant O(1) symbol-to-file lookup. Find where a function, class, type, or variable is defined. Returns the file path plus metadata (exports, imports, dependencies, LOC). Use before Grep.
| Parameter | Type | Required | Description |
|---|
name | string | yes | Exact export name to find (function, class, struct, type, trait, variable) |
fmm_list_exports
Search or list exported symbols across the codebase. Use 'pattern' for fuzzy discovery (e.g. 'auth' matches validateAuth, authMiddleware). Patterns with regex metacharacters (^, $, [, (, \, ., *, +, ?, {) are compiled as regex. Use 'directory' to scope results to a path prefix (e.g. 'packages/core/'). Use 'file' to list a specific file's exports. Use filter='source' to exclude test files, or filter='tests' to show only test exports. Default limit: 200. Use offset to page through large result sets.
| Parameter | Type | Required | Description |
|---|
pattern | string | no | Pattern to match against export names. Plain strings use case-insensitive substring match (e.g. 'auth' finds validate... |
file | string | no | File path — returns all exports from this specific file |
directory | string | no | Path prefix to scope results (e.g. 'packages/core/'). Only exports from files under this directory are returned. |
filter | enum: all | source | tests | no | File type filter. 'all' (default): no filtering. 'source': exclude test files using the same path and filename conven... |
limit | integer | no | Maximum number of results to return (default: 200). Increase for broader listings. |
offset | integer | no | Number of results to skip before returning (default: 0). Use for pagination: offset=200 returns results 201–400. |
fmm_dependency_graph
Get a file's dependency graph: upstream dependencies (what it imports) and downstream dependents (what would break if it changes). Use for impact analysis and blast radius. Add depth>1 for transitive traversal; depth=-1 for full closure. Set reverse=true to return only reverse dependents, and transitive=true for the full reverse-dependent closure with a count. Use filter='source' to exclude test files from downstream, or filter='tests' to see only test coverage.
| Parameter | Type | Required | Description |
|---|
file | string | yes | File path to analyze — returns all upstream dependencies and downstream dependents |
depth | integer | no | Traversal depth (default: 1 = direct deps only). depth=2 adds transitive deps. depth=-1 computes the full transitive ... |
filter | enum: all | source | tests | no | Filter upstream and downstream lists by file type. 'all' (default): no filtering. 'source': exclude test files (*.spe... |
reverse | boolean | no | When true, return reverse dependents only instead of the combined upstream/downstream graph. Use with transitive=true... |
transitive | boolean | no | Return the full transitive closure. For reverse=true, this returns all transitive reverse dependents with reverse_dep... |
fmm_dependency_cycles
Report strongly connected dependency cycles over the internal graph. Defaults to runtime edges, excluding TypeScript type-only imports and module-hierarchy facade edges. Use edge_mode='all' to include type-only edges. Set include_mod_hierarchy=true to restore facade edges. Set explain=true to include the edges that keep each SCC connected. Optional file scopes output to cycles containing that file. filter='source' excludes tests, filter='tests' shows only test files.
| Parameter | Type | Required | Description |
|---|
file | string | no | Optional file path to scope cycle reports to SCCs containing that file. |
filter | enum: all | source | tests | no | Filter the cycle graph by file type before SCC detection. 'all' (default): no filtering. 'source': exclude test files... |
edge_mode | enum: runtime | all | no | Edge mode for cycle reporting. 'runtime' (default) excludes TypeScript type-only edges. 'all' includes type-only edges. |
include_mod_hierarchy | boolean | no | When true, include module-hierarchy facade edges. Default false hides barrel, init, and Rust module facade cycles. |
explain | boolean | no | When true, include the resolved edges that keep each reported strongly connected component connected, with edge kind. |
fmm_read_symbol
Read the source code for a specific exported symbol or uniquely named non-exported top-level function. Returns the exact lines where the function/class/type/member is defined, without reading the entire file. Use ClassName.member notation to read a specific public/private method or indexed field: fmm_read_symbol(name: "Injector.loadInstance"). Bare Rust module names return the mod foo; declaration with kind: module; they do not follow into foo.rs or foo/mod.rs. Use path/to/file:helperFunction notation to disambiguate duplicate exports or duplicate non-exported top-level functions. Private methods discovered via fmm_file_outline(include_private: true) are accessible using the same dotted notation. For large symbols (>10KB) use truncate: false to get the full source. Use line_numbers: true to prepend absolute line numbers to each source line.
| Parameter | Type | Required | Description |
|---|
name | string | yes | Exact symbol name to read (function, class, struct, type, trait), ClassName.method for a specific public or private m... |
truncate | boolean | no | Whether to apply the 10KB response cap (default: true). Set to false to return the full source for large symbols that... |
line_numbers | boolean | no | When true, prepend absolute line numbers (right-aligned) to each source line. Useful when referencing specific lines ... |
fmm_file_outline
Get a spatial outline of a file: symbols with line ranges, size, signature, visibility, and kind when populated. Like a table-of-contents for the file. Use to understand file structure before reading specific symbols. Set include_private: true to add on-demand private members not already indexed plus non-exported top-level declarations inline in symbols. Stale queried files include one inline freshness annotation. Supported: TypeScript, JavaScript, Python, Rust. On-demand tree-sitter parse for private additions; no index rebuild needed.
| Parameter | Type | Required | Description |
|---|
file | string | yes | File path to outline — returns symbols with line ranges, sizes, signatures, visibility, and kind when populated |
include_private | boolean | no | When true, add on-demand private members not already indexed plus non-exported top-level declarations inline in symbo... |
truncate | boolean | no | When false, bypasses the 10KB MCP response cap and returns the full outline response. Default: true. |
fmm_search
Universal codebase search. Use 'term' for smart search across codebase-defined exports, file paths, import package names, and named-import call sites. The NAMED IMPORTS section shows files that import the term by name from any package — e.g. term: createServerFn finds every file that imports createServerFn from @tanstack/react-start. Use structured filters (export, imports, depends_on, LOC) for precise queries. Combine 'term' with filters to narrow results with AND semantics. Note: depends_on uses transitive matching (full import chain), not direct-only. For direct importers only, use fmm_dependency_graph with depth=1.
| Parameter | Type | Required | Description |
|---|
term | string | no | Search codebase-defined exports (exact then fuzzy), file paths, external import package names, and named-import call ... |
export | string | no | Find files exporting this symbol (exact match, then case-insensitive substring fallback) |
imports | string | no | Find all files that import an external package (npm, pip, crate, etc.) — substring match on the import name. For lo... |
depends_on | string | no | Find all files that transitively depend on this local path (full import chain, not just direct importers) — use for... |
min_loc | integer | no | Minimum lines of code — find files larger than this |
max_loc | integer | no | Maximum lines of code — find files smaller than this |
limit | integer | no | Maximum number of fuzzy export results (default: 50). Increase for broader searches. |
fmm_list_files
List all indexed files under a directory prefix. The first tool to reach for when exploring an unknown module or package. Returns file paths with LOC, export count, and downstream dependent count. Default sort: LOC descending (largest files first). sort_by options: loc (default), name/path, exports, downstream (blast-radius sort), modified (most recently changed first). Default limit: 200. Use offset to page through large directories.
| Parameter | Type | Required | Description |
|---|
directory | string | no | Directory prefix to filter files (e.g. 'src/cli/' or 'libs/agno/models'). Omit to list all indexed files. |
pattern | string | no | Shell-style glob pattern to filter by filename within the directory (e.g. '.py', 'test', 'file?.rs', '[ab].ts'). ... |
limit | integer | no | Maximum number of files to return (default: 200). Increase for broader listings. |
offset | integer | no | Number of files to skip before returning results (default: 0). Use for pagination: offset=200 returns files 201–400. |
sort_by | enum: name | path | loc | exports | downstream | modified | no | Sort field. 'loc' (default): lines of code descending. 'name' or 'path': alphabetical file path. 'exports': export co... |
order | enum: asc | desc | no | Sort order. Defaults: 'name' → asc, 'loc'/'exports'/'downstream' → desc. Explicit 'asc'/'desc' overrides the defa... |
group_by | enum: subdir | no | Collapse files into directory buckets. 'subdir': group by immediate subdirectory, showing file count and total LOC pe... |
filter | enum: all | source | tests | no | File type filter. 'all' (default): no filtering. 'source': exclude test files. 'tests': return only files classified ... |
fmm_glossary
Symbol-level impact analysis. Given a symbol name or pattern, returns all matching definitions and exactly which files import each one. Three-layer precision: bare names return named-import filtered callers (Layer 2, default); dotted method names (e.g. 'Injector.loadInstance') add call-site precision; dotted patterns use the same case-insensitive substring matching, so 'Type.foo' can match both 'Type.foo' and 'Type.foo_bar'. Set exact=true to match only the exact full export name. Dotted field names report kind: field without implying method callers; precision: 'call-site' adds Layer 3 tree-sitter verification to remove dead imports and annotate re-exports. Use before renaming or changing a signature.
| Parameter | Type | Required | Description |
|---|
pattern | string | yes | Required. Case-insensitive substring filter on export name unless exact=true. Bare name (e.g. 'loadInstance') returns... |
limit | integer | no | Max entries returned (default 10, hard cap at 50). Use a specific pattern to stay under the default. |
mode | enum: source | tests | all | no | source (default): excludes test symbols and test files. tests: only test exports. all: unfiltered. |
precision | enum: named | call-site | no | named (default): Layer 2 only, fast index lookup with no file reads. call-site: adds Layer 3 tree-sitter verification... |
exact | boolean | no | When true, match only the exact full export name instead of case-insensitive substring matching. Useful for symbols w... |
truncate | boolean | no | Whether to apply the 10KB response cap (default: true). Set to false to return the full glossary for symbols with man... |
fmm_find_similar
Find existing functions or types structurally similar to a probe, before writing new code, to prevent duplication. Probe by an existing symbol name, or supply a signature + kind for a symbol you are about to write. Deterministic: ranks by name-token overlap, signature shape, declaration kind, and shared-dependency neighborhood — no embeddings. Results are threshold-gated, so a probe with one real match returns one row. Use before authoring a new symbol to reuse instead of duplicate.
| Parameter | Type | Required | Description |
|---|
name | string | yes | Probe symbol name. In by-symbol mode this is an existing symbol whose signature and kind seed the probe; in pre-write... |
signature | string | no | Explicit signature for the symbol you are about to write, e.g. '(Path) -> Config'. Overrides the looked-up signature ... |
kind | string | no | Declaration kind to match: fn, method, struct, trait, enum, type, const. |
directory | string | no | Path prefix to scope candidates (e.g. 'crates/fmm-core/'). |
limit | integer | no | Maximum matches to return (default: 10). Results are threshold-gated, so fewer may return. |
include_tests | boolean | no | Include test functions and modules as candidates (default: false). |
fmm_dupe_clusters
Find repo wide structural duplicate candidate clusters by reusing the find similar ranker in batch mode. Deterministic: blocks candidates by declaration kind, rare name tokens, and signature shape, scores unique unordered pairs with the existing structural scorer, then union-finds accepted pairs into clusters.
| Parameter | Type | Required | Description |
|---|
directory | string | no | Path prefix to scope candidates (e.g. 'crates/fmm-core/'). |
kind | array | no | Declaration kinds to include. Repeat --kind in the CLI. Typical values: fn, method, struct, trait, enum, type, const. |
min_score | number | no | Minimum pair score required to join a cluster. Defaults to 0.90, calibrated separately from fmm similar for repo-wide... |
limit | integer | no | Maximum clusters to return (default: 10). |
include_tests | boolean | no | Include test functions and modules as candidates (default: false). |
Rules
- Never use
Read to understand structure — use fmm_file_outline
- Never use
Grep to find a symbol — use fmm_lookup_export or fmm_glossary
- Never use
Glob to explore a directory — use fmm_list_files
fmm_list_files first — orient before navigating
fmm_file_outline before reading — see the shape, then decide what to read
fmm_read_symbol("ClassName.method") — never read a full class to find one method
- Dotted pattern for rename safety —
fmm_glossary("ClassName.method") for call-site precision
- Read source only when editing — MCP tools tell you everything you need for navigation
- Trust the index — it updates automatically after every file write
CLI Fallback
If MCP tools are unavailable, use the CLI directly:
fmm lookup createPipeline
fmm read createPipeline
fmm deps src/core/pipeline.ts
fmm outline src/core/pipeline.ts
Line ranges from fmm outline enable surgical reads: Read(file, offset=10, limit=36).