Skip to content

Development Guide

MCP Filesystem Server Ultra (v4.5.29) — A safety-first MCP (Model Context Protocol) filesystem server written in Go, optimized for Claude Desktop and Claude Code. Provides 20 MCP tools (17 core + git + minify_js + help) for file operations, search, editing, backups, version control, JavaScript minification, and WSL/Windows integration. Speed is a feature, not the pitch: every operation is versioned, observable, and recoverable. (Compatibility aliases are disabled by default to keep the tool surface small and predictable.)

Terminal window
# Build (Windows) — v4 binary
go build -ldflags="-s -w" -trimpath -o filesystem-ultra-v4.exe .
# With ripgrep embedded (~4MB larger)
go build -ldflags="-s -w" -trimpath -tags embed_rg -o filesystem-ultra-v4-embed.exe .
# Or use the build scripts
build-windows.bat # default
build-windows-embed.bat # with ripgrep
# Run all tests
go test ./tests/...
go test ./core/...
go test ./tests/security/...
# Run with race detector
go test -race ./...
# Run security fuzzing
go test -fuzz=Fuzz ./tests/security
# Run specific test
go test ./tests/ -run TestName -v
# Build dashboard (separate binary)
go build -ldflags="-s -w" -trimpath -o dashboard.exe ./cmd/dashboard/
CORE (5): read_file, write_file, edit_file, list_directory, search_files
EDIT+ (2): multi_edit, project_replace (project_replace added v4.5.0)
FILES (4): move_file, copy_file, delete_file, create_directory
(delete_file is now soft-delete by default, v4.5.11)
BATCH (1): batch_operations (pipelines + batch rename; 8 operation types v4.5.14+)
BACKUP (1): backup (10 actions: list/info/compare/cleanup/restore/undo_last/undo_chain/list_trash/restore_trash/purge_trash)
ANALYSIS (1): analyze_operation (file, optimize, write, edit, delete)
WSL (1): wsl (sync + status via action param — auto-sync is env-var driven)
UTIL (1): server_info (help, stats, artifact via action param)
INFO (1): get_file_info
GIT (1): git (v4.5.2+ — 9 actions since v4.5.25: init, status, diff, log, show, add, commit, restore, branch)
MINIFY (1): minify_js (v4.5.7+ — pure-Go JS minifier; no Node)
HELP (1): help (discovery — standalone tool since v4.5.x)
  • read_file replaces: read_file, chunked_read_file, intelligent_read, read_file_range, read_base64
  • write_file replaces: write_file, create_file, streaming_write_file, intelligent_write, write_base64
  • edit_file replaces: edit_file, smart_edit_file, intelligent_edit, recovery_edit, search_and_replace, replace_nth_occurrence, regex_transform_file
  • search_files replaces: smart_search, advanced_text_search, count_occurrences
  • batch_operations replaces: execute_pipeline, batch_rename_files
  • backup replaces: restore_backup, list_backups, get_backup_info, compare_with_backup, cleanup_backups
  • wsl replaces: wsl_sync, wsl_status, wsl_to_windows_copy, windows_to_wsl_copy, configure_autosync
  • server_info replaces: stats, get_help, artifact, performance_stats, get_edit_telemetry
  • analyze_operation replaces: analyze_file, analyze_write, analyze_edit, analyze_delete, get_optimization_suggestion
