copilot-fs-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/BACKUPS.md ADDED
@@ -0,0 +1,173 @@
1
+ # 🔄 Sistema de Backups Automáticos
2
+
3
+ ## ¿Qué problema resuelve?
4
+
5
+ Cuando el servidor MCP modifica archivos directamente, VS Code pierde el historial de deshacer (Ctrl+Z). Para mitigar este problema, ahora el servidor **crea backups automáticos** antes de cada modificación.
6
+
7
+ ## 🎯 Características
8
+
9
+ - ✅ **Backups automáticos** antes de cada escritura
10
+ - ✅ **Sin intervención manual** requerida
11
+ - ✅ **Limpieza automática** de backups antiguos
12
+ - ✅ **Herramientas dedicadas** para listar y restaurar backups
13
+ - ✅ **Configurable** por archivo de configuración
14
+
15
+ ## 📦 ¿Dónde se guardan los backups?
16
+
17
+ Por defecto, los backups se guardan en `.mcp-backups/` en la raíz del workspace, manteniendo la estructura de directorios del archivo original:
18
+
19
+ ```
20
+ .mcp-backups/
21
+ src/
22
+ utils/
23
+ helper.ts.2026-03-23T10-30-45-123Z.backup
24
+ helper.ts.2026-03-23T09-15-30-456Z.backup
25
+ config/
26
+ settings.json.2026-03-23T11-00-00-789Z.backup
27
+ ```
28
+
29
+ ## 🔧 Configuración
30
+
31
+ Añade este bloque a tu `config.json`:
32
+
33
+ ```json
34
+ {
35
+ "version": "1.0",
36
+ "permissions": { ... },
37
+ "security": { ... },
38
+ "backup": {
39
+ "enabled": true,
40
+ "maxBackups": 10,
41
+ "backupDir": ".mcp-backups"
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### Opciones de configuración
47
+
48
+ | Campo | Tipo | Default | Descripción |
49
+ |-------|------|---------|-------------|
50
+ | `enabled` | boolean | `true` | Habilita/deshabilita backups automáticos |
51
+ | `maxBackups` | number | `10` | Cantidad máxima de backups por archivo |
52
+ | `backupDir` | string | `".mcp-backups"` | Carpeta donde guardar los backups |
53
+
54
+ ## 🛠️ Nuevas Herramientas
55
+
56
+ ### 1. `list_backups`
57
+
58
+ Lista todos los backups disponibles para un archivo.
59
+
60
+ **Parámetros:**
61
+ ```json
62
+ {
63
+ "path": "/ruta/absoluta/al/archivo.ts"
64
+ }
65
+ ```
66
+
67
+ **Ejemplo de respuesta:**
68
+ ```json
69
+ {
70
+ "file": "C:\\proyecto\\src\\utils\\helper.ts",
71
+ "backups": [
72
+ {
73
+ "index": 0,
74
+ "path": "C:\\proyecto\\.mcp-backups\\src\\utils\\helper.ts.2026-03-23T10-30-45-123Z.backup",
75
+ "timestamp": "2026-03-23T10:30:45.123Z",
76
+ "size": 2048,
77
+ "ageMinutes": 5
78
+ },
79
+ {
80
+ "index": 1,
81
+ "path": "C:\\proyecto\\.mcp-backups\\src\\utils\\helper.ts.2026-03-23T09-15-30-456Z.backup",
82
+ "timestamp": "2026-03-23T09:15:30.456Z",
83
+ "size": 1950,
84
+ "ageMinutes": 80
85
+ }
86
+ ]
87
+ }
88
+ ```
89
+
90
+ ### 2. `restore_backup`
91
+
92
+ Restaura un archivo desde un backup.
93
+
94
+ **Parámetros:**
95
+ ```json
96
+ {
97
+ "path": "/ruta/absoluta/al/archivo.ts",
98
+ "backupIndex": 0 // Opcional, default: 0 (más reciente)
99
+ }
100
+ ```
101
+
102
+ **Ejemplo de respuesta:**
103
+ ```json
104
+ {
105
+ "restored": "C:\\proyecto\\src\\utils\\helper.ts",
106
+ "from": "C:\\proyecto\\.mcp-backups\\src\\utils\\helper.ts.2026-03-23T10-30-45-123Z.backup",
107
+ "timestamp": "2026-03-23T10:30:45.123Z"
108
+ }
109
+ ```
110
+
111
+ ## 💡 Casos de uso
112
+
113
+ ### Restaurar la versión más reciente
114
+
115
+ Si acabas de modificar un archivo y te arrepentiste:
116
+
117
+ 1. Usa `list_backups` para ver los backups disponibles
118
+ 2. Usa `restore_backup` sin especificar índice (restaura el más reciente)
119
+
120
+ ### Restaurar una versión específica
121
+
122
+ Si necesitas volver a una versión anterior:
123
+
124
+ 1. Usa `list_backups` para ver todos los backups
125
+ 2. Identifica el índice del backup que quieres
126
+ 3. Usa `restore_backup` con el `backupIndex` específico
127
+
128
+ ## 📝 Respuesta de `write_file`
129
+
130
+ Ahora cuando escribes un archivo, la respuesta incluye información del backup:
131
+
132
+ ```json
133
+ {
134
+ "path": "C:\\proyecto\\src\\config.ts",
135
+ "bytes": 1024,
136
+ "backup": "C:\\proyecto\\.mcp-backups\\src\\config.ts.2026-03-23T10-30-45-123Z.backup"
137
+ }
138
+ ```
139
+
140
+ Si el archivo era nuevo (no existía backup previo), `backup` será `undefined`.
141
+
142
+ ## ⚙️ Gestión de backups
143
+
144
+ - Los backups se limpian automáticamente cuando superen `maxBackups`
145
+ - Los backups más antiguos se eliminan primero
146
+ - Puedes desactivar backups con `"enabled": false`
147
+ - El directorio `.mcp-backups/` se puede añadir al `.gitignore`
148
+
149
+ ## 🔒 Seguridad
150
+
151
+ El sistema de backups respeta las mismas reglas de permisos:
152
+ - Para listar backups necesitas permiso de **lectura** en el archivo
153
+ - Para restaurar backups necesitas permiso de **escritura** en el archivo
154
+
155
+ ## 🎨 Mejorando el flujo de trabajo
156
+
157
+ Aunque no recuperamos el Ctrl+Z de VS Code, este sistema te da:
158
+
159
+ 1. **Historial persistente**: Los backups permanecen aunque cierres VS Code
160
+ 2. **Más control**: Puedes ver todos los backups y elegir cuál restaurar
161
+ 3. **Tranquilidad**: Siempre puedes volver atrás, incluso días después
162
+ 4. **Automatización**: Todo funciona sin intervención manual
163
+
164
+ ## 🚀 Próximos pasos sugeridos
165
+
166
+ Considera añadir al `.gitignore`:
167
+
168
+ ```gitignore
169
+ # MCP Backups
170
+ .mcp-backups/
171
+ ```
172
+
173
+ Esto evita que los backups se suban al repositorio.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JDUG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,172 @@
1
+
2
+ # 🚀 Copilot FS MCP
3
+
4
+ [![npm version](https://badge.fury.io/js/copilot-fs-mcp.svg)](https://www.npmjs.com/package/copilot-fs-mcp)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js Version](https://img.shields.io/node/v/copilot-fs-mcp)](https://nodejs.org)
7
+
8
+ Servidor MCP (Model Context Protocol) para acceso seguro al sistema de archivos desde GitHub Copilot.
9
+
10
+ ## ✨ Características
11
+
12
+ - 🔒 **Sistema de permisos granular** - Control preciso sobre qué archivos se pueden leer/escribir
13
+ - 📝 **Operaciones de archivos** - Lectura, escritura, listado y búsqueda
14
+ - 🔄 **Backups automáticos** - Sistema de respaldo antes de cada modificación ([ver documentación](BACKUPS.md))
15
+ - 🔍 **Búsqueda de archivos** - Por nombre y contenido
16
+ - 📊 **Logging de accesos** - Auditoría completa de operaciones
17
+ - ⚡ **Hot-reload de configuración** - Cambios en tiempo real sin reiniciar
18
+
19
+
20
+ ## 📦 Instalación
21
+
22
+ ### Instalación global (recomendada)
23
+ ```bash
24
+ npm install -g copilot-fs-mcp
25
+ ```
26
+
27
+ ### Uso con npx (sin instalación global)
28
+ ```bash
29
+ npx copilot-fs-mcp
30
+ ```
31
+
32
+
33
+ ## 🚀 Quick Start
34
+
35
+ 1. Instala globalmente:
36
+ ```bash
37
+ npm install -g copilot-fs-mcp
38
+ ```
39
+ 2. Configura VSCode en settings.json:
40
+ ```json
41
+ {
42
+ "mcp": {
43
+ "servers": {
44
+ "local-filesystem": {
45
+ "command": "copilot-fs-mcp",
46
+ "args": ["--config", "ruta/a/config.json"]
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ```
52
+ 3. Crea tu archivo config.json (ver ejemplo abajo)
53
+ 4. ¡Listo! Usa Copilot Agent para acceder al sistema de archivos de forma segura.
54
+
55
+ ## ⚙️ Configuración
56
+
57
+ El servidor requiere un archivo de configuración JSON. Ejemplo mínimo:
58
+
59
+ ```json
60
+ {
61
+ "version": "1.0",
62
+ "permissions": {
63
+ "allowed": [
64
+ {
65
+ "path": "C:/Users/Usuario/Documents/proyecto",
66
+ "operations": ["read", "write", "list", "search"]
67
+ }
68
+ ],
69
+ "denied": []
70
+ },
71
+ "security": {
72
+ "maxFileSizeBytes": 5242880,
73
+ "allowedExtensions": [".ts", ".js", ".md", ".json", ".txt"],
74
+ "logAllAccess": true,
75
+ "logPath": "C:/Users/Usuario/.config/copilot-fs-mcp/logs"
76
+ },
77
+ "backup": {
78
+ "enabled": true,
79
+ "maxBackups": 10,
80
+ "backupDir": ".mcp-backups"
81
+ }
82
+ }
83
+ ```
84
+
85
+
86
+ ## 🚀 Uso CLI
87
+
88
+ Iniciar el servidor:
89
+ ```bash
90
+ copilot-fs-mcp --config /ruta/a/config.json
91
+ ```
92
+
93
+ Ver ayuda de comandos:
94
+ ```bash
95
+ copilot-fs-mcp --help
96
+ ```
97
+
98
+ ### Comandos principales:
99
+
100
+ - `init` — Asistente de configuración interactiva
101
+ - `add-path <ruta>` — Añade ruta permitida
102
+ - `remove-path <ruta>` — Revoca acceso a una ruta
103
+ - `list` — Muestra configuración actual
104
+ - `validate` — Verifica integridad de config.json
105
+ - `logs` — Muestra logs de auditoría
106
+
107
+
108
+ ## 🛠️ Herramientas disponibles
109
+
110
+ | Herramienta | Descripción | Ejemplo CLI |
111
+ |---------------------|--------------------------------------------------|------------------------------------|
112
+ | `read_file` | Lee el contenido de un archivo | copilot-fs-mcp read_file --path ...|
113
+ | `write_file` | Escribe contenido en un archivo (con backup) | copilot-fs-mcp write_file ... |
114
+ | `list_directory` | Lista archivos y carpetas en un directorio | copilot-fs-mcp list_directory ... |
115
+ | `search_files` | Busca archivos por nombre o contenido | copilot-fs-mcp search_files ... |
116
+ | `get_permissions` | Muestra la configuración de permisos actual | copilot-fs-mcp get_permissions |
117
+ | `list_backups` | Lista backups disponibles para un archivo | copilot-fs-mcp list_backups ... |
118
+ | `restore_backup` | Restaura un archivo desde un backup | copilot-fs-mcp restore_backup ... |
119
+
120
+ | Herramienta | Descripción |
121
+ |-------------|-------------|
122
+ | `read_file` | Lee el contenido de un archivo |
123
+ | `write_file` | Escribe contenido en un archivo (con backup automático) |
124
+ | `list_directory` | Lista archivos y carpetas en un directorio |
125
+ | `search_files` | Busca archivos por nombre o contenido |
126
+ | `get_permissions` | Muestra la configuración de permisos actual |
127
+ | `list_backups` | Lista backups disponibles para un archivo |
128
+ | `restore_backup` | Restaura un archivo desde un backup |
129
+
130
+
131
+ ## 🔄 Sistema de Backups
132
+
133
+ El servidor **crea backups automáticos** antes de modificar archivos, mitigando el problema de pérdida del historial de deshacer (Ctrl+Z) en VS Code cuando los archivos se modifican externamente.
134
+
135
+ **[📖 Ver documentación completa de backups →](BACKUPS.md)**
136
+
137
+ Características principales:
138
+ - ✅ Backups automáticos antes de cada escritura
139
+ - ✅ Limpieza automática de backups antiguos
140
+ - ✅ Herramientas para listar y restaurar versiones
141
+ - ✅ Completamente configurable
142
+
143
+
144
+ ## 🧪 Testing
145
+
146
+ ```bash
147
+ npm test # Ejecutar tests
148
+ npm run test:coverage # Ejecutar tests con coverage
149
+ ```
150
+
151
+ ## 🛠️ Troubleshooting
152
+
153
+ ### Server not connecting
154
+ - Verifica la ruta absoluta a config.json
155
+ - Revisa la consola de desarrollador de VSCode para errores
156
+
157
+ ### Permission denied errors
158
+ - Revisa que config.json permita la ruta y operación
159
+ - Verifica que las rutas usen barras correctas
160
+
161
+ ### Problemas comunes
162
+ - Si el binario no responde, asegúrate de tener Node.js >= 18
163
+ - Si el paquete no aparece tras instalar, revisa tu $PATH
164
+
165
+
166
+ ## 🤝 Contributing
167
+
168
+ ¡Contribuciones, issues y sugerencias son bienvenidas! Por favor, abre un issue o pull request en [GitHub](https://github.com/tu-usuario/copilot-fs-mcp).
169
+
170
+ ## 📄 Licencia
171
+
172
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,9 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+ | Version | Supported |
5
+ | ------- | ------------------ |
6
+ | 1.x | :white_check_mark: |
7
+
8
+ ## Reporting a Vulnerability
9
+ If you discover a security vulnerability, please report it by email to [jhonnathan.dev@gmail.com] or by creating a private security advisory on GitHub. We will respond as soon as possible and coordinate a fix.
@@ -0,0 +1,39 @@
1
+ {
2
+ "version": "1.0",
3
+ "permissions": {
4
+ "allowed": [
5
+ {
6
+ "path": "C:/Users/Usuario/Documents/proyecto",
7
+ "operations": ["read", "write", "list", "search"]
8
+ }
9
+ ],
10
+ "denied": [
11
+ "~/.ssh",
12
+ "~/.aws",
13
+ "~/.config/secrets"
14
+ ]
15
+ },
16
+ "security": {
17
+ "maxFileSizeBytes": 5242880,
18
+ "allowedExtensions": [
19
+ ".ts",
20
+ ".js",
21
+ ".jsx",
22
+ ".tsx",
23
+ ".md",
24
+ ".json",
25
+ ".txt",
26
+ ".css",
27
+ ".html",
28
+ ".yml",
29
+ ".yaml"
30
+ ],
31
+ "logAllAccess": true,
32
+ "logPath": "C:/Users/Usuario/.config/copilot-fs-mcp/logs"
33
+ },
34
+ "backup": {
35
+ "enabled": true,
36
+ "maxBackups": 10,
37
+ "backupDir": ".mcp-backups"
38
+ }
39
+ }
package/dist/index.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const server_1 = require("./server");
8
+ const read_file_1 = __importDefault(require("./tools/read-file"));
9
+ const write_file_1 = __importDefault(require("./tools/write-file"));
10
+ const list_directory_1 = __importDefault(require("./tools/list-directory"));
11
+ const search_files_1 = __importDefault(require("./tools/search-files"));
12
+ const get_permissions_1 = __importDefault(require("./tools/get-permissions"));
13
+ const backup_tools_1 = require("./tools/backup-tools");
14
+ const config_loader_1 = require("./permissions/config-loader");
15
+ const logger_1 = require("./utils/logger");
16
+ function getConfigArg() {
17
+ const idx = process.argv.indexOf('--config');
18
+ if (idx !== -1 && process.argv[idx + 1])
19
+ return process.argv[idx + 1];
20
+ return null;
21
+ }
22
+ async function main() {
23
+ const configPath = getConfigArg();
24
+ if (!configPath) {
25
+ console.error('Error: debes indicar la ruta del archivo de configuración.');
26
+ console.error('Uso: copilot-fs-mcp --config /ruta/a/tu/config.json');
27
+ process.exit(1);
28
+ }
29
+ const server = new server_1.Server();
30
+ // Store current config in memory
31
+ let currentConfig = null;
32
+ // register tools with MCP-compliant descriptions and inputSchema
33
+ // All tools now receive the current config
34
+ server.registerTool('read_file', async (input) => {
35
+ if (!currentConfig)
36
+ throw new Error('Configuration not loaded');
37
+ return (0, read_file_1.default)(input, currentConfig);
38
+ }, 'Read the contents of a file at the given path', { type: 'object', properties: { path: { type: 'string', description: 'Absolute path to the file' } }, required: ['path'] });
39
+ server.registerTool('write_file', async (input) => {
40
+ if (!currentConfig)
41
+ throw new Error('Configuration not loaded');
42
+ return (0, write_file_1.default)(input, currentConfig);
43
+ }, 'Write content to a file, creating directories if needed', { type: 'object', properties: { path: { type: 'string', description: 'Absolute path to the file' }, content: { type: 'string', description: 'Content to write' } }, required: ['path', 'content'] });
44
+ server.registerTool('list_directory', async (input) => {
45
+ if (!currentConfig)
46
+ throw new Error('Configuration not loaded');
47
+ return (0, list_directory_1.default)(input, currentConfig);
48
+ }, 'List files and folders in a directory', { type: 'object', properties: { path: { type: 'string', description: 'Absolute path to the directory' } }, required: ['path'] });
49
+ server.registerTool('search_files', async (input) => {
50
+ if (!currentConfig)
51
+ throw new Error('Configuration not loaded');
52
+ return (0, search_files_1.default)(input, currentConfig);
53
+ }, 'Search for files by name pattern or content', { type: 'object', properties: { rootPath: { type: 'string', description: 'Root directory to search in' }, pattern: { type: 'string', description: 'Glob pattern for filenames' }, searchContent: { type: 'string', description: 'Optional text to search inside files' } }, required: ['rootPath', 'pattern'] });
54
+ server.registerTool('get_permissions', async (input) => {
55
+ if (!currentConfig)
56
+ throw new Error('Configuration not loaded');
57
+ return (0, get_permissions_1.default)(input, currentConfig);
58
+ }, 'Show current permission configuration', { type: 'object', properties: {} });
59
+ server.registerTool('list_backups', async (input) => {
60
+ if (!currentConfig)
61
+ throw new Error('Configuration not loaded');
62
+ return (0, backup_tools_1.listBackupsTool)(input, currentConfig);
63
+ }, 'List all available backups for a file', { type: 'object', properties: { path: { type: 'string', description: 'Absolute path to the file' } }, required: ['path'] });
64
+ server.registerTool('restore_backup', async (input) => {
65
+ if (!currentConfig)
66
+ throw new Error('Configuration not loaded');
67
+ return (0, backup_tools_1.restoreBackupTool)(input, currentConfig);
68
+ }, 'Restore a file from a backup (default: most recent)', { type: 'object', properties: { path: { type: 'string', description: 'Absolute path to the file' }, backupIndex: { type: 'number', description: 'Index of backup to restore (0 = most recent)' } }, required: ['path'] });
69
+ // Watch config — auto-reloads on changes
70
+ const watcher = new config_loader_1.ConfigWatcher(configPath);
71
+ watcher.on('change', async (cfg) => {
72
+ currentConfig = cfg; // Update the config in memory
73
+ try {
74
+ await (0, logger_1.configureLogger)({ logPath: cfg.security.logPath, stderr: true });
75
+ }
76
+ catch { }
77
+ server.emit('config.loaded', cfg);
78
+ (0, logger_1.info)('config loaded/reloaded from', configPath);
79
+ });
80
+ await watcher.start();
81
+ (0, server_1.startStdioLoop)(server);
82
+ process.on('uncaughtException', (err) => {
83
+ console.error('uncaughtException', err);
84
+ });
85
+ }
86
+ main().catch((err) => {
87
+ console.error('startup error', err);
88
+ process.exit(1);
89
+ });
90
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}