Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

filesystem: search_files does not expand non-wildcard excludePatterns like directory_tree does

Ouverte Adaptée aux débutants
#5,216 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
72/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, typescript
Domaine
backend, testing

Piste de recherche

Lisez searchFilesWithValidation dans src/filesystem/lib.ts ainsi que buildTree dans src/filesystem/server.ts pour comparer la façon dont ils font correspondre excludePatterns. Ajoutez des tests dans src/filesystem/__tests__/lib.test.ts et src/filesystem/__tests__/server-tools.test.ts pour les exclusions simples dans les répertoires de premier niveau et les répertoires imbriqués. Le travail sera terminé lorsque search_files ignorera les sous-arborescences de répertoires correspondantes et aura le même comportement que directory_tree.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Summary

While auditing src/filesystem on v2.0.0 (origin/main) following the #4857 spec refactor, I found a behavioral mismatch in how excludePatterns is evaluated between directory_tree (src/filesystem/server.ts) and search_files (src/filesystem/lib.ts).

When an LLM or user passes a bare directory or file name in excludePatterns (for example, ["node_modules", ".git"]), directory_tree excludes both the directory and its entire subtree, whereas search_files still traverses into the excluded directory and returns all files inside it.

Server & Environment

  • Server: filesystem (@modelcontextprotocol/server-filesystem v2.0.0 / origin/main)
  • Files: src/filesystem/server.ts (buildTree) vs. src/filesystem/lib.ts (searchFilesWithValidation)
  • Protocol era / transport: Both 2026-07-28 and 2025-era over stdio / in-memory client transport

Reproduction / Root Cause in v2/main

  1. In directory_tree (src/filesystem/server.ts, lines 515–529), buildTree checks whether an exclusion pattern contains *. If it does not, it automatically expands the pattern to match nested paths and subtrees (**/${pattern} and **/${pattern}/**), and skips recursing into the excluded directory:
const shouldExclude = excludePatterns.some((pattern) => {
  if (pattern.includes("*")) {
    return minimatch(relativePath, pattern, { dot: true });
  }
  // For files: match exact name or as part of path
  // For directories: match as directory path
  return (
    minimatch(relativePath, pattern, { dot: true }) ||
    minimatch(relativePath, `**/${pattern}`, { dot: true }) ||
    minimatch(relativePath, `**/${pattern}/**`, { dot: true })
  );
});
if (shouldExclude) continue;
  1. In search_files (src/filesystem/lib.ts, lines 397–413), searchFilesWithValidation evaluates minimatch(relativePath, excludePattern, { dot: true }) directly without the non-wildcard expansion:
const relativePath = path.relative(rootPath, fullPath);
const shouldExclude = excludePatterns.some((excludePattern) =>
  minimatch(relativePath, excludePattern, { dot: true }),
);

if (shouldExclude) continue;
What happens when a caller passes excludePatterns: ["node_modules"] or ["sub"]:
  • At node_modules (top-level): relativePath is "node_modules". minimatch("node_modules", "node_modules") is true, so if (shouldExclude) continue skips recursing into top-level node_modules!
  • At packages/app/node_modules (nested directory): relativePath is "packages/app/node_modules". minimatch("packages/app/node_modules", "node_modules") is false! search_files enters packages/app/node_modules and traverses every file inside it.
  • When excludePatterns: ["node_modules/*"] or ["**/node_modules"] (without trailing /**) is passed: Even if a pattern matches files inside a directory, search_files still wastes I/O recursing unless the directory entry itself matches shouldExclude.

Expected vs. Actual Behavior

  • Expected: Passing excludePatterns: ["node_modules", ".git"] (or a bare filename/directory name without *) to search_files should behave identically to directory_tree: any nested directory or file matching pattern, **/${pattern}, or **/${pattern}/** is excluded and its directory subtree is not traversed.
  • Actual: directory_tree excludes nested packages/app/node_modules, while search_files traverses into packages/app/node_modules and returns matches from inside it unless the caller explicitly writes **/node_modules/**.

Prompt to Reproduce Fix in the Agentic Workflow

Per CONTRIBUTING.md, here is the exact prompt to fix and test this in the factory workflow:

Unify `excludePatterns` matching between `directory_tree` (`src/filesystem/server.ts`) and `search_files` (`src/filesystem/lib.ts`):

1. Extract a shared helper (or update `searchFilesWithValidation` in `src/filesystem/lib.ts` to match `buildTree` in `src/filesystem/server.ts`) so that when an entry in `excludePatterns` does not contain `*`, it matches `minimatch(relativePath, pattern, { dot: true }) || minimatch(relativePath, `**/${pattern}`, { dot: true }) || minimatch(relativePath, `**/${pattern}/**`, { dot: true })`.
2. Add a protocol-level test in `src/filesystem/__tests__/server-tools.test.ts` (and unit test in `src/filesystem/__tests__/lib.test.ts`) verifying that `search_files` with a bare name in `excludePatterns` (e.g. `excludePatterns: ["ignored_dir"]`) excludes both top-level `ignored_dir/file.txt` and nested `nested/ignored_dir/file.txt`, matching `directory_tree`'s behavior.
3. Run `npm run format` and `npm run local:gate`.
Langage dominant
TypeScript
Étoiles
91.4k
Forks
11.8k
Merge moyen
7 h 26 min
PR mergées (30 j)
130

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de modelcontextprotocol/servers

Toutes les issues de modelcontextprotocol/servers

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.