main.go # Entry point: CLI flags, 20 MCP tool registrations, server startup
tools_core.go # Core tool registrations (read_file/write_file/etc.)
tools_search.go # list_directory, search_files, analyze_operation
tools_files.go # get_file_info, move_file, copy_file, delete_file, create_directory
tools_batch.go # multi_edit, batch_operations, project_replace, backup
tools_platform.go # wsl, server_info (also registers help tool)
tools_git.go # git (v4.5.2+ — 8 actions: init, status, diff, log, add, commit, restore, branch)
tools_minify.go # minify_js (v4.5.7+ — pure-Go JS minifier; no Node)
tools_aliases.go # aliases DISABLED in registerTools() (see tools_core.go:103-105)
core/
engine.go # UltraFastEngine - central struct with cache, worker pool, metrics
edit_operations.go # EditFile, MultiEdit with backup, risk assessment, hooks
file_operations.go # RenameFile, SoftDeleteFile, CopyFile, MoveFile, etc.
streaming_operations.go # StreamingWriteFile, ChunkedReadFile, SmartEditFile
search_operations.go # SmartSearch, AdvancedTextSearch
backup_manager.go # BackupManager - create/restore/compare/cleanup backups
impact_analyzer.go # Risk assessment (LOW/MEDIUM/HIGH/CRITICAL)
edit_safety_layer.go # EditSafetyValidator - context validation, stale edit prevention
hooks.go # Pre/post operation hook system (16 event types — was 12 before v4.5.13 examples fix)
large_file_processor.go # Line-by-line and chunk-based processing
regex_transformer.go # Advanced regex transformations with capture groups
batch_operations.go # Batch file operations with rollback (8 types — extract added v4.5.14)
batch_rename.go # Batch file renaming
normalizer.go # Self-Learning Request Normalizer (14 built-in rules)
audit_logger.go # AuditLogger - JSON Lines operation log + MetricsSnapshot writer
claude_optimizer.go # Claude Desktop auto-optimization (small/large file strategy)
plan_mode.go # Dry-run analysis (analyze_write, analyze_edit, analyze_delete)
pipeline.go # Pipeline executor: sequential/parallel dispatch, action handlers
pipeline_types.go # Types: PipelineRequest, PipelineStep, StepResult, validation
pipeline_conditions.go # 9 condition types: evaluation and validation
pipeline_templates.go # {{step_id.field}} template resolution
pipeline_scheduler.go # DAG builder, topological sort, destructive step splitting
path_converter.go # WSL <-> Windows path conversion
path_detector.go # Path format detection
wsl_sync.go # WSL/Windows file synchronization
autosync_config.go # Auto-sync configuration system
watcher.go # File watcher for cache invalidation
mmap.go # Memory-mapped file I/O (Windows fallback)
config.go # Performance thresholds and constants
errors.go # Custom error types (PathError, ValidationError, EditError, etc.)
feedback.go # EditRewrite guard (v4.5.10) + knownHash OCC state (v4.5.17)
structure_check.go # Post-edit Go AST validation (v4.5.15) + brace-balance for non-.go
line_range.go # ComputeLineRangeReplacement (delete_range v4.5.14, replace_range v4.5.16)
minifier.go # Pure-Go JS minifier state machine (v4.5.7)
whitespace_matcher.go # tolerant_whitespace matcher (v4.5.7)
read_dedup.go # golang.org/x/sync singleflight on ReadFileContent (v4.5.9)
cache/
intelligent.go # 3-tier cache: BigCache (files) + go-cache (dirs) + go-cache (metadata)
mcp/
mcp.go # MCP type definitions (legacy, mostly unused)
tests/
mcp_functions_test.go # Core MCP function tests
bug5_test.go - bug28_test.go # Regression tests
normalizer_test.go # Normalizer unit tests
pipeline_test.go # Pipeline integration tests
edit_safety_test.go # Edit safety validation tests
security/ # Security & fuzzing tests (package: security)
cmd/
dashboard/
main.go # Separate binary: HTTP dashboard for logs/metrics/backups/trash (v4.5.12+)
static/ # Embedded web UI (go:embed) - HTML + vanilla JS + CSS
PackagePurpose
github.com/mark3labs/mcp-go v0.54.1MCP server SDK
github.com/allegro/bigcache/v3 v3.1.0High-performance file content cache
github.com/patrickmn/go-cache v2.1.0Directory/metadata cache
github.com/panjf2000/ants/v2 v2.12.1Goroutine worker pool
github.com/fsnotify/fsnotify v1.10.1File system event watching

