Support glob pattern in search_files tool (#745)

Co-authored-by: Adam Jones <adamj+git@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Adam Jones <adamj@anthropic.com>
This commit is contained in:
Finn Andersen
2025-08-23 09:37:53 +03:00
committed by GitHub
parent d381cf1ffd
commit fd886fac9c
4 changed files with 14 additions and 14 deletions

View File

@@ -145,12 +145,12 @@ The server's directory access control follows this flow:
- Fails if destination exists
- **search_files**
- Recursively search for files/directories
- Recursively search for files/directories that match or do not match patterns
- Inputs:
- `path` (string): Starting directory
- `pattern` (string): Search pattern
- `excludePatterns` (string[]): Exclude any patterns. Glob formats are supported.
- Case-insensitive matching
- `excludePatterns` (string[]): Exclude any patterns.
- Glob-style pattern matching
- Returns full paths to matches
- **directory_tree**

View File

@@ -316,7 +316,7 @@ describe('Lib Functions', () => {
const result = await searchFilesWithValidation(
testDir,
'test',
'*test*',
allowedDirs,
{ excludePatterns: ['*.log', 'node_modules'] }
);
@@ -346,7 +346,7 @@ describe('Lib Functions', () => {
const result = await searchFilesWithValidation(
testDir,
'test',
'*test*',
allowedDirs,
{}
);
@@ -370,7 +370,7 @@ describe('Lib Functions', () => {
const result = await searchFilesWithValidation(
testDir,
'test',
'*test*',
allowedDirs,
{ excludePatterns: ['*.backup'] }
);

View File

@@ -277,9 +277,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
name: "search_files",
description:
"Recursively search for files and directories matching a pattern. " +
"Searches through all subdirectories from the starting path. The search " +
"is case-insensitive and matches partial names. Returns full paths to all " +
"matching items. Great for finding files when you don't know their exact location. " +
"The patterns should be glob-style patterns that match paths relative to the working directory. " +
"Use pattern like '*.ext' to match files in current directory, and '**/*.ext' to match files in all subdirectories. " +
"Returns full paths to all matching items. Great for finding files when you don't know their exact location. " +
"Only searches within allowed directories.",
inputSchema: zodToJsonSchema(SearchFilesArgsSchema) as ToolInput,
},

View File

@@ -367,14 +367,14 @@ export async function searchFilesWithValidation(
await validatePath(fullPath);
const relativePath = path.relative(rootPath, fullPath);
const shouldExclude = excludePatterns.some(excludePattern => {
const globPattern = excludePattern.includes('*') ? excludePattern : `**/${excludePattern}/**`;
return minimatch(relativePath, globPattern, { dot: true });
});
const shouldExclude = excludePatterns.some(excludePattern =>
minimatch(relativePath, excludePattern, { dot: true })
);
if (shouldExclude) continue;
if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {
// Use glob matching for the search pattern
if (minimatch(relativePath, pattern, { dot: true })) {
results.push(fullPath);
}