Skip to main content
Glama
mvecchiett

filesystem-gitignore

by mvecchiett
README.md
# πŸ—‚οΈ MCP Filesystem Server

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

Un servidor MCP (Model Context Protocol) profesional que proporciona operaciones de sistema de archivos mientras **respeta automΓ‘ticamente los patrones de `.gitignore`**.

## 🎯 ¿Qué problema resuelve?

Cuando Claude trabaja con proyectos que tienen `venv/`, `node_modules/`, o `.git/`, intentar leer todo el directorio puede:
- ⚠️ **Agotar el límite de tokens** leyendo 50k+ archivos innecesarios
- ⏱️ **Ser extremadamente lento** al procesar directorios gigantes
- 🀯 **Ser confuso** mezclando código fuente con dependencias

**Este servidor resuelve eso** respetando `.gitignore` automΓ‘ticamente, igual que Git. Claude solo ve lo que realmente importa: tu cΓ³digo.

## ✨ Características

- βœ… **Respeta `.gitignore` automΓ‘ticamente**: Excluye `venv/`, `node_modules/`, `__pycache__/`, etc.
- βœ… **Optimizado para tokens**: Solo lee archivos relevantes de tu proyecto
- βœ… **Operaciones completas**: Leer, escribir, listar, buscar, y crear archivos/directorios
- βœ… **Seguridad por diseΓ±o**: Solo accede a directorios explΓ­citamente permitidos
- βœ… **Caracteres especiales**: Maneja espacios, `#`, `@`, y otros caracteres en nombres
- βœ… **Cache inteligente**: Cachea patrones `.gitignore` con invalidaciΓ³n automΓ‘tica
- βœ… **Type-safe**: Completamente tipado con dataclasses y type hints
- βœ… **Production-ready**: Tests, logging, manejo de errores robusto

## πŸ—οΈ Arquitectura

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MCP Protocol Layer                       β”‚
β”‚  (server.py - Adaptador que traduce MCP ↔ FileSystemService)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             Business Logic Layer                           β”‚
β”‚(filesystem_service.py - Orquesta validaciΓ³n + operaciones) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                              β”‚
       β–Ό                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Path Validation  β”‚         β”‚  .gitignore Manager  β”‚
β”‚ (path_validator) β”‚         β”‚  (ignore_manager)    β”‚
β”‚                  β”‚         β”‚                      β”‚
β”‚ - URL decoding   β”‚         β”‚ - Pattern matching   β”‚
β”‚ - Security check β”‚         β”‚ - Intelligent cache  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                              β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚    Data Access Layer            β”‚
       β”‚  (filesystem_operations.py)     β”‚
       β”‚                                 β”‚
       β”‚  - Pure I/O operations          β”‚
       β”‚  - No business logic            β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

**Responsabilidades por capa:**

1. **MCP Protocol Layer** (`server.py`): 
   - Traduce requests MCP a llamadas del service
   - Serializa responses a JSON
   - Maneja el protocolo stdio

2. **Business Logic Layer** (`filesystem_service.py`):
   - Orquesta validaciΓ³n + filtering + operaciones
   - Punto de entrada pΓΊblico del sistema
   - Combina mΓΊltiples componentes para cada operaciΓ³n

3. **Support Components**:
   - `path_validator`: Normaliza y valida paths (seguridad)
   - `ignore_manager`: Cache y matching de `.gitignore`
   - `filesystem_operations`: I/O puro, sin lΓ³gica de negocio

4. **Foundation**:
   - `config.py`: ConfiguraciΓ³n centralizada
   - `errors.py`: Excepciones tipadas
   - `models.py`: Dataclasses para type safety

**Beneficios de esta arquitectura:**
- βœ… Cada capa es testeable independientemente
- βœ… FΓ‘cil cambiar implementaciΓ³n de una capa sin afectar otras
- βœ… SeparaciΓ³n clara de responsabilidades
- βœ… CΓ³digo reutilizable (el service puede usarse fuera de MCP)

## πŸ“‹ Requisitos

- Python 3.10+
- Compatible con clientes MCP como Claude Desktop, Zed, Sourcegraph Cody y otros que implementen el estΓ‘ndar Model Context Protocol.

## πŸš€ InstalaciΓ³n RΓ‘pida

```bash
# 1. Clonar y navegar al proyecto
cd "C:\DesarrolloPython\MCP FileSystem"

# 2. Instalar dependencias de desarrollo
make.bat install-dev

# 3. Ejecutar tests para verificar
make.bat test
```

### Configurar Claude Desktop

Edita el archivo de configuraciΓ³n:

**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "filesystem-gitignore": {
      "command": "python",
      "args": [
        "-m",
        "mcp_filesystem"
      ],
      "env": {
        "ALLOWED_DIRECTORIES": "C:\\DesarrolloPython;C:\\MisProyectos"
      }
    }
  }
}
```

**Notas:**
- Usa paths absolutos
- Windows: separa directorios con `;`
- Unix/Mac: separa directorios con `:`

Reinicia Claude Desktop para aplicar cambios.

## πŸ”§ Uso

### Herramientas Disponibles

#### 1. `read_file` - Leer archivo de texto

```python
read_file(path="C:\\DesarrolloPython\\proyecto\\src\\main.py")
```

#### 2. `write_file` - Escribir archivo

```python
write_file(
    path="C:\\DesarrolloPython\\nuevo_archivo.py",
    content="print('Hello, World!')"
)
```

#### 3. `list_directory` - Listar contenido (no recursivo)

```python
# Por defecto respeta .gitignore
list_directory(path="C:\\DesarrolloPython\\proyecto")

