A Git-enforced filesystem MCP server that integrates git with filesystem operations, enforcing commits on writes, providing reads with history, and supporting staged branching.
- Direct Mode: Write and commit in one call with templated messages.
- Staged Mode: Open ephemeral branch, stage edits, preview, then merge/rebase or abort.
- Reader Subagent: Intent-directed extraction and summarization.
- Integrated Tools: Wraps file_system, text_replace, code_diff with git semantics.
- Safety: Path traversal protection, git safe.directory, dirty tree guards.
uv venv && uv pip install -e .[dev]
pre-commit install
The fs-git MCP server can be run in two ways:
Option 1: Using the CLI command
# For Claude Desktop and MCP Inspector (stdio transport)
fs-git serve
# For development/testing (TCP transport)
fs-git serve --transport tcp --port 8080
Option 2: Using the direct MCP server command
# stdio mode (default, for Claude Desktop)
fs-git-mcp
# TCP mode for development
fs-git-mcp --transport tcp --port 8080
Option 3: Using uvx (no installation required)
# Run directly without installation
uvx fs-git-mcp
# Or with the CLI
uvx --from . fs-git serve
Add this to your Claude Desktop configuration (~/.claude/config.json
):
{
"mcpServers": {
"fs-git": {
"command": "uvx",
"args": ["fs-git-mcp"]
}
}
}
Or if installed locally:
{
"mcpServers": {
"fs-git": {
"command": "fs-git-mcp"
}
}
}
# Install MCP Inspector
npm install -g @modelcontextprotocol/inspector
# Test the server
npx @modelcontextprotocol/inspector fs-git-mcp
The MCP server exposes these tool namespaces:
- git_fs:
write_and_commit
,read_with_history
,start_staged
,staged_write
,staged_preview
,finalize_staged
,abort_staged
- fs_reader:
extract
,answer_about_file
- fs_text_replace:
replace_and_commit
- fs_code_diff:
preview_diff
- fs_io:
read_file
,stat_file
,list_dir
,make_dir
FS-Git supports configurable path authorization for security. You can restrict which paths can be accessed using CLI parameters or environment variables.
# Allow only specific paths
fs-git write --repo <root> --path src/utils.py \
--allow-paths "src/**,docs/**" \
--deny-paths "!src/secrets/**,!**/node_modules/**" \
--file - --subject "[{op}] {path} – {summary}" \
--op "add" --summary "utility functions" <<'EOF'
def helper():
return "utility"
EOF
Set path patterns via environment variables for global configuration:
# Set allowed paths (comma-separated)
export FS_GIT_ALLOWED_PATHS="src/**,docs/**,*.md"
# Set denied paths (comma-separated, with ! prefix)
export FS_GIT_DENIED_PATHS="!**/node_modules/**,!**/.git/**,!src/secrets/**"
# Now all fs-git commands will use these patterns
fs-git write --repo <root> --path src/app.py --file - --subject "Add app" <<'EOF'
print("Hello World")
EOF
- Glob patterns:
src/**
,docs/**/*.md
,*.txt
- Regex patterns:
r".*\.py$"
,r".*\.js$"
- Deny patterns: Prefix with
!
(e.g.,!**/node_modules/**
) - Absolute paths:
/etc/hosts
,/usr/local/bin/
- Relative paths:
src/
,./docs/
Priority: CLI parameters override environment variables.
-
Initialize a repo:
fs-git init <repo_root>
-
Direct write:
fs-git write --repo <root> --path <p> --file <in> \ --subject "[{op}] {path} – {summary}" --op "edit" --summary "update"
-
Staged flow:
sid=$(fs-git staged start --repo <root> --ticket T-123) fs-git staged write --session "$sid" --path <p> --file <in> --summary "..." fs-git staged preview --session "$sid" fs-git staged finalize --session "$sid" --strategy rebase-merge
-
Reader extract:
fs-git reader extract --repo <root> --path <p> --query "foo.*bar" --regex
Run the basic demo script:
make demo
Run the complete copy-paste demo that showcases all features:
# From the fs-git project root
bash repos/fs-git/scripts/comprehensive_demo.sh
This comprehensive demo includes:
- Installation and setup
- Basic direct write operations with git commits
- Staged workflow with ephemeral branches
- Text replacement and patch application
- Path authorization with allowed/denied patterns
- Environment variable configuration
- MCP server testing
- Claude Desktop integration examples
- Tests:
make test
- Lint:
make fmt && make lint
- E2E:
make test-e2e
See ARCHITECTURE.md for module details.
See TOOLING.md for MCP schema and integrations.
- Import Errors: Ensure
mcp_server
is in PYTHONPATH or installed withuv pip install -e .
- Git Safe Directory: If git complains about unsafe repo, run
git config --global --add safe.directory <repo_root>
- Path Authorization Denied: Check your
FS_GIT_ALLOWED_PATHS
andFS_GIT_DENIED_PATHS
env vars or CLI flags. - Staged Session Not Found: Sessions are stored in
~/.fs_git_sessions
. Clear if corrupted. - MCP Inspector Connection: Use
fs-git serve
for stdio mode with Inspector. For TCP, use--transport tcp
. - Subprocess Python Errors: Tests use
sys.executable
to match your Python environment.
- Server logs: Check
server.log
or stderr. - Git logs: Use
git log --oneline -10
in repo.
Run with debug:
FS_GIT_DEBUG=true fs-git serve --transport tcp
See CHANGELOG.md.