| name | search |
| description | Master fs_search for blazing-fast code search (10-100x faster than grep). WHEN: User mentions "search", "find", "grep", "locate code/files", needs to discover patterns, asks "where is", "which files contain". WHEN NOT: Reading specific known file paths (use fs_read_file), listing directory contents (use fs_list_directory). |
| version | 0.1.0 |
fs_search Mastery Guide
Core Concept
mcp__plugin_kg_kodegen__fs_search is built on ripgrep - the fastest code search tool available (10-100x faster than grep). It automatically respects .gitignore, supports regex and literal search, handles multiline patterns, and can run searches in the background.
Two Independent Controls
1. WHERE to Search (search_in)
"content" (default): Search inside file contents
- Use for: Finding function definitions, error messages, TODO comments
- Example:
{search_in: "content", pattern: "fn getUserData"}
"filenames": Search file names/paths only
- Use for: Finding specific files, locating by extension
- Example:
{search_in: "filenames", pattern: "package.json"}
2. WHAT to Return (return_only)
"matches" (default): Full details with line numbers and matched content
- Use when: You need to see the actual code/text
- Returns: File path, line number, matched line
"paths": Just unique file paths (like rg -l)
- Use when: You only need to know WHICH files contain the pattern
- Returns: List of file paths only
"counts": Match counts per file (like rg -c)
- Use when: You need statistics (e.g., "how many TODOs per file")
- Returns: File path and count
These combine independently: any search_in works with any return_only.
Decision Tree
Finding Specific Files
User: "find package.json" or "locate Cargo.toml" or "which files are *.rs"
Use:
{
"search_in": "filenames",
"pattern": "package.json"
}
{
"search_in": "filenames",
"pattern": "\\.rs$"
}
Finding Code Patterns
User: "where is getUserData function" or "find TODO comments"
Use:
{
"search_in": "content",
"pattern": "fn getUserData"
}
{
"search_in": "content",
"pattern": "TODO"
}
Getting File Lists Only
User: "which files have errors" or "list files with console.log"
Use:
{
"search_in": "content",
"pattern": "error",
"return_only": "paths"
}
{
"search_in": "content",
"pattern": "console\\.log",
"return_only": "paths"
}
Counting Matches
User: "how many TODOs per file" or "count import statements"
Use:
{
"search_in": "content",
"pattern": "TODO",
"return_only": "counts"
}
{
"search_in": "content",
"pattern": "^import",
"return_only": "counts"
}
Critical Parameters
literal_search (default: false)
Set to true when searching for code with special regex characters:
// ❌ WRONG - regex interprets . and () as special chars
{"pattern": "toast.error('test')"}
// ✅ CORRECT - literal string match
{"pattern": "toast.error('test')", "literal_search": true}
// ❌ WRONG - brackets are regex character class
{"pattern": "array[0]"}
// ✅ CORRECT - literal bracket match
{"pattern": "array[0]", "literal_search": true}
Rule: If searching for actual code symbols like ., (, ), [, ], {, }, use literal_search: true.
boundary_mode
Controls pattern matching boundaries:
null(default): Match anywhere (substring)"test"matches intesting,attest,test()
"word": Match whole words only (uses\banchors)"test"matchestest()but NOTtestingorattest
"line": Match complete lines only (uses^$anchors)- Pattern must match the entire line
// Match whole word "test" (not "testing")
{
"pattern": "test",
"boundary_mode": "word"
}
case_mode (default: "sensitive")
"sensitive": Exact case matching"insensitive": Case-insensitive search"smart": Insensitive if pattern is all lowercase, sensitive otherwise
// Case-insensitive search
{
"pattern": "error",
"case_mode": "insensitive"
}
// Matches: error, Error, ERROR, ErRoR
file_pattern
Filter files by glob pattern:
// Only JavaScript and TypeScript
{"file_pattern": "*.{js,ts}"}
// Only Rust files
{"file_pattern": "*.rs"}
// Only Python test files
{"file_pattern": "test_*.py"}
type / type_not
Use ripgrep's built-in file type definitions:
// Only Rust and Python files
{"type": ["rust", "python"]}
// Exclude tests and JSON
{"type_not": ["test", "json"]}
Common types: rust, python, javascript, typescript, json, markdown, yaml, toml
pattern_mode (Filename Search Only)
IMPORTANT: This parameter ONLY works with search_in: "filenames". It has NO effect on content searches.
Control how filename patterns are interpreted:
// Auto-detection (default)
{
"search_in": "filenames",
"pattern": "*.md"
}
// → Auto-detected as Glob, matches: README.md, NOTES.md
// Force regex interpretation
{
"search_in": "filenames",
"pattern": "test.*",
"pattern_mode": "regex"
}
// → Regex mode, matches: test.js, test123.md, testing.txt
// Force substring (literal match)
{
"search_in": "filenames",
"pattern": "*.md",
"pattern_mode": "substring"
}
// → Substring mode, matches ONLY files literally named "*.md"
// Force glob interpretation
{
"search_in": "filenames",
"pattern": "lib",
"pattern_mode": "glob"
}
// → Glob mode, uses shell-style matching
Auto-Detection Priority: Regex > Glob > Substring
Detection Rules:
- Regex detected when pattern contains:
^,$,\.,\d,\w,.*,.+,|,[...]+,{n,m} - Glob detected when pattern contains:
*,?,**,{a,b},[abc](without regex markers) - Substring (default): No special characters detected
Common Use Cases:
// Find markdown files (auto-detected as glob)
{"search_in": "filenames", "pattern": "*.md"}
// → pattern_type: "glob"
// Find files starting with "test" (auto-detected as regex)
{"search_in": "filenames", "pattern": "^test"}
// → pattern_type: "regex"
// Find files containing "config" (auto-detected as substring)
{"search_in": "filenames", "pattern": "config"}
// → pattern_type: "substring"
// Override: match literal "*.md" filename
{"search_in": "filenames", "pattern": "*.md", "pattern_mode": "substring"}
// → pattern_type: "substring", matches file literally named "*.md"
Output Field: pattern_type
Every filename search response includes pattern_type showing how the pattern was interpreted:
{
"pattern": "*.rs",
"pattern_type": "glob",
"search_in": "filenames",
"results": [...]
}
This helps you understand:
- Whether auto-detection worked as expected
- Why certain files matched or didn't match
- If you need to override with
pattern_mode
Performance Optimization
For Large Codebases
Combine these for 10-100x speedup:
{
"path": "/large-monorepo",
"pattern": "config",
"max_depth": 3,
"max_filesize": 1048576,
"type_not": ["json", "lock"]
}
Why this works:
max_depth: 3-4avoids deep dependency trees (node_modules, vendor, target)max_filesize: 1048576(1MB) skips huge generated files (minified bundles, lock files)typeorfile_patternreduces the number of files to search
Performance gains:
max_depthalone: 10-25x fastermax_filesizealone: 10-30x faster- Combined: 100x+ faster on large monorepos
Background Execution
For searches that might take a while:
{
"path": "/huge-repo",
"pattern": "deprecated",
"await_completion_ms": 10000,
"search": 0
}
Behavior:
- Waits up to 10 seconds for results
- If timeout occurs: returns current partial results, search continues in background
- Check progress later:
{action: "READ", search: 0}
Multiline Patterns
Enable with multiline: true to search across lines:
{
"pattern": "struct Config \\{[\\s\\S]*?version",
"multiline": true
}
Matches:
struct Config {
port: u16,
version: String,
}
Use cases:
- Finding struct/class definitions with specific fields
- Matching function signatures across multiple lines
- Finding multi-line comments or documentation
Advanced: only_matching
Extract specific parts instead of whole lines:
{
"pattern": "https?://[^\\s]+",
"only_matching": true
}
Returns just the URLs, not the entire lines containing them.
Perfect for extracting:
- URLs from markdown or code
- Version numbers from package files
- Email addresses from documentation
- Function names from code
Common Search Patterns
Find Function Definitions (Rust)
{
"pattern": "fn \\w+\\(",
"search_in": "content",
"file_pattern": "*.rs"
}
Find TODO/FIXME Comments
{
"pattern": "(TODO|FIXME)",
"search_in": "content",
"return_only": "paths"
}
Find Files by Extension
{
"pattern": "\\.tsx?$",
"search_in": "filenames"
}
Count Imports Per File
{
"pattern": "^import",
"return_only": "counts"
}
Find Exact Code (with special chars)
{
"pattern": "if (user?.role === 'admin')",
"literal_search": true
}
Whole Word Search
{
"pattern": "test",
"boundary_mode": "word"
}
Find Error Handling Patterns
{
"pattern": "(Error|panic!|unwrap|expect)",
"file_pattern": "*.rs"
}
Find API Routes
{
"pattern": "(GET|POST|PUT|DELETE).*\\/api\\/",
"search_in": "content"
}
When to Use What
| Goal | Tool | Why |
|---|---|---|
| Find code pattern | fs_search (content) | Fast, regex support, respects .gitignore |
| Find specific file | fs_search (filenames) | Faster than glob when path unknown |
| List directory | fs_list_directory | Simple, one-level listing |
| Read known file | fs_read_file | Direct access, supports offset/length |
| Search + read | fs_search → fs_read_multiple_files | Parallel reads after discovery |
Troubleshooting
No Results Found
- Check regex special characters → use
literal_search: true - Check case sensitivity → try
case_mode: "insensitive" - Check file filtering → verify
file_patternortypeisn't too restrictive - Check .gitignore → use
no_ignore: trueto override
Search Too Slow
- Add
max_depth: 3to limit directory traversal - Add
max_filesize: 1048576to skip huge files - Use
file_patternortypeto filter file types - Consider background execution:
await_completion_ms: 0
Pattern Not Matching
- Escape regex special chars:
. * + ? [ ] { } ( ) | ^ $ - Or use literal search:
literal_search: true - For multiline patterns: set
multiline: true - Check boundaries: adjust
boundary_modeif needed
Pattern Not Matching Expected Files
- Check pattern_type in response → See how pattern was interpreted
- Override auto-detection → Use
pattern_mode: "regex","glob", or"substring" - Remember: Only works for
search_in: "filenames", not content search - Literal characters: Use
pattern_mode: "substring"orliteral_search: true
Quick Reference
// Basic content search
{
"path": "/project",
"pattern": "getUserData"
}
// Find files by name
{
"path": "/project",
"search_in": "filenames",
"pattern": "config"
}
// Get file list only
{
"path": "/project",
"pattern": "TODO",
"return_only": "paths"
}
// Literal search (exact match)
{
"path": "/project",
"pattern": "array[0]",
"literal_search": true
}
// Performance optimized
{
"path": "/project",
"pattern": "error",
"max_depth": 3,
"max_filesize": 1048576,
"type": ["rust"]
}
Remember
- Default is regex: Escape special characters or use
literal_search: true - Default searches content: Use
search_in: "filenames"for file names - Default shows matches: Use
return_only: "paths"for file lists only - Respects .gitignore: Use
no_ignore: trueto override - 10-100x faster than grep: Your primary search tool
- Background execution available: For long-running searches