fast_search_files
Search files by name or content using regex patterns, with auto-chunking, context lines, and binary file support for efficient file discovery.
Instructions
Searches for files (by name/content) - supports auto-chunking, regex, context, and line numbers
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Directory to search in | |
| pattern | Yes | Search pattern (regex supported) | |
| content_search | No | Search file content | |
| case_sensitive | No | Case-sensitive search | |
| max_results | No | Maximum number of results | |
| context_lines | No | Number of context lines around a match | |
| file_pattern | No | Filename filter pattern (e.g., *.js, *.txt) | |
| include_binary | No | Include binary files in search | |
| continuation_token | No | Continuation token from a previous call | |
| auto_chunk | No | Enable auto-chunking |
Implementation Reference
- api/server.ts:178-192 (registration)Registration of the 'fast_search_files' tool in the MCP_TOOLS array, including name, description, and input schema.{ name: 'fast_search_files', description: '파일을 검색합니다 (이름/내용)', inputSchema: { type: 'object', properties: { path: { type: 'string', description: '검색할 디렉토리' }, pattern: { type: 'string', description: '검색 패턴' }, content_search: { type: 'boolean', description: '파일 내용 검색', default: false }, case_sensitive: { type: 'boolean', description: '대소문자 구분', default: false }, max_results: { type: 'number', description: '최대 결과 수', default: 100 } }, required: ['path', 'pattern'] } },
- api/server.ts:338-340 (registration)Dispatch case in the main tools/call switch statement that invokes the handleSearchFiles function.case 'fast_search_files': result = await handleSearchFiles(args); break;
- api/server.ts:676-764 (handler)The complete handler function implementing the fast_search_files tool. Performs recursive directory search for files matching pattern in name or content (if enabled), with limits and exclusions.async function handleSearchFiles(args: any) { const { path: searchPath, pattern, content_search = false, case_sensitive = false, max_results = 100 } = args; const safePath_resolved = safePath(searchPath); const maxResults = Math.min(max_results, 200); const results: any[] = []; const searchPattern = case_sensitive ? pattern : pattern.toLowerCase(); async function searchDirectory(dirPath: string) { if (results.length >= maxResults) return; try { const entries = await fs.readdir(dirPath, { withFileTypes: true }); for (const entry of entries) { if (results.length >= maxResults) break; const fullPath = path.join(dirPath, entry.name); if (shouldExcludePath(fullPath)) continue; if (entry.isFile()) { const searchName = case_sensitive ? entry.name : entry.name.toLowerCase(); let matched = false; let matchType = ''; if (searchName.includes(searchPattern)) { matched = true; matchType = 'filename'; } if (!matched && content_search) { try { const stats = await fs.stat(fullPath); if (stats.size < 10 * 1024 * 1024) { // 10MB 제한 const content = await fs.readFile(fullPath, 'utf-8'); const searchContent = case_sensitive ? content : content.toLowerCase(); if (searchContent.includes(searchPattern)) { matched = true; matchType = 'content'; } } } catch { // 바이너리 파일 등 읽기 실패 무시 } } if (matched) { const stats = await fs.stat(fullPath); results.push({ path: fullPath, name: entry.name, match_type: matchType, size: stats.size, size_readable: formatSize(stats.size), modified: stats.mtime.toISOString(), extension: path.extname(fullPath) }); } } else if (entry.isDirectory()) { await searchDirectory(fullPath); } } } catch { // 권한 없는 디렉토리 등 무시 } } await searchDirectory(safePath_resolved); return { results: results, total_found: results.length, search_pattern: pattern, search_path: safePath_resolved, content_search: content_search, case_sensitive: case_sensitive, max_results_reached: results.length >= maxResults, timestamp: new Date().toISOString() }; }