n8n-mcp 2.67.3 → 2.68.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/.env.example +2 -1
- package/README.md +4 -1
- package/dist/mcp/handlers-n8n-manager.d.ts +6 -0
- package/dist/mcp/handlers-n8n-manager.d.ts.map +1 -1
- package/dist/mcp/handlers-n8n-manager.js +182 -2
- package/dist/mcp/handlers-n8n-manager.js.map +1 -1
- package/dist/mcp/handlers-workflow-diff.d.ts.map +1 -1
- package/dist/mcp/handlers-workflow-diff.js +10 -1
- package/dist/mcp/handlers-workflow-diff.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +19 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-docs/index.d.ts.map +1 -1
- package/dist/mcp/tool-docs/index.js +2 -1
- package/dist/mcp/tool-docs/index.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/index.d.ts +1 -0
- package/dist/mcp/tool-docs/workflow_management/index.d.ts.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/index.js +3 -1
- package/dist/mcp/tool-docs/workflow_management/index.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js +3 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-manage-folders.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-manage-folders.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-manage-folders.js +90 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-manage-folders.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js +6 -3
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map +1 -1
- package/dist/mcp/tools-documentation.d.ts.map +1 -1
- package/dist/mcp/tools-documentation.js +5 -2
- package/dist/mcp/tools-documentation.js.map +1 -1
- package/dist/mcp/tools-n8n-manager.d.ts.map +1 -1
- package/dist/mcp/tools-n8n-manager.js +54 -1
- package/dist/mcp/tools-n8n-manager.js.map +1 -1
- package/dist/services/n8n-api-client.d.ts +15 -2
- package/dist/services/n8n-api-client.d.ts.map +1 -1
- package/dist/services/n8n-api-client.js +107 -3
- package/dist/services/n8n-api-client.js.map +1 -1
- package/dist/services/n8n-validation.d.ts.map +1 -1
- package/dist/services/n8n-validation.js +2 -0
- package/dist/services/n8n-validation.js.map +1 -1
- package/dist/services/workflow-diff-engine.d.ts +2 -0
- package/dist/services/workflow-diff-engine.d.ts.map +1 -1
- package/dist/services/workflow-diff-engine.js +16 -0
- package/dist/services/workflow-diff-engine.js.map +1 -1
- package/dist/types/n8n-api.d.ts +48 -0
- package/dist/types/n8n-api.d.ts.map +1 -1
- package/dist/types/n8n-api.js.map +1 -1
- package/dist/types/workflow-diff.d.ts +5 -1
- package/dist/types/workflow-diff.d.ts.map +1 -1
- package/dist/types/workflow-diff.js.map +1 -1
- package/dist/utils/n8n-errors.d.ts.map +1 -1
- package/dist/utils/n8n-errors.js +19 -1
- package/dist/utils/n8n-errors.js.map +1 -1
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -133,10 +133,11 @@ AUTH_TOKEN=your-secure-token-here
|
|
|
133
133
|
# Eligible tools and their operations:
|
|
134
134
|
# n8n_executions — action: get, list, delete
|
|
135
135
|
# n8n_evaluations — action: list_runs, get_run, list_cases, run, cancel
|
|
136
|
+
# n8n_manage_folders — action: create, list, get, rename, move, delete
|
|
136
137
|
# n8n_workflow_versions — mode: list, get, rollback, delete, prune
|
|
137
138
|
#
|
|
138
139
|
# Read-only deployment recipe (blocks all destructive operations):
|
|
139
|
-
# DISABLED_TOOL_OPERATIONS=n8n_workflow_versions:delete,rollback,prune;n8n_executions:delete;n8n_evaluations:run,cancel
|
|
140
|
+
# DISABLED_TOOL_OPERATIONS=n8n_workflow_versions:delete,rollback,prune;n8n_executions:delete;n8n_evaluations:run,cancel;n8n_manage_folders:create,rename,move,delete
|
|
140
141
|
#
|
|
141
142
|
# Combine with n8n API key RBAC for defence in depth.
|
|
142
143
|
# Default: (empty - all operations enabled)
|
package/README.md
CHANGED
|
@@ -390,6 +390,9 @@ These tools require `N8N_API_URL` and `N8N_API_KEY` in your configuration.
|
|
|
390
390
|
- **`n8n_executions`** - Unified execution management (list, get, delete)
|
|
391
391
|
- **`n8n_evaluations`** - Run and read evaluation test runs (list runs, aggregated metrics, per-case results on n8n 2.30+; trigger and cancel on 2.32+)
|
|
392
392
|
|
|
393
|
+
#### Folder Management
|
|
394
|
+
- **`n8n_manage_folders`** - Manage workflow folders (create, list, get, rename, move, delete; n8n 2.19+). Place workflows into folders via `n8n_create_workflow`'s `parentFolderId` or `n8n_update_partial_workflow`'s `moveToFolder` operation (n8n 2.32+)
|
|
395
|
+
|
|
393
396
|
#### Data Table Management
|
|
394
397
|
- **`n8n_manage_datatable`** - Manage n8n data tables and rows (list, get, create, update, delete)
|
|
395
398
|
|
|
@@ -413,7 +416,7 @@ DISABLED_TOOLS=n8n_create_workflow,n8n_update_full_workflow,n8n_update_partial_w
|
|
|
413
416
|
For tools that bundle read and write operations under one name, block only the destructive operations while keeping `list` and `get`:
|
|
414
417
|
|
|
415
418
|
```bash
|
|
416
|
-
DISABLED_TOOL_OPERATIONS=n8n_workflow_versions:delete,rollback,prune;n8n_executions:delete;n8n_evaluations:run,cancel
|
|
419
|
+
DISABLED_TOOL_OPERATIONS=n8n_workflow_versions:delete,rollback,prune;n8n_executions:delete;n8n_evaluations:run,cancel;n8n_manage_folders:create,rename,move,delete
|
|
417
420
|
```
|
|
418
421
|
|
|
419
422
|
Combine with a read-only n8n API key (Settings → API in your n8n instance) for defence in depth. See [Read-Only Deployment Recipe](./docs/HTTP_DEPLOYMENT.md#read-only-deployment-recipe) for the full setup guide.
|
|
@@ -50,5 +50,11 @@ export declare function handleCreateCredential(args: unknown, context?: Instance
|
|
|
50
50
|
export declare function handleUpdateCredential(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
51
51
|
export declare function handleDeleteCredential(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
52
52
|
export declare function handleGetCredentialSchema(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
53
|
+
export declare function handleCreateFolder(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
54
|
+
export declare function handleListFolders(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
55
|
+
export declare function handleGetFolder(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
56
|
+
export declare function handleRenameFolder(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
57
|
+
export declare function handleMoveFolder(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
58
|
+
export declare function handleDeleteFolder(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
53
59
|
export declare function handleAuditInstance(args: unknown, context?: InstanceContext): Promise<McpToolResponse>;
|
|
54
60
|
//# sourceMappingURL=handlers-n8n-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D,OAAO,EAML,eAAe,EAKhB,MAAM,kBAAkB,CAAC;AAoB1B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAA+C,MAAM,2BAA2B,CAAC;AAOzG,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA0NhE,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAMD,wBAAgB,uBAAuB,gDAEtC;AAKD,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAwF9E;AA0CD,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlD;
|
|
1
|
+
{"version":3,"file":"handlers-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D,OAAO,EAML,eAAe,EAKhB,MAAM,kBAAkB,CAAC;AAoB1B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAA+C,MAAM,2BAA2B,CAAC;AAOzG,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA0NhE,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAMD,wBAAgB,uBAAuB,gDAEtC;AAKD,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAwF9E;AA0CD,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlD;AA4KD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA2G7G;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC1G;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAoDjH;AAED,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAqDnH;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyCjH;AAWD,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA8DlH;AAUD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwFhH;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAwM1B;AAeD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC7G;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiE5G;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA0F1B;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAoK1B;AAQD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwJ3G;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA8H3G;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgD7G;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC9G;AA2JD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAmC3G;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAczG;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyB5G;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiB7G;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiB5G;AAID,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwG3F;AAkLD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAsQxG;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAkL1B;AA+BD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA6M1B;AAQD,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyErH;AAyFD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB1G;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBzG;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CASvG;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB1G;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAS1G;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAuBtG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAazG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAazG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAazG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyBzG;AAqID,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAkD9G;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA4C5G;AAmDD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB/G;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC/G;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAa/G;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAalH;AA+FD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAoB3G;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA0B1G;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAUxG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAc3G;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiBzG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB3G;AAeD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwG5G"}
|
|
@@ -80,6 +80,12 @@ exports.handleCreateCredential = handleCreateCredential;
|
|
|
80
80
|
exports.handleUpdateCredential = handleUpdateCredential;
|
|
81
81
|
exports.handleDeleteCredential = handleDeleteCredential;
|
|
82
82
|
exports.handleGetCredentialSchema = handleGetCredentialSchema;
|
|
83
|
+
exports.handleCreateFolder = handleCreateFolder;
|
|
84
|
+
exports.handleListFolders = handleListFolders;
|
|
85
|
+
exports.handleGetFolder = handleGetFolder;
|
|
86
|
+
exports.handleRenameFolder = handleRenameFolder;
|
|
87
|
+
exports.handleMoveFolder = handleMoveFolder;
|
|
88
|
+
exports.handleDeleteFolder = handleDeleteFolder;
|
|
83
89
|
exports.handleAuditInstance = handleAuditInstance;
|
|
84
90
|
const crypto_1 = require("crypto");
|
|
85
91
|
const n8n_api_client_1 = require("../services/n8n-api-client");
|
|
@@ -238,6 +244,7 @@ const createWorkflowSchema = zod_1.z.object({
|
|
|
238
244
|
})).optional(),
|
|
239
245
|
nodeGroups: zod_1.z.any().optional(),
|
|
240
246
|
projectId: zod_1.z.string().optional(),
|
|
247
|
+
parentFolderId: optionalEmptyAware(zod_1.z.string().trim().min(1)),
|
|
241
248
|
});
|
|
242
249
|
const updateWorkflowSchema = zod_1.z.object({
|
|
243
250
|
id: zod_1.z.string(),
|
|
@@ -246,6 +253,7 @@ const updateWorkflowSchema = zod_1.z.object({
|
|
|
246
253
|
connections: zod_1.z.preprocess(mcp_input_normalizer_1.normalizeMcpWorkflowConnections, zod_1.z.record(zod_1.z.string(), zod_1.z.any())).optional(),
|
|
247
254
|
settings: zod_1.z.preprocess(mcp_input_normalizer_1.normalizeMcpJsonValue, zod_1.z.any()).optional(),
|
|
248
255
|
nodeGroups: zod_1.z.any().optional(),
|
|
256
|
+
parentFolderId: optionalEmptyAware(zod_1.z.string().trim().min(1).nullable()),
|
|
249
257
|
createBackup: zod_1.z.boolean().optional(),
|
|
250
258
|
intent: zod_1.z.string().optional(),
|
|
251
259
|
});
|
|
@@ -715,11 +723,13 @@ async function handleUpdateWorkflow(args, repository, context) {
|
|
|
715
723
|
const sessionId = `mutation_${Date.now()}_${(0, crypto_1.randomUUID)()}`;
|
|
716
724
|
let workflowBefore = null;
|
|
717
725
|
let userIntent = 'Full workflow update';
|
|
726
|
+
let sentParentFolderId = false;
|
|
718
727
|
try {
|
|
719
728
|
const client = ensureApiConfigured(context);
|
|
720
729
|
const input = updateWorkflowSchema.parse(args);
|
|
721
730
|
const { id, createBackup, intent, ...updateData } = input;
|
|
722
731
|
userIntent = intent || 'Full workflow update';
|
|
732
|
+
sentParentFolderId = updateData.parentFolderId !== undefined;
|
|
723
733
|
const current = await client.getWorkflow(id);
|
|
724
734
|
workflowBefore = JSON.parse(JSON.stringify(current));
|
|
725
735
|
if (updateData.nodes && current.nodes) {
|
|
@@ -840,11 +850,16 @@ async function handleUpdateWorkflow(args, repository, context) {
|
|
|
840
850
|
};
|
|
841
851
|
}
|
|
842
852
|
if (error instanceof n8n_errors_1.N8nApiError) {
|
|
853
|
+
const baseDetails = error.details;
|
|
843
854
|
return {
|
|
844
855
|
success: false,
|
|
845
|
-
error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error)
|
|
856
|
+
error: (0, n8n_errors_1.getUserFriendlyErrorMessage)(error) + (sentParentFolderId
|
|
857
|
+
? ' A folder move in the failed update may still have persisted - n8n cannot report or restore folder placement.'
|
|
858
|
+
: ''),
|
|
846
859
|
code: error.code,
|
|
847
|
-
details:
|
|
860
|
+
details: sentParentFolderId
|
|
861
|
+
? { ...(baseDetails ?? {}), folderMoveMayHavePersisted: true }
|
|
862
|
+
: baseDetails
|
|
848
863
|
};
|
|
849
864
|
}
|
|
850
865
|
return {
|
|
@@ -2980,6 +2995,171 @@ async function handleGetCredentialSchema(args, context) {
|
|
|
2980
2995
|
return handleCrudError(error);
|
|
2981
2996
|
}
|
|
2982
2997
|
}
|
|
2998
|
+
const FOLDER_PROJECT_ROOT = '0';
|
|
2999
|
+
const folderProjectSchema = zod_1.z.object({
|
|
3000
|
+
projectId: optionalEmptyAware(zod_1.z.string().trim().min(1)).transform((v) => v ?? 'personal'),
|
|
3001
|
+
});
|
|
3002
|
+
const folderIdSchema = folderProjectSchema.extend({
|
|
3003
|
+
folderId: zod_1.z.string().trim().min(1),
|
|
3004
|
+
});
|
|
3005
|
+
const nullOrEmptyToUndefined = (v) => (v === null ? undefined : emptyToUndefined(v));
|
|
3006
|
+
const optionalParentFolderId = zod_1.z.preprocess(nullOrEmptyToUndefined, zod_1.z.string().trim().min(1).optional());
|
|
3007
|
+
const createFolderSchema = folderProjectSchema.extend({
|
|
3008
|
+
name: zod_1.z.string().trim().min(1),
|
|
3009
|
+
parentFolderId: optionalParentFolderId,
|
|
3010
|
+
});
|
|
3011
|
+
const listFoldersSchema = folderProjectSchema.extend({
|
|
3012
|
+
nameFilter: optionalEmptyAware(zod_1.z.string().trim().min(1)),
|
|
3013
|
+
parentFolderId: optionalParentFolderId,
|
|
3014
|
+
sortBy: zod_1.z.enum(['name:asc', 'name:desc', 'createdAt:asc', 'createdAt:desc', 'updatedAt:asc', 'updatedAt:desc']).optional(),
|
|
3015
|
+
skip: zod_1.z.number().int().min(0).optional(),
|
|
3016
|
+
take: zod_1.z.number().int().min(1).max(100).optional(),
|
|
3017
|
+
});
|
|
3018
|
+
const renameFolderSchema = folderIdSchema.extend({
|
|
3019
|
+
name: zod_1.z.string().trim().min(1),
|
|
3020
|
+
});
|
|
3021
|
+
const moveFolderSchema = folderIdSchema.extend({
|
|
3022
|
+
parentFolderId: zod_1.z.preprocess(emptyToUndefined, zod_1.z.string().trim().min(1).nullable()),
|
|
3023
|
+
});
|
|
3024
|
+
const deleteFolderSchema = folderIdSchema.extend({
|
|
3025
|
+
transferToFolderId: optionalEmptyAware(zod_1.z.string().trim().min(1)),
|
|
3026
|
+
});
|
|
3027
|
+
function handleFolderError(error) {
|
|
3028
|
+
const response = handleCrudError(error);
|
|
3029
|
+
if (error instanceof n8n_errors_1.N8nApiError) {
|
|
3030
|
+
const appendHint = (hint) => {
|
|
3031
|
+
const base = (response.error ?? '').trimEnd();
|
|
3032
|
+
response.error = `${base}${/[.!?]$/.test(base) ? '' : '.'} ${hint}`;
|
|
3033
|
+
};
|
|
3034
|
+
if (error.statusCode === 403) {
|
|
3035
|
+
appendHint('Folders need an API key with folder:* scopes AND a licensed instance: folders unlock on the registered free Community tier (Settings -> Usage and plan -> register) and up.');
|
|
3036
|
+
}
|
|
3037
|
+
else if (error.statusCode === 404) {
|
|
3038
|
+
appendHint('Check the projectId and folderId; on n8n older than 2.19 the folders API does not exist at all.');
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
return response;
|
|
3042
|
+
}
|
|
3043
|
+
async function resolveFolderProjectId(client, projectId) {
|
|
3044
|
+
return projectId === 'personal' ? await client.resolvePersonalProjectId() : projectId;
|
|
3045
|
+
}
|
|
3046
|
+
const FOLDER_LIST_SELECT = ['id', 'name', 'createdAt', 'updatedAt', 'parentFolder', 'workflowCount', 'subFolderCount', 'path'];
|
|
3047
|
+
async function handleCreateFolder(args, context) {
|
|
3048
|
+
try {
|
|
3049
|
+
const client = ensureApiConfigured(context);
|
|
3050
|
+
const input = createFolderSchema.parse(args);
|
|
3051
|
+
const folder = await client.createFolder(input.projectId, {
|
|
3052
|
+
name: input.name,
|
|
3053
|
+
...(input.parentFolderId ? { parentFolderId: input.parentFolderId } : {}),
|
|
3054
|
+
});
|
|
3055
|
+
if (!folder || !folder.id) {
|
|
3056
|
+
return { success: false, error: 'Folder creation failed: n8n API returned an empty or invalid response' };
|
|
3057
|
+
}
|
|
3058
|
+
return {
|
|
3059
|
+
success: true,
|
|
3060
|
+
data: { id: folder.id, name: folder.name, parentFolderId: folder.parentFolderId ?? null },
|
|
3061
|
+
message: `Folder "${folder.name}" created with ID: ${folder.id}. Place workflows in it via n8n_create_workflow's parentFolderId or the moveToFolder operation of n8n_update_partial_workflow.`,
|
|
3062
|
+
};
|
|
3063
|
+
}
|
|
3064
|
+
catch (error) {
|
|
3065
|
+
return handleFolderError(error);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
async function handleListFolders(args, context) {
|
|
3069
|
+
try {
|
|
3070
|
+
const client = ensureApiConfigured(context);
|
|
3071
|
+
const input = listFoldersSchema.parse(args || {});
|
|
3072
|
+
const projectId = await resolveFolderProjectId(client, input.projectId);
|
|
3073
|
+
const filter = {};
|
|
3074
|
+
if (input.nameFilter)
|
|
3075
|
+
filter.name = input.nameFilter;
|
|
3076
|
+
if (input.parentFolderId)
|
|
3077
|
+
filter.parentFolderId = input.parentFolderId;
|
|
3078
|
+
const result = await client.listFolders(projectId, {
|
|
3079
|
+
...(Object.keys(filter).length > 0 ? { filter } : {}),
|
|
3080
|
+
select: FOLDER_LIST_SELECT,
|
|
3081
|
+
sortBy: input.sortBy ?? 'updatedAt:desc',
|
|
3082
|
+
skip: input.skip ?? 0,
|
|
3083
|
+
take: input.take ?? 50,
|
|
3084
|
+
});
|
|
3085
|
+
return {
|
|
3086
|
+
success: true,
|
|
3087
|
+
data: {
|
|
3088
|
+
folders: result.data,
|
|
3089
|
+
count: result.count,
|
|
3090
|
+
projectId,
|
|
3091
|
+
},
|
|
3092
|
+
};
|
|
3093
|
+
}
|
|
3094
|
+
catch (error) {
|
|
3095
|
+
return handleFolderError(error);
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
async function handleGetFolder(args, context) {
|
|
3099
|
+
try {
|
|
3100
|
+
const client = ensureApiConfigured(context);
|
|
3101
|
+
const input = folderIdSchema.parse(args);
|
|
3102
|
+
const projectId = await resolveFolderProjectId(client, input.projectId);
|
|
3103
|
+
const folder = await client.getFolder(projectId, input.folderId);
|
|
3104
|
+
return { success: true, data: { ...folder, projectId } };
|
|
3105
|
+
}
|
|
3106
|
+
catch (error) {
|
|
3107
|
+
return handleFolderError(error);
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
async function handleRenameFolder(args, context) {
|
|
3111
|
+
try {
|
|
3112
|
+
const client = ensureApiConfigured(context);
|
|
3113
|
+
const input = renameFolderSchema.parse(args);
|
|
3114
|
+
const projectId = await resolveFolderProjectId(client, input.projectId);
|
|
3115
|
+
const folder = await client.updateFolder(projectId, input.folderId, { name: input.name });
|
|
3116
|
+
return {
|
|
3117
|
+
success: true,
|
|
3118
|
+
data: { id: folder.id, name: folder.name },
|
|
3119
|
+
message: `Folder renamed to "${folder.name}"`,
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
catch (error) {
|
|
3123
|
+
return handleFolderError(error);
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
async function handleMoveFolder(args, context) {
|
|
3127
|
+
try {
|
|
3128
|
+
const client = ensureApiConfigured(context);
|
|
3129
|
+
const input = moveFolderSchema.parse(args);
|
|
3130
|
+
const projectId = await resolveFolderProjectId(client, input.projectId);
|
|
3131
|
+
const target = input.parentFolderId ?? FOLDER_PROJECT_ROOT;
|
|
3132
|
+
const folder = await client.updateFolder(projectId, input.folderId, { parentFolderId: target });
|
|
3133
|
+
return {
|
|
3134
|
+
success: true,
|
|
3135
|
+
data: { id: folder.id, name: folder.name, parentFolderId: folder.parentFolderId ?? null },
|
|
3136
|
+
message: target === FOLDER_PROJECT_ROOT
|
|
3137
|
+
? `Folder "${folder.name}" moved to the project root`
|
|
3138
|
+
: `Folder "${folder.name}" moved under folder ${target}`,
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3141
|
+
catch (error) {
|
|
3142
|
+
return handleFolderError(error);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
async function handleDeleteFolder(args, context) {
|
|
3146
|
+
try {
|
|
3147
|
+
const client = ensureApiConfigured(context);
|
|
3148
|
+
const input = deleteFolderSchema.parse(args);
|
|
3149
|
+
const projectId = await resolveFolderProjectId(client, input.projectId);
|
|
3150
|
+
await client.deleteFolder(projectId, input.folderId, input.transferToFolderId);
|
|
3151
|
+
return {
|
|
3152
|
+
success: true,
|
|
3153
|
+
data: { id: input.folderId, deleted: true },
|
|
3154
|
+
message: input.transferToFolderId
|
|
3155
|
+
? `Folder ${input.folderId} deleted; contents transferred to ${input.transferToFolderId === FOLDER_PROJECT_ROOT ? 'the project root' : `folder ${input.transferToFolderId}`}`
|
|
3156
|
+
: `Folder ${input.folderId} deleted; its workflows were moved to the project root and ARCHIVED, sub-folders were deleted`,
|
|
3157
|
+
};
|
|
3158
|
+
}
|
|
3159
|
+
catch (error) {
|
|
3160
|
+
return handleFolderError(error);
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
2983
3163
|
const auditInstanceSchema = zod_1.z.object({
|
|
2984
3164
|
categories: zod_1.z.array(zod_1.z.enum([
|
|
2985
3165
|
'credentials', 'database', 'nodes', 'instance', 'filesystem',
|