unix-disk-mcp 0.3.0 → 0.4.1
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/README.md +27 -12
- package/config.sample.json +1 -6
- package/dist/config/index.d.ts +0 -3
- package/dist/server.js +2 -1
- package/dist/tools/exploration.js +94 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,11 +13,15 @@ Traditional disk cleaners use fixed rules. This tool lets AI *reason* about your
|
|
|
13
13
|
## Security
|
|
14
14
|
|
|
15
15
|
The AI **cannot delete files**. Ever. This is architectural:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
16
|
+
|
|
17
|
+
**What AI can do:**
|
|
18
|
+
- Explore filesystem
|
|
19
|
+
- Suggest items to delete
|
|
20
|
+
- Stage items for deletion
|
|
21
|
+
|
|
22
|
+
**What AI cannot do:**
|
|
23
|
+
- Execute deletion
|
|
24
|
+
- Run delete script
|
|
21
25
|
|
|
22
26
|
You run `unix-disk-mcp delete` manually to review and confirm.
|
|
23
27
|
|
|
@@ -32,7 +36,7 @@ The setup wizard configures everything. Or manually:
|
|
|
32
36
|
|
|
33
37
|
**1. Add to MCP client config:**
|
|
34
38
|
|
|
35
|
-
VS Code:
|
|
39
|
+
VS Code: `~/Library/Application Support/Code/User/mcp.json` (macOS) or `~/.config/Code/User/mcp.json` (Linux)
|
|
36
40
|
```json
|
|
37
41
|
{
|
|
38
42
|
"servers": {
|
|
@@ -44,11 +48,24 @@ VS Code: `~/.config/Code/User/mcp.json` (Linux) or `~/Library/Application Suppor
|
|
|
44
48
|
}
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
Cursor: `~/.cursor/mcp.json`
|
|
48
52
|
```json
|
|
49
53
|
{
|
|
50
54
|
"mcpServers": {
|
|
51
55
|
"unix-disk-mcp": {
|
|
56
|
+
"command": "unix-disk-mcp",
|
|
57
|
+
"args": []
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Claude: `~/.claude.json`
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"servers": {
|
|
67
|
+
"unix-disk-mcp": {
|
|
68
|
+
"type": "stdio",
|
|
52
69
|
"command": "unix-disk-mcp"
|
|
53
70
|
}
|
|
54
71
|
}
|
|
@@ -60,10 +77,7 @@ Claude Desktop: `~/.config/Claude/claude_desktop_config.json` (Linux) or `~/Libr
|
|
|
60
77
|
Run `unix-disk-mcp config` to see config location, then edit:
|
|
61
78
|
```json
|
|
62
79
|
{
|
|
63
|
-
"protected_paths": ["/System", "/Library", "~/.ssh", "~/.gnupg"]
|
|
64
|
-
"ignore_patterns": [".git"],
|
|
65
|
-
"max_delete_size_gb": 10,
|
|
66
|
-
"dry_run": false
|
|
80
|
+
"protected_paths": ["/System", "/Library", "~/.ssh", "~/.gnupg"]
|
|
67
81
|
}
|
|
68
82
|
```
|
|
69
83
|
|
|
@@ -95,6 +109,7 @@ unix-disk-mcp delete
|
|
|
95
109
|
- `get_disk_usage` - Disk space overview
|
|
96
110
|
- `find_large_items` - Find big files/folders (supports progressive depth exploration)
|
|
97
111
|
- `get_item_info` - Details on specific paths
|
|
112
|
+
- `search_files` - Find files/directories by name pattern
|
|
98
113
|
|
|
99
114
|
**Discovery:**
|
|
100
115
|
- `list_applications` - Installed apps with last-opened dates (macOS only)
|
|
@@ -147,4 +162,4 @@ unix-disk-mcp help # Show help
|
|
|
147
162
|
|
|
148
163
|
## License
|
|
149
164
|
|
|
150
|
-
|
|
165
|
+
GPL-3.0-or-later
|
package/config.sample.json
CHANGED
package/dist/config/index.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -5,7 +5,8 @@ import { registerStagingTools } from "./tools/staging.js";
|
|
|
5
5
|
export function createServer(config) {
|
|
6
6
|
const server = new McpServer({
|
|
7
7
|
name: "unix-disk-mcp",
|
|
8
|
-
version: "0.1
|
|
8
|
+
version: "0.4.1",
|
|
9
|
+
description: "AI-assisted disk cleanup for Unix systems. **Recommended workflow:** 1) Start with get_disk_usage for overview 2) Use search_files or find_large_items to identify targets 3) Stage items for deletion 4) User executes deletion manually. You can explore but never delete files.",
|
|
9
10
|
});
|
|
10
11
|
// Register all tools
|
|
11
12
|
registerExplorationTools(server, config);
|
|
@@ -67,7 +67,7 @@ export function registerExplorationTools(server, config) {
|
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
// get_disk_usage
|
|
70
|
-
server.tool("get_disk_usage", "Get overview of disk space usage", {}, async () => {
|
|
70
|
+
server.tool("get_disk_usage", "Get overview of disk space usage. **Use this first** when exploring disk usage to understand which filesystems/volumes need attention and get a breakdown of home directory space.", {}, async () => {
|
|
71
71
|
try {
|
|
72
72
|
let disk;
|
|
73
73
|
if (process.platform === 'darwin') {
|
|
@@ -331,4 +331,97 @@ export function registerExplorationTools(server, config) {
|
|
|
331
331
|
};
|
|
332
332
|
}
|
|
333
333
|
});
|
|
334
|
+
// search_files
|
|
335
|
+
server.tool("search_files", "Search for files and directories by name pattern. Use this to find all instances of an app, package, or file type across the system.", {
|
|
336
|
+
query: z.string().describe("Search query - can be exact name or pattern (e.g., 'Anki', 'node_modules', '*.mp4')"),
|
|
337
|
+
search_path: z.string().optional().describe("Starting directory (defaults to home directory)"),
|
|
338
|
+
max_results: z.number().optional().default(50).describe("Maximum number of results to return"),
|
|
339
|
+
}, async ({ query, search_path, max_results }) => {
|
|
340
|
+
try {
|
|
341
|
+
const startPath = search_path ? expandPath(search_path) : homedir();
|
|
342
|
+
let results = [];
|
|
343
|
+
if (process.platform === 'darwin') {
|
|
344
|
+
// macOS: Use mdfind (Spotlight) for fast searching
|
|
345
|
+
try {
|
|
346
|
+
const mdfindCmd = search_path
|
|
347
|
+
? `mdfind -onlyin "${startPath}" -name "${query}"`
|
|
348
|
+
: `mdfind -name "${query}"`;
|
|
349
|
+
const output = execSync(mdfindCmd, {
|
|
350
|
+
encoding: "utf-8",
|
|
351
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
352
|
+
});
|
|
353
|
+
results = output.trim().split("\n").filter(Boolean);
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
// Fall back to find if mdfind fails
|
|
357
|
+
const findCmd = `find "${startPath}" -iname "*${query}*" 2>/dev/null`;
|
|
358
|
+
const output = execSync(findCmd, {
|
|
359
|
+
encoding: "utf-8",
|
|
360
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
361
|
+
});
|
|
362
|
+
results = output.trim().split("\n").filter(Boolean);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
// Linux: Use find
|
|
367
|
+
const findCmd = `find "${startPath}" -iname "*${query}*" 2>/dev/null`;
|
|
368
|
+
const output = execSync(findCmd, {
|
|
369
|
+
encoding: "utf-8",
|
|
370
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
371
|
+
});
|
|
372
|
+
results = output.trim().split("\n").filter(Boolean);
|
|
373
|
+
}
|
|
374
|
+
// Limit results and get sizes
|
|
375
|
+
const limitedResults = results.slice(0, max_results);
|
|
376
|
+
const items = limitedResults.map(path => {
|
|
377
|
+
try {
|
|
378
|
+
const stats = statSync(path);
|
|
379
|
+
return {
|
|
380
|
+
path,
|
|
381
|
+
type: stats.isDirectory() ? "directory" : "file",
|
|
382
|
+
size: stats.size,
|
|
383
|
+
modified: stats.mtime.toISOString(),
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
return {
|
|
388
|
+
path,
|
|
389
|
+
type: "unknown",
|
|
390
|
+
size: 0,
|
|
391
|
+
error: "Could not read stats",
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
return {
|
|
396
|
+
content: [
|
|
397
|
+
{
|
|
398
|
+
type: "text",
|
|
399
|
+
text: JSON.stringify({
|
|
400
|
+
success: true,
|
|
401
|
+
data: {
|
|
402
|
+
query,
|
|
403
|
+
total_found: results.length,
|
|
404
|
+
returned: items.length,
|
|
405
|
+
items,
|
|
406
|
+
},
|
|
407
|
+
}, null, 2),
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
return {
|
|
414
|
+
content: [
|
|
415
|
+
{
|
|
416
|
+
type: "text",
|
|
417
|
+
text: JSON.stringify({
|
|
418
|
+
success: false,
|
|
419
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
420
|
+
code: "SEARCH_FILES_FAILED",
|
|
421
|
+
}),
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
});
|
|
334
427
|
}
|