n8n-mcp 2.7.15 → 2.7.17
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 +1 -0
- package/README.md +48 -2
- package/data/nodes.db +0 -0
- package/dist/http-server-single-session.d.ts.map +1 -1
- package/dist/http-server-single-session.js +18 -0
- package/dist/http-server-single-session.js.map +1 -1
- package/dist/http-server.d.ts.map +1 -1
- package/dist/http-server.js +18 -0
- package/dist/http-server.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +0 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-docs/configuration/get-node-as-tool-info.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/get-node-as-tool-info.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-as-tool-info.js +73 -0
- package/dist/mcp/tool-docs/configuration/get-node-as-tool-info.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-documentation.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/get-node-documentation.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-documentation.js +47 -0
- package/dist/mcp/tool-docs/configuration/get-node-documentation.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-essentials.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/get-node-essentials.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-essentials.js +88 -0
- package/dist/mcp/tool-docs/configuration/get-node-essentials.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-info.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/get-node-info.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-node-info.js +100 -0
- package/dist/mcp/tool-docs/configuration/get-node-info.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-property-dependencies.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/get-property-dependencies.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/get-property-dependencies.js +81 -0
- package/dist/mcp/tool-docs/configuration/get-property-dependencies.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/index.d.ts +7 -0
- package/dist/mcp/tool-docs/configuration/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/index.js +16 -0
- package/dist/mcp/tool-docs/configuration/index.js.map +1 -0
- package/dist/mcp/tool-docs/configuration/search-node-properties.d.ts +3 -0
- package/dist/mcp/tool-docs/configuration/search-node-properties.d.ts.map +1 -0
- package/dist/mcp/tool-docs/configuration/search-node-properties.js +99 -0
- package/dist/mcp/tool-docs/configuration/search-node-properties.js.map +1 -0
- package/dist/mcp/tool-docs/discovery/get-database-statistics.d.ts +3 -0
- package/dist/mcp/tool-docs/discovery/get-database-statistics.d.ts.map +1 -0
- package/dist/mcp/tool-docs/discovery/get-database-statistics.js +69 -0
- package/dist/mcp/tool-docs/discovery/get-database-statistics.js.map +1 -0
- package/dist/mcp/tool-docs/discovery/index.d.ts +5 -0
- package/dist/mcp/tool-docs/discovery/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/discovery/index.js +12 -0
- package/dist/mcp/tool-docs/discovery/index.js.map +1 -0
- package/dist/mcp/tool-docs/discovery/list-ai-tools.d.ts +3 -0
- package/dist/mcp/tool-docs/discovery/list-ai-tools.d.ts.map +1 -0
- package/dist/mcp/tool-docs/discovery/list-ai-tools.js +49 -0
- package/dist/mcp/tool-docs/discovery/list-ai-tools.js.map +1 -0
- package/dist/mcp/tool-docs/discovery/list-nodes.d.ts +3 -0
- package/dist/mcp/tool-docs/discovery/list-nodes.d.ts.map +1 -0
- package/dist/mcp/tool-docs/discovery/list-nodes.js +54 -0
- package/dist/mcp/tool-docs/discovery/list-nodes.js.map +1 -0
- package/dist/mcp/tool-docs/discovery/search-nodes.d.ts +3 -0
- package/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map +1 -0
- package/dist/mcp/tool-docs/discovery/search-nodes.js +56 -0
- package/dist/mcp/tool-docs/discovery/search-nodes.js.map +1 -0
- package/dist/mcp/tool-docs/index.d.ts +4 -0
- package/dist/mcp/tool-docs/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/index.js +51 -0
- package/dist/mcp/tool-docs/index.js.map +1 -0
- package/dist/mcp/tool-docs/special/code-node-guide.d.ts +3 -0
- package/dist/mcp/tool-docs/special/code-node-guide.d.ts.map +1 -0
- package/dist/mcp/tool-docs/special/code-node-guide.js +61 -0
- package/dist/mcp/tool-docs/special/code-node-guide.js.map +1 -0
- package/dist/mcp/tool-docs/special/index.d.ts +2 -0
- package/dist/mcp/tool-docs/special/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/special/index.js +6 -0
- package/dist/mcp/tool-docs/special/index.js.map +1 -0
- package/dist/mcp/tool-docs/system/index.d.ts +5 -0
- package/dist/mcp/tool-docs/system/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/system/index.js +12 -0
- package/dist/mcp/tool-docs/system/index.js.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts +3 -0
- package/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-diagnostic.js +81 -0
- package/dist/mcp/tool-docs/system/n8n-diagnostic.js.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-health-check.d.ts +3 -0
- package/dist/mcp/tool-docs/system/n8n-health-check.d.ts.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-health-check.js +77 -0
- package/dist/mcp/tool-docs/system/n8n-health-check.js.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts +3 -0
- package/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map +1 -0
- package/dist/mcp/tool-docs/system/n8n-list-available-tools.js +75 -0
- package/dist/mcp/tool-docs/system/n8n-list-available-tools.js.map +1 -0
- package/dist/mcp/tool-docs/system/tools-documentation.d.ts +3 -0
- package/dist/mcp/tool-docs/system/tools-documentation.d.ts.map +1 -0
- package/dist/mcp/tool-docs/system/tools-documentation.js +65 -0
- package/dist/mcp/tool-docs/system/tools-documentation.js.map +1 -0
- package/dist/mcp/tool-docs/templates/get-node-for-task.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/get-node-for-task.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/get-node-for-task.js +50 -0
- package/dist/mcp/tool-docs/templates/get-node-for-task.js.map +1 -0
- package/dist/mcp/tool-docs/templates/get-template.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/get-template.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/get-template.js +76 -0
- package/dist/mcp/tool-docs/templates/get-template.js.map +1 -0
- package/dist/mcp/tool-docs/templates/get-templates-for-task.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/get-templates-for-task.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/get-templates-for-task.js +76 -0
- package/dist/mcp/tool-docs/templates/get-templates-for-task.js.map +1 -0
- package/dist/mcp/tool-docs/templates/index.d.ts +7 -0
- package/dist/mcp/tool-docs/templates/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/index.js +16 -0
- package/dist/mcp/tool-docs/templates/index.js.map +1 -0
- package/dist/mcp/tool-docs/templates/list-node-templates.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/list-node-templates.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/list-node-templates.js +80 -0
- package/dist/mcp/tool-docs/templates/list-node-templates.js.map +1 -0
- package/dist/mcp/tool-docs/templates/list-tasks.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/list-tasks.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/list-tasks.js +48 -0
- package/dist/mcp/tool-docs/templates/list-tasks.js.map +1 -0
- package/dist/mcp/tool-docs/templates/search-templates.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/search-templates.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/search-templates.js +83 -0
- package/dist/mcp/tool-docs/templates/search-templates.js.map +1 -0
- package/dist/mcp/tool-docs/types.d.ts +30 -0
- package/dist/mcp/tool-docs/types.d.ts.map +1 -0
- package/dist/mcp/tool-docs/types.js +3 -0
- package/dist/mcp/tool-docs/types.js.map +1 -0
- package/dist/mcp/tool-docs/validation/index.d.ts +6 -0
- package/dist/mcp/tool-docs/validation/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/index.js +14 -0
- package/dist/mcp/tool-docs/validation/index.js.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-node-minimal.d.ts +3 -0
- package/dist/mcp/tool-docs/validation/validate-node-minimal.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-node-minimal.js +49 -0
- package/dist/mcp/tool-docs/validation/validate-node-minimal.js.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-node-operation.d.ts +3 -0
- package/dist/mcp/tool-docs/validation/validate-node-operation.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-node-operation.js +94 -0
- package/dist/mcp/tool-docs/validation/validate-node-operation.js.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-connections.d.ts +3 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-connections.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-connections.js +58 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-connections.js.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-expressions.d.ts +3 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-expressions.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-expressions.js +58 -0
- package/dist/mcp/tool-docs/validation/validate-workflow-expressions.js.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/validation/validate-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/validation/validate-workflow.js +83 -0
- package/dist/mcp/tool-docs/validation/validate-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/index.d.ts +15 -0
- package/dist/mcp/tool-docs/workflow_management/index.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/index.js +32 -0
- package/dist/mcp/tool-docs/workflow_management/index.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js +99 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-execution.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-execution.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-execution.js +59 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-execution.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js +52 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-execution.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-execution.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-execution.js +64 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-execution.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-details.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-details.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-details.js +51 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-details.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.js +51 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.js +51 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js +51 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-executions.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-executions.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-executions.js +86 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-executions.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js +57 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.js +80 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js +57 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js +82 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts +3 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map +1 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js +73 -0
- package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map +1 -0
- package/dist/mcp/tools-documentation-new.d.ts +6 -0
- package/dist/mcp/tools-documentation-new.d.ts.map +1 -0
- package/dist/mcp/tools-documentation-new.js +163 -0
- package/dist/mcp/tools-documentation-new.js.map +1 -0
- package/dist/mcp/tools-documentation.d.ts +1 -29
- package/dist/mcp/tools-documentation.d.ts.map +1 -1
- package/dist/mcp/tools-documentation.js +506 -1235
- package/dist/mcp/tools-documentation.js.map +1 -1
- package/dist/scripts/rebuild.js +2 -1
- package/dist/scripts/rebuild.js.map +1 -1
- package/dist/scripts/test-tools-documentation.d.ts +2 -0
- package/dist/scripts/test-tools-documentation.d.ts.map +1 -0
- package/dist/scripts/test-tools-documentation.js +41 -0
- package/dist/scripts/test-tools-documentation.js.map +1 -0
- package/dist/services/enhanced-config-validator.d.ts +0 -1
- package/dist/services/enhanced-config-validator.d.ts.map +1 -1
- package/dist/services/enhanced-config-validator.js +2 -91
- package/dist/services/enhanced-config-validator.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,1389 +1,660 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toolsDocumentation = void 0;
|
|
4
3
|
exports.getToolDocumentation = getToolDocumentation;
|
|
5
4
|
exports.getToolsOverview = getToolsOverview;
|
|
6
5
|
exports.searchToolDocumentation = searchToolDocumentation;
|
|
7
6
|
exports.getToolsByCategory = getToolsByCategory;
|
|
8
7
|
exports.getAllCategories = getAllCategories;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
essentials: {
|
|
14
|
-
description: 'Search nodes. Primary nodes ranked first.',
|
|
15
|
-
keyParameters: ['query', 'limit', 'mode'],
|
|
16
|
-
example: 'search_nodes({query: "webhook"})',
|
|
17
|
-
performance: 'Fast - FTS5 when available',
|
|
18
|
-
tips: [
|
|
19
|
-
'Primary nodes first: webhook→Webhook, http→HTTP Request',
|
|
20
|
-
'Modes: OR (any word), AND (all words), FUZZY (typos OK)'
|
|
21
|
-
]
|
|
22
|
-
},
|
|
23
|
-
full: {
|
|
24
|
-
description: 'Search n8n nodes using FTS5 full-text search (when available) with relevance ranking. Supports OR (default), AND, and FUZZY search modes. Results are sorted by relevance, ensuring primary nodes like Webhook and HTTP Request appear first.',
|
|
25
|
-
parameters: {
|
|
26
|
-
query: { type: 'string', description: 'Search terms. Wrap in quotes for exact phrase matching', required: true },
|
|
27
|
-
limit: { type: 'number', description: 'Maximum results to return (default: 20)', required: false },
|
|
28
|
-
mode: { type: 'string', description: 'Search mode: OR (any word), AND (all words in ANY field), FUZZY (typo-tolerant using edit distance)', required: false }
|
|
29
|
-
},
|
|
30
|
-
returns: 'Array of nodes sorted by relevance with nodeType, displayName, description, category. AND mode includes searchInfo explaining the search scope.',
|
|
31
|
-
examples: [
|
|
32
|
-
'search_nodes({query: "webhook"}) - Webhook node appears first',
|
|
33
|
-
'search_nodes({query: "http call"}) - HTTP Request node appears first',
|
|
34
|
-
'search_nodes({query: "send message", mode: "AND"}) - Nodes with both words anywhere in their data',
|
|
35
|
-
'search_nodes({query: "slak", mode: "FUZZY"}) - Finds Slack using typo tolerance'
|
|
36
|
-
],
|
|
37
|
-
useCases: [
|
|
38
|
-
'Finding primary nodes quickly (webhook, http, email)',
|
|
39
|
-
'Discovering nodes with typo tolerance',
|
|
40
|
-
'Precise searches with AND mode',
|
|
41
|
-
'Exploratory searches with OR mode'
|
|
42
|
-
],
|
|
43
|
-
performance: 'FTS5: <20ms for most queries. Falls back to optimized LIKE queries if FTS5 unavailable.',
|
|
44
|
-
bestPractices: [
|
|
45
|
-
'Default OR mode is best for exploration',
|
|
46
|
-
'Use AND mode when you need all terms present',
|
|
47
|
-
'Use FUZZY mode if unsure of spelling',
|
|
48
|
-
'Quotes force exact phrase matching',
|
|
49
|
-
'Primary nodes are boosted in relevance'
|
|
50
|
-
],
|
|
51
|
-
pitfalls: [
|
|
52
|
-
'AND mode searches ALL fields (description, documentation, operations) not just names',
|
|
53
|
-
'FUZZY mode uses edit distance - may return unexpected matches for very short queries',
|
|
54
|
-
'Special characters are ignored in search',
|
|
55
|
-
'FTS5 syntax errors fallback to basic LIKE search'
|
|
56
|
-
],
|
|
57
|
-
relatedTools: ['list_nodes', 'get_node_essentials', 'get_node_info']
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
get_node_essentials: {
|
|
61
|
-
name: 'get_node_essentials',
|
|
62
|
-
category: 'configuration',
|
|
63
|
-
essentials: {
|
|
64
|
-
description: 'Get 10-20 key properties with examples',
|
|
65
|
-
keyParameters: ['nodeType'],
|
|
66
|
-
example: 'get_node_essentials("nodes-base.slack")',
|
|
67
|
-
performance: '<5KB vs 100KB+',
|
|
68
|
-
tips: [
|
|
69
|
-
'Use this first! Has examples.'
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
|
-
full: {
|
|
73
|
-
description: 'Returns a curated set of essential properties for a node, typically 10-20 most commonly used properties. Includes working examples and is 95% smaller than get_node_info. Designed for efficient node configuration.',
|
|
74
|
-
parameters: {
|
|
75
|
-
nodeType: { type: 'string', description: 'Full node type (e.g., "n8n-nodes-base.slack")', required: true }
|
|
76
|
-
},
|
|
77
|
-
returns: 'Object with node info, essential properties, examples, and common patterns',
|
|
78
|
-
examples: [
|
|
79
|
-
'get_node_essentials("n8n-nodes-base.httpRequest") - Get HTTP request essentials',
|
|
80
|
-
'get_node_essentials("n8n-nodes-base.webhook") - Get webhook configuration',
|
|
81
|
-
'get_node_essentials("n8n-nodes-base.slack") - Get Slack essentials'
|
|
82
|
-
],
|
|
83
|
-
useCases: [
|
|
84
|
-
'Quickly configuring nodes without information overload',
|
|
85
|
-
'Getting working examples for immediate use',
|
|
86
|
-
'Understanding the most important node options',
|
|
87
|
-
'Building workflows efficiently'
|
|
88
|
-
],
|
|
89
|
-
performance: 'Extremely fast - returns pre-filtered data. Response size <5KB vs 100KB+ for full node info.',
|
|
90
|
-
bestPractices: [
|
|
91
|
-
'Always try this before get_node_info',
|
|
92
|
-
'Use included examples as starting points',
|
|
93
|
-
'Check commonPatterns for typical configurations',
|
|
94
|
-
'Combine with validate_node_minimal for quick validation'
|
|
95
|
-
],
|
|
96
|
-
pitfalls: [
|
|
97
|
-
'May not include rarely-used properties',
|
|
98
|
-
'Some advanced options might be missing',
|
|
99
|
-
'Use search_node_properties if specific property not found'
|
|
100
|
-
],
|
|
101
|
-
relatedTools: ['get_node_info', 'search_node_properties', 'validate_node_minimal']
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
list_nodes: {
|
|
105
|
-
name: 'list_nodes',
|
|
106
|
-
category: 'discovery',
|
|
107
|
-
essentials: {
|
|
108
|
-
description: 'List all available n8n nodes with optional filtering',
|
|
109
|
-
keyParameters: ['category', 'limit', 'onlyTriggers'],
|
|
110
|
-
example: 'list_nodes({category: "communication", limit: 20})',
|
|
111
|
-
performance: 'Fast - direct database query',
|
|
112
|
-
tips: [
|
|
113
|
-
'Great for browsing nodes by category',
|
|
114
|
-
'Use onlyTriggers:true to find workflow starters'
|
|
115
|
-
]
|
|
116
|
-
},
|
|
117
|
-
full: {
|
|
118
|
-
description: 'Lists all available n8n nodes with comprehensive filtering options. Can filter by category, package, trigger status, and more. Returns complete node metadata.',
|
|
119
|
-
parameters: {
|
|
120
|
-
category: { type: 'string', description: 'Filter by category (e.g., "communication", "data")', required: false },
|
|
121
|
-
limit: { type: 'number', description: 'Maximum results (default: 50)', required: false },
|
|
122
|
-
offset: { type: 'number', description: 'Pagination offset', required: false },
|
|
123
|
-
onlyTriggers: { type: 'boolean', description: 'Only show trigger nodes', required: false },
|
|
124
|
-
onlyAITools: { type: 'boolean', description: 'Only show AI-capable nodes', required: false },
|
|
125
|
-
package: { type: 'string', description: 'Filter by package name', required: false }
|
|
126
|
-
},
|
|
127
|
-
returns: 'Array of nodes with complete metadata including type, name, description, category',
|
|
128
|
-
examples: [
|
|
129
|
-
'list_nodes() - Get first 50 nodes',
|
|
130
|
-
'list_nodes({category: "trigger"}) - All trigger nodes',
|
|
131
|
-
'list_nodes({onlyAITools: true}) - Nodes marked as AI tools',
|
|
132
|
-
'list_nodes({package: "n8n-nodes-base", limit: 100}) - Core nodes'
|
|
133
|
-
],
|
|
134
|
-
useCases: [
|
|
135
|
-
'Browsing available nodes by category',
|
|
136
|
-
'Finding all triggers or webhooks',
|
|
137
|
-
'Discovering AI-capable nodes',
|
|
138
|
-
'Getting overview of available integrations'
|
|
139
|
-
],
|
|
140
|
-
performance: 'Fast - uses indexed queries. Returns in <100ms even for large result sets.',
|
|
141
|
-
bestPractices: [
|
|
142
|
-
'Use categories for focused browsing',
|
|
143
|
-
'Combine with search_nodes for keyword search',
|
|
144
|
-
'Use pagination for large result sets',
|
|
145
|
-
'Check onlyTriggers for workflow starting points'
|
|
146
|
-
],
|
|
147
|
-
pitfalls: [
|
|
148
|
-
'No text search - use search_nodes for that',
|
|
149
|
-
'Categories are predefined, not all nodes have them',
|
|
150
|
-
'Large result sets without limit can be overwhelming'
|
|
151
|
-
],
|
|
152
|
-
relatedTools: ['search_nodes', 'list_ai_tools', 'get_node_essentials']
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
validate_node_minimal: {
|
|
156
|
-
name: 'validate_node_minimal',
|
|
157
|
-
category: 'validation',
|
|
158
|
-
essentials: {
|
|
159
|
-
description: 'Quick validation checking only required fields',
|
|
160
|
-
keyParameters: ['nodeType', 'config'],
|
|
161
|
-
example: 'validate_node_minimal("n8n-nodes-base.slack", {resource: "message", operation: "post"})',
|
|
162
|
-
performance: 'Very fast - minimal checks only',
|
|
163
|
-
tips: [
|
|
164
|
-
'Use for quick validation during configuration',
|
|
165
|
-
'Follow up with validate_node_operation for full validation'
|
|
166
|
-
]
|
|
167
|
-
},
|
|
168
|
-
full: {
|
|
169
|
-
description: 'Performs minimal validation checking only required fields. Fastest validation option, perfect for iterative configuration. Checks if all required fields are present without complex dependency validation.',
|
|
170
|
-
parameters: {
|
|
171
|
-
nodeType: { type: 'string', description: 'Full node type', required: true },
|
|
172
|
-
config: { type: 'object', description: 'Node configuration to validate', required: true }
|
|
173
|
-
},
|
|
174
|
-
returns: 'Object with isValid boolean, missing required fields, and basic feedback',
|
|
175
|
-
examples: [
|
|
176
|
-
'validate_node_minimal("n8n-nodes-base.httpRequest", {url: "https://api.example.com"})',
|
|
177
|
-
'validate_node_minimal("n8n-nodes-base.slack", {resource: "message", operation: "post", channel: "general"})'
|
|
178
|
-
],
|
|
179
|
-
useCases: [
|
|
180
|
-
'Quick validation during iterative configuration',
|
|
181
|
-
'Checking if minimum requirements are met',
|
|
182
|
-
'Fast feedback loop while building',
|
|
183
|
-
'Pre-validation before full check'
|
|
184
|
-
],
|
|
185
|
-
performance: 'Extremely fast - only checks required fields. Typically <10ms.',
|
|
186
|
-
bestPractices: [
|
|
187
|
-
'Use during configuration for quick feedback',
|
|
188
|
-
'Follow with validate_node_operation for complete validation',
|
|
189
|
-
'Great for iterative development',
|
|
190
|
-
'Combine with get_node_essentials for requirements'
|
|
191
|
-
],
|
|
192
|
-
pitfalls: [
|
|
193
|
-
'Doesn\'t check field dependencies',
|
|
194
|
-
'Won\'t catch configuration conflicts',
|
|
195
|
-
'Missing optional but recommended fields'
|
|
196
|
-
],
|
|
197
|
-
relatedTools: ['validate_node_operation', 'get_node_essentials', 'validate_workflow']
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
validate_node_operation: {
|
|
201
|
-
name: 'validate_node_operation',
|
|
202
|
-
category: 'validation',
|
|
203
|
-
essentials: {
|
|
204
|
-
description: 'Full validation with operation-aware checking and helpful suggestions',
|
|
205
|
-
keyParameters: ['nodeType', 'config', 'profile'],
|
|
206
|
-
example: 'validate_node_operation("n8n-nodes-base.slack", {resource: "message", operation: "post", channel: "general"})',
|
|
207
|
-
performance: 'Moderate - comprehensive validation',
|
|
208
|
-
tips: [
|
|
209
|
-
'Provides specific error messages and fixes',
|
|
210
|
-
'Use "strict" profile for production workflows'
|
|
211
|
-
]
|
|
212
|
-
},
|
|
213
|
-
full: {
|
|
214
|
-
description: 'Comprehensive validation that understands operation-specific requirements. Checks dependencies, validates field values, and provides helpful suggestions for fixing issues.',
|
|
215
|
-
parameters: {
|
|
216
|
-
nodeType: { type: 'string', description: 'Full node type', required: true },
|
|
217
|
-
config: { type: 'object', description: 'Complete node configuration', required: true },
|
|
218
|
-
profile: { type: 'string', description: 'Validation profile: "development" or "strict"', required: false }
|
|
219
|
-
},
|
|
220
|
-
returns: 'Detailed validation results with errors, warnings, suggestions, and fixes',
|
|
221
|
-
examples: [
|
|
222
|
-
'validate_node_operation("n8n-nodes-base.httpRequest", {method: "POST", url: "{{$json.url}}", bodyParametersUi: {...}})',
|
|
223
|
-
'validate_node_operation("n8n-nodes-base.postgres", {operation: "executeQuery", query: "SELECT * FROM users"}, "strict")'
|
|
224
|
-
],
|
|
225
|
-
useCases: [
|
|
226
|
-
'Final validation before deployment',
|
|
227
|
-
'Understanding complex field dependencies',
|
|
228
|
-
'Getting suggestions for configuration improvements',
|
|
229
|
-
'Validating operation-specific requirements'
|
|
230
|
-
],
|
|
231
|
-
performance: 'Moderate speed - performs comprehensive checks. 50-200ms depending on complexity.',
|
|
232
|
-
bestPractices: [
|
|
233
|
-
'Use after validate_node_minimal passes',
|
|
234
|
-
'Apply suggested fixes from response',
|
|
235
|
-
'Use strict profile for production',
|
|
236
|
-
'Check warnings even if validation passes'
|
|
237
|
-
],
|
|
238
|
-
pitfalls: [
|
|
239
|
-
'Slower than minimal validation',
|
|
240
|
-
'May be overkill for simple configurations',
|
|
241
|
-
'Strict profile might be too restrictive for development'
|
|
242
|
-
],
|
|
243
|
-
relatedTools: ['validate_node_minimal', 'validate_workflow', 'get_property_dependencies']
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
get_node_for_task: {
|
|
247
|
-
name: 'get_node_for_task',
|
|
248
|
-
category: 'templates',
|
|
249
|
-
essentials: {
|
|
250
|
-
description: 'Get pre-configured node settings for common tasks',
|
|
251
|
-
keyParameters: ['task'],
|
|
252
|
-
example: 'get_node_for_task("send_slack_message")',
|
|
253
|
-
performance: 'Instant - returns pre-built configurations',
|
|
254
|
-
tips: [
|
|
255
|
-
'Use list_tasks() to see all available tasks',
|
|
256
|
-
'Look for userMustProvide fields to complete'
|
|
257
|
-
]
|
|
258
|
-
},
|
|
259
|
-
full: {
|
|
260
|
-
description: 'Returns pre-configured node settings for common automation tasks. Each template includes the correct node type, operation settings, and clear markers for what needs user input.',
|
|
261
|
-
parameters: {
|
|
262
|
-
task: { type: 'string', description: 'Task identifier (use list_tasks to see all)', required: true }
|
|
263
|
-
},
|
|
264
|
-
returns: 'Complete node configuration with parameters, position, and user guidance',
|
|
265
|
-
examples: [
|
|
266
|
-
'get_node_for_task("send_slack_message") - Slack message template',
|
|
267
|
-
'get_node_for_task("receive_webhook") - Webhook trigger setup',
|
|
268
|
-
'get_node_for_task("query_database") - Database query template'
|
|
269
|
-
],
|
|
270
|
-
useCases: [
|
|
271
|
-
'Quickly setting up common automation patterns',
|
|
272
|
-
'Learning correct node configurations',
|
|
273
|
-
'Avoiding configuration mistakes',
|
|
274
|
-
'Rapid workflow prototyping'
|
|
275
|
-
],
|
|
276
|
-
performance: 'Instant - returns static templates. No computation required.',
|
|
277
|
-
bestPractices: [
|
|
278
|
-
'Check userMustProvide fields for required inputs',
|
|
279
|
-
'Use list_tasks() to discover available templates',
|
|
280
|
-
'Validate with validate_node_minimal after filling in',
|
|
281
|
-
'Use as starting point, then customize'
|
|
282
|
-
],
|
|
283
|
-
pitfalls: [
|
|
284
|
-
'Templates are generic - customize for specific needs',
|
|
285
|
-
'Not all tasks have templates',
|
|
286
|
-
'Some fields marked userMustProvide are critical'
|
|
287
|
-
],
|
|
288
|
-
relatedTools: ['list_tasks', 'get_node_essentials', 'validate_node_minimal']
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
n8n_create_workflow: {
|
|
292
|
-
name: 'n8n_create_workflow',
|
|
293
|
-
category: 'workflow_management',
|
|
294
|
-
essentials: {
|
|
295
|
-
description: 'Create a new workflow in n8n via API',
|
|
296
|
-
keyParameters: ['name', 'nodes', 'connections'],
|
|
297
|
-
example: 'n8n_create_workflow({name: "My Workflow", nodes: [...], connections: {...}})',
|
|
298
|
-
performance: 'API call - depends on n8n instance',
|
|
299
|
-
tips: [
|
|
300
|
-
'ALWAYS use node names in connections, never IDs',
|
|
301
|
-
'Error handling properties go at NODE level, not inside parameters!',
|
|
302
|
-
'Requires N8N_API_URL and N8N_API_KEY configuration'
|
|
303
|
-
]
|
|
304
|
-
},
|
|
305
|
-
full: {
|
|
306
|
-
description: 'Creates a new workflow in your n8n instance via API. Requires proper API configuration. Returns the created workflow with assigned ID.\n\n⚠️ CRITICAL: Error handling properties (onError, retryOnFail, etc.) are NODE-LEVEL properties, not inside parameters!',
|
|
307
|
-
parameters: {
|
|
308
|
-
name: { type: 'string', description: 'Workflow name', required: true },
|
|
309
|
-
nodes: { type: 'array', description: 'Array of node configurations', required: true },
|
|
310
|
-
connections: { type: 'object', description: 'Node connections (use names!)', required: true },
|
|
311
|
-
settings: { type: 'object', description: 'Workflow settings', required: false },
|
|
312
|
-
tags: { type: 'array', description: 'Tag IDs (not names)', required: false }
|
|
313
|
-
},
|
|
314
|
-
returns: 'Created workflow object with id, name, nodes, connections, and metadata',
|
|
315
|
-
examples: [
|
|
316
|
-
`// Basic workflow with proper error handling
|
|
317
|
-
n8n_create_workflow({
|
|
318
|
-
name: "Slack Notification with Error Handling",
|
|
319
|
-
nodes: [
|
|
320
|
-
{
|
|
321
|
-
id: "1",
|
|
322
|
-
name: "Webhook",
|
|
323
|
-
type: "n8n-nodes-base.webhook",
|
|
324
|
-
typeVersion: 2,
|
|
325
|
-
position: [250, 300],
|
|
326
|
-
parameters: {
|
|
327
|
-
path: "/webhook",
|
|
328
|
-
method: "POST"
|
|
329
|
-
},
|
|
330
|
-
// ✅ CORRECT - Error handling at node level
|
|
331
|
-
onError: "continueRegularOutput"
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
id: "2",
|
|
335
|
-
name: "Database Query",
|
|
336
|
-
type: "n8n-nodes-base.postgres",
|
|
337
|
-
typeVersion: 2.4,
|
|
338
|
-
position: [450, 300],
|
|
339
|
-
parameters: {
|
|
340
|
-
operation: "executeQuery",
|
|
341
|
-
query: "SELECT * FROM users"
|
|
342
|
-
},
|
|
343
|
-
// ✅ CORRECT - Error handling at node level
|
|
344
|
-
onError: "continueErrorOutput",
|
|
345
|
-
retryOnFail: true,
|
|
346
|
-
maxTries: 3,
|
|
347
|
-
waitBetweenTries: 2000
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
id: "3",
|
|
351
|
-
name: "Error Handler",
|
|
352
|
-
type: "n8n-nodes-base.slack",
|
|
353
|
-
typeVersion: 2.2,
|
|
354
|
-
position: [650, 450],
|
|
355
|
-
parameters: {
|
|
356
|
-
resource: "message",
|
|
357
|
-
operation: "post",
|
|
358
|
-
channel: "#errors",
|
|
359
|
-
text: "Database query failed!"
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
],
|
|
363
|
-
connections: {
|
|
364
|
-
"Webhook": {
|
|
365
|
-
main: [[{node: "Database Query", type: "main", index: 0}]]
|
|
366
|
-
},
|
|
367
|
-
"Database Query": {
|
|
368
|
-
main: [[{node: "Success Handler", type: "main", index: 0}]],
|
|
369
|
-
error: [[{node: "Error Handler", type: "main", index: 0}]] // Error output
|
|
8
|
+
const tool_docs_1 = require("./tool-docs");
|
|
9
|
+
function getToolDocumentation(toolName, depth = 'essentials') {
|
|
10
|
+
if (toolName === 'javascript_code_node_guide') {
|
|
11
|
+
return getJavaScriptCodeNodeGuide(depth);
|
|
370
12
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
],
|
|
374
|
-
useCases: [
|
|
375
|
-
'Deploying workflows programmatically',
|
|
376
|
-
'Automating workflow creation',
|
|
377
|
-
'Migrating workflows between instances',
|
|
378
|
-
'Creating workflows from templates',
|
|
379
|
-
'Building error-resilient workflows'
|
|
380
|
-
],
|
|
381
|
-
performance: 'Depends on n8n instance and network. Typically 100-500ms.',
|
|
382
|
-
bestPractices: [
|
|
383
|
-
'CRITICAL: Use node NAMES in connections, not IDs',
|
|
384
|
-
'CRITICAL: Place error handling at NODE level, not in parameters',
|
|
385
|
-
'Validate workflow before creating',
|
|
386
|
-
'Use meaningful workflow names',
|
|
387
|
-
'Add error handling to external service nodes',
|
|
388
|
-
'Check n8n_health_check before creating'
|
|
389
|
-
],
|
|
390
|
-
pitfalls: [
|
|
391
|
-
'Placing error handling properties inside parameters object',
|
|
392
|
-
'Using node IDs in connections breaks UI display',
|
|
393
|
-
'Workflow not automatically activated',
|
|
394
|
-
'Tags must exist (use tag IDs not names)',
|
|
395
|
-
'API must be configured correctly'
|
|
396
|
-
],
|
|
397
|
-
relatedTools: ['validate_workflow', 'n8n_update_partial_workflow', 'n8n_list_workflows']
|
|
398
|
-
}
|
|
399
|
-
},
|
|
400
|
-
n8n_update_partial_workflow: {
|
|
401
|
-
name: 'n8n_update_partial_workflow',
|
|
402
|
-
category: 'workflow_management',
|
|
403
|
-
essentials: {
|
|
404
|
-
description: 'Update workflows using diff operations - only send changes, not entire workflow',
|
|
405
|
-
keyParameters: ['id', 'operations'],
|
|
406
|
-
example: 'n8n_update_partial_workflow({id: "123", operations: [{type: "updateNode", nodeName: "Slack", changes: {onError: "continueRegularOutput"}}]})',
|
|
407
|
-
performance: '80-90% more efficient than full updates',
|
|
408
|
-
tips: [
|
|
409
|
-
'Maximum 5 operations per request',
|
|
410
|
-
'Can reference nodes by name or ID',
|
|
411
|
-
'Error handling properties go at NODE level, not inside parameters!'
|
|
412
|
-
]
|
|
413
|
-
},
|
|
414
|
-
full: {
|
|
415
|
-
description: 'Update existing workflows using diff operations. Much more efficient than full updates as it only sends the changes. Supports 13 different operation types.\n\n⚠️ CRITICAL: Error handling properties (onError, retryOnFail, maxTries, etc.) are NODE-LEVEL properties, not parameters!',
|
|
416
|
-
parameters: {
|
|
417
|
-
id: { type: 'string', description: 'Workflow ID to update', required: true },
|
|
418
|
-
operations: { type: 'array', description: 'Array of diff operations (max 5)', required: true },
|
|
419
|
-
validateOnly: { type: 'boolean', description: 'Only validate without applying', required: false }
|
|
420
|
-
},
|
|
421
|
-
returns: 'Updated workflow with applied changes and operation results',
|
|
422
|
-
examples: [
|
|
423
|
-
`// Update node parameters (properties inside parameters object)
|
|
424
|
-
n8n_update_partial_workflow({
|
|
425
|
-
id: "123",
|
|
426
|
-
operations: [{
|
|
427
|
-
type: "updateNode",
|
|
428
|
-
nodeName: "Slack",
|
|
429
|
-
changes: {
|
|
430
|
-
"parameters.channel": "#general", // Nested property
|
|
431
|
-
"parameters.text": "Hello world" // Nested property
|
|
13
|
+
if (toolName === 'python_code_node_guide') {
|
|
14
|
+
return getPythonCodeNodeGuide(depth);
|
|
432
15
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
n8n_update_partial_workflow({
|
|
437
|
-
id: "123",
|
|
438
|
-
operations: [{
|
|
439
|
-
type: "updateNode",
|
|
440
|
-
nodeName: "HTTP Request",
|
|
441
|
-
changes: {
|
|
442
|
-
onError: "continueErrorOutput", // ✅ Correct - node level
|
|
443
|
-
retryOnFail: true, // ✅ Correct - node level
|
|
444
|
-
maxTries: 3, // ✅ Correct - node level
|
|
445
|
-
waitBetweenTries: 2000 // ✅ Correct - node level
|
|
16
|
+
const tool = tool_docs_1.toolsDocumentation[toolName];
|
|
17
|
+
if (!tool) {
|
|
18
|
+
return `Tool '${toolName}' not found. Use tools_documentation() to see available tools.`;
|
|
446
19
|
}
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// ❌ BAD: changes: {"parameters.onError": "continueErrorOutput"}
|
|
451
|
-
// ✅ GOOD: changes: {onError: "continueErrorOutput"}`,
|
|
452
|
-
`// Add error connection between nodes
|
|
453
|
-
n8n_update_partial_workflow({
|
|
454
|
-
id: "123",
|
|
455
|
-
operations: [{
|
|
456
|
-
type: "addConnection",
|
|
457
|
-
source: "Database Query",
|
|
458
|
-
target: "Error Handler",
|
|
459
|
-
sourceOutput: "error", // Error output
|
|
460
|
-
targetInput: "main"
|
|
461
|
-
}]
|
|
462
|
-
})`
|
|
463
|
-
],
|
|
464
|
-
useCases: [
|
|
465
|
-
'Updating node configurations',
|
|
466
|
-
'Adding error handling to nodes',
|
|
467
|
-
'Adding/removing connections',
|
|
468
|
-
'Enabling/disabling nodes',
|
|
469
|
-
'Moving nodes in canvas',
|
|
470
|
-
'Updating workflow metadata'
|
|
471
|
-
],
|
|
472
|
-
performance: 'Very efficient - only sends changes. 80-90% less data than full updates.',
|
|
473
|
-
bestPractices: [
|
|
474
|
-
'Error handling properties (onError, retryOnFail, etc.) go at NODE level, not in parameters',
|
|
475
|
-
'Use dot notation for nested properties: "parameters.url"',
|
|
476
|
-
'Batch related operations together',
|
|
477
|
-
'Use validateOnly:true to test first',
|
|
478
|
-
'Reference nodes by name for clarity'
|
|
479
|
-
],
|
|
480
|
-
pitfalls: [
|
|
481
|
-
'Placing error handling properties inside parameters (common mistake!)',
|
|
482
|
-
'Maximum 5 operations per request',
|
|
483
|
-
'Some operations have dependencies',
|
|
484
|
-
'Node must exist for update operations',
|
|
485
|
-
'Connection nodes must both exist'
|
|
486
|
-
],
|
|
487
|
-
relatedTools: ['n8n_get_workflow', 'n8n_update_full_workflow', 'validate_workflow']
|
|
488
|
-
}
|
|
489
|
-
},
|
|
490
|
-
code_node_guide: {
|
|
491
|
-
name: 'code_node_guide',
|
|
492
|
-
category: 'code_node',
|
|
493
|
-
essentials: {
|
|
494
|
-
description: 'Comprehensive guide for writing Code node JavaScript and Python',
|
|
495
|
-
keyParameters: ['topic'],
|
|
496
|
-
example: 'tools_documentation({topic: "code_node_guide"})',
|
|
497
|
-
performance: 'Instant - returns documentation',
|
|
498
|
-
tips: [
|
|
499
|
-
'Essential reading before writing Code node scripts',
|
|
500
|
-
'Covers all built-in variables and helpers',
|
|
501
|
-
'Includes common patterns and error handling'
|
|
502
|
-
]
|
|
503
|
-
},
|
|
504
|
-
full: {
|
|
505
|
-
description: `Complete reference for the n8n Code node, covering JavaScript and Python execution environments, built-in variables, helper functions, and best practices.
|
|
506
|
-
|
|
507
|
-
## Code Node Basics
|
|
508
|
-
|
|
509
|
-
The Code node allows custom JavaScript or Python code execution within workflows. It runs in a sandboxed environment with access to n8n-specific variables and helpers.
|
|
510
|
-
|
|
511
|
-
### JavaScript Environment
|
|
512
|
-
- **ES2022 support** with async/await
|
|
513
|
-
- **Built-in libraries**:
|
|
514
|
-
- **luxon** (DateTime) - Date/time manipulation
|
|
515
|
-
- **jmespath** - JSON queries via $jmespath()
|
|
516
|
-
- **crypto** - Available via require('crypto') despite editor warnings!
|
|
517
|
-
- **Node.js globals**: Buffer, process.env (limited)
|
|
518
|
-
- **require() IS available** for built-in modules only (crypto, util, etc.)
|
|
519
|
-
- **No npm packages** - only Node.js built-ins and n8n-provided libraries
|
|
520
|
-
|
|
521
|
-
### Python Environment
|
|
522
|
-
- **Python 3.10+** with standard library (Pyodide runtime)
|
|
523
|
-
- **No pip install** - standard library only
|
|
524
|
-
- **Variables use underscore prefix**: \`_input\`, \`_json\`, \`_jmespath\` (not \`$\`)
|
|
525
|
-
- **item.json is JsProxy**: Use \`.to_py()\` to convert to Python dict
|
|
526
|
-
- **Shared state** between Code nodes in same execution
|
|
527
|
-
|
|
528
|
-
## Essential Variables
|
|
529
|
-
|
|
530
|
-
### $input
|
|
531
|
-
Access to all incoming data:
|
|
532
|
-
\`\`\`javascript
|
|
533
|
-
// Get all items from all inputs
|
|
534
|
-
const allItems = $input.all(); // Returns: Item[][]
|
|
20
|
+
if (depth === 'essentials') {
|
|
21
|
+
const { essentials } = tool;
|
|
22
|
+
return `# ${tool.name}
|
|
535
23
|
|
|
536
|
-
|
|
537
|
-
const firstInput = $input.all(0); // Returns: Item[]
|
|
24
|
+
${essentials.description}
|
|
538
25
|
|
|
539
|
-
|
|
540
|
-
const firstItem = $input.first(); // Returns: Item
|
|
26
|
+
**Example**: ${essentials.example}
|
|
541
27
|
|
|
542
|
-
|
|
543
|
-
const lastItem = $input.last(); // Returns: Item
|
|
28
|
+
**Key parameters**: ${essentials.keyParameters.join(', ')}
|
|
544
29
|
|
|
545
|
-
|
|
546
|
-
const item = $input.item(2); // Returns: Item at index 2
|
|
547
|
-
\`\`\`
|
|
30
|
+
**Performance**: ${essentials.performance}
|
|
548
31
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
\`\`\`javascript
|
|
552
|
-
// items is equivalent to $input.all()[0]
|
|
553
|
-
for (const item of items) {
|
|
554
|
-
console.log(item.json); // Access JSON data
|
|
555
|
-
console.log(item.binary); // Access binary data
|
|
556
|
-
}
|
|
557
|
-
\`\`\`
|
|
32
|
+
**Tips**:
|
|
33
|
+
${essentials.tips.map(tip => `- ${tip}`).join('\n')}
|
|
558
34
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
const value1 = $json.fieldName;
|
|
564
|
-
const value2 = items[0].json.fieldName;
|
|
565
|
-
\`\`\`
|
|
35
|
+
For full documentation, use: tools_documentation({topic: "${toolName}", depth: "full"})`;
|
|
36
|
+
}
|
|
37
|
+
const { full } = tool;
|
|
38
|
+
return `# ${tool.name}
|
|
566
39
|
|
|
567
|
-
|
|
568
|
-
Access data from other nodes using $('Node Name') syntax:
|
|
569
|
-
\`\`\`javascript
|
|
570
|
-
// Access another node's output - use $('Node Name') NOT $node
|
|
571
|
-
const prevData = $('Previous Node').all();
|
|
572
|
-
const firstItem = $('Previous Node').first();
|
|
573
|
-
const specificItem = $('Previous Node').item(0);
|
|
40
|
+
${full.description}
|
|
574
41
|
|
|
575
|
-
|
|
576
|
-
|
|
42
|
+
## Parameters
|
|
43
|
+
${Object.entries(full.parameters).map(([param, info]) => `- **${param}** (${info.type}${info.required ? ', required' : ''}): ${info.description}`).join('\n')}
|
|
577
44
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
\`\`\`
|
|
45
|
+
## Returns
|
|
46
|
+
${full.returns}
|
|
581
47
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
- **Code Node**: \`$('Previous Node').first().json.field\`
|
|
585
|
-
- These are NOT interchangeable!
|
|
48
|
+
## Examples
|
|
49
|
+
${full.examples.map(ex => `\`\`\`javascript\n${ex}\n\`\`\``).join('\n\n')}
|
|
586
50
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
\`\`\`javascript
|
|
590
|
-
const workflowId = $workflow.id;
|
|
591
|
-
const workflowName = $workflow.name;
|
|
592
|
-
const isActive = $workflow.active;
|
|
593
|
-
\`\`\`
|
|
51
|
+
## Common Use Cases
|
|
52
|
+
${full.useCases.map(uc => `- ${uc}`).join('\n')}
|
|
594
53
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
\`\`\`javascript
|
|
598
|
-
const executionId = $execution.id;
|
|
599
|
-
const executionMode = $execution.mode; // 'manual', 'trigger', etc.
|
|
600
|
-
const resumeUrl = $execution.resumeUrl; // For wait nodes
|
|
601
|
-
\`\`\`
|
|
54
|
+
## Performance
|
|
55
|
+
${full.performance}
|
|
602
56
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
\`\`\`javascript
|
|
606
|
-
const prevOutput = $prevNode.outputIndex; // Which output triggered this
|
|
607
|
-
const prevData = $prevNode.data; // Previous node's data
|
|
608
|
-
const prevName = $prevNode.name; // Previous node's name
|
|
609
|
-
\`\`\`
|
|
57
|
+
## Best Practices
|
|
58
|
+
${full.bestPractices.map(bp => `- ${bp}`).join('\n')}
|
|
610
59
|
|
|
611
|
-
##
|
|
60
|
+
## Common Pitfalls
|
|
61
|
+
${full.pitfalls.map(p => `- ${p}`).join('\n')}
|
|
612
62
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
63
|
+
## Related Tools
|
|
64
|
+
${full.relatedTools.map(t => `- ${t}`).join('\n')}`;
|
|
65
|
+
}
|
|
66
|
+
function getToolsOverview(depth = 'essentials') {
|
|
67
|
+
if (depth === 'essentials') {
|
|
68
|
+
return `# n8n MCP Tools Reference
|
|
618
69
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
70
|
+
## Code Node Configuration
|
|
71
|
+
When working with Code nodes, always start by calling the relevant guide:
|
|
72
|
+
- tools_documentation({topic: "javascript_code_node_guide"}) for JavaScript Code nodes
|
|
73
|
+
- tools_documentation({topic: "python_code_node_guide"}) for Python Code nodes
|
|
622
74
|
|
|
623
|
-
|
|
624
|
-
const tomorrow = now.plus({ days: 1 });
|
|
625
|
-
const hourAgo = now.minus({ hours: 1 });
|
|
626
|
-
\`\`\`
|
|
75
|
+
## Standard Workflow Pattern
|
|
627
76
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
const names = $jmespath(data, 'users[*].name'); // ['John', 'Jane']
|
|
77
|
+
1. **Find** the node you need:
|
|
78
|
+
- search_nodes({query: "slack"}) - Search by keyword
|
|
79
|
+
- list_nodes({category: "communication"}) - List by category
|
|
80
|
+
- list_ai_tools() - List AI-capable nodes
|
|
633
81
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
82
|
+
2. **Configure** the node:
|
|
83
|
+
- get_node_essentials("nodes-base.slack") - Get essential properties only (5KB)
|
|
84
|
+
- get_node_info("nodes-base.slack") - Get complete schema (100KB+)
|
|
85
|
+
- search_node_properties("nodes-base.slack", "auth") - Find specific properties
|
|
637
86
|
|
|
638
|
-
|
|
639
|
-
|
|
87
|
+
3. **Validate** before deployment:
|
|
88
|
+
- validate_node_minimal("nodes-base.slack", config) - Check required fields
|
|
89
|
+
- validate_node_operation("nodes-base.slack", config) - Full validation with fixes
|
|
90
|
+
- validate_workflow(workflow) - Validate entire workflow
|
|
640
91
|
|
|
641
|
-
|
|
642
|
-
const expensive = $jmespath(items, '[?price > \`100\`]');
|
|
643
|
-
const inStock = $jmespath(products, '[?quantity >= \`1\`]');
|
|
644
|
-
const highPriority = $jmespath(tasks, '[?priority == \`1\`]');
|
|
92
|
+
## Tool Categories
|
|
645
93
|
|
|
646
|
-
|
|
647
|
-
|
|
94
|
+
**Discovery Tools**
|
|
95
|
+
- search_nodes - Full-text search across all nodes
|
|
96
|
+
- list_nodes - List nodes with filtering by category, package, or type
|
|
97
|
+
- list_ai_tools - List all AI-capable nodes with usage guidance
|
|
98
|
+
|
|
99
|
+
**Configuration Tools**
|
|
100
|
+
- get_node_essentials - Returns 10-20 key properties with examples
|
|
101
|
+
- get_node_info - Returns complete node schema with all properties
|
|
102
|
+
- search_node_properties - Search for specific properties within a node
|
|
103
|
+
- get_property_dependencies - Analyze property visibility dependencies
|
|
104
|
+
|
|
105
|
+
**Validation Tools**
|
|
106
|
+
- validate_node_minimal - Quick validation of required fields only
|
|
107
|
+
- validate_node_operation - Full validation with operation awareness
|
|
108
|
+
- validate_workflow - Complete workflow validation including connections
|
|
109
|
+
|
|
110
|
+
**Template Tools**
|
|
111
|
+
- list_tasks - List common task templates
|
|
112
|
+
- get_node_for_task - Get pre-configured node for specific tasks
|
|
113
|
+
- search_templates - Search workflow templates by keyword
|
|
114
|
+
- get_template - Get complete workflow JSON by ID
|
|
115
|
+
|
|
116
|
+
**n8n API Tools** (requires N8N_API_URL configuration)
|
|
117
|
+
- n8n_create_workflow - Create new workflows
|
|
118
|
+
- n8n_update_partial_workflow - Update workflows using diff operations
|
|
119
|
+
- n8n_validate_workflow - Validate workflow from n8n instance
|
|
120
|
+
- n8n_trigger_webhook_workflow - Trigger workflow execution
|
|
121
|
+
|
|
122
|
+
## Performance Characteristics
|
|
123
|
+
- Instant (<10ms): search_nodes, list_nodes, get_node_essentials
|
|
124
|
+
- Fast (<100ms): validate_node_minimal, get_node_for_task
|
|
125
|
+
- Moderate (100-500ms): validate_workflow, get_node_info
|
|
126
|
+
- Network-dependent: All n8n_* tools
|
|
127
|
+
|
|
128
|
+
For comprehensive documentation on any tool:
|
|
129
|
+
tools_documentation({topic: "tool_name", depth: "full"})`;
|
|
130
|
+
}
|
|
131
|
+
const categories = getAllCategories();
|
|
132
|
+
return `# n8n MCP Tools - Complete Reference
|
|
133
|
+
|
|
134
|
+
## Code Node Guides
|
|
135
|
+
For Code node configuration, use these comprehensive guides:
|
|
136
|
+
- tools_documentation({topic: "javascript_code_node_guide", depth: "full"}) - JavaScript patterns, n8n variables, error handling
|
|
137
|
+
- tools_documentation({topic: "python_code_node_guide", depth: "full"}) - Python patterns, data access, debugging
|
|
138
|
+
|
|
139
|
+
## All Available Tools by Category
|
|
140
|
+
|
|
141
|
+
${categories.map(cat => {
|
|
142
|
+
const tools = getToolsByCategory(cat);
|
|
143
|
+
const categoryName = cat.charAt(0).toUpperCase() + cat.slice(1).replace('_', ' ');
|
|
144
|
+
return `### ${categoryName}
|
|
145
|
+
${tools.map(toolName => {
|
|
146
|
+
const tool = tool_docs_1.toolsDocumentation[toolName];
|
|
147
|
+
return `- **${toolName}**: ${tool.essentials.description}`;
|
|
148
|
+
}).join('\n')}`;
|
|
149
|
+
}).join('\n\n')}
|
|
150
|
+
|
|
151
|
+
## Usage Notes
|
|
152
|
+
- All node types require the "nodes-base." or "nodes-langchain." prefix
|
|
153
|
+
- Use get_node_essentials() first for most tasks (95% smaller than get_node_info)
|
|
154
|
+
- Validation profiles: minimal (editing), runtime (default), strict (deployment)
|
|
155
|
+
- n8n API tools only available when N8N_API_URL and N8N_API_KEY are configured
|
|
156
|
+
|
|
157
|
+
For detailed documentation on any tool:
|
|
158
|
+
tools_documentation({topic: "tool_name", depth: "full"})`;
|
|
159
|
+
}
|
|
160
|
+
function searchToolDocumentation(keyword) {
|
|
161
|
+
const results = [];
|
|
162
|
+
for (const [toolName, tool] of Object.entries(tool_docs_1.toolsDocumentation)) {
|
|
163
|
+
const searchText = `${toolName} ${tool.essentials.description} ${tool.full.description}`.toLowerCase();
|
|
164
|
+
if (searchText.includes(keyword.toLowerCase())) {
|
|
165
|
+
results.push(toolName);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return results;
|
|
169
|
+
}
|
|
170
|
+
function getToolsByCategory(category) {
|
|
171
|
+
return Object.entries(tool_docs_1.toolsDocumentation)
|
|
172
|
+
.filter(([_, tool]) => tool.category === category)
|
|
173
|
+
.map(([name, _]) => name);
|
|
174
|
+
}
|
|
175
|
+
function getAllCategories() {
|
|
176
|
+
const categories = new Set();
|
|
177
|
+
Object.values(tool_docs_1.toolsDocumentation).forEach(tool => {
|
|
178
|
+
categories.add(tool.category);
|
|
179
|
+
});
|
|
180
|
+
return Array.from(categories);
|
|
181
|
+
}
|
|
182
|
+
function getJavaScriptCodeNodeGuide(depth = 'essentials') {
|
|
183
|
+
if (depth === 'essentials') {
|
|
184
|
+
return `# JavaScript Code Node Guide
|
|
648
185
|
|
|
649
|
-
|
|
650
|
-
const pythonAdults = _jmespath(data, 'users[?age >= \`18\`]');
|
|
651
|
-
\`\`\`
|
|
186
|
+
Essential patterns for JavaScript in n8n Code nodes.
|
|
652
187
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
2. **Numeric literals in filters MUST use backticks**: \`[?age >= \`18\`]\`
|
|
658
|
-
- This is n8n-specific and differs from standard JMESPath documentation!
|
|
188
|
+
**Key Concepts**:
|
|
189
|
+
- Access all items: \`$input.all()\` (not items[0])
|
|
190
|
+
- Current item data: \`$json\`
|
|
191
|
+
- Return format: \`[{json: {...}}]\` (array of objects)
|
|
659
192
|
|
|
660
|
-
|
|
193
|
+
**Available Helpers**:
|
|
194
|
+
- \`$helpers.httpRequest()\` - Make HTTP requests
|
|
195
|
+
- \`$jmespath()\` - Query JSON data
|
|
196
|
+
- \`DateTime\` - Luxon for date handling
|
|
661
197
|
|
|
662
|
-
|
|
198
|
+
**Common Patterns**:
|
|
663
199
|
\`\`\`javascript
|
|
664
|
-
//
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
200
|
+
// Process all items
|
|
201
|
+
const allItems = $input.all();
|
|
202
|
+
return allItems.map(item => ({
|
|
203
|
+
json: {
|
|
204
|
+
processed: true,
|
|
205
|
+
original: item.json,
|
|
206
|
+
timestamp: DateTime.now().toISO()
|
|
207
|
+
}
|
|
208
|
+
}));
|
|
673
209
|
\`\`\`
|
|
674
210
|
|
|
675
|
-
**
|
|
211
|
+
**Tips**:
|
|
212
|
+
- Webhook data is under \`.body\` property
|
|
213
|
+
- Use async/await for HTTP requests
|
|
214
|
+
- Always return array format
|
|
215
|
+
|
|
216
|
+
For full guide: tools_documentation({topic: "javascript_code_node_guide", depth: "full"})`;
|
|
217
|
+
}
|
|
218
|
+
return `# JavaScript Code Node Complete Guide
|
|
676
219
|
|
|
677
|
-
|
|
220
|
+
Comprehensive guide for using JavaScript in n8n Code nodes.
|
|
221
|
+
|
|
222
|
+
## Data Access Patterns
|
|
223
|
+
|
|
224
|
+
### Accessing Input Data
|
|
678
225
|
\`\`\`javascript
|
|
679
|
-
//
|
|
680
|
-
|
|
681
|
-
const staticData = $getWorkflowStaticData('global'); // Global static data
|
|
682
|
-
const nodeData = $getWorkflowStaticData('node'); // Node-specific data
|
|
226
|
+
// Get all items from previous node
|
|
227
|
+
const allItems = $input.all();
|
|
683
228
|
|
|
684
|
-
//
|
|
685
|
-
const
|
|
686
|
-
staticData.counter = (staticData.counter || 0) + 1;
|
|
229
|
+
// Get specific node's output
|
|
230
|
+
const webhookData = $node["Webhook"].json;
|
|
687
231
|
|
|
688
|
-
//
|
|
689
|
-
|
|
232
|
+
// Current item in loop
|
|
233
|
+
const currentItem = $json;
|
|
690
234
|
|
|
691
|
-
//
|
|
692
|
-
const
|
|
235
|
+
// First item only
|
|
236
|
+
const firstItem = $input.first().json;
|
|
693
237
|
\`\`\`
|
|
694
238
|
|
|
695
|
-
|
|
239
|
+
### Webhook Data Structure
|
|
240
|
+
**CRITICAL**: Webhook data is nested under \`.body\`:
|
|
696
241
|
\`\`\`javascript
|
|
697
|
-
//
|
|
698
|
-
|
|
242
|
+
// WRONG - Won't work
|
|
243
|
+
const data = $json.name;
|
|
244
|
+
|
|
245
|
+
// CORRECT - Webhook data is under body
|
|
246
|
+
const data = $json.body.name;
|
|
247
|
+
\`\`\`
|
|
699
248
|
|
|
700
|
-
|
|
249
|
+
## Available Built-in Functions
|
|
250
|
+
|
|
251
|
+
### HTTP Requests
|
|
252
|
+
\`\`\`javascript
|
|
253
|
+
// Make HTTP request
|
|
701
254
|
const response = await $helpers.httpRequest({
|
|
702
255
|
method: 'GET',
|
|
703
256
|
url: 'https://api.example.com/data',
|
|
704
|
-
headers: {
|
|
257
|
+
headers: {
|
|
258
|
+
'Authorization': 'Bearer token'
|
|
259
|
+
}
|
|
705
260
|
});
|
|
706
|
-
|
|
707
|
-
// Binary data preparation
|
|
708
|
-
const binaryData = await $helpers.prepareBinaryData(
|
|
709
|
-
Buffer.from('content'),
|
|
710
|
-
'file.txt',
|
|
711
|
-
'text/plain'
|
|
712
|
-
);
|
|
713
|
-
|
|
714
|
-
// Check if $helpers exists before using:
|
|
715
|
-
if (typeof $helpers !== 'undefined' && $helpers.httpRequest) {
|
|
716
|
-
// Use $helpers.httpRequest
|
|
717
|
-
} else {
|
|
718
|
-
throw new Error('HTTP requests not available in this n8n version');
|
|
719
|
-
}
|
|
720
261
|
\`\`\`
|
|
721
262
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
263
|
+
### Date/Time Handling
|
|
264
|
+
\`\`\`javascript
|
|
265
|
+
// Using Luxon DateTime
|
|
266
|
+
const now = DateTime.now();
|
|
267
|
+
const formatted = now.toFormat('yyyy-MM-dd');
|
|
268
|
+
const iso = now.toISO();
|
|
269
|
+
const plus5Days = now.plus({ days: 5 });
|
|
270
|
+
\`\`\`
|
|
728
271
|
|
|
729
|
-
|
|
272
|
+
### JSON Querying
|
|
273
|
+
\`\`\`javascript
|
|
274
|
+
// JMESPath queries
|
|
275
|
+
const result = $jmespath($json, "users[?age > 30].name");
|
|
276
|
+
\`\`\`
|
|
730
277
|
|
|
731
|
-
|
|
278
|
+
## Return Format Requirements
|
|
732
279
|
|
|
280
|
+
### Correct Format
|
|
733
281
|
\`\`\`javascript
|
|
734
|
-
//
|
|
735
|
-
return [
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
282
|
+
// MUST return array of objects with json property
|
|
283
|
+
return [{
|
|
284
|
+
json: {
|
|
285
|
+
result: "success",
|
|
286
|
+
data: processedData
|
|
287
|
+
}
|
|
288
|
+
}];
|
|
739
289
|
|
|
740
|
-
//
|
|
741
|
-
return
|
|
290
|
+
// Multiple items
|
|
291
|
+
return items.map(item => ({
|
|
292
|
+
json: {
|
|
293
|
+
id: item.id,
|
|
294
|
+
processed: true
|
|
295
|
+
}
|
|
296
|
+
}));
|
|
297
|
+
\`\`\`
|
|
742
298
|
|
|
743
|
-
|
|
299
|
+
### Binary Data
|
|
300
|
+
\`\`\`javascript
|
|
301
|
+
// Return with binary data
|
|
744
302
|
return [{
|
|
745
|
-
json: { filename:
|
|
303
|
+
json: { filename: "report.pdf" },
|
|
746
304
|
binary: {
|
|
747
|
-
data:
|
|
748
|
-
data: base64String,
|
|
749
|
-
mimeType: 'application/pdf',
|
|
750
|
-
fileName: 'report.pdf'
|
|
751
|
-
}
|
|
305
|
+
data: Buffer.from(pdfContent).toString('base64')
|
|
752
306
|
}
|
|
753
307
|
}];
|
|
754
|
-
|
|
755
|
-
// ❌ WRONG - Not an array
|
|
756
|
-
return { json: { result: 'success' } };
|
|
757
|
-
|
|
758
|
-
// ❌ WRONG - No json property
|
|
759
|
-
return [{ result: 'success' }];
|
|
760
|
-
|
|
761
|
-
// ❌ WRONG - Not wrapped in object
|
|
762
|
-
return ['item1', 'item2'];
|
|
763
308
|
\`\`\`
|
|
764
309
|
|
|
765
310
|
## Common Patterns
|
|
766
311
|
|
|
767
|
-
### Data
|
|
312
|
+
### Processing Webhook Data
|
|
768
313
|
\`\`\`javascript
|
|
769
|
-
//
|
|
770
|
-
const
|
|
771
|
-
|
|
772
|
-
transformedItems.push({
|
|
773
|
-
json: {
|
|
774
|
-
...item.json,
|
|
775
|
-
processed: true,
|
|
776
|
-
timestamp: DateTime.now().toISO(),
|
|
777
|
-
uppercaseName: item.json.name?.toUpperCase()
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
return transformedItems;
|
|
782
|
-
\`\`\`
|
|
314
|
+
// Extract webhook payload
|
|
315
|
+
const webhookBody = $json.body;
|
|
316
|
+
const { username, email, items } = webhookBody;
|
|
783
317
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
318
|
+
// Process and return
|
|
319
|
+
return [{
|
|
320
|
+
json: {
|
|
321
|
+
username,
|
|
322
|
+
email,
|
|
323
|
+
itemCount: items.length,
|
|
324
|
+
processedAt: DateTime.now().toISO()
|
|
325
|
+
}
|
|
326
|
+
}];
|
|
790
327
|
\`\`\`
|
|
791
328
|
|
|
792
|
-
###
|
|
329
|
+
### Aggregating Data
|
|
793
330
|
\`\`\`javascript
|
|
794
|
-
//
|
|
795
|
-
const
|
|
796
|
-
const
|
|
331
|
+
// Sum values across all items
|
|
332
|
+
const allItems = $input.all();
|
|
333
|
+
const total = allItems.reduce((sum, item) => {
|
|
334
|
+
return sum + (item.json.amount || 0);
|
|
335
|
+
}, 0);
|
|
797
336
|
|
|
798
337
|
return [{
|
|
799
|
-
json: {
|
|
338
|
+
json: {
|
|
800
339
|
total,
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
items: items.map(i => i.json)
|
|
340
|
+
itemCount: allItems.length,
|
|
341
|
+
average: total / allItems.length
|
|
804
342
|
}
|
|
805
343
|
}];
|
|
806
344
|
\`\`\`
|
|
807
345
|
|
|
808
346
|
### Error Handling
|
|
809
347
|
\`\`\`javascript
|
|
810
|
-
// Safe data access with defaults
|
|
811
|
-
const results = [];
|
|
812
|
-
for (const item of items) {
|
|
813
|
-
try {
|
|
814
|
-
const value = item.json?.nested?.field || 'default';
|
|
815
|
-
results.push({
|
|
816
|
-
json: {
|
|
817
|
-
processed: value,
|
|
818
|
-
status: 'success'
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
|
-
} catch (error) {
|
|
822
|
-
results.push({
|
|
823
|
-
json: {
|
|
824
|
-
error: error.message,
|
|
825
|
-
status: 'failed',
|
|
826
|
-
originalItem: item.json
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
return results;
|
|
832
|
-
\`\`\`
|
|
833
|
-
|
|
834
|
-
### Working with APIs
|
|
835
|
-
\`\`\`javascript
|
|
836
|
-
// Make HTTP request and process response
|
|
837
348
|
try {
|
|
838
349
|
const response = await $helpers.httpRequest({
|
|
839
|
-
|
|
840
|
-
url: 'https://api.example.com/process',
|
|
841
|
-
body: {
|
|
842
|
-
data: items.map(item => item.json)
|
|
843
|
-
},
|
|
844
|
-
headers: {
|
|
845
|
-
'Content-Type': 'application/json'
|
|
846
|
-
}
|
|
350
|
+
url: 'https://api.example.com/data'
|
|
847
351
|
});
|
|
848
352
|
|
|
849
|
-
return [{
|
|
353
|
+
return [{
|
|
354
|
+
json: {
|
|
355
|
+
success: true,
|
|
356
|
+
data: response
|
|
357
|
+
}
|
|
358
|
+
}];
|
|
850
359
|
} catch (error) {
|
|
851
|
-
|
|
852
|
-
}
|
|
853
|
-
\`\`\`
|
|
854
|
-
|
|
855
|
-
### Async Operations
|
|
856
|
-
\`\`\`javascript
|
|
857
|
-
// Process items with async operations
|
|
858
|
-
const results = [];
|
|
859
|
-
for (const item of items) {
|
|
860
|
-
// Simulate async operation
|
|
861
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
862
|
-
|
|
863
|
-
results.push({
|
|
360
|
+
return [{
|
|
864
361
|
json: {
|
|
865
|
-
|
|
866
|
-
|
|
362
|
+
success: false,
|
|
363
|
+
error: error.message
|
|
867
364
|
}
|
|
868
|
-
}
|
|
365
|
+
}];
|
|
869
366
|
}
|
|
870
|
-
return results;
|
|
871
367
|
\`\`\`
|
|
872
368
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
369
|
+
## Available Node.js Modules
|
|
370
|
+
- crypto (built-in)
|
|
371
|
+
- Buffer
|
|
372
|
+
- URL/URLSearchParams
|
|
373
|
+
- Basic Node.js globals
|
|
877
374
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
375
|
+
## Common Pitfalls
|
|
376
|
+
1. Using \`items[0]\` instead of \`$input.all()\`
|
|
377
|
+
2. Forgetting webhook data is under \`.body\`
|
|
378
|
+
3. Returning plain objects instead of \`[{json: {...}}]\`
|
|
379
|
+
4. Using \`require()\` for external modules (not allowed)
|
|
380
|
+
5. Trying to use expression syntax \`{{}}\` inside code
|
|
883
381
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
382
|
+
## Best Practices
|
|
383
|
+
1. Always validate input data exists before accessing
|
|
384
|
+
2. Use try-catch for HTTP requests
|
|
385
|
+
3. Return early on validation failures
|
|
386
|
+
4. Keep code simple and readable
|
|
387
|
+
5. Use descriptive variable names
|
|
888
388
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
}
|
|
898
|
-
}];
|
|
389
|
+
## Related Tools
|
|
390
|
+
- get_node_essentials("nodes-base.code")
|
|
391
|
+
- validate_node_operation()
|
|
392
|
+
- python_code_node_guide (for Python syntax)`;
|
|
393
|
+
}
|
|
394
|
+
function getPythonCodeNodeGuide(depth = 'essentials') {
|
|
395
|
+
if (depth === 'essentials') {
|
|
396
|
+
return `# Python Code Node Guide
|
|
899
397
|
|
|
900
|
-
|
|
901
|
-
// - Schedule Trigger: items[0].json contains timestamp
|
|
902
|
-
// - Database Trigger: items[0].json contains row data
|
|
903
|
-
// - File Trigger: items[0].json contains file info
|
|
904
|
-
\`\`\`
|
|
398
|
+
Essential patterns for Python in n8n Code nodes.
|
|
905
399
|
|
|
906
|
-
|
|
400
|
+
**Key Concepts**:
|
|
401
|
+
- Access all items: \`_input.all()\` (not items[0])
|
|
402
|
+
- Current item data: \`_json\`
|
|
403
|
+
- Return format: \`[{"json": {...}}]\` (list of dicts)
|
|
907
404
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
# Access items - Python uses underscore prefix for built-in variables
|
|
914
|
-
results = []
|
|
915
|
-
for item in _input.all():
|
|
916
|
-
# IMPORTANT: item.json is NOT a standard Python dict!
|
|
917
|
-
# Use to_py() to convert to a proper Python dict
|
|
918
|
-
processed_item = item.json.to_py() # Converts JsProxy to Python dict
|
|
919
|
-
processed_item['timestamp'] = datetime.now().isoformat()
|
|
920
|
-
results.append({'json': processed_item})
|
|
921
|
-
|
|
922
|
-
return results
|
|
923
|
-
\`\`\`
|
|
405
|
+
**Limitations**:
|
|
406
|
+
- No external libraries (no requests, pandas, numpy)
|
|
407
|
+
- Use built-in functions only
|
|
408
|
+
- No pip install available
|
|
924
409
|
|
|
925
|
-
|
|
410
|
+
**Common Patterns**:
|
|
926
411
|
\`\`\`python
|
|
927
|
-
#
|
|
928
|
-
|
|
929
|
-
total = sum(item.json.get('amount', 0) for item in items)
|
|
930
|
-
average = total / len(items) if items else 0
|
|
931
|
-
|
|
932
|
-
# For safe dict operations, convert JsProxy to Python dict
|
|
933
|
-
safe_items = []
|
|
934
|
-
for item in items:
|
|
935
|
-
# Convert JsProxy to dict to avoid KeyError with null values
|
|
936
|
-
safe_dict = item.json.to_py()
|
|
937
|
-
safe_items.append(safe_dict)
|
|
938
|
-
|
|
939
|
-
# Return aggregated result
|
|
412
|
+
# Process all items
|
|
413
|
+
all_items = _input.all()
|
|
940
414
|
return [{
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
'processed_at': datetime.now().isoformat(),
|
|
946
|
-
'items': safe_items # Now these are proper Python dicts
|
|
415
|
+
"json": {
|
|
416
|
+
"processed": True,
|
|
417
|
+
"count": len(all_items),
|
|
418
|
+
"first_item": all_items[0]["json"] if all_items else None
|
|
947
419
|
}
|
|
948
420
|
}]
|
|
949
421
|
\`\`\`
|
|
950
422
|
|
|
951
|
-
|
|
423
|
+
**Tips**:
|
|
424
|
+
- Webhook data is under ["body"] key
|
|
425
|
+
- Use json module for parsing
|
|
426
|
+
- datetime for date handling
|
|
952
427
|
|
|
953
|
-
|
|
428
|
+
For full guide: tools_documentation({topic: "python_code_node_guide", depth: "full"})`;
|
|
429
|
+
}
|
|
430
|
+
return `# Python Code Node Complete Guide
|
|
954
431
|
|
|
955
|
-
|
|
956
|
-
// Code node configured as AI tool
|
|
957
|
-
// Name: "Calculate Discount"
|
|
958
|
-
// Description: "Calculates discount based on quantity"
|
|
432
|
+
Comprehensive guide for using Python in n8n Code nodes.
|
|
959
433
|
|
|
960
|
-
|
|
961
|
-
const basePrice = $json.price || 0;
|
|
434
|
+
## Data Access Patterns
|
|
962
435
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
else if (quantity >= 10) discount = 0.05;
|
|
436
|
+
### Accessing Input Data
|
|
437
|
+
\`\`\`python
|
|
438
|
+
# Get all items from previous node
|
|
439
|
+
all_items = _input.all()
|
|
968
440
|
|
|
969
|
-
|
|
970
|
-
|
|
441
|
+
# Get specific node's output (use _node)
|
|
442
|
+
webhook_data = _node["Webhook"]["json"]
|
|
971
443
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
discountAmount,
|
|
978
|
-
finalPrice,
|
|
979
|
-
savings: discountAmount
|
|
980
|
-
}
|
|
981
|
-
}];
|
|
444
|
+
# Current item in loop
|
|
445
|
+
current_item = _json
|
|
446
|
+
|
|
447
|
+
# First item only
|
|
448
|
+
first_item = _input.first()["json"]
|
|
982
449
|
\`\`\`
|
|
983
450
|
|
|
984
|
-
|
|
451
|
+
### Webhook Data Structure
|
|
452
|
+
**CRITICAL**: Webhook data is nested under ["body"]:
|
|
453
|
+
\`\`\`python
|
|
454
|
+
# WRONG - Won't work
|
|
455
|
+
data = _json["name"]
|
|
985
456
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
// ✅ Crypto IS available despite editor warnings!
|
|
989
|
-
const crypto = require('crypto');
|
|
990
|
-
|
|
991
|
-
// Generate secure random values
|
|
992
|
-
const randomBytes = crypto.randomBytes(32);
|
|
993
|
-
const randomUUID = crypto.randomUUID();
|
|
994
|
-
|
|
995
|
-
// Create hashes
|
|
996
|
-
const hash = crypto.createHash('sha256')
|
|
997
|
-
.update('data to hash')
|
|
998
|
-
.digest('hex');
|
|
999
|
-
|
|
1000
|
-
// HMAC for signatures
|
|
1001
|
-
const hmac = crypto.createHmac('sha256', 'secret-key')
|
|
1002
|
-
.update('data to sign')
|
|
1003
|
-
.digest('hex');
|
|
457
|
+
# CORRECT - Webhook data is under body
|
|
458
|
+
data = _json["body"]["name"]
|
|
1004
459
|
\`\`\`
|
|
1005
460
|
|
|
1006
|
-
|
|
1007
|
-
- No file system access (fs module) - except read-only for some paths
|
|
1008
|
-
- No network requests except via $helpers.httpRequest
|
|
1009
|
-
- No child process execution
|
|
1010
|
-
- No external npm packages (only built-in Node.js modules)
|
|
1011
|
-
- No eval() or Function() constructor
|
|
461
|
+
## Available Built-in Modules
|
|
1012
462
|
|
|
1013
|
-
###
|
|
1014
|
-
\`\`\`
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
463
|
+
### Standard Library Only
|
|
464
|
+
\`\`\`python
|
|
465
|
+
import json
|
|
466
|
+
import datetime
|
|
467
|
+
import base64
|
|
468
|
+
import hashlib
|
|
469
|
+
import urllib.parse
|
|
470
|
+
import re
|
|
471
|
+
import math
|
|
472
|
+
import random
|
|
473
|
+
\`\`\`
|
|
1018
474
|
|
|
1019
|
-
|
|
1020
|
-
|
|
475
|
+
### Date/Time Handling
|
|
476
|
+
\`\`\`python
|
|
477
|
+
from datetime import datetime, timedelta
|
|
1021
478
|
|
|
1022
|
-
|
|
1023
|
-
|
|
479
|
+
# Current time
|
|
480
|
+
now = datetime.now()
|
|
481
|
+
iso_format = now.isoformat()
|
|
1024
482
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
483
|
+
# Date arithmetic
|
|
484
|
+
future = now + timedelta(days=5)
|
|
485
|
+
formatted = now.strftime("%Y-%m-%d")
|
|
486
|
+
\`\`\`
|
|
1029
487
|
|
|
1030
|
-
|
|
1031
|
-
|
|
488
|
+
### JSON Operations
|
|
489
|
+
\`\`\`python
|
|
490
|
+
# Parse JSON string
|
|
491
|
+
data = json.loads(json_string)
|
|
1032
492
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const providedToken = item.json.token;
|
|
1036
|
-
const tokensMatch = crypto.timingSafeEqual(
|
|
1037
|
-
Buffer.from(expectedToken),
|
|
1038
|
-
Buffer.from(providedToken || '')
|
|
1039
|
-
);
|
|
493
|
+
# Convert to JSON
|
|
494
|
+
json_output = json.dumps({"key": "value"})
|
|
1040
495
|
\`\`\`
|
|
1041
496
|
|
|
1042
|
-
##
|
|
497
|
+
## Return Format Requirements
|
|
1043
498
|
|
|
1044
|
-
###
|
|
1045
|
-
\`\`\`
|
|
1046
|
-
|
|
1047
|
-
console.log('Processing item:', item.json.id);
|
|
1048
|
-
console.error('Error details:', error);
|
|
1049
|
-
|
|
1050
|
-
// Return debug info in development
|
|
499
|
+
### Correct Format
|
|
500
|
+
\`\`\`python
|
|
501
|
+
# MUST return list of dictionaries with "json" key
|
|
1051
502
|
return [{
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
itemCount: items.length,
|
|
1056
|
-
executionId: $execution.id,
|
|
1057
|
-
timestamp: new Date().toISOString()
|
|
503
|
+
"json": {
|
|
504
|
+
"result": "success",
|
|
505
|
+
"data": processed_data
|
|
1058
506
|
}
|
|
1059
|
-
|
|
1060
|
-
}];
|
|
1061
|
-
\`\`\`
|
|
1062
|
-
|
|
1063
|
-
### Error Messages
|
|
1064
|
-
\`\`\`javascript
|
|
1065
|
-
// Provide helpful error context
|
|
1066
|
-
if (!item.json.requiredField) {
|
|
1067
|
-
throw new Error(\`Missing required field 'requiredField' in item \${items.indexOf(item)}\`);
|
|
1068
|
-
}
|
|
507
|
+
}]
|
|
1069
508
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
}
|
|
509
|
+
# Multiple items
|
|
510
|
+
return [
|
|
511
|
+
{"json": {"id": item["json"]["id"], "processed": True}}
|
|
512
|
+
for item in all_items
|
|
513
|
+
]
|
|
1076
514
|
\`\`\`
|
|
1077
515
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
3. **Limit HTTP requests** - batch when possible
|
|
1083
|
-
4. **Return early** for error conditions
|
|
1084
|
-
5. **Keep state minimal** - Code nodes are stateless between executions
|
|
1085
|
-
|
|
1086
|
-
## Common Mistakes to Avoid
|
|
1087
|
-
|
|
1088
|
-
1. **Forgetting to return an array**
|
|
1089
|
-
2. **Not wrapping in json property**
|
|
1090
|
-
3. **Modifying items array directly**
|
|
1091
|
-
4. **Using undefined variables**
|
|
1092
|
-
5. **Infinite loops with while statements**
|
|
1093
|
-
6. **Not handling missing data gracefully**
|
|
1094
|
-
7. **Forgetting await for async operations**`,
|
|
1095
|
-
parameters: {
|
|
1096
|
-
topic: { type: 'string', description: 'Specific Code node topic (optional)', required: false }
|
|
1097
|
-
},
|
|
1098
|
-
returns: 'Comprehensive Code node documentation and examples',
|
|
1099
|
-
examples: [
|
|
1100
|
-
'tools_documentation({topic: "code_node_guide"}) - Full guide',
|
|
1101
|
-
'tools_documentation({topic: "code_node_guide", depth: "full"}) - Complete reference'
|
|
1102
|
-
],
|
|
1103
|
-
useCases: [
|
|
1104
|
-
'Learning Code node capabilities',
|
|
1105
|
-
'Understanding built-in variables',
|
|
1106
|
-
'Finding the right helper function',
|
|
1107
|
-
'Debugging Code node issues',
|
|
1108
|
-
'Building custom AI tools'
|
|
1109
|
-
],
|
|
1110
|
-
performance: 'Instant - returns static documentation',
|
|
1111
|
-
bestPractices: [
|
|
1112
|
-
'Read before writing Code nodes',
|
|
1113
|
-
'Reference for variable names',
|
|
1114
|
-
'Copy examples as starting points',
|
|
1115
|
-
'Check security considerations'
|
|
1116
|
-
],
|
|
1117
|
-
pitfalls: [
|
|
1118
|
-
'Not all Node.js features available',
|
|
1119
|
-
'Python has limited libraries',
|
|
1120
|
-
'State not preserved between executions'
|
|
1121
|
-
],
|
|
1122
|
-
relatedTools: ['get_node_essentials', 'validate_node_operation', 'get_node_for_task']
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
};
|
|
1126
|
-
function getToolDocumentation(toolName, depth = 'essentials') {
|
|
1127
|
-
const tool = exports.toolsDocumentation[toolName];
|
|
1128
|
-
if (!tool) {
|
|
1129
|
-
return `Tool '${toolName}' not found. Use tools_documentation() to see available tools.`;
|
|
1130
|
-
}
|
|
1131
|
-
if (depth === 'essentials') {
|
|
1132
|
-
const { essentials } = tool;
|
|
1133
|
-
return `# ${tool.name}
|
|
516
|
+
### Binary Data
|
|
517
|
+
\`\`\`python
|
|
518
|
+
# Return with binary data
|
|
519
|
+
import base64
|
|
1134
520
|
|
|
1135
|
-
|
|
521
|
+
return [{
|
|
522
|
+
"json": {"filename": "report.pdf"},
|
|
523
|
+
"binary": {
|
|
524
|
+
"data": base64.b64encode(pdf_content).decode()
|
|
525
|
+
}
|
|
526
|
+
}]
|
|
527
|
+
\`\`\`
|
|
1136
528
|
|
|
1137
|
-
|
|
529
|
+
## Common Patterns
|
|
1138
530
|
|
|
1139
|
-
|
|
531
|
+
### Processing Webhook Data
|
|
532
|
+
\`\`\`python
|
|
533
|
+
# Extract webhook payload
|
|
534
|
+
webhook_body = _json["body"]
|
|
535
|
+
username = webhook_body.get("username")
|
|
536
|
+
email = webhook_body.get("email")
|
|
537
|
+
items = webhook_body.get("items", [])
|
|
1140
538
|
|
|
1141
|
-
|
|
539
|
+
# Process and return
|
|
540
|
+
return [{
|
|
541
|
+
"json": {
|
|
542
|
+
"username": username,
|
|
543
|
+
"email": email,
|
|
544
|
+
"item_count": len(items),
|
|
545
|
+
"processed_at": datetime.now().isoformat()
|
|
546
|
+
}
|
|
547
|
+
}]
|
|
548
|
+
\`\`\`
|
|
1142
549
|
|
|
1143
|
-
|
|
1144
|
-
|
|
550
|
+
### Aggregating Data
|
|
551
|
+
\`\`\`python
|
|
552
|
+
# Sum values across all items
|
|
553
|
+
all_items = _input.all()
|
|
554
|
+
total = sum(item["json"].get("amount", 0) for item in all_items)
|
|
1145
555
|
|
|
1146
|
-
|
|
556
|
+
return [{
|
|
557
|
+
"json": {
|
|
558
|
+
"total": total,
|
|
559
|
+
"item_count": len(all_items),
|
|
560
|
+
"average": total / len(all_items) if all_items else 0
|
|
1147
561
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
562
|
+
}]
|
|
563
|
+
\`\`\`
|
|
1150
564
|
|
|
1151
|
-
|
|
565
|
+
### Error Handling
|
|
566
|
+
\`\`\`python
|
|
567
|
+
try:
|
|
568
|
+
# Process data
|
|
569
|
+
webhook_data = _json["body"]
|
|
570
|
+
result = process_data(webhook_data)
|
|
571
|
+
|
|
572
|
+
return [{
|
|
573
|
+
"json": {
|
|
574
|
+
"success": True,
|
|
575
|
+
"data": result
|
|
576
|
+
}
|
|
577
|
+
}]
|
|
578
|
+
except Exception as e:
|
|
579
|
+
return [{
|
|
580
|
+
"json": {
|
|
581
|
+
"success": False,
|
|
582
|
+
"error": str(e)
|
|
583
|
+
}
|
|
584
|
+
}]
|
|
585
|
+
\`\`\`
|
|
1152
586
|
|
|
1153
|
-
|
|
1154
|
-
|
|
587
|
+
### Data Transformation
|
|
588
|
+
\`\`\`python
|
|
589
|
+
# Transform all items
|
|
590
|
+
all_items = _input.all()
|
|
591
|
+
transformed = []
|
|
592
|
+
|
|
593
|
+
for item in all_items:
|
|
594
|
+
data = item["json"]
|
|
595
|
+
transformed.append({
|
|
596
|
+
"json": {
|
|
597
|
+
"id": data.get("id"),
|
|
598
|
+
"name": data.get("name", "").upper(),
|
|
599
|
+
"timestamp": datetime.now().isoformat(),
|
|
600
|
+
"valid": bool(data.get("email"))
|
|
601
|
+
}
|
|
602
|
+
})
|
|
1155
603
|
|
|
1156
|
-
|
|
1157
|
-
|
|
604
|
+
return transformed
|
|
605
|
+
\`\`\`
|
|
1158
606
|
|
|
1159
|
-
##
|
|
1160
|
-
${full.examples.map(ex => `\`\`\`javascript\n${ex}\n\`\`\``).join('\n\n')}
|
|
607
|
+
## Limitations & Workarounds
|
|
1161
608
|
|
|
1162
|
-
|
|
1163
|
-
|
|
609
|
+
### No External Libraries
|
|
610
|
+
\`\`\`python
|
|
611
|
+
# CANNOT USE:
|
|
612
|
+
# import requests # Not available
|
|
613
|
+
# import pandas # Not available
|
|
614
|
+
# import numpy # Not available
|
|
1164
615
|
|
|
1165
|
-
|
|
1166
|
-
|
|
616
|
+
# WORKAROUND: Use JavaScript Code node for HTTP requests
|
|
617
|
+
# Or use HTTP Request node before Code node
|
|
618
|
+
\`\`\`
|
|
1167
619
|
|
|
1168
|
-
|
|
1169
|
-
|
|
620
|
+
### HTTP Requests Alternative
|
|
621
|
+
Since Python requests library is not available, use:
|
|
622
|
+
1. JavaScript Code node with $helpers.httpRequest()
|
|
623
|
+
2. HTTP Request node before your Python Code node
|
|
624
|
+
3. Webhook node to receive data
|
|
1170
625
|
|
|
1171
626
|
## Common Pitfalls
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
function getToolsOverview(depth = 'essentials') {
|
|
1178
|
-
if (depth === 'essentials') {
|
|
1179
|
-
return `# n8n MCP Tools Quick Reference
|
|
1180
|
-
|
|
1181
|
-
Welcome! Here's how to efficiently work with n8n nodes:
|
|
1182
|
-
|
|
1183
|
-
## Essential Workflow
|
|
1184
|
-
1. **Find**: search_nodes({query: "slack"})
|
|
1185
|
-
2. **Configure**: get_node_essentials("n8n-nodes-base.slack")
|
|
1186
|
-
3. **Validate**: validate_node_minimal() → validate_node_operation()
|
|
1187
|
-
4. **Deploy**: n8n_create_workflow() (if API configured)
|
|
1188
|
-
|
|
1189
|
-
## Key Tips
|
|
1190
|
-
- Always use get_node_essentials instead of get_node_info (95% smaller!)
|
|
1191
|
-
- Use node NAMES in connections, never IDs
|
|
1192
|
-
- Try get_node_for_task() for common patterns
|
|
1193
|
-
- Call validate_node_minimal() for quick checks
|
|
1194
|
-
|
|
1195
|
-
## Get Help
|
|
1196
|
-
- tools_documentation({topic: "search_nodes"}) - Get help for specific tool
|
|
1197
|
-
- tools_documentation({topic: "code_node_guide"}) - Essential Code node reference
|
|
1198
|
-
- tools_documentation({topic: "overview", depth: "full"}) - See complete guide
|
|
1199
|
-
- list_tasks() - See available task templates
|
|
1200
|
-
|
|
1201
|
-
Available tools: ${Object.keys(exports.toolsDocumentation).join(', ')}`;
|
|
1202
|
-
}
|
|
1203
|
-
return `# n8n MCP Tools Complete Guide
|
|
627
|
+
1. Trying to import external libraries (requests, pandas)
|
|
628
|
+
2. Using items[0] instead of _input.all()
|
|
629
|
+
3. Forgetting webhook data is under ["body"]
|
|
630
|
+
4. Returning dictionaries instead of [{"json": {...}}]
|
|
631
|
+
5. Not handling missing keys with .get()
|
|
1204
632
|
|
|
1205
|
-
##
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
- **search_nodes**: Find nodes by keyword (uses OR logic)
|
|
1212
|
-
- **list_nodes**: Browse nodes by category, package, or type
|
|
1213
|
-
- **list_ai_tools**: See all AI-capable nodes (263 available)
|
|
1214
|
-
|
|
1215
|
-
### Configuration Tools
|
|
1216
|
-
- **get_node_essentials**: Get key properties only (<5KB vs 100KB+)
|
|
1217
|
-
- **get_node_info**: Get complete node details (use sparingly)
|
|
1218
|
-
- **search_node_properties**: Find specific properties in large nodes
|
|
1219
|
-
- **get_property_dependencies**: Understand field relationships
|
|
1220
|
-
|
|
1221
|
-
### Validation Tools
|
|
1222
|
-
- **validate_node_minimal**: Quick required field check
|
|
1223
|
-
- **validate_node_operation**: Full operation-aware validation
|
|
1224
|
-
- **validate_workflow**: Complete workflow validation
|
|
1225
|
-
- **validate_workflow_connections**: Check node connections
|
|
1226
|
-
- **validate_workflow_expressions**: Validate n8n expressions
|
|
1227
|
-
|
|
1228
|
-
### Task & Template Tools
|
|
1229
|
-
- **list_tasks**: See available task templates
|
|
1230
|
-
- **get_node_for_task**: Get pre-configured nodes
|
|
1231
|
-
- **list_node_templates**: Find workflow templates
|
|
1232
|
-
- **search_templates**: Search template library
|
|
1233
|
-
|
|
1234
|
-
### Workflow Management (requires API config)
|
|
1235
|
-
- **n8n_create_workflow**: Create new workflows
|
|
1236
|
-
- **n8n_update_partial_workflow**: Efficient diff-based updates
|
|
1237
|
-
- **n8n_update_full_workflow**: Replace entire workflow
|
|
1238
|
-
- **n8n_list_workflows**: List workflows with filtering
|
|
1239
|
-
|
|
1240
|
-
## Recommended Patterns
|
|
1241
|
-
|
|
1242
|
-
### Building a Simple Workflow
|
|
1243
|
-
\`\`\`javascript
|
|
1244
|
-
// 1. Find what you need
|
|
1245
|
-
search_nodes({query: "webhook"})
|
|
1246
|
-
search_nodes({query: "slack"})
|
|
1247
|
-
|
|
1248
|
-
// 2. Get configurations
|
|
1249
|
-
get_node_essentials("n8n-nodes-base.webhook")
|
|
1250
|
-
get_node_essentials("n8n-nodes-base.slack")
|
|
1251
|
-
|
|
1252
|
-
// 3. Build and validate
|
|
1253
|
-
const workflow = {
|
|
1254
|
-
name: "My Webhook to Slack",
|
|
1255
|
-
nodes: [...],
|
|
1256
|
-
connections: {"Webhook": {main: [[{node: "Slack", type: "main", index: 0}]]}}
|
|
1257
|
-
};
|
|
1258
|
-
validate_workflow(workflow)
|
|
1259
|
-
|
|
1260
|
-
// 4. Deploy (if API configured)
|
|
1261
|
-
n8n_create_workflow(workflow)
|
|
1262
|
-
\`\`\`
|
|
1263
|
-
|
|
1264
|
-
### Working with Code Nodes
|
|
1265
|
-
The Code node is essential for custom logic. Always reference the guide:
|
|
1266
|
-
\`\`\`javascript
|
|
1267
|
-
// Get comprehensive Code node documentation
|
|
1268
|
-
tools_documentation({topic: "code_node_guide"})
|
|
1269
|
-
|
|
1270
|
-
// Common Code node pattern
|
|
1271
|
-
get_node_essentials("n8n-nodes-base.code")
|
|
1272
|
-
// Returns minimal config with JavaScript/Python examples
|
|
1273
|
-
|
|
1274
|
-
// Validate Code node configuration
|
|
1275
|
-
validate_node_operation("n8n-nodes-base.code", {
|
|
1276
|
-
language: "javaScript",
|
|
1277
|
-
jsCode: "return items.map(item => ({json: {...item.json, processed: true}}))"
|
|
1278
|
-
})
|
|
1279
|
-
\`\`\`
|
|
1280
|
-
|
|
1281
|
-
### Node-Level Properties Reference
|
|
1282
|
-
⚠️ **CRITICAL**: These properties go at the NODE level, not inside parameters!
|
|
633
|
+
## Best Practices
|
|
634
|
+
1. Always use .get() for dictionary access
|
|
635
|
+
2. Validate data before processing
|
|
636
|
+
3. Handle empty input arrays
|
|
637
|
+
4. Use list comprehensions for transformations
|
|
638
|
+
5. Return meaningful error messages
|
|
1283
639
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
"name": "Node Name",
|
|
1289
|
-
"type": "n8n-nodes-base.postgres",
|
|
1290
|
-
"typeVersion": 2.6,
|
|
1291
|
-
"position": [450, 300],
|
|
1292
|
-
"parameters": { /* operation-specific params */ },
|
|
1293
|
-
|
|
1294
|
-
// Optional properties (all at node level!)
|
|
1295
|
-
"credentials": {
|
|
1296
|
-
"postgres": {
|
|
1297
|
-
"id": "cred-id",
|
|
1298
|
-
"name": "My Postgres"
|
|
1299
|
-
}
|
|
1300
|
-
},
|
|
1301
|
-
"disabled": false, // Disable node execution
|
|
1302
|
-
"notes": "Internal note", // Node documentation
|
|
1303
|
-
"notesInFlow": true, // Show notes on canvas
|
|
1304
|
-
"executeOnce": true, // Execute only once per run
|
|
1305
|
-
|
|
1306
|
-
// Error handling (at node level!)
|
|
1307
|
-
"onError": "continueErrorOutput", // or "continueRegularOutput", "stopWorkflow"
|
|
1308
|
-
"retryOnFail": true,
|
|
1309
|
-
"maxTries": 3,
|
|
1310
|
-
"waitBetweenTries": 2000,
|
|
1311
|
-
"alwaysOutputData": true,
|
|
1312
|
-
|
|
1313
|
-
// Deprecated (use onError instead)
|
|
1314
|
-
"continueOnFail": false
|
|
1315
|
-
}
|
|
1316
|
-
\`\`\`
|
|
640
|
+
## Type Conversions
|
|
641
|
+
\`\`\`python
|
|
642
|
+
# String to number
|
|
643
|
+
value = float(_json.get("amount", "0"))
|
|
1317
644
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
- **disabled**: Node won't execute when true
|
|
1321
|
-
- **notes**: Internal documentation for the node
|
|
1322
|
-
- **notesInFlow**: Display notes on workflow canvas
|
|
1323
|
-
- **executeOnce**: Execute node only once even with multiple input items
|
|
1324
|
-
- **onError**: Modern error handling - what to do on failure
|
|
1325
|
-
- **retryOnFail**: Automatically retry failed executions
|
|
1326
|
-
- **maxTries**: Number of retry attempts (with retryOnFail)
|
|
1327
|
-
- **waitBetweenTries**: Milliseconds between retries
|
|
1328
|
-
- **alwaysOutputData**: Output data even on error (for debugging)
|
|
1329
|
-
|
|
1330
|
-
### Using AI Tools
|
|
1331
|
-
Any node can be an AI tool! Connect it to an AI Agent's ai_tool port:
|
|
1332
|
-
\`\`\`javascript
|
|
1333
|
-
get_node_as_tool_info("n8n-nodes-base.slack")
|
|
1334
|
-
// Returns how to configure Slack as an AI tool
|
|
1335
|
-
\`\`\`
|
|
645
|
+
# Boolean conversion
|
|
646
|
+
is_active = str(_json.get("active", "")).lower() == "true"
|
|
1336
647
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
operations: [
|
|
1343
|
-
{type: "updateNode", nodeId: "Slack", updates: {parameters: {channel: "general"}}}
|
|
1344
|
-
]
|
|
1345
|
-
})
|
|
648
|
+
# Safe JSON parsing
|
|
649
|
+
try:
|
|
650
|
+
data = json.loads(_json.get("json_string", "{}"))
|
|
651
|
+
except json.JSONDecodeError:
|
|
652
|
+
data = {}
|
|
1346
653
|
\`\`\`
|
|
1347
654
|
|
|
1348
|
-
##
|
|
1349
|
-
-
|
|
1350
|
-
-
|
|
1351
|
-
-
|
|
1352
|
-
- **Slow**: get_node_info (100KB+), validate_workflow (full analysis)
|
|
1353
|
-
|
|
1354
|
-
## Common Pitfalls to Avoid
|
|
1355
|
-
1. Using get_node_info when get_node_essentials would work
|
|
1356
|
-
2. Using node IDs instead of names in connections
|
|
1357
|
-
3. Not validating before creating workflows
|
|
1358
|
-
4. Searching with long phrases instead of keywords
|
|
1359
|
-
5. Forgetting to configure N8N_API_URL for management tools
|
|
1360
|
-
|
|
1361
|
-
## Getting More Help
|
|
1362
|
-
- Use tools_documentation({topic: "toolname"}) for any tool
|
|
1363
|
-
- Check CLAUDE.md for latest updates and examples
|
|
1364
|
-
- Run n8n_health_check() to verify API connectivity`;
|
|
1365
|
-
}
|
|
1366
|
-
function searchToolDocumentation(query) {
|
|
1367
|
-
const results = [];
|
|
1368
|
-
const searchTerms = query.toLowerCase().split(' ');
|
|
1369
|
-
for (const [toolName, tool] of Object.entries(exports.toolsDocumentation)) {
|
|
1370
|
-
const searchText = `${toolName} ${tool.essentials.description} ${tool.category}`.toLowerCase();
|
|
1371
|
-
if (searchTerms.some(term => searchText.includes(term))) {
|
|
1372
|
-
results.push(toolName);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
return results;
|
|
1376
|
-
}
|
|
1377
|
-
function getToolsByCategory(category) {
|
|
1378
|
-
return Object.entries(exports.toolsDocumentation)
|
|
1379
|
-
.filter(([_, tool]) => tool.category === category)
|
|
1380
|
-
.map(([name, _]) => name);
|
|
1381
|
-
}
|
|
1382
|
-
function getAllCategories() {
|
|
1383
|
-
const categories = new Set();
|
|
1384
|
-
Object.values(exports.toolsDocumentation).forEach(tool => {
|
|
1385
|
-
categories.add(tool.category);
|
|
1386
|
-
});
|
|
1387
|
-
return Array.from(categories);
|
|
655
|
+
## Related Tools
|
|
656
|
+
- get_node_essentials("nodes-base.code")
|
|
657
|
+
- validate_node_operation()
|
|
658
|
+
- javascript_code_node_guide (for JavaScript syntax)`;
|
|
1388
659
|
}
|
|
1389
660
|
//# sourceMappingURL=tools-documentation.js.map
|