docs/tools/search-files.mdx
Search files in the workspace. One tool answers two questions: what is written in the files (regex search inside contents) and where is that file (match by file name), selected with the target parameter.
The Agent prefers this tool over running grep / find in the terminal: it returns structured results, skips dependency directories automatically, and works the same on Windows.
No extra dependencies, available by default. If ripgrep (rg) is installed it is used automatically for faster searches.
| Parameter | Type | Required | Description |
|---|---|---|---|
pattern | string | Yes | A regex when target=content; a file-name glob such as *.py when target=files |
target | string | No | content searches inside files (default); files finds files by name |
path | string | No | Where to start, defaults to the workspace root; relative paths are based on the workspace |
file_glob | string | No | Limit which files are searched, e.g. *.py, *.{ts,tsx}; defaults to all (target=content only) |
output_mode | string | No | content returns matching lines (default), files returns only file paths, count returns matches per file |
ignore_case | boolean | No | Case-insensitive match, default false |
no_ignore | boolean | No | Search content that is excluded by default, default false; see "Excluded directories" below |
max_results | integer | No | Maximum results to return, default 50, capped at 500 |
The default mode. Returns the file, line number and line text for each match:
{
"matches": [
{ "file": "channel/wechat_channel.py", "line": 42, "match": "def handle_message(self, msg):" }
],
"match_count": 1
}
When you only need to know which files matched, output_mode=files cuts the output down substantially.
With target=files, pattern is matched against the file name, and results are ordered most-recently-modified first - when several files match, the one just worked on is usually the one wanted:
{
"files": ["websites/ai-news-report.md", "archive/ai-news-report.md"],
"match_count": 2
}
A bare word (no * or ?) is treated as a contains-match, so ai-news is equivalent to *ai-news* and you do not need to recall the full name.
These directories are always skipped so results are not drowned out by dependencies and build output:
.git, node_modules, __pycache__, .venv, venv, .mypy_cache, .pytest_cache, dist, build, .next, target, vendor, .tox, coverage, .idea.
In addition, files ignored by .gitignore are skipped when ripgrep is installed.
When you do need to search them (inspecting third-party sources, for example), no_ignore=true lifts both kinds of exclusion at once. If a search returns nothing and such a directory happened to be skipped, the result carries a notice naming which ones.