How to Use Glob Patterns for File Searching in the MCP Filesystem Server

The MCP Filesystem server provides a search_files tool that accepts glob-style patterns via the pattern parameter and uses the minimatch library to recursively match files within configured allowed directories.

The modelcontextprotocol/servers repository includes a reference Filesystem server that exposes secure file operations via the Model Context Protocol (MCP). When you need to locate specific files across directory trees, the search_files tool enables powerful recursive searches using standard glob patterns while maintaining strict security boundaries through path validation.

How Glob Pattern Matching Works in MCP Filesystem

The server implements glob matching through a validated search pipeline defined in src/filesystem/lib.ts and exposed via src/filesystem/index.ts.

Tool Registration and Schema

In src/filesystem/index.ts (lines 632-635), the server registers the search_files tool with a JSON schema that requires three key inputs:

  • path — The root directory to search (must be within allowed directories)
  • pattern — The glob-style pattern to match against relative paths
  • excludePatterns — Optional array of glob patterns to exclude from results

The tool description explicitly states that patterns should be "glob-style patterns that match paths relative to the working directory."

Search Implementation Details

When the tool is invoked, the handler in src/filesystem/index.ts (lines 645-648) executes searchFilesWithValidation. This function recursively traverses the directory tree and for each entry:

  1. Validates the path is within allowed directories using validatePath (src/filesystem/lib.ts, lines 889-891)
  2. Checks against excludePatterns using minimatch (lines 993-996)
  3. Matches against the user-supplied pattern using minimatch (lines 999-1002)

When a pattern matches, the absolute path is added to the result list, which is returned as newline-separated text.

Supported Glob Pattern Syntax

The search_files tool interprets patterns using the minimatch library. Patterns are evaluated relative to the path argument you supply and must resolve within the server's allowed directories.

  • *.ext — Matches files with the extension .ext in the immediate directory (example: *.md)
  • **/*.ext — Recursively matches files with extension .ext at any depth (example: **/*.ts)
  • folder/** — Matches everything under folder/, including subdirectories (example: src/**)
  • !pattern — Negates a pattern, useful within excludePatterns (example: !node_modules/**)
  • ?.* — Uses single-character wildcards (example: ?.txt matches a.txt but not ab.txt)

Security Validation and Path Restrictions

All file system operations pass through validatePath in src/filesystem/lib.ts, which:

  • Expands home directory shortcuts (~)
  • Resolves paths against allowed directories configured via MCP roots or command-line arguments
  • Blocks directory traversal attempts using .. or symlinks that escape the sandbox

This ensures glob patterns cannot force the server to access files outside its configured boundaries, regardless of how the pattern is constructed.

Practical Code Examples

JSON-RPC Request Format

Direct tool invocation via JSON-RPC:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "search_files",
  "params": {
    "path": ".",
    "pattern": "**/*.ts",
    "excludePatterns": ["node_modules/**", "dist/**"]
  }
}

The response contains matching absolute paths joined by newline characters:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "/home/mcp/project/src/index.ts\n/home/mcp/project/src/lib/util.ts" }
    ]
  }
}

TypeScript SDK Implementation

Using the official TypeScript MCP SDK:

import { McpClient } from "@modelcontextprotocol/typescript-sdk";

async function findMarkdownFiles() {
  const client = await McpClient.connectStdIO();
  const result = await client.callTool("search_files", {
    path: ".",
    pattern: "**/*.md",
    excludePatterns: ["node_modules/**"]
  });

  console.log("Matches:\n", result.content[0].text);
}

findMarkdownFiles();

Testing Glob Behavior

The test suite in src/filesystem/__tests__/directory-tree.test.ts demonstrates glob handling:

it('should handle glob patterns correctly', async () => {
  const tree = await buildTreeForTesting(testDir, testDir, ['*.env']);
  const fileNames = tree.map(entry => entry.name);
  expect(fileNames).not.toContain('.env');       // *.env excludes .env
  expect(fileNames).toContain('.env.local');    // does NOT exclude .env.local
});

This confirms that *.env is treated as a glob matching files whose entire name ends with .env, excluding files like .env.local.

Key Source Files

Summary

  • The search_files tool accepts standard glob patterns via the pattern parameter using the minimatch library
  • excludePatterns accepts an array of glob strings to filter results, supporting negation with ! prefixes
  • All candidate paths are validated against allowed directories via validatePath in src/filesystem/lib.ts
  • Patterns are matched relative to the path argument, returning absolute paths of all matches
  • The implementation prevents directory traversal attacks regardless of glob pattern complexity

Frequently Asked Questions

What glob syntax does the MCP Filesystem server support?

The server supports standard minimatch glob syntax including * (wildcards), ** (recursive directories), ? (single character), and ! (negation). Patterns like **/*.ts match TypeScript files at any depth, while *.env matches only files in the immediate directory, not subdirectories.

How do I exclude directories like node_modules from search results?

Pass an array of exclusion patterns to the excludePatterns parameter, such as ["node_modules/**", "dist/**"]. The server evaluates these patterns using minimatch before applying the main pattern, ensuring excluded paths never appear in results.

Can I use glob patterns to search outside the allowed directories?

No. Every candidate path passes through validatePath in src/filesystem/lib.ts, which verifies the resolved absolute path remains within the server's configured allowed directories. Attempts to traverse upward using .. or escape via symlinks are blocked regardless of the glob pattern used.

What is the difference between pattern and excludePatterns parameters?

The pattern parameter defines which files to include in results (inclusion filter), while excludePatterns defines which files to omit (exclusion filters). The server first validates directory boundaries, then checks exclusions, and finally applies the inclusion pattern. Both accept glob strings, but excludePatterns accepts an array for multiple exclusion rules.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →