Install
$ agentstack add mcp-richardwooding-file-search-on ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
file-search-on
Content-type aware file search with CEL-powered attribute filtering.
file-search-on walks a directory tree and returns files matching a CEL expression evaluated over each file's metadata and content-type-specific attributes. Instead of grepping by name, ask things like:
file-search-on 'is_pdf && page_count > 10 && author == "Jane Doe"'
file-search-on 'is_image && gps_lat > 51.4 && gps_lat = 2160 && video_codec == "h265"'
file-search-on 'is_office && language == "fr"'
file-search-on 'is_markdown && "longread" in tags && word_count > 1000'
# Or match fuzzily — typos in the data are no longer fatal:
file-search-on 'is_audio && levenshtein(artist, "Radiohead") 0.6' # substring-tolerant title match
Across 74 file formats organised into thirteen content-type families (documents, data, images, audio, video, office, ebooks, plain text, archives, compiled binaries, email, source code, notebooks), with format-specific metadata extraction.
Built in the open — issues, PRs, and feature requests warmly welcomed. See [Contributing](#contributing).
Quick start
Install with Homebrew, then hand the search tools to Claude Code — two commands:
# 1. Install the binary (macOS / Linux)
brew install richardwooding/tap/file-search-on
# 2. Register it as an MCP server in Claude Code
claude mcp add file-search-on -- file-search-on mcp
That's it. Claude Code can now query your files by typed content-type attributes — ask it things like "find every PDF over 10 pages I haven't opened this year", "which Go files have the highest git churn?", or "are there any AWS keys in this repo?" and it drives the [MCP tools](#mcp-server-mode) behind the scenes — including a cross-file code graph (imported_by, find_definition, who_calls, calls, dead_code) for "who depends on X?", "where is Y defined?", "who calls Z?", and "what does Z call?".
- Make it available in every project (not just the current one) with the user scope:
claude mcp add -s user file-search-on -- file-search-on mcp. - Confirm the connection with
claude mcp list, or/mcpinside a Claude Code session.
Prefer the command line? The same binary is a standalone CLI — file-search-on 'is_pdf && page_count > 10'. See [Usage](#usage). Other install methods (Docker, pre-built binaries, go install) are under [Install](#install).
Features
- Pluggable content-type detection — extension-first with magic-byte fallback. New formats are a single registration call.
- Thirteen content-type families, each with its own metadata extractors:
| Family | Formats | Bundle of attributes | | --- | --- | --- | | Documents | PDF, EPUB | title, author, language, pagecount | | Markup | Markdown, HTML, XML | title, wordcount, frontmatter, language, rootelement | | Data | JSON, YAML, TOML, CSV, TSV | jsonkind, yamlkind, yamldocumentcount, columncount, csvcolumns | | Plain text | TXT, log, … | linecount, wordcount | | Images | JPEG, PNG, GIF, WebP, TIFF, BMP, SVG, HEIC, RAW (Canon CR2 / CR3, Nikon NEF, Sony ARW, Adobe DNG, Fujifilm RAF, Olympus ORF, Panasonic RW2) — predicates is_raw_photo, is_cr2, is_cr3, is_nef, is_arw, is_dng, is_raf, is_orf, is_rw2. HEIC + sibling MOV → Apple Live Photo pairing (is_live_photo, is_live_photo_video). | dimensions + EXIF: camera, lens, GPS, ISO, focallength, takenat; RAW adds raw_kind, raw_vendor; Live Photo adds live_photo_video_path, live_photo_video_size, live_photo_image_path | | Audio | MP3, M4A, FLAC, OGG, WAV | tags (artist, album, genre, year, …) + duration, bitrate / nominalbitrate, samplerate, channels, bitdepth, ReplayGain | | Video | MP4, MOV, MKV, WebM, AVI | duration, bitrate / nominalbitrate, videocodec, audiocodec, videowidth/height, framerate, rotation, HDR / colour-space, subtitles | | Office | DOCX, XLSX, PPTX, ODT | title, author, language (Dublin Core) | | Archives | ZIP (incl. JAR / WAR / EAR), TAR, TAR.GZ, GZIP | entrycount, uncompressedsize, toplevelentries, hasrootdir | | Binaries | ELF (Linux/BSD), Mach-O (macOS, incl. universal), PE (Windows). Mach-O code signature parsing surfaces team ID + entitlements. | architectures, bitness, binaryformat, binarytype, isdynamicallylinked, isstripped, entrypoint, iscodesigned, isapplesigned, isthirdpartysigned, codesignidentifier, codesignteamid, codesignhashtype, codesignhardenedruntime, codesignlibraryvalidation, codesignkilled, codesignadhoc, entitlements, entitlementappsandbox, entitlementfulldiskaccess, entitlementnetworkclient, entitlementnetworkserver | | Email | RFC 5322 (.eml), Unix mbox (.mbox) | title (subject), author (from), emailto, emailcc, sentat, attachmentcount, emailcount | | Source code | Go, Python, JS/TS, Rust, C/C++, Java, Ruby, Swift, Kotlin, Scala, Shell, Lua, Elixir, Clojure, Haskell, OCaml, Zig, C#, PHP, Perl, R, Ada, SQL, Visual Basic, Fortran, MATLAB, Assembly, Pascal/Delphi | language, linecount, loc, commentloc, blankloc, functions / type_names / imports / references (Go via stdlib AST; 15 other languages — Python / Java / C# / PHP / Perl / R / MATLAB / Scala / Rust / TypeScript / JavaScript / Ruby / Swift / Kotlin / C / C++ — via embedded tree-sitter), max_complexity (per-file hotspot signal) | | Notebooks | Jupyter .ipynb, Apache Zeppelin .zpln | cellcount, codecellcount, markdowncellcount, kernel, language, title | | Disk images | DMG (UDIF), ISO 9660, VHD, VHDX, VMDK (sparse), QCOW2, WIM | diskimageformat, virtualsize, disktype, volumelabel, diskimagecreatedat, clusterbits, isencrypted, imagecount | | Install packages | macOS .pkg (XAR), Debian .deb, Red Hat .rpm, Linux .appimage | packageformat, packagename, packageversion, packagerelease, packagearch, packagekind, appimageversion | | VM bytecode | Java .class (JVM), Python .pyc / .pyo, WebAssembly .wasm | bytecodeformat, runtimeversion, classname (JVM), superclass (JVM), interfaces (JVM), methodcount (JVM), fieldcount (JVM), accessflags (JVM), pythonversion, sourcemtime, wasmversion, sectioncount, importcount, exportcount | | Science data | FITS (Flexible Image Transport System), VOTable (IVOA astronomical tables), HDF5 (Hierarchical Data Format v5 — LSST, LIGO, NetCDF4, scientific simulations), PDS3 + PDS4 (NASA Planetary Data System — Voyager, Mars rovers, Perseverance, Lucy), CDF (NASA Common Data Format — heliophysics: ACE, Wind, MMS, Parker Solar Probe) | scienceformat, telescope, instrument, object (→ title), observer (→ author), dateobs (→ takenat), exptime, filter, airmass, ra, dec, bitpix, naxis, naxis1, naxis2, hducount, fitskind, votableversion, tablecount, totalrows, fieldnames, fieldunits, fielducds, votabledataformat, hdf5formatversion, hdf5sizeofoffsets, hdf5sizeoflengths, pdsversion, missionname, spacecraftname, instrumentname, targetname, productid, starttime (→ takenat), cdfversion, cdfencoding, cdfmajority, variablecount, attributecount | | Databases | SQLite v3 + WAL / SHM sidecars + FTS3/4/5 body extraction (the most-deployed database in the world — every iOS / Android app, every browser, every CLI with a local store) | databaseformat, sqlitepagesize, sqliteformatversion, sqlitepagecount, sqliteschemaversion, sqlitetextencoding, sqliteuserversion, sqliteapplicationid, sqliteapplicationname, sqliteftstablecount, sqliteftstablenames, sqlitewalformatversion, sqlitewalpagesize, sqlitewalcheckpointseq, sqlitewalframecount, sqlitewalbyteorder | | Apple property lists | Binary (bplist00) + XML .plist — Info.plist, LaunchAgents, LaunchDaemons, Preferences, .webloc | plistformat, plistrootkind, plistkind, plistbundleidentifier, plistbundlename, plistbundleversion, plistbundleshortversion, plistexecutable, plistminosversion, plistlabel, plistprogram, plistprogramarguments, plistrunatload, plistkeepalive | | Browser bookmarks | Chromium-family (Chrome / Brave / Edge / Chromium / Opera / Vivaldi / Arc) Bookmarks JSON + Safari Bookmarks.plist | bookmarkcount, bookmarkfoldercount, bookmarkfolders, bookmarkurls, bookmarktitles, browservendor, bookmarkprofile | | Chat exports | Slack workspace exports, Discord (DiscordChatExporter) dumps, signal-cli --json — detected by JSON shape (is_chat_export / is_slack_export / is_discord_export / is_signal_export) | chatmessagecount, chatparticipants, chatchannel, chatworkspace, chatstartat, chatendat | | Fonts | TTF, OTF, TTC / OTC collections, WOFF1, WOFF2 (brotli decompression — full attribute extraction) | fontformat, fontoutlinekind, fontfamily, fontsubfamily, fontfullname, fontversion, fontpostscriptname, fontmanufacturer, fontdesigner, fontlicense, fontlicenseurl, fonttypographicfamily, fontweight, fontwidth, fontembedding, fontpanose, fontunicoderanges, fontrevision, fontunitsperem, fontmacstyle, fontitalicangle, fontglyphcount, fontaxiscount, fontaxes, fontcollectioncount, fontcollectionfamilies, woff2totalsfntsize, woff2totalcompressedsize | | 3D models | STL (ASCII + binary), Wavefront OBJ, glTF 2.0 (.gltf + .glb) — predicates is_3d_model, is_stl, is_obj, is_gltf | model3dformat, vertexcount, facecount, hasnormals, hastextures, materials, boundingbox |
Type predicates (is_pdf, is_image, is_audio, is_video, is_office, is_epub, …) light up automatically from the registered content type. See [examples/](./examples/) for recipes by family.
- Exact-name content types for common repo files —
Dockerfile,Makefile,LICENSE,.gitignore,go.mod,package.json,Cargo.toml,Pipfile,Gemfile,requirements.txt,Procfile,Vagrantfile, and more — with per-type predicates (is_dockerfile,is_gomod,is_node_manifest, …) plus family predicates (is_build,is_repo_meta,is_ignore,is_manifest,is_platform). Predicates cross-fire:package.jsonis bothis_node_manifestandis_json. See [examples/repo-files.md](./examples/repo-files.md). - OS-generated metadata files —
.DS_Store/.localized(macOS),Thumbs.db/Desktop.ini(Windows),.directory(KDE) — with per-type predicates (is_ds_store,is_localized,is_thumbs_db,is_desktop_ini,is_kde_directory), OS-specific family predicates (is_macos_metadata,is_windows_metadata,is_linux_metadata), and the cross-OSis_system_metadata. Lets agents answer "find every macOS leftover under~/Code" or "what platform-cruft is in this archive?" in one query. - Apple property lists (
.plist) — binary (bplist00) and XML variants. Surfacesis_plistplus a typed attribute set (plist_format,plist_root_kind,plist_kind,plist_bundle_identifier,plist_bundle_name,plist_bundle_version,plist_bundle_short_version,plist_executable,plist_min_os_version,plist_label,plist_program,plist_program_arguments,plist_run_at_load,plist_keep_alive). Path-basedplist_kindregistry labels Info.plist / LaunchAgents / LaunchDaemons / Preferences / .webloc files. Lets agents answer "which LaunchAgents run on login?", "what apps require macOS 14+?", or "find the Info.plist forcom.example.bundle" in one query. - Browser bookmarks — Chromium-family
Bookmarks(Chrome / Brave / Edge / Chromium / Opera / Vivaldi / Arc) and SafariBookmarks.plist. Surfacesis_bookmark_file/is_chromium_bookmarks/is_safari_bookmarksplusbookmark_count,bookmark_folder_count,bookmark_folders,bookmark_urls,bookmark_titles,browser_vendor(chrome / chromium / edge / brave / opera / vivaldi / arc / safari), andbookmark_profile. With--body, thebodyCEL variable carriestitle\turllines sobody.contains("kubernetes")answers "did I bookmark anything about kubernetes?" across every profile in one query. - Chat exports — offline Slack workspace exports, Discord (DiscordChatExporter) JSON dumps, and signal-cli
--jsonoutput. All three are plain.jsonfiles with arbitrary names, so they're detected by a streaming top-level-JSON-shape discriminator rather than by extension. Surfacesis_chat_exportplus per-formatis_slack_export/is_discord_export/is_signal_export, and a shared attribute set:chat_message_count,chat_participants(distinct authors),chat_channel,chat_workspace(guild for Discord; empty for Signal),chat_start_at, andchat_end_at. With--body, thebodyCEL variable carries one{timestamp}\t{author}\t{text}line per message sois_chat_export && body.contains("kubernetes")greps the conversation text across an entire export. See [examples/chat-exports.md](./examples/chat-exports.md). - Screenshot OCR —
--ocrruns OCR overimage/*files via the registered provider (macOS Vision today; Linux Tesseract / Windows.Media.Ocr deferred under the same hook). The recognized text populates thebodyCEL variable sobody.contains("kubernetes")queries work over~/Desktopscreenshots the same way they do over markdown files. Plus three new attributes:ocr_confidence(0..1 average across recognized lines),ocr_language(BCP-47 dominant language),ocr_provider(registered engine name). On macOS the OCR helper is bundled in the Homebrew cask; for local devmake ocr-helperbuilds it. On platforms without a registered provider,--ocris a clean no-op. Cached in the body cache (bodies_v1) so subsequent walks are free. See [examples/ocr.md](./examples/ocr.md). - Fonts — TrueType (
.ttf), OpenType (.otf), TTC / OTC collections, WOFF1 (.woff), and WOFF2 (.woff2). WOFF2 attribute extraction runs the brotli decompression hop, then slices the metadata tables (name/OS/2/head/post/maxp/fvar) from the decompressed stream and dispatches to the same per-table decoders as the bare-sfnt path —font_family,font_designer,font_weight,font_axesall populate for.woff2collections in modern frontend projects. Surfaces format-family predicates (is_font,is_ttf,is_otf,is_font_collection,is_woff,is_woff2) plus trait predicates (is_variable_font,is_color_font,is_monospace_font,is_italic_font,is_bold_font). Extracted attributes cover thenametable (family, designer, version, manufacturer, license),OS/2(weight, width, embedding permissions, panose, Unicode ranges),head(revision, units-per-em, mac style),post(italic angle),maxp(glyph count), andfvar(variable-font axes —wght/wdth/slnt/ital/opsz). Lets agents answer "find every variable font with an optical-size axis", "license audit — fonts without OFL", or "find Adobe-designed bold fonts" in one query. See [examples/fonts.md](./examples/fonts.md). - Project-type detection —
detect-project/find-projects/which-projectsubcommands identify Go / Node / Rust / Python / Ruby / Java / .NET / PHP / Swift / Scala (sbt + Mill) / CMake / Autotools / R / Zig / Perl / MATLAB / Terraform / Docker Compose / Hugo / Jekyll / Eleventy / Astro / Gatsby / MkDocs / Docusaurus / Pelican projects (28 built-in types: 8 SSG + 20 others). Pair with--resolve-projects(file-levelproject_typefilter) and--prune-build-artefacts(skipvendor/node_modules/target/__pycache__/public/_siteetc. automatically). Theis_static_siteCEL predicate addresses any SSG as a group. Define custom project types via CEL in YAML — see [examples/projects.md](./examples/projects.md). - First-class Markdown front-matter — YAML (
---), TOML (+++), and JSON ({ ... }) are recognised by leading bytes. Common keys (title,author,language,tags,categories,draft, `dat
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: richardwooding
- Source: richardwooding/file-search-on
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.