Skip to content

Search Operations

In v4.0.0, all search functionality is unified into a single search_files tool. It replaces the four separate v3 tools (smart_search, advanced_text_search, mcp_search, count_occurrences) and automatically routes to the optimal search engine based on the parameters you provide.

For search-and-replace operations, use edit_file with mode:"search_replace" — see the Search and Replace section below.

v3 Toolv4 Equivalent
smart_searchsearch_files({ path, pattern })
advanced_text_searchsearch_files({ path, pattern, case_sensitive: true })
mcp_searchsearch_files({ path, pattern })
count_occurrencessearch_files({ path, pattern, count_only: true })
search_and_replaceedit_file({ path, mode: "search_replace", pattern, replacement })

ParameterRequiredTypeDescription
pathYesstringBase directory or file path (WSL or Windows format)
patternYesstringRegex or literal search pattern
include_contentNobooleanSearch inside file contents (default: false — searches file names)
file_typesNostringComma-separated file extensions to filter (e.g., .go,.ts,.js)
case_sensitiveNobooleanCase-sensitive matching (default: false)
whole_wordNobooleanMatch whole words only (default: false)
include_contextNobooleanInclude surrounding lines around each match (default: false)
context_linesNonumberNumber of context lines to include (default: 3)
count_onlyNobooleanReturn only the count of matches, not the matches themselves (default: false)
return_linesNostringWhen count_only is true, also return line numbers of matches ("true" or "false")

The search_files tool automatically selects the best search engine based on the parameters you provide. You do not need to think about which engine to use — just pass the parameters you need.

Parameters ProvidedEngine SelectedBehavior
path + pattern onlyFast Smart SearchFastest path for simple file/content search
case_sensitive, whole_word, or include_contextAdvanced Text SearchFull-featured regex search with context
count_only: trueOccurrence CounterReturns match counts per file without full results

Find files matching a pattern by name:

search_files({ path: "C:\\project", pattern: "main.go" })

Response:

Found 3 matches:
C:\project\main.go
C:\project\cmd\main.go
C:\project\tests\main.go

Search inside file contents by enabling include_content:

search_files({
path: "C:\\project\\src",
pattern: "TODO",
include_content: true,
file_types: ".go,.ts"
})

Response:

Found 8 matches in 4 files:
src/handler.go:23: // TODO: add error handling
src/handler.go:45: // TODO: refactor this
src/config.ts:12: // TODO: validate inputs
...

When you need case sensitivity, whole word matching, or surrounding context lines, the tool auto-routes to the advanced text search engine:

search_files({
path: ".",
pattern: "func.*Error",
case_sensitive: true,
include_context: true,
context_lines: 2
})

Response:

Found 5 matches in 3 files:
--- core/engine.go:45 ---
43: }
44:
45: func handleError(ctx context.Context, err error) {
46: if err == nil {
47: return
--- core/errors.go:12 ---
...

Avoid partial matches (e.g., matching count without matching counter or accounting):

search_files({
path: "src/",
pattern: "count",
whole_word: true,
include_content: true
})

Get a quick count of how many times a pattern appears without retrieving full results:

search_files({
path: "main.go",
pattern: "fmt\\.Sprintf",
count_only: true
})

Response:

Count: 12 occurrences in main.go

When you need to know where each occurrence is but do not need context:

search_files({
path: "main.go",
pattern: "TODO",
count_only: true,
return_lines: "true"
})

Response:

Count: 5 occurrences in main.go
Lines: 23, 45, 78, 112, 156

Restrict search to specific file extensions:

search_files({
path: ".",
pattern: "interface\\{\\}",
include_content: true,
file_types: ".go"
})

Search-and-replace across multiple files is handled by edit_file with mode:"search_replace". This was the search_and_replace tool in v3.

edit_file({
path: "src/",
mode: "search_replace",
pattern: "oldFunctionName",
replacement: "newFunctionName"
})

This recursively searches all files under src/ and replaces every occurrence of oldFunctionName with newFunctionName.

Section titled “Recommended Workflow: Search First, Then Replace”

For safety, search before replacing to understand the scope:

// Step 1: Count how many files and occurrences are affected
search_files({
path: "src/",
pattern: "oldFunctionName",
include_content: true,
count_only: true
})
// Step 2: Preview the edit risk
analyze_operation({
operation: "edit",
path: "src/specific-file.go",
old_text: "oldFunctionName",
new_text: "newFunctionName"
})
// Step 3: Apply the replacement
edit_file({
path: "src/",
mode: "search_replace",
pattern: "oldFunctionName",
replacement: "newFunctionName"
})

For advanced pattern-based transformations with capture groups, use edit_file with mode:"regex":

edit_file({
path: "handler.go",
mode: "regex",
patterns_json: JSON.stringify([
{
pattern: "fmt\\.Errorf\\(\"(\\w+): %v\", err\\)",
replacement: "fmt.Errorf(\"$1: %w\", err)",
limit: -1
}
]),
dry_run: true
})

See the Core Tools API Reference for complete edit_file parameter documentation.


Searching before reading is the most token-efficient workflow. Instead of reading an entire 3000-line file (approximately 75,000 tokens), search for the specific section first:

// Step 1: Find the location (~500 tokens)
search_files({ path: "large-file.go", pattern: "targetFunction", include_content: true })
// Step 2: Read only the relevant lines (~400 tokens)
read_file({ path: "large-file.go", start_line: 145, end_line: 160 })
// Step 3: Apply the edit (~300 tokens)
edit_file({ path: "large-file.go", old_text: "old code", new_text: "new code" })

Total: approximately 1,200 tokens instead of 150,000 tokens for a full read-modify-write cycle.

Search results benefit from the 3-tier caching system. Directory listings and file metadata are cached, so repeated searches in the same directory are faster. The cache hit rate typically reaches 85-95% during a session and 98%+ after warmup.

By default, search returns up to 1,000 results. This can be configured with --max-search-results at server startup. For very large codebases, combine file_types filtering with specific path scoping to keep results manageable.


For multi-step workflows involving search, use the pipeline system via batch_operations with pipeline_json. The pipeline search action feeds its results directly into subsequent steps:

batch_operations({
pipeline_json: JSON.stringify({
name: "find-and-fix-todos",
stop_on_error: true,
create_backup: true,
steps: [
{
id: "find",
action: "search",
params: { path: "./src", pattern: "TODO", file_types: [".go"] }
},
{
id: "count",
action: "count_occurrences",
input_from: "find",
params: { pattern: "TODO" }
},
{
id: "fix",
action: "edit",
input_from: "find",
condition: { type: "count_gt", step_ref: "count", value: "0" },
params: { old_text: "TODO", new_text: "DONE" }
}
]
})
})

This executes all three steps in a single MCP call, reducing token overhead by 4-5x compared to individual calls. See Pipeline Transformation System for details.



Last updated: March 2026 Version: 4.0.0