find_files
Search for files matching a specific pattern within allowed directories and display their paths. Exclude specified directories to refine results.
Instructions
在允許的目錄中找尋所有符合檔名模式的檔案並標示其檔案路徑
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| excludeDirs | No | ||
| filePattern | Yes |
Implementation Reference
- main.ts:479-509 (registration)Registration of the 'find_files' tool, including input schema (filePattern: string, excludeDirs?: string[]), description, and inline async handler that delegates to FileSearchTool for directory retrieval and file searching.server.tool("find_files", "在允許的目錄中找尋所有符合檔名模式的檔案並標示其檔案路徑", { filePattern: z.string(), excludeDirs: z.array(z.string()).optional() }, async ({ filePattern, excludeDirs = ['node_modules', '.git', 'dist', 'bin', 'obj'] }) => { try { // 獲取允許的目錄列表 const allowedDirs = await FileSearchTool.getAllowedDirectories(); // 檢查是否有允許的目錄 if (allowedDirs.length === 0) { return { content: [{ type: "text", text: '錯誤:未提供允許的目錄參數。請在啟動時指定至少一個允許的目錄。' }] }; } // 在允許的目錄中搜尋檔案 const result = await FileSearchTool.searchFilesInAllowedDirs(allowedDirs, filePattern, excludeDirs); return { content: [{ type: "text", text: result }] }; } catch (error) { return { content: [{ type: "text", text: `搜尋檔案失敗: ${error instanceof Error ? error.message : "未知錯誤"}` }] }; } } );
- main.ts:485-508 (handler)The execution handler for the 'find_files' tool: validates inputs, retrieves allowed directories, performs search via FileSearchTool, and returns formatted text response in MCP format.async ({ filePattern, excludeDirs = ['node_modules', '.git', 'dist', 'bin', 'obj'] }) => { try { // 獲取允許的目錄列表 const allowedDirs = await FileSearchTool.getAllowedDirectories(); // 檢查是否有允許的目錄 if (allowedDirs.length === 0) { return { content: [{ type: "text", text: '錯誤:未提供允許的目錄參數。請在啟動時指定至少一個允許的目錄。' }] }; } // 在允許的目錄中搜尋檔案 const result = await FileSearchTool.searchFilesInAllowedDirs(allowedDirs, filePattern, excludeDirs); return { content: [{ type: "text", text: result }] }; } catch (error) { return { content: [{ type: "text", text: `搜尋檔案失敗: ${error instanceof Error ? error.message : "未知錯誤"}` }] }; } }
- main.ts:482-484 (schema)Zod input schema defining parameters: filePattern (required string for filename glob), excludeDirs (optional array of directory names to skip).filePattern: z.string(), excludeDirs: z.array(z.string()).optional() },
- tools/fileSearchTool.ts:71-110 (helper)Key helper method invoked by the tool handler; searches for files matching filePattern across all allowedDirs, excludes specified dirs, collects paths, formats numbered list result string.public static async searchFilesInAllowedDirs( allowedDirs: string[], filePattern: string, excludeDirs: string[] = ['node_modules', '.git', 'dist', 'bin', 'obj'] ): Promise<string> { try { if (!filePattern) { return '錯誤: 請提供檔名模式'; } // 檢查是否有允許的目錄 if (allowedDirs.length === 0) { return '錯誤:未提供允許的目錄參數。請在啟動時指定至少一個允許的目錄。'; } let allResults: string[] = []; for (const dir of allowedDirs) { // 檢查目錄是否存在 if (!fs.existsSync(dir)) { continue; } const results = await this.searchFiles(dir, filePattern, excludeDirs); allResults = allResults.concat(results); } if (allResults.length === 0) { return `未找到符合模式 "${filePattern}" 的檔案`; } // 將搜尋結果格式化為字串 const formattedResults = allResults .map((filePath, index) => `${index + 1}. ${filePath}`) .join('\n'); return `找到 ${allResults.length} 個符合模式 "${filePattern}" 的檔案:\n${formattedResults}`; } catch (error) { return `搜尋檔案失敗: ${error instanceof Error ? error.message : '未知錯誤'}`; } }
- tools/fileSearchTool.ts:16-62 (helper)Core recursive file finder: traverses directory tree from rootDir, skips excludeDirs, matches filenames against pattern using regex, collects matching file paths.public static async searchFiles( rootDir: string, filePattern: string, excludeDirs: string[] = [] ): Promise<string[]> { const readdir = util.promisify(fs.readdir); const stat = util.promisify(fs.stat); const results: string[] = []; // 將文件模式轉換為正則表達式 const patternRegex = this.convertPatternToRegex(filePattern); // 遞迴搜尋函數 async function searchDir(dir: string) { try { // 檢查是否有權限讀取目錄 await util.promisify(fs.access)(dir, fs.constants.R_OK); const files = await readdir(dir); for (const file of files) { // 跳過排除的目錄 if (excludeDirs.includes(file)) { continue; } const fullPath = path.join(dir, file); const fileStat = await stat(fullPath); if (fileStat.isDirectory()) { // 遞迴搜尋子目錄 await searchDir(fullPath); } else if (patternRegex.test(file)) { // 檔名符合模式 results.push(fullPath); } } } catch (error) { // 忽略讀取目錄失敗的錯誤 console.error(`無法讀取目錄 ${dir}: ${error instanceof Error ? error.message : '未知錯誤'}`); } } // 開始搜尋 await searchDir(rootDir); return results; }