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 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
- - ✅ Explore filesystem
17
- - Suggest items to delete
18
- - Stage items for deletion
19
- - Cannot execute deletion
20
- - Cannot run delete script
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: `~/.config/Code/User/mcp.json` (Linux) or `~/Library/Application Support/Code/User/mcp.json` (macOS)
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
- Claude Desktop: `~/.config/Claude/claude_desktop_config.json` (Linux) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
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
- MIT
165
+ GPL-3.0-or-later
@@ -4,10 +4,5 @@
4
4
  "/Library",
5
5
  "~/.ssh",
6
6
  "~/.gnupg"
7
- ],
8
- "ignore_patterns": [
9
- ".git"
10
- ],
11
- "max_delete_size_gb": 10,
12
- "dry_run": false
7
+ ]
13
8
  }
@@ -1,8 +1,5 @@
1
1
  export interface Config {
2
2
  protected_paths: string[];
3
- ignore_patterns: string[];
4
- max_delete_size_gb: number;
5
- dry_run: boolean;
6
3
  }
7
4
  export declare function expandPath(path: string): string;
8
5
  export declare function loadConfig(): Config;
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.0",
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unix-disk-mcp",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "MCP server for AI-assisted disk cleanup on Unix systems (macOS and Linux)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",