Go version: 1.26.5 (bumped from 1.26.4 in v4.5.29 for additional govulncheck hardening; GO-2026-5039 / GO-2026-5037 were fixed in 1.26.4, current baseline is 1.26.5)

if len(e.config.AllowedPaths) > 0 {
if !e.isPathAllowed(path) {
return nil, &PathError{Op: "operation", Path: path, Err: fmt.Errorf("access denied")}
}
}

isPathAllowed() resolves symlinks via filepath.EvalSymlinks() before checking containment. Allowed paths resolved once at engine startup. Empty AllowedPaths = no restrictions.

Custom error types in core/errors.go: PathError, ValidationError, CacheError, EditError, ContextError. Always wrap with fmt.Errorf("context: %w", err).

// Success (text-only — used by all 13 tools that don't publish outputSchema)
return mcp.NewToolResultText("result text"), nil
// Success with structuredContent (v4.5.26+ — used by read_file, write_file,
// edit_file, multi_edit). Wraps the same text verbatim and adds a JSON
// payload that conforms to the tool's outputSchema.
return mcp.NewToolResultStructured(attachMessage(sc, msg), msg), nil
// Error
return mcp.NewToolResultError("error message"), nil

outputSchema registration (v4.5.26+). Use mcp.WithRawOutputSchema (NOT WithOutputSchema[T] — there’s a mcp-go marshal-time conflict). Schemas live in output_schemas.go as json.RawMessage. Coherence with the payload is enforced by output_schema_test.go: every payload field must be declared in the schema and every required schema field must be present. See Structured Output.

s.AddTool(mcp.NewTool("tool_name",
mcp.WithDescription("description"),
mcp.WithString("param", mcp.Description("desc"), mcp.Required()),
), auditWrap("tool_name", func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// implementation
}, auditLogger))

All handlers wrapped with auditWrap() for normalization + audit logging. Parameter extraction: request.GetArguments() returns map[string]interface{}, use request.RequireString("param") or type assertions.

  • engine.operationSem channel-based semaphore limits parallel ops
  • engine.pool (ants worker pool) for goroutine management
  • sync.RWMutex for shared caches (regex cache, env detection)
  • All public methods accept context.Context
  • Small: < 100KB (direct I/O)
  • Medium: < 500KB (streaming)
  • Large: < 5MB (chunking)
  • VeryLarge: < 50MB (special handling, edit rejected above this)
  • LOW: < 30% of file modified, < 50 occurrences
  • MEDIUM: ≥ 30% of file modified, OR ≥ 50 occurrences
  • HIGH: ≥ 50% of file modified, OR > 100 occurrences
  • CRITICAL: ≥ 90% of file modified (no longer hard-blocks in v4 — auto-proceeds with backup)

Additional blocking conditions (none bypassed by force:true):

  • Accidental-rewrite guard (v4.5.10) in core/feedback.go — blocks when new_text > 2 × old_text AND > 50% of file is outside the matched block AND new_text > 500 B / > 50% file size. Override with allow_rewrite:true.
  • --auto-occ=block (v4.5.17) in core/feedback.go — rejects when the session’s content_hash baseline differs from the on-disk hash. Set --auto-occ off to disable.

Backups stored in configurable dir (default: temp/mcp-batch-backups). Backup IDs are timestamp-random format. Metadata stored as JSON alongside backup files. Sanitized against path traversal.

  • Naming: PascalCase for exported types/functions, camelCase for unexported
  • Imports: stdlib first, then third-party, then local packages
  • Context: All public operations accept context.Context as first param
  • Compact mode: Many functions check e.config.CompactMode to return shorter responses
  • Path normalization: NormalizePath() called early in every tool handler for WSL/Windows compat
  • Language: Code in English, user-facing docs in both English and Spanish

