Hooks System
Hooks System Documentation
Section titled “Hooks System Documentation”Overview
Section titled “Overview”The MCP Filesystem Ultra-Fast server includes a powerful hooks system inspired by Claude Code, allowing you to execute custom commands before and after file operations. This enables automatic code formatting, validation, linting, and custom workflows.
Features
Section titled “Features”- 12 Hook Events: Pre/post hooks for write, edit, delete, create, move, and copy operations
- Pattern Matching: Target specific files using exact matches, wildcards, or patterns
- Parallel Execution: Hooks run concurrently with automatic deduplication
- Content Modification: Hooks can modify content (e.g., auto-format code before writing)
- Flexible Output: Support for both simple exit codes and advanced JSON responses
- Timeout Control: Configurable timeouts per hook (default: 60 seconds)
- Error Handling: Choose whether operations should fail if hooks fail
Hook Events
Section titled “Hook Events”File Writing
Section titled “File Writing”pre-write: Executes before writing a file (can format/validate content)post-write: Executes after successfully writing a file
File Editing
Section titled “File Editing”pre-edit: Executes before editing a file (can validate changes)post-edit: Executes after successfully editing a file (can verify compilation)
File Deletion
Section titled “File Deletion”pre-delete: Executes before deleting a file/directory (can prevent deletion)post-delete: Executes after successfully deleting
Directory Creation
Section titled “Directory Creation”pre-create: Executes before creating a directorypost-create: Executes after successfully creating a directory
File Moving
Section titled “File Moving”pre-move: Executes before moving a file/directorypost-move: Executes after successfully moving
File Copying
Section titled “File Copying”pre-copy: Executes before copying a file/directorypost-copy: Executes after successfully copying
Configuration
Section titled “Configuration”Enable Hooks
Section titled “Enable Hooks”Start the server with hooks enabled:
mcp-filesystem-ultra.exe --hooks-enabled --hooks-config=hooks.jsonConfiguration File Format
Section titled “Configuration File Format”Create a hooks.json file:
{ "hooks": { "pre-write": [ { "pattern": "*.go", "hooks": [ { "type": "command", "command": "gofmt -w", "timeout": 10, "failOnError": false, "description": "Format Go files before writing", "enabled": true } ] } ], "post-edit": [ { "pattern": "*.go", "hooks": [ { "type": "command", "command": "go build", "timeout": 60, "failOnError": false, "description": "Verify Go files compile after edit", "enabled": true } ] } ] }}Hook Configuration Options
Section titled “Hook Configuration Options”Matcher
Section titled “Matcher”{ "pattern": "*.go", // Pattern to match files "hooks": [...] // Array of hooks to execute}Pattern Types:
- Exact:
"main.go"- Matches exactly “main.go” - Wildcard:
"*.go"- Matches all .go files - Wildcard:
"test_*"- Matches files starting with “test_” - Universal:
"*"- Matches all files
Hook Object
Section titled “Hook Object”{ "type": "command", // "command" or "script" "command": "gofmt -w", // Command to execute "script": "/path/to/script.sh", // Script path (if type=script) "timeout": 10, // Timeout in seconds (default: 60) "failOnError": false, // Fail operation if hook fails "description": "Format code", // Human-readable description "enabled": true // Enable/disable this hook}Hook Input
Section titled “Hook Input”Hooks receive a JSON object via stdin with the following structure:
{ "event": "pre-write", "tool_name": "write_file", "file_path": "C:\\project\\main.go", "operation": "write", "content": "package main...", "old_content": "...", "new_content": "...", "source_path": "...", "dest_path": "...", "timestamp": "2026-02-08T10:30:00Z", "working_dir": "C:\\project", "metadata": {}}Hook Output
Section titled “Hook Output”Simple Mode (Exit Codes)
Section titled “Simple Mode (Exit Codes)”Return exit codes to indicate success or failure:
0: Success - Operation proceeds, stdout shown in logs2: Block operation - stderr message fed to Claude- Other: Non-blocking error - logged but operation proceeds
Example bash script:
#!/bin/bash# Read JSON from stdininput=$(cat)
# Extract file pathfile_path=$(echo "$input" | jq -r '.file_path')
# Run formatterif gofmt -w "$file_path"; then exit 0 # Successelse echo "Formatting failed" >&2 exit 2 # Block operationfiAdvanced Mode (JSON Output)
Section titled “Advanced Mode (JSON Output)”Return structured JSON via stdout for fine-grained control:
{ "decision": "allow", "reason": "File formatted successfully", "modified_content": "package main\n\nfunc main() {\n\tfmt.Println(\"formatted\")\n}", "additional_context": "Applied gofmt formatting", "metadata": { "formatter": "gofmt", "lines_changed": 3 }}Decision Values:
allow: Allow the operation to proceeddeny: Deny the operation (with reason)continue: Continue with next hook
Response Fields:
decision(string): The decision (allow/deny/continue)reason(string): Explanation for the decisionmodified_content(string): Modified file content (for pre-write/pre-edit hooks)additional_context(string): Additional context to logmetadata(object): Custom metadata
Example Python script:
#!/usr/bin/env python3import jsonimport sysimport subprocess
# Read hook context from stdincontext = json.load(sys.stdin)file_path = context['file_path']content = context.get('content', '')
# Run black formattertry: result = subprocess.run( ['black', '--quiet', '-'], input=content.encode(), capture_output=True, check=True ) formatted_content = result.stdout.decode()
# Return formatted content response = { "decision": "allow", "modified_content": formatted_content, "reason": "Code formatted with black" } print(json.dumps(response)) sys.exit(0)
except subprocess.CalledProcessError: # Formatting failed - deny operation response = { "decision": "deny", "reason": "Black formatter failed - code may have syntax errors" } print(json.dumps(response)) sys.exit(2)Common Use Cases
Section titled “Common Use Cases”1. Auto-Format Code Before Writing
Section titled “1. Auto-Format Code Before Writing”{ "hooks": { "pre-write": [ { "pattern": "*.go", "hooks": [{ "command": "gofmt -w", "failOnError": false, "enabled": true }] }, { "pattern": "*.js", "hooks": [{ "command": "prettier --write", "failOnError": false, "enabled": true }] }, { "pattern": "*.py", "hooks": [{ "command": "black", "failOnError": false, "enabled": true }] } ] }}2. Validate Code After Editing
Section titled “2. Validate Code After Editing”{ "hooks": { "post-edit": [ { "pattern": "*.go", "hooks": [{ "command": "go vet", "timeout": 30, "failOnError": false, "enabled": true }] } ] }}3. Run Tests Before Committing
Section titled “3. Run Tests Before Committing”{ "hooks": { "pre-write": [ { "pattern": "*_test.go", "hooks": [{ "command": "go test -v", "timeout": 120, "failOnError": true, "enabled": true }] } ] }}4. Prevent Deletion of Important Files
Section titled “4. Prevent Deletion of Important Files”{ "hooks": { "pre-delete": [ { "pattern": "*.env", "hooks": [{ "command": "echo 'Cannot delete .env files' && exit 2", "failOnError": true, "enabled": true }] } ] }}5. Backup Before Editing
Section titled “5. Backup Before Editing”{ "hooks": { "pre-edit": [ { "pattern": "*", "hooks": [{ "command": "cp \"$FILE_PATH\" \"$FILE_PATH.backup\"", "failOnError": false, "enabled": true }] } ] }}Hook Execution Details
Section titled “Hook Execution Details”Parallel Execution
Section titled “Parallel Execution”- Multiple hooks for the same event run concurrently
- Hooks with identical commands are deduplicated (run only once)
- All hooks must complete before the operation proceeds
Timeout Handling
Section titled “Timeout Handling”- Default timeout: 60 seconds
- Configurable per hook
- If a hook times out, it’s treated as a non-blocking error (unless
failOnError: true)
Error Handling
Section titled “Error Handling”failOnError: false(default): Errors are logged but don’t block the operationfailOnError: true: Hook failures cancel the operation
Content Modification
Section titled “Content Modification”For pre-write and pre-edit hooks:
- If a hook returns
modified_content, that content is used instead of the original - Multiple hooks can modify content sequentially
- The final modified content is what gets written
Security Considerations
Section titled “Security Considerations”⚠️ IMPORTANT: Hooks execute arbitrary commands on your system. Follow these security best practices:
- Validate Inputs: Always validate file paths and content in your hook scripts
- Quote Variables: Use proper quoting in shell commands to prevent injection
- Use Absolute Paths: Specify full paths for scripts and executables
- Restrict Patterns: Use specific patterns instead of wildcards when possible
- Review Configuration: Audit your hooks.json before enabling hooks
- Sandbox Scripts: Consider running hooks in restricted environments
- Avoid Sensitive Files: Don’t create hooks that expose
.env, keys, or credentials
Example: Safe Hook Script
Section titled “Example: Safe Hook Script”#!/bin/bashset -euo pipefail # Exit on error, undefined variables, pipe failures
# Read and validate inputinput=$(cat)file_path=$(echo "$input" | jq -r '.file_path')
# Validate file path (prevent path traversal)if [[ "$file_path" =~ \.\. ]]; then echo "Invalid file path" >&2 exit 2fi
# Process file safely# ... your logic here ...Debugging Hooks
Section titled “Debugging Hooks”Enable debug mode to see hook execution details:
mcp-filesystem-ultra.exe --hooks-enabled --hooks-config=hooks.json --debugDebug output includes:
- Hook execution start/end
- Hook stdout/stderr
- Execution duration
- Decision results
Performance Considerations
Section titled “Performance Considerations”- Hooks add latency to file operations
- Use timeouts to prevent hanging operations
- Consider disabling hooks in performance-critical scenarios
- Hooks run in parallel but overall operation waits for all hooks
Troubleshooting
Section titled “Troubleshooting”Hook Not Executing
Section titled “Hook Not Executing”- Check pattern matches the file:
"*.go"for Go files - Verify
enabled: truein hook configuration - Ensure hooks are enabled:
--hooks-enabled - Check hook configuration path:
--hooks-config=hooks.json
Hook Failing
Section titled “Hook Failing”- Test command manually in terminal
- Check timeout is sufficient
- Verify command exists in PATH
- Review stderr output in debug mode
- Check file permissions
Content Not Modified
Section titled “Content Not Modified”- Ensure hook returns
modified_contentin JSON output - Check hook decision is
allownotcontinue - Verify hook runs before write/edit (use
pre-write/pre-edit)
Examples
Section titled “Examples”See hooks.example.json for a complete configuration example with:
- Go formatting (gofmt)
- JavaScript formatting (prettier)
- Python formatting (black)
- Go validation (go vet)
- Build verification (go build)
API Reference
Section titled “API Reference”HookContext Structure
Section titled “HookContext Structure”type HookContext struct { Event string // Hook event name ToolName string // MCP tool being executed FilePath string // File being operated on Operation string // Operation type Content string // File content (for write/edit) OldContent string // Previous content (for edit) NewContent string // New content (for edit) SourcePath string // Source path (for move/copy) DestPath string // Destination path (for move/copy) Timestamp time.Time // Operation timestamp WorkingDir string // Current working directory Metadata map[string]interface{} // Additional metadata}HookResult Structure
Section titled “HookResult Structure”type HookResult struct { Decision string // allow, deny, or continue Reason string // Reason for decision ModifiedContent string // Modified file content AdditionalContext string // Additional context Metadata map[string]interface{} // Custom metadata Stdout string // Command stdout Stderr string // Command stderr ExitCode int // Command exit code Duration time.Duration // Execution duration}Next Steps
Section titled “Next Steps”- Efficient Code Editing - Token-saving workflows for AI agents
- Core Tools - All available file operation tools
- Backups - Automatic backup system
For questions or issues, report them on GitHub.