file-organizer-mcp 3.1.2 → 3.1.4
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/ARCHITECTURE.md +588 -582
- package/CHANGELOG.md +195 -155
- package/CONTRIBUTING.md +314 -312
- package/MIGRATION.md +365 -358
- package/README.md +803 -773
- package/bin/file-organizer-mcp.mjs +141 -0
- package/bin/file-organizer-setup.mjs +76 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +40 -7
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +179 -8
- package/dist/index.js.map +1 -1
- package/dist/schemas/common.schemas.d.ts +1 -1
- package/dist/schemas/common.schemas.js +1 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/organize.schemas.d.ts +1 -1
- package/dist/schemas/organize.schemas.js +1 -1
- package/dist/schemas/scan.schemas.d.ts +1 -1
- package/dist/schemas/scan.schemas.js +1 -1
- package/dist/schemas/security.schemas.d.ts +1 -1
- package/dist/schemas/security.schemas.js +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/services/auto-organize.service.d.ts +18 -4
- package/dist/services/auto-organize.service.d.ts.map +1 -1
- package/dist/services/auto-organize.service.js +71 -19
- package/dist/services/auto-organize.service.js.map +1 -1
- package/dist/services/categorizer.service.d.ts +1 -1
- package/dist/services/categorizer.service.js +2 -2
- package/dist/services/categorizer.service.js.map +1 -1
- package/dist/services/duplicate-finder.service.d.ts +1 -1
- package/dist/services/duplicate-finder.service.js +1 -1
- package/dist/services/file-scanner.service.d.ts +1 -1
- package/dist/services/file-scanner.service.d.ts.map +1 -1
- package/dist/services/file-scanner.service.js +42 -29
- package/dist/services/file-scanner.service.js.map +1 -1
- package/dist/services/hash-calculator.service.d.ts +1 -1
- package/dist/services/hash-calculator.service.js +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/metadata.service.d.ts.map +1 -1
- package/dist/services/metadata.service.js +0 -2
- package/dist/services/metadata.service.js.map +1 -1
- package/dist/services/organizer.service.d.ts +1 -1
- package/dist/services/organizer.service.js +2 -2
- package/dist/services/organizer.service.js.map +1 -1
- package/dist/services/path-validator.service.d.ts +1 -1
- package/dist/services/path-validator.service.js +1 -1
- package/dist/services/renaming.service.d.ts +1 -1
- package/dist/services/renaming.service.js +2 -2
- package/dist/services/renaming.service.js.map +1 -1
- package/dist/services/rollback.service.d.ts +1 -1
- package/dist/services/rollback.service.js +1 -1
- package/dist/services/security/rate-limiter.service.d.ts +1 -1
- package/dist/services/security/rate-limiter.service.js +1 -1
- package/dist/services/streaming-scanner.service.d.ts +1 -1
- package/dist/services/streaming-scanner.service.js +1 -1
- package/dist/tests/test-edge-cases.js +3 -1
- package/dist/tests/test-edge-cases.js.map +1 -1
- package/dist/tools/duplicate-management.d.ts +1 -1
- package/dist/tools/duplicate-management.js +1 -1
- package/dist/tools/file-analysis.d.ts +1 -1
- package/dist/tools/file-analysis.js +1 -1
- package/dist/tools/file-categorization.d.ts +1 -1
- package/dist/tools/file-categorization.js +1 -1
- package/dist/tools/file-duplicates.d.ts +1 -1
- package/dist/tools/file-duplicates.js +1 -1
- package/dist/tools/file-listing.d.ts +1 -1
- package/dist/tools/file-listing.js +1 -1
- package/dist/tools/file-management.d.ts +1 -1
- package/dist/tools/file-management.js +1 -1
- package/dist/tools/file-organization.d.ts +1 -1
- package/dist/tools/file-organization.js +1 -1
- package/dist/tools/file-renaming.d.ts +1 -1
- package/dist/tools/file-renaming.js +1 -1
- package/dist/tools/file-scanning.d.ts +1 -1
- package/dist/tools/file-scanning.js +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/metadata-inspection.d.ts +1 -1
- package/dist/tools/metadata-inspection.js +1 -1
- package/dist/tools/organization-preview.d.ts +1 -1
- package/dist/tools/organization-preview.js +1 -1
- package/dist/tools/rollback.d.ts +1 -1
- package/dist/tools/rollback.js +1 -1
- package/dist/tools/watch.tool.d.ts +1 -1
- package/dist/tools/watch.tool.js +1 -1
- package/dist/tui/client-detector.d.ts +49 -0
- package/dist/tui/client-detector.d.ts.map +1 -0
- package/dist/tui/client-detector.js +515 -0
- package/dist/tui/client-detector.js.map +1 -0
- package/dist/tui/index.d.ts +2 -2
- package/dist/tui/index.js +14 -3
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/setup-wizard.d.ts +14 -0
- package/dist/tui/setup-wizard.d.ts.map +1 -1
- package/dist/tui/setup-wizard.js +253 -129
- package/dist/tui/setup-wizard.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utils/diagnostics.d.ts +22 -0
- package/dist/utils/diagnostics.d.ts.map +1 -0
- package/dist/utils/diagnostics.js +551 -0
- package/dist/utils/diagnostics.js.map +1 -0
- package/dist/utils/error-handler.d.ts +5 -1
- package/dist/utils/error-handler.d.ts.map +1 -1
- package/dist/utils/error-handler.js +10 -1
- package/dist/utils/error-handler.js.map +1 -1
- package/dist/utils/file-utils.d.ts +1 -1
- package/dist/utils/file-utils.js +1 -1
- package/dist/utils/formatters.d.ts +1 -1
- package/dist/utils/formatters.js +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/path-security.d.ts +1 -1
- package/dist/utils/path-security.js +1 -1
- package/package.json +11 -8
- package/scripts/postinstall.cjs +55 -0
- package/scripts/prepare.cjs +65 -0
- package/scripts/postinstall.js +0 -38
package/ARCHITECTURE.md
CHANGED
|
@@ -1,582 +1,588 @@
|
|
|
1
|
-
# Architecture Documentation
|
|
2
|
-
|
|
3
|
-
## 🏗️ System Overview
|
|
4
|
-
|
|
5
|
-
File Organizer MCP is a security-hardened Model Context Protocol (MCP) server that provides intelligent file organization capabilities to Large Language Models (LLMs). The architecture follows a layered service pattern with comprehensive security validation at every level.
|
|
6
|
-
|
|
7
|
-
### Core Principles
|
|
8
|
-
|
|
9
|
-
1. **Security First** - Multi-layer validation and sanitization
|
|
10
|
-
2. **Service Isolation** - Clear separation of concerns
|
|
11
|
-
3. **Type Safety** - Strict TypeScript with Zod validation
|
|
12
|
-
4. **Testability** - Dependency injection and modular design
|
|
13
|
-
5. **Performance** - Streaming operations and resource limits
|
|
14
|
-
|
|
15
|
-
## 📐 Architecture Layers
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
19
|
-
│ MCP Client (LLM) │
|
|
20
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
21
|
-
│ JSON-RPC 2.0
|
|
22
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
23
|
-
│ MCP Server Layer │
|
|
24
|
-
│ (server.ts - Protocol Handler) │
|
|
25
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
26
|
-
│
|
|
27
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
28
|
-
│ Tools Layer │
|
|
29
|
-
│ ┌──────────┬──────────┬───────────┬─────────────┐ │
|
|
30
|
-
│ │ Scan │ Organize │ Duplicate │ Categorize │ │
|
|
31
|
-
│ │ Files │ Files │ Find │ Files │ │
|
|
32
|
-
│ └──────────┴──────────┴───────────┴─────────────┘ │
|
|
33
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
34
|
-
│
|
|
35
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
36
|
-
│ Services Layer │
|
|
37
|
-
│ ┌────────────┬──────────────┬─────────────┬──────────┐ │
|
|
38
|
-
│ │ Path │ Organizer │ Hash │ Scanner │ │
|
|
39
|
-
│ │ Validator │ Service │ Calculator │ Service │ │
|
|
40
|
-
│ └────────────┴──────────────┴─────────────┴──────────┘ │
|
|
41
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
42
|
-
│
|
|
43
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
44
|
-
│ Utils Layer │
|
|
45
|
-
│ ┌──────────┬──────────┬───────────┬──────────┐ │
|
|
46
|
-
│ │ Logger │ Error │ File │ Format- │ │
|
|
47
|
-
│ │ │ Handler │ Utils │ ters │ │
|
|
48
|
-
│ └──────────┴──────────┴───────────┴──────────┘ │
|
|
49
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
50
|
-
│
|
|
51
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
52
|
-
│ File System │
|
|
53
|
-
└─────────────────────────────────────────────────────────────┘
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## 🔐 Security Architecture
|
|
57
|
-
|
|
58
|
-
### 8-Layer Path Validation Pipeline
|
|
59
|
-
|
|
60
|
-
Every file path goes through these validation layers:
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
Input Path
|
|
64
|
-
↓
|
|
65
|
-
1. Type Validation (Zod Schema)
|
|
66
|
-
↓
|
|
67
|
-
2. Null Byte & Basic Sanitization
|
|
68
|
-
↓
|
|
69
|
-
3. Path Normalization & Windows Case Adjustment
|
|
70
|
-
↓
|
|
71
|
-
4. Traversal Sequence Prevention (../)
|
|
72
|
-
↓
|
|
73
|
-
5. Absolute Path Resolution
|
|
74
|
-
↓
|
|
75
|
-
6. Security Check (Whitelist & Blacklist)
|
|
76
|
-
↓
|
|
77
|
-
7. Symlink Resolution & Target Validation
|
|
78
|
-
↓
|
|
79
|
-
8. Existence & Access Check
|
|
80
|
-
↓
|
|
81
|
-
Validated Path ✅
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Implementation:** [`src/services/path-validator.service.ts`](file:///c:/Users/NewAdmin/Desktop/File-Organizer-MCP/src/services/path-validator.service.ts)
|
|
85
|
-
|
|
86
|
-
### Race Condition Mitigation (TOCTOU Protection)
|
|
87
|
-
|
|
88
|
-
**Problem:** Time-of-Check-Time-of-Use vulnerabilities can occur when a file is checked, then used later, allowing an attacker to swap the file between operations.
|
|
89
|
-
|
|
90
|
-
**Solution:** Multi-layered approach:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// Layer 1: File Descriptor Validation
|
|
94
|
-
// Open file with O_NOFOLLOW to prevent symlink following
|
|
95
|
-
const handle = await fs.open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
96
|
-
|
|
97
|
-
// Layer 2: Atomic Copy Operations
|
|
98
|
-
// Use COPYFILE_EXCL to ensure destination doesn't exist
|
|
99
|
-
await fs.copyFile(source, dest, constants.COPYFILE_EXCL);
|
|
100
|
-
|
|
101
|
-
// Layer 3: Safe Overwrites
|
|
102
|
-
// Move existing file to backup before replacing
|
|
103
|
-
const backupPath = path.join('.file-organizer-backups', `${Date.now()}_overwrite_${basename}`);
|
|
104
|
-
await fs.rename(existingFile, backupPath);
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Limitations:**
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
-
|
|
345
|
-
↓
|
|
346
|
-
|
|
347
|
-
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
├──
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
│
|
|
375
|
-
|
|
376
|
-
│
|
|
377
|
-
│
|
|
378
|
-
├──
|
|
379
|
-
│ ├── file-
|
|
380
|
-
│ ├──
|
|
381
|
-
│
|
|
382
|
-
│
|
|
383
|
-
|
|
384
|
-
│
|
|
385
|
-
├──
|
|
386
|
-
│ ├──
|
|
387
|
-
│ ├──
|
|
388
|
-
│
|
|
389
|
-
│
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
│
|
|
411
|
-
├──
|
|
412
|
-
│ ├──
|
|
413
|
-
│ │ └──
|
|
414
|
-
│ └──
|
|
415
|
-
│
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
- **
|
|
492
|
-
|
|
493
|
-
**
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
-
|
|
576
|
-
-
|
|
577
|
-
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
1
|
+
# Architecture Documentation
|
|
2
|
+
|
|
3
|
+
## 🏗️ System Overview
|
|
4
|
+
|
|
5
|
+
File Organizer MCP is a security-hardened Model Context Protocol (MCP) server that provides intelligent file organization capabilities to Large Language Models (LLMs). The architecture follows a layered service pattern with comprehensive security validation at every level.
|
|
6
|
+
|
|
7
|
+
### Core Principles
|
|
8
|
+
|
|
9
|
+
1. **Security First** - Multi-layer validation and sanitization
|
|
10
|
+
2. **Service Isolation** - Clear separation of concerns
|
|
11
|
+
3. **Type Safety** - Strict TypeScript with Zod validation
|
|
12
|
+
4. **Testability** - Dependency injection and modular design
|
|
13
|
+
5. **Performance** - Streaming operations and resource limits
|
|
14
|
+
|
|
15
|
+
## 📐 Architecture Layers
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ MCP Client (LLM) │
|
|
20
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
21
|
+
│ JSON-RPC 2.0
|
|
22
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
23
|
+
│ MCP Server Layer │
|
|
24
|
+
│ (server.ts - Protocol Handler) │
|
|
25
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
26
|
+
│
|
|
27
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
28
|
+
│ Tools Layer │
|
|
29
|
+
│ ┌──────────┬──────────┬───────────┬─────────────┐ │
|
|
30
|
+
│ │ Scan │ Organize │ Duplicate │ Categorize │ │
|
|
31
|
+
│ │ Files │ Files │ Find │ Files │ │
|
|
32
|
+
│ └──────────┴──────────┴───────────┴─────────────┘ │
|
|
33
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
34
|
+
│
|
|
35
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
36
|
+
│ Services Layer │
|
|
37
|
+
│ ┌────────────┬──────────────┬─────────────┬──────────┐ │
|
|
38
|
+
│ │ Path │ Organizer │ Hash │ Scanner │ │
|
|
39
|
+
│ │ Validator │ Service │ Calculator │ Service │ │
|
|
40
|
+
│ └────────────┴──────────────┴─────────────┴──────────┘ │
|
|
41
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
42
|
+
│
|
|
43
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
44
|
+
│ Utils Layer │
|
|
45
|
+
│ ┌──────────┬──────────┬───────────┬──────────┐ │
|
|
46
|
+
│ │ Logger │ Error │ File │ Format- │ │
|
|
47
|
+
│ │ │ Handler │ Utils │ ters │ │
|
|
48
|
+
│ └──────────┴──────────┴───────────┴──────────┘ │
|
|
49
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
50
|
+
│
|
|
51
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
52
|
+
│ File System │
|
|
53
|
+
└─────────────────────────────────────────────────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 🔐 Security Architecture
|
|
57
|
+
|
|
58
|
+
### 8-Layer Path Validation Pipeline
|
|
59
|
+
|
|
60
|
+
Every file path goes through these validation layers:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
Input Path
|
|
64
|
+
↓
|
|
65
|
+
1. Type Validation (Zod Schema)
|
|
66
|
+
↓
|
|
67
|
+
2. Null Byte & Basic Sanitization
|
|
68
|
+
↓
|
|
69
|
+
3. Path Normalization & Windows Case Adjustment
|
|
70
|
+
↓
|
|
71
|
+
4. Traversal Sequence Prevention (../)
|
|
72
|
+
↓
|
|
73
|
+
5. Absolute Path Resolution
|
|
74
|
+
↓
|
|
75
|
+
6. Security Check (Whitelist & Blacklist)
|
|
76
|
+
↓
|
|
77
|
+
7. Symlink Resolution & Target Validation
|
|
78
|
+
↓
|
|
79
|
+
8. Existence & Access Check
|
|
80
|
+
↓
|
|
81
|
+
Validated Path ✅
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Implementation:** [`src/services/path-validator.service.ts`](file:///c:/Users/NewAdmin/Desktop/File-Organizer-MCP/src/services/path-validator.service.ts)
|
|
85
|
+
|
|
86
|
+
### Race Condition Mitigation (TOCTOU Protection)
|
|
87
|
+
|
|
88
|
+
**Problem:** Time-of-Check-Time-of-Use vulnerabilities can occur when a file is checked, then used later, allowing an attacker to swap the file between operations.
|
|
89
|
+
|
|
90
|
+
**Solution:** Multi-layered approach:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Layer 1: File Descriptor Validation
|
|
94
|
+
// Open file with O_NOFOLLOW to prevent symlink following
|
|
95
|
+
const handle = await fs.open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
96
|
+
|
|
97
|
+
// Layer 2: Atomic Copy Operations
|
|
98
|
+
// Use COPYFILE_EXCL to ensure destination doesn't exist
|
|
99
|
+
await fs.copyFile(source, dest, constants.COPYFILE_EXCL);
|
|
100
|
+
|
|
101
|
+
// Layer 3: Safe Overwrites
|
|
102
|
+
// Move existing file to backup before replacing
|
|
103
|
+
const backupPath = path.join('.file-organizer-backups', `${Date.now()}_overwrite_${basename}`);
|
|
104
|
+
await fs.rename(existingFile, backupPath);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Limitations:**
|
|
108
|
+
|
|
109
|
+
- File deletion on Windows uses path-based locking (not file descriptor)
|
|
110
|
+
- Symlinks are blocked for security but may limit legitimate use cases
|
|
111
|
+
|
|
112
|
+
### Resource Protection
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Security Constants
|
|
116
|
+
const SECURITY_LIMITS = {
|
|
117
|
+
MAX_FILE_SIZE: 100 * 1024 * 1024, // 100 MB
|
|
118
|
+
MAX_FILES: 10000, // Per operation
|
|
119
|
+
MAX_DEPTH: 10, // Directory recursion
|
|
120
|
+
MAX_PATH_LENGTH: 4096, // Characters
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 📦 Core Components
|
|
125
|
+
|
|
126
|
+
### 1. Server Layer (`server.ts`)
|
|
127
|
+
|
|
128
|
+
**Responsibility:** MCP protocol handling and tool registration
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Key responsibilities:
|
|
132
|
+
- Initialize MCP server
|
|
133
|
+
- Register tools with schemas
|
|
134
|
+
- Handle tool invocations
|
|
135
|
+
- Manage error responses
|
|
136
|
+
- Coordinate with services
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Key Features:**
|
|
140
|
+
|
|
141
|
+
- Automatic tool discovery from `tools/` directory
|
|
142
|
+
- Structured response formatting (JSON/Markdown)
|
|
143
|
+
- Centralized error handling
|
|
144
|
+
|
|
145
|
+
### 2. Tools Layer (`tools/`)
|
|
146
|
+
|
|
147
|
+
**Responsibility:** MCP tool implementations (user-facing API)
|
|
148
|
+
|
|
149
|
+
Each tool follows this pattern:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
export const toolDefinition: ToolDefinition = {
|
|
153
|
+
name: 'tool_name',
|
|
154
|
+
description: 'What it does',
|
|
155
|
+
inputSchema: ZodSchema, // Validation
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export async function handleTool(args: ToolArgs): Promise<ToolResponse> {
|
|
159
|
+
// 1. Validate inputs (Zod)
|
|
160
|
+
// 2. Validate security (PathValidator)
|
|
161
|
+
// 3. Call service layer
|
|
162
|
+
// 4. Format response
|
|
163
|
+
// 5. Handle errors
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Available Tools:**
|
|
168
|
+
|
|
169
|
+
1. **List Files in Directory** (`file_organizer_list_files`)
|
|
170
|
+
2. **Scan Directory for Detailed Info** (`file_organizer_scan_directory`)
|
|
171
|
+
3. **Categorize Files by Type** (`file_organizer_categorize_files`)
|
|
172
|
+
4. **Find Largest Files** (`file_organizer_find_largest_files`)
|
|
173
|
+
5. **Find Duplicate Files** (`file_organizer_find_duplicate_files`)
|
|
174
|
+
6. **Preview File Organization Plan** (`file_organizer_preview_organization`)
|
|
175
|
+
7. **Get Available File Categories** (`file_organizer_get_categories`)
|
|
176
|
+
8. **Analyze Duplicate Files with Smart Recommendations** (`file_organizer_analyze_duplicates`)
|
|
177
|
+
9. **Organize Files** (`file_organizer_organize_files`)
|
|
178
|
+
10. **Set Custom Organization Rules** (`file_organizer_set_custom_rules`)
|
|
179
|
+
11. **Delete Duplicate Files** (`file_organizer_delete_duplicates`)
|
|
180
|
+
12. **Undo Last Organization Operation** (`file_organizer_undo_last_operation`)
|
|
181
|
+
|
|
182
|
+
### 3. Services Layer (`services/`)
|
|
183
|
+
|
|
184
|
+
**Responsibility:** Core business logic
|
|
185
|
+
|
|
186
|
+
#### PathValidatorService
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
class PathValidatorService {
|
|
190
|
+
// Multi-layer path validation
|
|
191
|
+
async validateStrictPath(inputPath: unknown, options?: ValidatePathOptions): Promise<string>;
|
|
192
|
+
|
|
193
|
+
// Symlink resolution
|
|
194
|
+
async resolvePath(path: string): Promise<string>;
|
|
195
|
+
|
|
196
|
+
// Containment checking
|
|
197
|
+
isPathWithinRoots(path: string, roots: string[]): boolean;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### OrganizerService
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
class OrganizerService {
|
|
205
|
+
// Generate organization plan
|
|
206
|
+
async generateOrganizationPlan(
|
|
207
|
+
directory: string,
|
|
208
|
+
files: FileWithSize[],
|
|
209
|
+
strategy?: ConflictStrategy // 'rename' | 'skip' | 'overwrite' | 'overwrite_if_newer'
|
|
210
|
+
): Promise<OrganizationPlan>;
|
|
211
|
+
|
|
212
|
+
// Execute organization with safety guarantees
|
|
213
|
+
async organize(
|
|
214
|
+
directory: string,
|
|
215
|
+
files: FileWithSize[],
|
|
216
|
+
options?: OrganizeOptions
|
|
217
|
+
): Promise<OrganizeResult>;
|
|
218
|
+
|
|
219
|
+
// Safety mechanisms:
|
|
220
|
+
// 1. File descriptor validation before move
|
|
221
|
+
// 2. Atomic copy with COPYFILE_EXCL (race-safe)
|
|
222
|
+
// 3. Automatic backup to .file-organizer-backups/ on overwrite
|
|
223
|
+
// 4. Retry loop for race condition recovery
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### HashCalculatorService
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
class HashCalculatorService {
|
|
231
|
+
// Streaming hash calculation
|
|
232
|
+
async calculateHash(filePath: string): Promise<string>;
|
|
233
|
+
|
|
234
|
+
// Find duplicates (memory-safe)
|
|
235
|
+
async findDuplicates(files: FileWithSize[]): Promise<DuplicateGroup[]>;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### FileScannerService
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
class FileScannerService {
|
|
243
|
+
// Recursive directory scanning
|
|
244
|
+
async getAllFiles(directory: string, options?: ScanOptions): Promise<FileWithSize[]>;
|
|
245
|
+
|
|
246
|
+
// Size calculation
|
|
247
|
+
async calculateDirectorySize(directory: string): Promise<number>;
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### CategorizerService
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
class CategorizerService {
|
|
255
|
+
// File categorization
|
|
256
|
+
getCategory(fileName: string): CategoryName;
|
|
257
|
+
|
|
258
|
+
// Custom rules support
|
|
259
|
+
setCustomRules(rules: CategoryRule[]): void;
|
|
260
|
+
|
|
261
|
+
// Category statistics
|
|
262
|
+
categorizeFiles(files: FileWithSize[]): CategoryBreakdown;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### RollbackService
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
class RollbackService {
|
|
270
|
+
// Create rollback manifest
|
|
271
|
+
async createManifest(actions: OrganizeAction[]): Promise<string>;
|
|
272
|
+
|
|
273
|
+
// Execute rollback
|
|
274
|
+
async rollback(manifestId: string): Promise<RollbackResult>;
|
|
275
|
+
|
|
276
|
+
// List available rollbacks
|
|
277
|
+
async listRollbacks(): Promise<RollbackManifest[]>;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 4. Utils Layer (`utils/`)
|
|
282
|
+
|
|
283
|
+
**Responsibility:** Shared utility functions
|
|
284
|
+
|
|
285
|
+
#### Logger
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
class Logger {
|
|
289
|
+
// Structured JSON logging to stderr (MCP stdio protocol)
|
|
290
|
+
debug(message: string, context?: Record<string, any>): void;
|
|
291
|
+
info(message: string, context?: Record<string, any>): void;
|
|
292
|
+
warn(message: string, context?: Record<string, any>): void;
|
|
293
|
+
error(message: string, error?: Error, context?: Record<string, any>): void;
|
|
294
|
+
|
|
295
|
+
// Features:
|
|
296
|
+
// - ISO 8601 timestamps
|
|
297
|
+
// - Configurable log levels (debug/info/warn/error)
|
|
298
|
+
// - Error stack traces for error logs
|
|
299
|
+
// - JSON format for machine parsing
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- **error-handler.ts** - Centralized error handling
|
|
304
|
+
- **file-utils.ts** - File system helpers
|
|
305
|
+
- **formatters.ts** - Data formatting (bytes, dates, etc.)
|
|
306
|
+
|
|
307
|
+
### 5. Schemas Layer (`schemas/`)
|
|
308
|
+
|
|
309
|
+
**Responsibility:** Input validation using Zod
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Example: Path validation
|
|
313
|
+
export const PathSchema = z
|
|
314
|
+
.string()
|
|
315
|
+
.min(1, 'Path cannot be empty')
|
|
316
|
+
.max(4096, 'Path exceeds maximum length')
|
|
317
|
+
.refine((path) => !path.includes('\0'), 'Path contains null bytes');
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## 🔄 Data Flow
|
|
321
|
+
|
|
322
|
+
### Example: Organize Files Operation
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
1. LLM Request
|
|
326
|
+
↓
|
|
327
|
+
2. MCP Server (server.ts)
|
|
328
|
+
- Parse JSON-RPC request
|
|
329
|
+
- Route to organize tool
|
|
330
|
+
↓
|
|
331
|
+
3. Tool Handler (tools/file-organization.ts)
|
|
332
|
+
- Validate args with Zod
|
|
333
|
+
- Call PathValidatorService
|
|
334
|
+
↓
|
|
335
|
+
4. PathValidatorService
|
|
336
|
+
- 7-layer validation
|
|
337
|
+
- Return validated path
|
|
338
|
+
↓
|
|
339
|
+
5. FileScannerService
|
|
340
|
+
- Scan directory
|
|
341
|
+
- Apply resource limits
|
|
342
|
+
↓
|
|
343
|
+
6. CategorizerService
|
|
344
|
+
- Categorize each file
|
|
345
|
+
↓
|
|
346
|
+
7. OrganizerService
|
|
347
|
+
- Generate organization plan
|
|
348
|
+
- Check conflicts
|
|
349
|
+
- Execute moves (if not dry run)
|
|
350
|
+
↓
|
|
351
|
+
8. RollbackService
|
|
352
|
+
- Create rollback manifest
|
|
353
|
+
↓
|
|
354
|
+
9. Tool Handler
|
|
355
|
+
- Format response (JSON/Markdown)
|
|
356
|
+
↓
|
|
357
|
+
10. MCP Server
|
|
358
|
+
- Send JSON-RPC response
|
|
359
|
+
↓
|
|
360
|
+
11. LLM receives result
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## 💾 File Organization
|
|
364
|
+
|
|
365
|
+
### Source Structure
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
src/
|
|
369
|
+
├── server.ts # MCP server entry point
|
|
370
|
+
├── index.ts # Main entry point
|
|
371
|
+
├── types.ts # TypeScript type definitions
|
|
372
|
+
├── constants.ts # Application constants
|
|
373
|
+
├── config.ts # Configuration management
|
|
374
|
+
│
|
|
375
|
+
├── services/ # Core business logic
|
|
376
|
+
│ ├── path-validator.service.ts
|
|
377
|
+
│ ├── organizer.service.ts
|
|
378
|
+
│ ├── hash-calculator.service.ts
|
|
379
|
+
│ ├── file-scanner.service.ts
|
|
380
|
+
│ ├── categorizer.service.ts
|
|
381
|
+
│ └── rollback.service.ts
|
|
382
|
+
│
|
|
383
|
+
├── tools/ # MCP tool implementations
|
|
384
|
+
│ ├── file-scanning.ts
|
|
385
|
+
│ ├── file-organization.ts
|
|
386
|
+
│ ├── file-duplicates.ts
|
|
387
|
+
│ ├── file-categorization.ts
|
|
388
|
+
│ └── ...
|
|
389
|
+
│
|
|
390
|
+
├── schemas/ # Zod validation schemas
|
|
391
|
+
│ ├── security.schemas.ts
|
|
392
|
+
│ ├── common.schemas.ts
|
|
393
|
+
│ ├── scan.schemas.ts
|
|
394
|
+
│ └── organize.schemas.ts
|
|
395
|
+
│
|
|
396
|
+
└── utils/ # Shared utilities
|
|
397
|
+
├── logger.ts
|
|
398
|
+
├── error-handler.ts
|
|
399
|
+
├── file-utils.ts
|
|
400
|
+
└── formatters.ts
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## 🧪 Testing Architecture
|
|
404
|
+
|
|
405
|
+
### Test Structure
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
tests/
|
|
409
|
+
├── unit/ # Unit tests for services
|
|
410
|
+
│ ├── services/
|
|
411
|
+
│ │ ├── path-validator.test.ts
|
|
412
|
+
│ │ ├── organizer.test.ts
|
|
413
|
+
│ │ └── ...
|
|
414
|
+
│ └── utils/
|
|
415
|
+
│
|
|
416
|
+
├── integration/ # Integration tests for tools
|
|
417
|
+
│ ├── tools/
|
|
418
|
+
│ │ └── organize.test.ts
|
|
419
|
+
│ └── edge-cases.test.ts
|
|
420
|
+
│
|
|
421
|
+
└── performance/ # Performance benchmarks
|
|
422
|
+
└── performance.test.ts
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Test Philosophy
|
|
426
|
+
|
|
427
|
+
1. **Unit Tests** - Test services in isolation
|
|
428
|
+
2. **Integration Tests** - Test complete workflows
|
|
429
|
+
3. **Security Tests** - Validate all security controls
|
|
430
|
+
4. **Performance Tests** - Ensure scalability
|
|
431
|
+
|
|
432
|
+
## 🚀 Performance Considerations
|
|
433
|
+
|
|
434
|
+
### Streaming Operations
|
|
435
|
+
|
|
436
|
+
Large files are processed using streams to avoid memory exhaustion:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
// Hash calculation uses streams
|
|
440
|
+
const hash = crypto.createHash('sha256');
|
|
441
|
+
const stream = createReadStream(filePath, { highWaterMark: 64 * 1024 });
|
|
442
|
+
stream.on('data', (chunk) => hash.update(chunk));
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Resource Limits
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
// Enforced at multiple levels:
|
|
449
|
+
- File size: Skip files > 100MB for hashing
|
|
450
|
+
- File count: Max 10,000 files per operation
|
|
451
|
+
- Recursion depth: Max 10 levels
|
|
452
|
+
- Path length: Max 4,096 characters
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Caching Strategy
|
|
456
|
+
|
|
457
|
+
- Category mappings cached in-memory
|
|
458
|
+
- File stats cached during single operation
|
|
459
|
+
- No persistent caching (stateless design)
|
|
460
|
+
|
|
461
|
+
## 🔧 Configuration
|
|
462
|
+
|
|
463
|
+
### Configuration System (`config.ts`)
|
|
464
|
+
|
|
465
|
+
The server uses a platform-aware configuration system that combines hardcoded defaults with user customization.
|
|
466
|
+
|
|
467
|
+
**Structure:**
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
export const CONFIG = {
|
|
471
|
+
VERSION: '3.0.0',
|
|
472
|
+
|
|
473
|
+
security: {
|
|
474
|
+
enablePathValidation: true,
|
|
475
|
+
allowCustomDirectories: true,
|
|
476
|
+
logAccess: true,
|
|
477
|
+
maxScanDepth: 10,
|
|
478
|
+
maxFilesPerOperation: 10000,
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
paths: {
|
|
482
|
+
defaultAllowed: getDefaultAllowedDirs(), // Platform-aware safe directories
|
|
483
|
+
customAllowed: loadCustomAllowedDirs(), // User-defined from config.json
|
|
484
|
+
alwaysBlocked: getAlwaysBlockedPatterns(), // System protection patterns
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Default Allowed Directories:**
|
|
490
|
+
|
|
491
|
+
- **Windows:** Desktop, Documents, Downloads, Pictures, Videos, Music, OneDrive, Projects
|
|
492
|
+
- **macOS:** Desktop, Documents, Downloads, Movies, Music, Pictures, iCloud Drive, Projects
|
|
493
|
+
- **Linux:** Desktop, Documents, Downloads, Music, Pictures, Videos, ~/dev, ~/workspace
|
|
494
|
+
|
|
495
|
+
**User Configuration:**
|
|
496
|
+
|
|
497
|
+
- **Windows:** `%APPDATA%\file-organizer-mcp\config.json`
|
|
498
|
+
- **macOS:** `~/Library/Application Support/file-organizer-mcp/config.json`
|
|
499
|
+
- **Linux:** `~/.config/file-organizer-mcp/config.json`
|
|
500
|
+
|
|
501
|
+
**Config File Format:**
|
|
502
|
+
|
|
503
|
+
```json
|
|
504
|
+
{
|
|
505
|
+
"customAllowedDirectories": ["C:\\Users\\Name\\CustomFolder", "D:\\Projects"],
|
|
506
|
+
"settings": {
|
|
507
|
+
"maxScanDepth": 10,
|
|
508
|
+
"logAccess": true
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## 🎯 Design Patterns
|
|
514
|
+
|
|
515
|
+
### Dependency Injection
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
// Services receive dependencies via constructor
|
|
519
|
+
class OrganizerService {
|
|
520
|
+
constructor(
|
|
521
|
+
private categorizer: CategorizerService,
|
|
522
|
+
private rollback?: RollbackService
|
|
523
|
+
) {}
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Error Handling
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
// Centralized error handling
|
|
531
|
+
try {
|
|
532
|
+
const result = await operation();
|
|
533
|
+
} catch (error) {
|
|
534
|
+
return createErrorResponse(error);
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Type Safety
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// Strict types with Zod runtime validation
|
|
542
|
+
const ArgsSchema = z.object({
|
|
543
|
+
directory: PathSchema,
|
|
544
|
+
dry_run: z.boolean().optional(),
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
type Args = z.infer<typeof ArgsSchema>;
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
## 📊 Monitoring & Logging
|
|
551
|
+
|
|
552
|
+
### Structured Logging
|
|
553
|
+
|
|
554
|
+
```json
|
|
555
|
+
{
|
|
556
|
+
"timestamp": "2026-02-02T14:09:04.413Z",
|
|
557
|
+
"level": "info",
|
|
558
|
+
"message": "Created rollback manifest: uuid (6 actions)"
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Log Levels
|
|
563
|
+
|
|
564
|
+
- `error` - Critical failures
|
|
565
|
+
- `warn` - Recoverable issues (e.g., skipped files)
|
|
566
|
+
- `info` - Operation milestones
|
|
567
|
+
- `debug` - Detailed diagnostics
|
|
568
|
+
|
|
569
|
+
## 🔮 Future Architecture Changes
|
|
570
|
+
|
|
571
|
+
### Planned Improvements
|
|
572
|
+
|
|
573
|
+
1. **Plugin System** - Allow custom categorization rules
|
|
574
|
+
2. **Database Layer** - Persistent state for large operations
|
|
575
|
+
3. **Queue System** - Background processing for large directories
|
|
576
|
+
4. **Metrics Collection** - Performance monitoring
|
|
577
|
+
5. **Multi-language Support** - i18n infrastructure
|
|
578
|
+
|
|
579
|
+
## 📚 References
|
|
580
|
+
|
|
581
|
+
- [Model Context Protocol Spec](https://modelcontextprotocol.io)
|
|
582
|
+
- [Zod Documentation](https://zod.dev)
|
|
583
|
+
- [TypeScript Handbook](https://www.typescriptlang.org/docs)
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
**Last Updated:** February 3, 2026
|
|
588
|
+
**Version:** 3.0.0
|