Key flags parsed in main.go:

  • --allowed-paths — Comma-separated or positional args for allowed base paths
  • --compact-mode — Minimal token responses for Claude Desktop
  • --cache-size — Cache memory limit (default: 100MB)
  • --parallel-ops — Max concurrent ops (default: 2x CPU, max 16)
  • --hooks-enabled / --hooks-config — Hook system
  • --backup-dir / --backup-max-age / --backup-max-count — Backup config
  • --risk-threshold-medium / --risk-threshold-high — Risk thresholds
  • --debug / --log-level — Logging (debug, info, warn, error — configures slog JSON handler)
  • --log-dir — Directory for audit logs and metrics snapshots (enables operation logging)
  • --normalizer-rules — Path to external normalizer rules JSON file
  • --auto-occoff / warn (default) / block. Automatic OCC on edits without explicit expected_hash (v4.5.17)

When --log-dir is set, the MCP server writes:

  • operations.jsonl — JSON Lines audit log (one entry per tool call, auto-rotates at 10MB, keeps last 3)
  • metrics.json — Performance metrics snapshot (updated every 30 seconds)
  • normalizer_stats.json — Normalizer activity (by tool, by rule, recent normalizations)

All 20 tools are wrapped with auditWrap() in audit.go which records timing, status, path, bytes_in/out, file_size, args summary, risk level, lines_changed, and matches count. Zero overhead when --log-dir is not set.

Separate binary in cmd/dashboard/ — reads log files and serves a web UI:

Terminal window
dashboard.exe --log-dir=<same as MCP server> --backup-dir=<backup path> --port=9100
  • No coupling with MCP server (file-based communication only)
  • Embedded web assets via go:embed (single binary)
  • Real-time updates via SSE (Server-Sent Events)
  • Pages: Dashboard (metrics), Operations (audit log), Backups (enterprise recovery), Statistics, Normalizer, Error Patterns, Edit Analysis

Data-driven normalization engine between MCP transport and tool handlers. Handles Claude Desktop parameter mismatches automatically.

TypeDescriptionExample
param_aliasRename parameterold_strold_text
param_defaultAdd missing parameterMissing id → auto-generated
type_coerceConvert string to type"true"true (bool)
json_accept_bothAccept raw JSON or string[{...}]"[{...}]"
nested_aliasRename field inside JSONstep typeaction
nested_defaultAdd missing nested fieldstep missing id → auto-generated

Covers: old_str/new_str aliases, string-to-bool coercion for force/count_only/dry_run/permanent/recursive, raw JSON array acceptance for edits_json, pipeline typeaction alias, and auto-generated step IDs.

Custom rules via --normalizer-rules rules.json.

12-action pipeline system via batch_operations with pipeline_json parameter.

ActionTypeDescription
searchReadSearch files by pattern
read_rangesReadRead file contents
count_occurrencesReadCount pattern occurrences
editWriteSearch-and-replace
multi_editWriteMultiple edits per file
regex_transformWriteRegex with capture groups
copyWriteCopy files
renameWriteRename/move files
deleteWriteSoft-delete files
aggregateMetaCombine content from steps
diffMetaUnified diff between files
mergeMetaUnion/intersection of file lists
  • Step chaining: input_from and input_from_all for data flow between steps
  • Conditional steps: 9 condition types (has_matches, count_gt, file_exists, etc.)
  • Template variables: {{step_id.field}} resolves to prior step results
  • Parallel execution: parallel: true enables DAG-based scheduling
  • Safety: dry_run, force, stop_on_error, create_backup flags
  • Progress tracking: Per-step audit entries when --log-dir is set
  • All temp files use crypto/rand for names (not predictable timestamps)
  • Backup IDs sanitized: only alphanumeric, -, _ allowed
  • isPathAllowed() resolves symlinks before containment check
  • copyDirectory() skips symlinks
  • Temp files and backup metadata use 0600 permissions
  • No unsafe package usage in production code
  • Line endings normalized via normalizeLineEndings() before risk assessment