# Forzar mostrar TODO (incluso venv)
list_directory(path="C:\\DesarrolloPython\\proyecto", respect_gitignore=False)
```

#### 4. `directory_tree` - Árbol recursivo

```python
directory_tree(
    path="C:\\DesarrolloPython\\proyecto",
    max_depth=5,
    respect_gitignore=True  # Default
)
```

#### 5. `search_files` - Buscar archivos

```python
search_files(
    path="C:\\DesarrolloPython",
    pattern="config",  # Case-insensitive
    respect_gitignore=True
)
```

#### 6. `get_file_info` - InformaciΓ³n detallada

```python
get_file_info(path="C:\\DesarrolloPython\\proyecto\\README.md")
```

#### 7. `create_directory` - Crear directorio

```python
create_directory(path="C:\\DesarrolloPython\\nuevo_proyecto\\src")
```

## πŸ“ Decisiones de DiseΓ±o

### ΒΏCΓ³mo se maneja `.gitignore`?

1. **Parseo con pathspec**: Usamos la librerΓ­a `pathspec` que implementa el mismo algoritmo que Git
2. **Cache inteligente**: 
   - Cada `.gitignore` se parsea una sola vez y se cachea
   - El cache se invalida automΓ‘ticamente cuando el `.gitignore` cambia (detecta por `mtime`)
   - Cache por directorio (cada dir tiene su propio `.gitignore`)
3. **Matching preciso**: 
   - Convierte paths a formato POSIX (forward slashes)
   - Agrega `/` al final de directorios (convenciΓ³n de Git)
   - Usa `gitwildmatch` para matching exacto

### ΒΏCΓ³mo se optimiza el consumo de tokens?

1. **Filtrado temprano**: Los archivos ignorados ni siquiera se listan
2. **Control de profundidad**: `directory_tree` limita profundidad mΓ‘xima (default: 5)
3. **Sin lectura de contenido**: Solo lista nombres, no lee contenidos
4. **Respeto opcional**: Todas las herramientas tienen `respect_gitignore` flag (default: `True`)

**ComparaciΓ³n:**

```python
# ❌ Sin .gitignore (50k+ archivos en venv):
directory_tree("C:\\proyecto")  # πŸ”₯ Consume 100k+ tokens

# βœ… Con .gitignore (solo archivos de proyecto):
directory_tree("C:\\proyecto")  # βœ… ~2k tokens
```

### Seguridad: ΒΏPor quΓ© directorios permitidos?

- Previene acceso a archivos sensibles del sistema
- Claude solo puede trabajar en tus proyectos
- ValidaciΓ³n en cada operaciΓ³n (no se puede "escapar" con `../../../`)

## πŸ§ͺ Testing

```bash
# Ejecutar todos los tests
make.bat test

# Solo tests unitarios
make.bat test-unit

# Solo tests de integraciΓ³n
make.bat test-integration

# Con reporte de coverage
make.bat test-cov
```

## πŸ› οΈ Desarrollo

```bash
# Formatear cΓ³digo
make.bat format

# Linters
make.bat lint

# Limpiar archivos generados
make.bat clean
```

## πŸ› Troubleshooting

### "ALLOWED_DIRECTORIES environment variable must be set"

**SoluciΓ³n:** Configura la variable de entorno en Claude Desktop config.

### "Access denied"

**Causa:** El path no estΓ‘ en `ALLOWED_DIRECTORIES`

**SoluciΓ³n:** Agrega el directorio a la lista.

### No respeta `.gitignore`

**Verifica:**
1. ΒΏExiste `.gitignore` en el directorio?
2. ΒΏLos patrones estΓ‘n bien escritos?
3. ΒΏEstΓ‘s usando `respect_gitignore=True`? (es el default)

### Consume muchos tokens

**SoluciΓ³n:**
1. Crea/mejora tu `.gitignore`
2. Reduce `max_depth` en `directory_tree`

```gitignore
# .gitignore recomendado para Python:
venv/
env/
__pycache__/
*.pyc
.git/
.pytest_cache/
.mypy_cache/
htmlcov/
```

## πŸ“š Referencias

- [MCP Protocol Specification](https://github.com/modelcontextprotocol/specification)
- [pathspec library](https://pypi.org/project/pathspec/)
- [gitignore patterns](https://git-scm.com/docs/gitignore)

## 🀝 Contribuciones

Β‘Las contribuciones son bienvenidas!

**Antes de hacer PR:**
- βœ… Ejecuta `make.bat test` (todos los tests deben pasar)
- βœ… Ejecuta `make.bat lint` (sin warnings)
- βœ… Ejecuta `make.bat format` (cΓ³digo formateado)
- βœ… Agrega tests para nueva funcionalidad

## πŸ“„ Licencia

MIT License - Úsalo libremente.

---

**Desarrollado con ❀️ para optimizar la interacción de Claude con proyectos reales**