mdfind Search (macOS Spotlight CLI)
macOS Spotlight maintains a constantly-updated index of all files. mdfind is the CLI interface to this index - blazing fast with zero setup, no RAG, no external tools.
When to use mdfind vs other tools
| Scenario | Best tool |
|---|---|
| Broad content search across many files | mdfind (pre-indexed, fast) |
| Regex patterns with line numbers/context | Grep (precise) |
| Find files by name pattern | Glob (simple) or mdfind (fuzzy) |
| Search by file metadata (date, type, size) | mdfind (Spotlight metadata) |
| Fuzzy/natural language file search | mdfind (tolerant) |
Basic usage
Content search (full-text)
# Search current directory for content
mdfind -onlyin . "stakeholder feedback"
# Search specific path
mdfind -onlyin /path/to/project "authentication error"
# Search entire machine (omit -onlyin)
mdfind "quarterly report 2025"
Filename search
# Find by filename pattern
mdfind -onlyin . "kMDItemFSName == '*charles*.md'"
# Case-insensitive filename
mdfind -onlyin . "kMDItemFSName == '*README*'c"
Metadata queries
# Files modified in last 7 days
mdfind -onlyin . "kMDItemContentModificationDate > \$time.today(-7)"
# Files created today
mdfind -onlyin . "kMDItemContentCreationDate > \$time.today"
# Large files (> 10MB)
mdfind -onlyin . "kMDItemFSSize > 10000000"
# By file type
mdfind -onlyin . "kMDItemContentType == 'net.daringfireball.markdown'"
mdfind -onlyin . "kMDItemContentType == 'public.python-script'"
mdfind -onlyin . "kMDItemKind == 'PDF Document'"
Combining queries
Content + metadata
# Markdown files containing "stakeholder"
mdfind -onlyin . "kMDItemContentType == 'net.daringfireball.markdown' && stakeholder"
# Recent TypeScript files with "auth"
mdfind -onlyin . "kMDItemContentType == 'public.source-code' && kMDItemFSName == '*.ts' && auth"
# PDFs modified this week
mdfind -onlyin . "kMDItemKind == 'PDF Document' && kMDItemContentModificationDate > \$time.today(-7)"
Boolean operators
# OR conditions
mdfind -onlyin . "authentication || authorization"
# AND conditions (implicit with &&)
mdfind -onlyin . "user && login && error"
# Exclusion (use grep post-filter)
mdfind -onlyin . "config" | grep -v node_modules
Common metadata attributes
| Attribute | Description | Example |
|---|---|---|
kMDItemFSName | Filename | "kMDItemFSName == '*.md'" |
kMDItemContentType | UTI type | "kMDItemContentType == 'public.python-script'" |
kMDItemKind | Human-readable type | "kMDItemKind == 'PDF Document'" |
kMDItemContentModificationDate | Modified date | "> \$time.today(-7)" |
kMDItemContentCreationDate | Created date | "> \$time.today(-30)" |
kMDItemFSSize | File size (bytes) | "> 1000000" |
kMDItemTextContent | File contents | "kMDItemTextContent == '*error*'" |
kMDItemAuthors | Document authors | "kMDItemAuthors == 'Sam'" |
kMDItemTitle | Document title | "kMDItemTitle == '*quarterly*'" |
Time expressions
$time.now # Current time
$time.today # Start of today
$time.today(-1) # Yesterday
$time.today(-7) # 7 days ago
$time.this_week # Start of this week
$time.this_month # Start of this month
$time.this_year # Start of this year
$time.iso(2025-01-15) # Specific date
Useful flags
| Flag | Description |
|---|---|
-onlyin <path> | Scope search to directory |
-name <pattern> | Search by filename only |
-live | Keep running, show new matches |
-count | Just return count of matches |
-0 | Null-separate output (for xargs) |
Practical patterns
Find files to read
# Find all meeting notes from January
mdfind -onlyin . "kMDItemFSName == '*meeting*' && kMDItemContentModificationDate > \$time.iso(2025-01-01) && kMDItemContentModificationDate < \$time.iso(2025-02-01)"
Find recent work
# What did I work on today?
mdfind -onlyin . "kMDItemContentModificationDate > \$time.today"
# What got modified in last hour?
mdfind -onlyin . "kMDItemContentModificationDate > \$time.now(-3600)"
Find by content type
# All Python files mentioning "async"
mdfind -onlyin . "kMDItemContentType == 'public.python-script' && async"
# All images
mdfind -onlyin . "kMDItemContentTypeTree == 'public.image'"
Combine with other tools
# Find files then read them
mdfind -onlyin . "quarterly report" | head -5 | xargs -I {} echo "File: {}"
# Count matches
mdfind -onlyin . -count "TODO"
# Live monitoring for new matches
mdfind -onlyin . -live "error log"
Troubleshooting
Index not up to date?
# Force reindex of a directory
mdimport /path/to/directory
# Check indexing status
mdutil -s /
Query not working?
# List available attributes for a file
mdls /path/to/file.md
# Test query syntax
mdfind -onlyin . "kMDItemFSName == '*.md'" 2>&1 | head
Integration with workflow
When searching this repository:
- First pass: Use
mdfind -onlyin . "search terms"for broad discovery - Refine: Use Grep for regex precision with line numbers
- Read: Use Read tool for specific file content
mdfind is especially valuable for:
- "What files mention X?" queries
- Finding files by fuzzy/natural language
- Metadata-based searches (recent, by type, by size)
- When you don't know exact filenames or patterns