Skip to content

Commit 0968e43

Browse files
authored
Merge pull request #256 from devin-open-source/devin/1733521206-add-exclude-patterns-to-search-files
Add excludePatterns to search_files in filesystem server
2 parents 79794fe + 245aece commit 0968e43

File tree

4 files changed

+49
-8
lines changed

4 files changed

+49
-8
lines changed

package-lock.json

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/filesystem/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Node.js server implementing Model Context Protocol (MCP) for filesystem operatio
8282
- Inputs:
8383
- `path` (string): Starting directory
8484
- `pattern` (string): Search pattern
85+
- `excludePatterns` (string[]): Exclude any patterns. Glob formats are supported.
8586
- Case-insensitive matching
8687
- Returns full paths to matches
8788

src/filesystem/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import os from 'os';
1313
import { z } from "zod";
1414
import { zodToJsonSchema } from "zod-to-json-schema";
1515
import { diffLines, createTwoFilesPatch } from 'diff';
16+
import { minimatch } from 'minimatch';
1617

1718
// Command line argument parsing
1819
const args = process.argv.slice(2);
@@ -134,6 +135,7 @@ const MoveFileArgsSchema = z.object({
134135
const SearchFilesArgsSchema = z.object({
135136
path: z.string(),
136137
pattern: z.string(),
138+
excludePatterns: z.array(z.string()).optional().default([])
137139
});
138140

139141
const GetFileInfoArgsSchema = z.object({
@@ -183,6 +185,7 @@ async function getFileStats(filePath: string): Promise<FileInfo> {
183185
async function searchFiles(
184186
rootPath: string,
185187
pattern: string,
188+
excludePatterns: string[] = []
186189
): Promise<string[]> {
187190
const results: string[] = [];
188191

@@ -191,11 +194,22 @@ async function searchFiles(
191194

192195
for (const entry of entries) {
193196
const fullPath = path.join(currentPath, entry.name);
194-
197+
195198
try {
196199
// Validate each path before processing
197200
await validatePath(fullPath);
198201

202+
// Check if path matches any exclude pattern
203+
const relativePath = path.relative(rootPath, fullPath);
204+
const shouldExclude = excludePatterns.some(pattern => {
205+
const globPattern = pattern.includes('*') ? pattern : `**/${pattern}/**`;
206+
return minimatch(relativePath, globPattern, { dot: true });
207+
});
208+
209+
if (shouldExclude) {
210+
continue;
211+
}
212+
199213
if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {
200214
results.push(fullPath);
201215
}
@@ -522,7 +536,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
522536
throw new Error(`Invalid arguments for search_files: ${parsed.error}`);
523537
}
524538
const validPath = await validatePath(parsed.data.path);
525-
const results = await searchFiles(validPath, parsed.data.pattern);
539+
const results = await searchFiles(validPath, parsed.data.pattern, parsed.data.excludePatterns);
526540
return {
527541
content: [{ type: "text", text: results.length > 0 ? results.join("\n") : "No matches found" }],
528542
};
@@ -544,9 +558,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
544558

545559
case "list_allowed_directories": {
546560
return {
547-
content: [{
548-
type: "text",
549-
text: `Allowed directories:\n${allowedDirectories.join('\n')}`
561+
content: [{
562+
type: "text",
563+
text: `Allowed directories:\n${allowedDirectories.join('\n')}`
550564
}],
551565
};
552566
}
@@ -574,4 +588,4 @@ async function runServer() {
574588
runServer().catch((error) => {
575589
console.error("Fatal error running server:", error);
576590
process.exit(1);
577-
});
591+
});

src/filesystem/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
"@modelcontextprotocol/sdk": "0.5.0",
2323
"diff": "^5.1.0",
2424
"glob": "^10.3.10",
25+
"minimatch": "^10.0.1",
2526
"zod-to-json-schema": "^3.23.5"
2627
},
2728
"devDependencies": {
2829
"@types/diff": "^5.0.9",
30+
"@types/minimatch": "^5.1.2",
2931
"@types/node": "^20.11.0",
3032
"shx": "^0.3.4",
3133
"typescript": "^5.3.3"
3234
}
33-
}
35+
}

0 commit comments

Comments
 (0)