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 pathsexcludePatterns— 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:
- Validates the path is within allowed directories using
validatePath(src/filesystem/lib.ts, lines 889-891) - Checks against
excludePatternsusingminimatch(lines 993-996) - Matches against the user-supplied
patternusingminimatch(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.extin the immediate directory (example:*.md)**/*.ext— Recursively matches files with extension.extat any depth (example:**/*.ts)folder/**— Matches everything underfolder/, including subdirectories (example:src/**)!pattern— Negates a pattern, useful withinexcludePatterns(example:!node_modules/**)?.*— Uses single-character wildcards (example:?.txtmatchesa.txtbut notab.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
src/filesystem/lib.ts— ContainssearchFilesWithValidationandvalidatePathimplementations withminimatchintegrationsrc/filesystem/index.ts— Registers thesearch_filestool and connects it to the search logicsrc/filesystem/__tests__/directory-tree.test.ts— Unit tests illustrating glob pattern interpretation and exclusion behavior
Summary
- The
search_filestool accepts standard glob patterns via thepatternparameter using theminimatchlibrary excludePatternsaccepts an array of glob strings to filter results, supporting negation with!prefixes- All candidate paths are validated against allowed directories via
validatePathinsrc/filesystem/lib.ts - Patterns are matched relative to the
pathargument, 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →