restic-defensive-mcp
Servidor MCP stdio estructuralmente de solo lectura para inspeccionar repositorios restic. Los repositorios y credenciales se sellan al inicio; solo se puede ejecutar un subconjunto fijo de subcomandos de restic (snapshots/ls/find/stats). Sin shell, sin backup/restore/forget/prune.
Documentación
restic-defensive-mcp
Servidor MCP estructuralmente de solo lectura (stdio) para inspeccionar repositorios de restic a través de un cliente MCP no confiable sin exponer un shell, CLI de forma libre o ruta de mutación.
¿Están mis respaldos presentes y recientes, es legible su metadato, y contiene una instantánea los archivos que espero?
¿Por qué no exponer restic directamente?
Restic es una herramienta de respaldo poderosa. Un llamador sin restricciones puede:
- eliminar el historial de retención (
forget/prune) - sobrescribir o extraer datos (
backup/restore/dump) - desbloquear o reescribir el estado del repositorio
- aceptar URLs de repositorio arbitrarias y comandos de contraseña
Los envoltorios delgados que exponen "ejecuta restic con estos argumentos" o anulaciones de repositorio por llamada recrean ese radio de explosión dentro de MCP.
Este proyecto es diferente por construcción:
- Los repositorios están declarados y sellados al inicio del proceso
- La superficie MCP es exclusivamente de solo lectura (sin indicador de función para escrituras)
- Solo se puede compilar un subconjunto incorporado de subcomandos de restic
- Sin shell:
exec.CommandContextcon argv fijo solamente - Hosts, etiquetas, rutas y tamaños de resultados están acotados
- Los secretos provienen de archivos con permisos verificados, nunca de
RESTIC_PASSWORD_COMMAND - Los errores están estructurados y redactados
- Cada herramienta reporta una clase de costo explícita (
light/moderate/expensive)
Requisitos
- Go 1.25+ (compilación)
- restic 0.17.1+ en
PATH(orestic_binaryen configuración); probado con 0.19.x - Un cliente MCP que admita servidores stdio locales
Instalación (desde fuente)
git clone https://github.com/ThomasCrouzet/restic-defensive-mcp.git
cd restic-defensive-mcp
make build
./bin/restic-defensive-mcp --version
Inicio rápido
- Crea archivos de contraseña y ubicación del repositorio (archivos regulares, sin enlaces simbólicos). Evita colocar la contraseña en el historial del shell:
secret_dir="${XDG_CONFIG_HOME:-$HOME/.config}/restic-defensive-mcp"
install -d -m 700 "$secret_dir"
install -m 600 /dev/null "$secret_dir/repository"
printf '%s\n' '/path/to/your/repo' > "$secret_dir/repository"
install -m 600 /dev/null "$secret_dir/password"
"${EDITOR:-vi}" "$secret_dir/password"
-
Copia y edita
config.example.yaml, incluyendo las dos rutas de archivo anteriores. -
Ejecuta el binario recién compilado:
./bin/restic-defensive-mcp --config /path/to/config.yaml
- Apunta tu host MCP al binario con
--config(solo transporte stdio).
Ejemplo de fragmento de host MCP (ilustrativo):
{
"mcpServers": {
"restic-defensive": {
"command": "/absolute/path/to/restic-defensive-mcp",
"args": ["--config", "/etc/restic-defensive-mcp/config.yaml"]
}
}
}
Herramientas (exactamente siete)
| Herramienta | Costo | Propósito |
|---|---|---|
restic_capabilities | ligero | Versiones, límites, backends, advertencias |
list_repositories | ligero | IDs configurados y listas permitidas (sin URLs) |
list_snapshots | ligero | Lista de instantáneas acotada |
get_snapshot | ligero | Metadato de una instantánea |
browse_snapshot | moderado | Listado de directorio dentro de ruta permitida |
find_files | moderado–costoso | Búsqueda simple con glob (no regex arbitrario) |
repository_stats | moderado–costoso | Estadísticas de tamaño/conteo para modos permitidos |
No hay run_restic, backup, restore, forget, prune, unlock,
check --read-data, ni argumento de URL de repositorio.
Formas completas de solicitud/respuesta: docs/tool-contract.md.
Configuración
Consulta config.example.yaml. Principios:
- Los llamadores MCP pasan solo
repository_id - Prefiere
repository_file+password_filesobre secretos en línea - Las ubicaciones del repositorio y las credenciales del backend se cargan y sellan al arrancar; cambiar sus archivos fuente no redirige un servidor en ejecución
allowed_hosts/allowed_tags/allowed_pathsson aplicación de reglas, no cosmética- Las listas permitidas vacías significan sin restricción para esa dimensión; el servidor registra una
advertencia al arrancar (
empty_allowlist) para que los operadores lo noten - Las claves YAML desconocidas y los documentos YAML múltiples se rechazan
- Los archivos de secretos deben ser archivos regulares, sin enlaces simbólicos; Unix requiere modo
0600o más estricto, mientras que las implementaciones de Windows deben aplicar ACLs NTFS equivalentes find_filesrequiere unpathexplícito cuando se permiten múltiples raíces- Límites de tiempo de ejecución: los ceros se convierten en valores predeterminados; los valores fuera del mínimo/máximo absoluto se rechazan (no se ajustan silenciosamente). Los valores predeterminados son el punto de partida recomendado; los valores pueden aumentarse solo hasta esos techos
Backends compatibles (v0.1)
| Backend | Compatible |
|---|---|
| sistema de archivos local | sí (solo rutas absolutas) |
| S3 | sí (credenciales mediante archivos de entorno permitidos) |
| Backblaze B2 | sí |
| servidor REST | sí |
| SFTP | no (genera ssh) |
| rclone | no (genera rclone) |
| otro | no |
Notas de compatibilidad: docs/restic-compatibility.md.
Efectos locales: caché y bloqueos
La inspección no es una operación pura sin efectos en el disco ni en la tabla de bloqueos del repositorio:
- restic puede crear o actualizar una caché local (
cache_diro predeterminada) - restic puede tomar un bloqueo de repositorio durante instantáneas/ls/find/stats
Este servidor nunca muta intencionalmente contenidos de respaldo o conjuntos de instantáneas.
Tampoco ejecuta verificación completa de datos (restic check --read-data).
repository_stats responde solo preguntas de tamaño/conteo.
Detalles: SECURITY.md.
Límites de privacidad
Los nombres de archivos de instantáneas, rutas, hosts, etiquetas, tamaños y marcas de tiempo son sensibles. Este servidor:
- nunca devuelve contenidos de archivos
- nunca devuelve URLs de repositorio ni rutas de archivos de secretos
- acota listados y resultados de búsqueda
- sanitiza caracteres de control en nombres
- mantiene los registros de auditoría libres de rutas completas por defecto
Demo (repositorio temporal local)
make demo
Ejecuta el arnés de extremo a extremo contra un repositorio restic desechable creado por
internal/testrepo. Ejercita cada herramienta MCP, prueba la denegación de rutas y la
ausencia de herramientas de mutación, luego elimina el accesorio. Las operaciones del repositorio permanecen
locales; las descargas normales de módulos Go pueden ocurrir en una copia nueva.
Desarrollo
make fmt
make lint
make test # unit tests
make race # race detector
make fuzz-smoke # short run of every fuzz target
make integration # real restic temp repo (requires restic)
make vet
Dependencias
| Módulo | Por qué |
|---|---|
github.com/modelcontextprotocol/go-sdk | SDK oficial de MCP Go (servidor/cliente stdio) |
gopkg.in/yaml.v3 | Análisis de archivos de configuración |
Restic en sí es un binario externo, no un módulo Go.
No objetivos
- Orquestación o programación de respaldos
- Restaurar / olvidar / podar / desbloquear / reparar
- Proxy genérico de CLI de restic
- Importación de configuración de Autorestic
- API remota multiinquilino
restic check --read-datacompleto como herramienta casual- Telemetría o actualización automática
Licencia
MIT, consulta LICENSE.