TypeScript implementation of a local filesystem Model Context Protocol (MCP) server with a final target-state architecture split into application, domain, and infrastructure boundaries. The public MCP surface is composed once at the application layer, while tool behavior and contract ownership stay inside the domains that own them.
| Layer | Responsibility | Representative files |
|---|---|---|
application |
MCP server bootstrap, tool registration composition, MCP logging capability, server description/instructions, and server-scope concerns | src/application/server/filesystem-server.ts, src/application/server/register-tool-catalog.ts, src/application/server/register-inspection-tool-catalog.ts, src/application/server/register-comparison-and-mutation-tool-catalog.ts, src/application/server/register-server-scope-tools.ts, src/application/server/tool-registration-presets.ts |
domain |
Tool-owned handlers, input schemas, and structured result contracts for inspection, comparison, and mutation capabilities | src/domain/inspection/*, src/domain/comparison/*, src/domain/mutation/* |
infrastructure |
Technical capabilities that support the server without owning MCP transport or domain contracts | src/infrastructure/filesystem/path-guard.ts, src/infrastructure/logging/logger.ts |
list_directory_entriesread_files_with_line_numbersfind_paths_by_namefind_files_by_globsearch_file_contents_by_regexcount_linesget_path_metadataget_file_checksumsverify_file_checksums
diff_filesdiff_text_contentcreate_filesappend_filesreplace_file_line_rangescreate_directoriescopy_pathsmove_pathsdelete_paths
list_allowed_directories
The public tool catalog is the final direct target-state surface. It is composed from bounded registration modules rather than from a monolithic flat registry.
FilesystemServercreates the MCP server, enables logging capability, installs request handlers, and connects the stdio transport.registerToolCatalogcomposes the public surface by delegating to:registerInspectionToolCatalogregisterComparisonAndMutationToolCatalogregisterServerScopeTools
- The application-layer
executeToolwrapper centralizes call/result/error logging and normalizes plain-string results into MCPcontent. tool-registration-presets.tskeeps annotation presets and optional task-support hints centralized so registration modules stay thin and consistent.server-description.tsandserver-instructions.tsdefine the stable initialization metadata exposed by the server shell.
- Contract and schema ownership lives in the bounded context that owns the tool behavior.
- Inspection result schemas stay with inspection modules.
- Comparison and mutation behavior stays in their respective domains.
- The application layer composes these contracts into one MCP surface but does not re-declare them as a second source of truth.
- Bounded registration modules reduce change blast radius.
- The composition root stays readable and easy to review.
- Tool families can evolve independently without reopening unrelated registration code.
- Shared registration presets eliminate repeated policy wiring and keep cross-cutting application concerns consistent.
- The application layer owns transport initialization, server identity, logging capability negotiation, and tool registration.
- Domain handlers provide behavior and structured results.
- Server instructions explicitly describe cross-tool rules such as array-based multi-target inputs, allowed-directory scoping, and authoritative structured output when present.
- The server shell remains stateless with respect to business workflows.
- Runtime scope is configuration-driven through allowed-directory inputs rather than hard-coded workspace assumptions.
- Logging level is configuration-aware, while the MCP shell separately controls client-visible logging notifications.
- The delivery boundary can replace or recompose the server shell without rewriting domain logic.
- All path-based operations must remain inside configured allowed directories.
list_allowed_directoriesstays application-owned because it describes server scope, not a domain filesystem capability.- Domain modules remain the only canonical owners of tool behavior and contract definitions.
- Infrastructure modules keep technical concerns such as path guarding and canonical logging out of the application composition root.
- This documentation describes only the current final architecture and intentionally avoids legacy flat-structure or monolithic registration narratives.
The recursive inspection surface now follows one shared traversal policy that narrows broad-root requests before endpoint-specific traversal begins.
When callers provide broad roots, traversal-oriented discovery and recursive inspection tools exclude vendor, cache, and generated directory classes by default. This keeps high-noise trees such as node_modules, package caches, build outputs, and coverage directories out of broad traversal passes unless the caller explicitly targets them.
The hardening model does not block intentional access to excluded trees. Callers can still provide explicit roots inside excluded directories, and those roots remain valid because the policy distinguishes between broad-root traversal and explicit path targeting.
includeExcludedGlobs reopens named descendants without widening the whole traversal request. This keeps the default exclusion baseline intact while still allowing focused access to known subtrees that matter for a specific workflow.
Root-local .gitignore participation is optional and additive. The server-owned traversal policy remains the canonical default baseline, while respectGitIgnore can layer repository-local ignore rules on top when callers want additional narrowing.
Traversal runtime budgets cap visited entries, visited directories, and soft wall-clock time for traversal-heavy operations. These budgets exist to prevent oversized recursive scans from degrading response quality, consuming excessive runtime, or timing out before returning a stable result.
This model exists to protect prompting efficiency and runtime stability without removing legitimate access paths. Broad-root requests stay safe by default, while explicit roots and additive re-include controls preserve deliberate access to excluded areas when callers truly need it.
src/
application/server/
filesystem-server.ts
register-tool-catalog.ts
register-inspection-tool-catalog.ts
register-comparison-and-mutation-tool-catalog.ts
register-server-scope-tools.ts
tool-registration-presets.ts
server-description.ts
server-instructions.ts
domain/
inspection/
comparison/
mutation/
infrastructure/
filesystem/path-guard.ts
logging/logger.ts
This repository now represents a modular MCP filesystem server whose layers are intentionally separated:
applicationowns orchestration and exposure,domainowns tool behavior and contracts,infrastructureowns technical capabilities.
That separation is the final architectural source of truth for maintainers, users, and autonomous agents working in this workspace.