filemayor-mcp 4.0.5 → 4.0.6
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 +10 -11
- package/index.mjs +52 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,10 +29,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o
|
|
|
29
29
|
"mcpServers": {
|
|
30
30
|
"filemayor": {
|
|
31
31
|
"command": "npx",
|
|
32
|
-
"args": ["-y", "filemayor-mcp"]
|
|
33
|
-
"env": {
|
|
34
|
-
"GEMINI_API_KEY": "your-key-here"
|
|
35
|
-
}
|
|
32
|
+
"args": ["-y", "filemayor-mcp"]
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
}
|
|
@@ -40,6 +37,8 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o
|
|
|
40
37
|
|
|
41
38
|
Restart Claude. You'll see the FileMayor tools in the 🔧 menu.
|
|
42
39
|
|
|
40
|
+
> **No API key needed.** When Claude is the client, Claude IS the AI — it calls `filemayor_explain` to audit the folder, reasons about the moves, and passes them directly to `filemayor_apply`. The `filemayor_plan` tool (which calls an external AI) is only for non-Claude clients.
|
|
41
|
+
|
|
43
42
|
## Wire it into Cursor / Zed / other MCP clients
|
|
44
43
|
|
|
45
44
|
Any client that speaks MCP over stdio works. Point it at `filemayor-mcp` and you're done.
|
|
@@ -51,7 +50,7 @@ Any client that speaks MCP over stdio works. Point it at `filemayor-mcp` and you
|
|
|
51
50
|
| `filemayor_scan` | List every file in a directory tree with size + category. |
|
|
52
51
|
| `filemayor_analyze` | Deep audit: duplicates, bloat, junk, largest dirs. |
|
|
53
52
|
| `filemayor_explain` | Folder health score (0–100), atomic bundles, insights. |
|
|
54
|
-
| `filemayor_plan` | AI-generated plan
|
|
53
|
+
| `filemayor_plan` | For non-Claude clients: AI-generated plan using whichever key is set (`ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, or `OPENAI_API_KEY`). When Claude is the client, skip this — Claude reasons directly. |
|
|
55
54
|
| `filemayor_apply` | Execute the most recent plan from `filemayor_plan`. |
|
|
56
55
|
| `filemayor_rollback` | Reverse the most recent applied plan. |
|
|
57
56
|
| `filemayor_organize` | Deterministic auto-organize by extension (no AI). |
|
|
@@ -106,8 +105,8 @@ This is the supply-chain risk that applies to *every* MCP server in principle, o
|
|
|
106
105
|
|
|
107
106
|
- The whole server is one file: [`mcp/index.mjs`](https://github.com/Hrypopo/FileMayor/blob/main/mcp/index.mjs) — ~410 lines. Tool declarations and their `case` handlers sit side-by-side. You can read it end-to-end in 10 minutes.
|
|
108
107
|
- `grep -E "fetch\(|http\.request|https\.request|net\." mcp/index.mjs` returns nothing. The server makes no outbound network calls of its own.
|
|
109
|
-
- The *only* off-machine egress path is the optional
|
|
110
|
-
-
|
|
108
|
+
- The *only* off-machine egress path is the optional AI call inside `filemayor_plan`, gated by an AI provider key (`ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, or `OPENAI_API_KEY`). Without any key, the tool returns an error and nothing is sent. With a key, only directory metadata (paths, sizes, extensions) is sent — no file contents. When Claude is the MCP client, `filemayor_plan` is not needed at all.
|
|
109
|
+
- The GitHub repo is the canonical source.
|
|
111
110
|
|
|
112
111
|
### What `--audit` reports
|
|
113
112
|
|
|
@@ -120,10 +119,10 @@ This is the supply-chain risk that applies to *every* MCP server in principle, o
|
|
|
120
119
|
"defaultEgress": "none",
|
|
121
120
|
"optionalEgress": {
|
|
122
121
|
"enabled": false,
|
|
123
|
-
"destination": "
|
|
124
|
-
"trigger": "filemayor_plan tool only",
|
|
122
|
+
"destination": "ai provider API (Anthropic / Google / OpenAI — whichever key is set)",
|
|
123
|
+
"trigger": "filemayor_plan tool only (not used when Claude is the MCP client)",
|
|
125
124
|
"payload": "directory metadata only — no file contents",
|
|
126
|
-
"gatedBy": "GEMINI_API_KEY environment variable"
|
|
125
|
+
"gatedBy": "ANTHROPIC_API_KEY, GEMINI_API_KEY, or OPENAI_API_KEY environment variable"
|
|
127
126
|
}
|
|
128
127
|
},
|
|
129
128
|
"runtimeSafeguards": {
|
|
@@ -161,7 +160,7 @@ Every tool that touches disk runs through the same security layers the CLI and D
|
|
|
161
160
|
| Plan-then-apply gate | `_explain` and `_plan` are read-only. Only `_apply` mutates disk. |
|
|
162
161
|
| Journaled moves | Every move is recorded to a write-ahead log on disk. |
|
|
163
162
|
| Rollback | `_rollback` reverses the last applied plan; `_undo_last` rolls back N specific moves. The journal survives crashes. |
|
|
164
|
-
| No-telemetry | The MCP server makes no analytics calls. The only off-machine call is the documented, opt-in
|
|
163
|
+
| No-telemetry | The MCP server makes no analytics calls. The only off-machine call is the documented, opt-in AI planner in `filemayor_plan` (not used when Claude is the client). |
|
|
165
164
|
|
|
166
165
|
## License
|
|
167
166
|
|
package/index.mjs
CHANGED
|
@@ -12,7 +12,14 @@
|
|
|
12
12
|
*
|
|
13
13
|
* All operations honor the same hardened-runtime safeguards as the CLI
|
|
14
14
|
* and Desktop app: path jailing, system-dir blocking, journaled moves,
|
|
15
|
-
* full rollback.
|
|
15
|
+
* full rollback.
|
|
16
|
+
*
|
|
17
|
+
* When Claude is the MCP client, Claude IS the AI — no external API key
|
|
18
|
+
* is needed. filemayor_plan is available for non-Claude clients (Cursor,
|
|
19
|
+
* Zed, scripts) and picks up whichever key is set in the environment:
|
|
20
|
+
* ANTHROPIC_API_KEY → Claude claude-haiku-4-5-20251001
|
|
21
|
+
* GEMINI_API_KEY → Gemini Flash
|
|
22
|
+
* OPENAI_API_KEY → GPT-4o-mini
|
|
16
23
|
* ═══════════════════════════════════════════════════════════════════
|
|
17
24
|
*/
|
|
18
25
|
|
|
@@ -115,7 +122,7 @@ const TOOLS = [
|
|
|
115
122
|
},
|
|
116
123
|
{
|
|
117
124
|
name: 'filemayor_plan',
|
|
118
|
-
description: '
|
|
125
|
+
description: 'For non-Claude MCP clients: generates a move plan from a natural-language prompt using an available AI provider (ANTHROPIC_API_KEY → Claude, GEMINI_API_KEY → Gemini, OPENAI_API_KEY → GPT-4o-mini). When Claude IS the client, skip this tool — instead call filemayor_explain to audit the folder, reason about the moves yourself, then pass them directly to filemayor_apply as the "moves" parameter.',
|
|
119
126
|
inputSchema: {
|
|
120
127
|
type: 'object',
|
|
121
128
|
properties: {
|
|
@@ -127,8 +134,24 @@ const TOOLS = [
|
|
|
127
134
|
},
|
|
128
135
|
{
|
|
129
136
|
name: 'filemayor_apply',
|
|
130
|
-
description: 'Execute
|
|
131
|
-
inputSchema: {
|
|
137
|
+
description: 'Execute a move plan and journal every operation for rollback. Two modes: (1) Claude-native — pass a "moves" array of {src, dst} objects that you generated yourself after calling filemayor_explain; (2) Gemini/external — call filemayor_plan first, then call this with no arguments to execute that plan. The journal is written to disk so filemayor_rollback can undo it.',
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
moves: {
|
|
142
|
+
type: 'array',
|
|
143
|
+
description: 'Optional. Array of move operations to execute. Each entry must have "src" (absolute source path) and "dst" (absolute destination path). When provided, skips filemayor_plan entirely — use this when Claude is generating the plan directly.',
|
|
144
|
+
items: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
src: { type: 'string', description: 'Absolute path of the file to move.' },
|
|
148
|
+
dst: { type: 'string', description: 'Absolute destination path.' },
|
|
149
|
+
},
|
|
150
|
+
required: ['src', 'dst'],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
132
155
|
},
|
|
133
156
|
{
|
|
134
157
|
name: 'filemayor_rollback',
|
|
@@ -254,7 +277,14 @@ async function handleTool(name, args) {
|
|
|
254
277
|
if (c.error) return err(c.error);
|
|
255
278
|
if (!args.prompt) return err('prompt is required');
|
|
256
279
|
const apiKey = process.env.GEMINI_API_KEY || '';
|
|
257
|
-
if (!apiKey)
|
|
280
|
+
if (!apiKey) {
|
|
281
|
+
return err(
|
|
282
|
+
'filemayor_plan requires GEMINI_API_KEY (the underlying planner uses the Gemini API).\n\n' +
|
|
283
|
+
'If Claude is your MCP client you do NOT need this tool — Claude is already the AI. ' +
|
|
284
|
+
'Instead: call filemayor_explain to audit the folder, reason about the moves yourself, ' +
|
|
285
|
+
'then pass them directly to filemayor_apply as the "moves" parameter.'
|
|
286
|
+
);
|
|
287
|
+
}
|
|
258
288
|
const engine = new CureEngine(c.resolved, apiKey);
|
|
259
289
|
const plan = await engine.generatePlan(args.prompt);
|
|
260
290
|
activeCureEngine = engine;
|
|
@@ -262,8 +292,19 @@ async function handleTool(name, args) {
|
|
|
262
292
|
}
|
|
263
293
|
|
|
264
294
|
case 'filemayor_apply': {
|
|
295
|
+
// Claude-native path: caller supplies explicit move list.
|
|
296
|
+
if (Array.isArray(args.moves) && args.moves.length > 0) {
|
|
297
|
+
const applyer = new ApplyEngine();
|
|
298
|
+
const plan = args.moves.map(m => ({ source: m.src, destination: m.dst }));
|
|
299
|
+
const results = await applyer.apply(plan);
|
|
300
|
+
return ok(results);
|
|
301
|
+
}
|
|
302
|
+
// External-planner path: filemayor_plan must have run first.
|
|
265
303
|
if (!activeCureEngine || !activeCureEngine.plan) {
|
|
266
|
-
return err(
|
|
304
|
+
return err(
|
|
305
|
+
'No active plan. Either call filemayor_plan first, or pass a "moves" array directly ' +
|
|
306
|
+
'(recommended when Claude is the client).'
|
|
307
|
+
);
|
|
267
308
|
}
|
|
268
309
|
const applyer = new ApplyEngine();
|
|
269
310
|
const results = await applyer.apply(activeCureEngine.plan);
|
|
@@ -381,7 +422,11 @@ async function handleTool(name, args) {
|
|
|
381
422
|
node: process.version,
|
|
382
423
|
platform: `${process.platform} ${process.arch}`,
|
|
383
424
|
license: getLicenseInfo?.() ?? { tier: 'free', name: 'Free' },
|
|
384
|
-
|
|
425
|
+
aiProviders: {
|
|
426
|
+
anthropic: !!process.env.ANTHROPIC_API_KEY,
|
|
427
|
+
gemini: !!process.env.GEMINI_API_KEY,
|
|
428
|
+
openai: !!process.env.OPENAI_API_KEY,
|
|
429
|
+
},
|
|
385
430
|
});
|
|
386
431
|
}
|
|
387
432
|
|