file-discovery-mcp is a stdio Model Context Protocol (MCP) server for read-only, scoped filesystem discovery (similar to fd / find), with structured JSON and no shell.
Stack: Go 1.25+ (see go.mod), modelcontextprotocol/go-sdk for MCP.
Current release: v0.3.0 — see CHANGELOG.md.
- Build the binary:
go build -o file-discovery-mcp ./cmd/file-discovery-mcp(or use a published release). - Register
file-discovery-mcpin your MCP host as a stdio server (command = path to the binary; set cwd and optionalFILE_DISCOVERY_MCP_ROOTSif you need specific search boundaries). - Use the assistant’s tools
get_server_infoandfind_filesas exposed by the host.
Step-by-step orientation, example searches (by name, by extension), what to expect in results, and limitations: docs/user-guide.md.
Examples: call find_files with {"pattern": "*.go", "root": "/path/to/repo"} for all Go files under that directory; add "max_depth": 2 and "max_results": 50 to cap depth and list size. Sample MCP configs, success/failure JSON, and edge cases: docs/examples.md.
Extended guides and outlines live under docs/. Start at docs/index.md for the full map (architecture, development, security, client contract, and more).
file-discovery-mcp is a stdio MCP server with a thin MCP layer (internal/mcpapp), a safety layer (internal/allowlist, env limits), and a read-only discovery layer (internal/findfiles: optional fd subprocess with fixed argv, else in-process walk). For the full component model, request/response flow, principles, and non-goals, see docs/architecture.md.
Clone, build, test, run the stdio server, branching conventions, commit habits, and what GitHub Actions runs: see docs/development.md.
Branch naming, commits, pull requests, code and documentation expectations, and how to report issues: see CONTRIBUTING.md (full guide: docs/contributing.md). Community standards: CODE_OF_CONDUCT.md.
Normative MCP tool names, input/output JSON fields, error codes, safety guarantees, and versioning expectations for integrators: see docs/client-contract.md.
Threat model (command execution and path exposure), implemented mitigations, safe operational defaults, residual risks, and responsible disclosure: docs/security.md.
- Transport: MCP over stdin/stdout (
file-discovery-mcpwith no arguments). - Shutdown: SIGINT → clean exit status 0 (see
runExitCodeincmd/file-discovery-mcp). get_server_info: version and flags (no filesystem I/O).find_files: list files under an allowed directory whose basename matches a glob (e.g.*.go).- Backend: uses
fdonPATHwhen available (exec.Command, fixed argv only); otherwise afilepath.WalkDirimplementation. Nosh -c, no user-controlled executables. - Limits:
max_resultsis clamped byFILE_DISCOVERY_MCP_ABSOLUTE_MAX(default cap 50000). Default per-request ceiling when omitted comes fromFILE_DISCOVERY_MCP_MAX_RESULTS(default 500). - Optional:
max_depth(non-negative) limits directory depth belowroot.
- Backend: uses
| Mechanism | Behavior |
|---|---|
| Root allowlist | Env FILE_DISCOVERY_MCP_ROOTS: list of directories (OS path-list separator, same as PATH). If unset, current working directory at process start is the only root. Every find_files root must resolve inside one of these directories (after filepath.Clean / abs); otherwise PATH_NOT_ALLOWED. |
| Read-only | Tools do not create, modify, or delete files. |
| No arbitrary execution | fd is invoked with a fixed argument shape; patterns are not passed through a shell. |
| Bounded output | Results are capped by max_results (after clamping). truncated: true when the cap may have cut off further matches. |
- Glob is filename / basename only (not full-path patterns); semantics follow
filepath.Matchfor the walk backend andfd --globwhenfdis used (minor differences possible). - Symlink-heavy trees may behave subtly vs. a fully canonicalized policy; containment checks use
filepathsemantics as documented ininternal/allowlist. - MCP resource/prompt surfaces are not implemented.
- Write access, arbitrary commands, interactive shell integration.
- Background indexers or network sync.
go build -o file-discovery-mcp ./cmd/file-discovery-mcpRun (typical MCP client configuration: command = built binary, optional env):
./file-discovery-mcpExample restrict roots (Unix):
FILE_DISCOVERY_MCP_ROOTS=/safe/project:/tmp/readonly ./file-discovery-mcpgo test ./...
go vet ./...
test -z "$(gofmt -l .)"- Branch from
develop(feature/*,bugfix/*,chore/*, etc.). - Run
gofmt,go vet, andgo test ./...before pushing. - Open a PR into
develop; CI runs build, tests,gofmt, andgo vet.
Copyright 2026 Ioannis Polyzos. Licensed under the Apache License, Version 2.0. See LICENSE.
- Tighten symlink / cross-platform edge cases; richer error codes if needed.
- Optional depth-first streaming or paging for huge directories.
- Ongoing releases via
mainwith version tags.