n8n-mcp 2.41.3 → 2.42.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/data/nodes.db +0 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +125 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map +1 -1
- package/dist/mcp/tool-docs/discovery/search-nodes.js +7 -4
- package/dist/mcp/tool-docs/discovery/search-nodes.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +9 -4
- package/dist/mcp/tools.js.map +1 -1
- package/dist/parsers/property-extractor.d.ts.map +1 -1
- package/dist/parsers/property-extractor.js +7 -3
- package/dist/parsers/property-extractor.js.map +1 -1
- package/dist/scripts/mine-workflow-patterns.d.ts +3 -0
- package/dist/scripts/mine-workflow-patterns.d.ts.map +1 -0
- package/dist/scripts/mine-workflow-patterns.js +429 -0
- package/dist/scripts/mine-workflow-patterns.js.map +1 -0
- package/dist/services/expression-validator.d.ts +2 -0
- package/dist/services/expression-validator.d.ts.map +1 -1
- package/dist/services/expression-validator.js +25 -0
- package/dist/services/expression-validator.js.map +1 -1
- package/dist/services/n8n-validation.d.ts +3 -2
- package/dist/services/n8n-validation.d.ts.map +1 -1
- package/dist/services/n8n-validation.js +53 -59
- package/dist/services/n8n-validation.js.map +1 -1
- package/dist/services/node-specific-validators.d.ts.map +1 -1
- package/dist/services/node-specific-validators.js +6 -2
- package/dist/services/node-specific-validators.js.map +1 -1
- package/dist/services/workflow-validator.d.ts.map +1 -1
- package/dist/services/workflow-validator.js +12 -0
- package/dist/services/workflow-validator.js.map +1 -1
- package/package.json +1 -1
package/data/nodes.db
CHANGED
|
Binary file
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare class N8NDocumentationMCPServer {
|
|
|
46
46
|
private getNodeDocumentation;
|
|
47
47
|
private safeJsonParse;
|
|
48
48
|
private getDatabaseStatistics;
|
|
49
|
+
private buildOperationsTree;
|
|
49
50
|
private getNodeEssentials;
|
|
50
51
|
private getNode;
|
|
51
52
|
private handleInfoMode;
|
|
@@ -74,6 +75,8 @@ export declare class N8NDocumentationMCPServer {
|
|
|
74
75
|
private listNodeTemplates;
|
|
75
76
|
private getTemplate;
|
|
76
77
|
private searchTemplates;
|
|
78
|
+
private workflowPatternsCache;
|
|
79
|
+
private getWorkflowPatterns;
|
|
77
80
|
private getTemplatesForTask;
|
|
78
81
|
private searchTemplatesByMetadata;
|
|
79
82
|
private getTaskDescription;
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAmGnE,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,qBAAqB,CAAsB;IACnD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,eAAe,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,gBAAgB;IA8GvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA+Cd,kBAAkB;YAiDlB,wBAAwB;IA0BtC,OAAO,CAAC,kBAAkB;YA6CZ,iBAAiB;IAa/B,OAAO,CAAC,eAAe,CAAkB;YAE3B,sBAAsB;IAgDpC,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAiYrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IA0E1B,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,qBAAqB;IAiF7B,OAAO,CAAC,2BAA2B;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAmGnE,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,qBAAqB,CAAsB;IACnD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,eAAe,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,gBAAgB;IA8GvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA+Cd,kBAAkB;YAiDlB,wBAAwB;IA0BtC,OAAO,CAAC,kBAAkB;YA6CZ,iBAAiB;IAa/B,OAAO,CAAC,eAAe,CAAkB;YAE3B,sBAAsB;IAgDpC,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAiYrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IA0E1B,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,qBAAqB;IAiF7B,OAAO,CAAC,2BAA2B;YAiWrB,SAAS;YA2DT,WAAW;YAkFX,WAAW;YA2CX,cAAc;YAuNd,gBAAgB;IAuE9B,OAAO,CAAC,mBAAmB;IAwE3B,OAAO,CAAC,eAAe;YAsBT,eAAe;IA4M7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,uBAAuB;IA0D/B,OAAO,CAAC,iBAAiB;YAqFX,WAAW;YAgCX,oBAAoB;IAuFlC,OAAO,CAAC,aAAa;YAQP,qBAAqB;IA4DnC,OAAO,CAAC,mBAAmB;YAyCb,iBAAiB;YAiKjB,OAAO;YAgDP,cAAc;YAwFd,iBAAiB;IAqC/B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,4BAA4B;YAKtB,oBAAoB;IAsDlC,OAAO,CAAC,gBAAgB;YAiBV,SAAS;YA6CT,kBAAkB;YAqElB,uBAAuB;YAsDvB,iBAAiB;IAqE/B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IA4D/B,OAAO,CAAC,wBAAwB;IAkChC,OAAO,CAAC,iBAAiB;YAoDX,mBAAmB;YAoEnB,qBAAqB;IAS7B,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAS9B,aAAa;YAcb,iBAAiB;YAoBjB,WAAW;YAwBX,eAAe;IAqB7B,OAAO,CAAC,qBAAqB,CASb;IAEhB,OAAO,CAAC,mBAAmB;YAgDb,mBAAmB;YAwBnB,yBAAyB;IA4CvC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6HhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAgEhC"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -86,6 +86,7 @@ class N8NDocumentationMCPServer {
|
|
|
86
86
|
this.sharedDbState = null;
|
|
87
87
|
this.isShutdown = false;
|
|
88
88
|
this.dbHealthChecked = false;
|
|
89
|
+
this.workflowPatternsCache = null;
|
|
89
90
|
this.instanceContext = instanceContext;
|
|
90
91
|
this.earlyLogger = earlyLogger || null;
|
|
91
92
|
const envDbPath = process.env.NODE_DB_PATH;
|
|
@@ -934,6 +935,7 @@ class N8NDocumentationMCPServer {
|
|
|
934
935
|
return this.searchNodes(args.query, limit, {
|
|
935
936
|
mode: args.mode,
|
|
936
937
|
includeExamples: args.includeExamples,
|
|
938
|
+
includeOperations: args.includeOperations,
|
|
937
939
|
source: args.source
|
|
938
940
|
});
|
|
939
941
|
case 'get_node':
|
|
@@ -1025,6 +1027,8 @@ class N8NDocumentationMCPServer {
|
|
|
1025
1027
|
requiredService: args.requiredService,
|
|
1026
1028
|
targetAudience: args.targetAudience
|
|
1027
1029
|
}, searchLimit, searchOffset);
|
|
1030
|
+
case 'patterns':
|
|
1031
|
+
return this.getWorkflowPatterns(args.task, searchLimit);
|
|
1028
1032
|
case 'keyword':
|
|
1029
1033
|
default:
|
|
1030
1034
|
if (!args.query) {
|
|
@@ -1273,7 +1277,7 @@ class N8NDocumentationMCPServer {
|
|
|
1273
1277
|
return { query, results: [], totalCount: 0 };
|
|
1274
1278
|
}
|
|
1275
1279
|
if (mode === 'FUZZY') {
|
|
1276
|
-
return this.searchNodesFuzzy(cleanedQuery, limit);
|
|
1280
|
+
return this.searchNodesFuzzy(cleanedQuery, limit, { includeOperations: options?.includeOperations });
|
|
1277
1281
|
}
|
|
1278
1282
|
let ftsQuery;
|
|
1279
1283
|
if (cleanedQuery.startsWith('"') && cleanedQuery.endsWith('"')) {
|
|
@@ -1341,7 +1345,7 @@ class N8NDocumentationMCPServer {
|
|
|
1341
1345
|
const hasHttpRequest = scoredNodes.some(n => n.node_type === 'nodes-base.httpRequest');
|
|
1342
1346
|
if (cleanedQuery.toLowerCase().includes('http') && !hasHttpRequest) {
|
|
1343
1347
|
logger_1.logger.debug('FTS missed HTTP Request node, augmenting with LIKE search');
|
|
1344
|
-
return this.searchNodesLIKE(query, limit);
|
|
1348
|
+
return this.searchNodesLIKE(query, limit, options);
|
|
1345
1349
|
}
|
|
1346
1350
|
const result = {
|
|
1347
1351
|
query,
|
|
@@ -1365,6 +1369,12 @@ class N8NDocumentationMCPServer {
|
|
|
1365
1369
|
nodeResult.npmDownloads = node.npm_downloads;
|
|
1366
1370
|
}
|
|
1367
1371
|
}
|
|
1372
|
+
if (options?.includeOperations) {
|
|
1373
|
+
const opsTree = this.buildOperationsTree(node.operations);
|
|
1374
|
+
if (opsTree) {
|
|
1375
|
+
nodeResult.operationsTree = opsTree;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1368
1378
|
return nodeResult;
|
|
1369
1379
|
}),
|
|
1370
1380
|
totalCount: scoredNodes.length
|
|
@@ -1415,7 +1425,7 @@ class N8NDocumentationMCPServer {
|
|
|
1415
1425
|
return this.searchNodesLIKE(query, limit);
|
|
1416
1426
|
}
|
|
1417
1427
|
}
|
|
1418
|
-
async searchNodesFuzzy(query, limit) {
|
|
1428
|
+
async searchNodesFuzzy(query, limit, options) {
|
|
1419
1429
|
if (!this.db)
|
|
1420
1430
|
throw new Error('Database not initialized');
|
|
1421
1431
|
const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0);
|
|
@@ -1443,14 +1453,23 @@ class N8NDocumentationMCPServer {
|
|
|
1443
1453
|
return {
|
|
1444
1454
|
query,
|
|
1445
1455
|
mode: 'FUZZY',
|
|
1446
|
-
results: matchingNodes.map(node =>
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1456
|
+
results: matchingNodes.map(node => {
|
|
1457
|
+
const nodeResult = {
|
|
1458
|
+
nodeType: node.node_type,
|
|
1459
|
+
workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package_name, node.node_type),
|
|
1460
|
+
displayName: node.display_name,
|
|
1461
|
+
description: node.description,
|
|
1462
|
+
category: node.category,
|
|
1463
|
+
package: node.package_name
|
|
1464
|
+
};
|
|
1465
|
+
if (options?.includeOperations) {
|
|
1466
|
+
const opsTree = this.buildOperationsTree(node.operations);
|
|
1467
|
+
if (opsTree) {
|
|
1468
|
+
nodeResult.operationsTree = opsTree;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
return nodeResult;
|
|
1472
|
+
}),
|
|
1454
1473
|
totalCount: matchingNodes.length
|
|
1455
1474
|
};
|
|
1456
1475
|
}
|
|
@@ -1571,6 +1590,12 @@ class N8NDocumentationMCPServer {
|
|
|
1571
1590
|
nodeResult.npmDownloads = node.npm_downloads;
|
|
1572
1591
|
}
|
|
1573
1592
|
}
|
|
1593
|
+
if (options?.includeOperations) {
|
|
1594
|
+
const opsTree = this.buildOperationsTree(node.operations);
|
|
1595
|
+
if (opsTree) {
|
|
1596
|
+
nodeResult.operationsTree = opsTree;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1574
1599
|
return nodeResult;
|
|
1575
1600
|
}),
|
|
1576
1601
|
totalCount: rankedNodes.length
|
|
@@ -1638,6 +1663,12 @@ class N8NDocumentationMCPServer {
|
|
|
1638
1663
|
nodeResult.npmDownloads = node.npm_downloads;
|
|
1639
1664
|
}
|
|
1640
1665
|
}
|
|
1666
|
+
if (options?.includeOperations) {
|
|
1667
|
+
const opsTree = this.buildOperationsTree(node.operations);
|
|
1668
|
+
if (opsTree) {
|
|
1669
|
+
nodeResult.operationsTree = opsTree;
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1641
1672
|
return nodeResult;
|
|
1642
1673
|
}),
|
|
1643
1674
|
totalCount: rankedNodes.length
|
|
@@ -1941,6 +1972,47 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
1941
1972
|
})),
|
|
1942
1973
|
};
|
|
1943
1974
|
}
|
|
1975
|
+
buildOperationsTree(operationsRaw) {
|
|
1976
|
+
if (!operationsRaw)
|
|
1977
|
+
return undefined;
|
|
1978
|
+
let ops;
|
|
1979
|
+
if (typeof operationsRaw === 'string') {
|
|
1980
|
+
try {
|
|
1981
|
+
ops = JSON.parse(operationsRaw);
|
|
1982
|
+
}
|
|
1983
|
+
catch {
|
|
1984
|
+
return undefined;
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
else if (Array.isArray(operationsRaw)) {
|
|
1988
|
+
ops = operationsRaw;
|
|
1989
|
+
}
|
|
1990
|
+
else {
|
|
1991
|
+
return undefined;
|
|
1992
|
+
}
|
|
1993
|
+
if (!Array.isArray(ops) || ops.length === 0)
|
|
1994
|
+
return undefined;
|
|
1995
|
+
const byResource = new Map();
|
|
1996
|
+
for (const op of ops) {
|
|
1997
|
+
const resource = op.resource || 'default';
|
|
1998
|
+
const opName = op.name || op.operation;
|
|
1999
|
+
if (!opName)
|
|
2000
|
+
continue;
|
|
2001
|
+
if (!byResource.has(resource)) {
|
|
2002
|
+
byResource.set(resource, []);
|
|
2003
|
+
}
|
|
2004
|
+
const list = byResource.get(resource);
|
|
2005
|
+
if (!list.includes(opName)) {
|
|
2006
|
+
list.push(opName);
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
if (byResource.size === 0)
|
|
2010
|
+
return undefined;
|
|
2011
|
+
return Array.from(byResource.entries()).map(([resource, operations]) => ({
|
|
2012
|
+
resource,
|
|
2013
|
+
operations
|
|
2014
|
+
}));
|
|
2015
|
+
}
|
|
1944
2016
|
async getNodeEssentials(nodeType, includeExamples) {
|
|
1945
2017
|
await this.ensureInitialized();
|
|
1946
2018
|
if (!this.repository)
|
|
@@ -2798,6 +2870,48 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2798
2870
|
tip: `Found ${result.total} templates matching "${query}". Showing ${result.items.length}.`
|
|
2799
2871
|
};
|
|
2800
2872
|
}
|
|
2873
|
+
getWorkflowPatterns(category, limit = 10) {
|
|
2874
|
+
if (!this.workflowPatternsCache) {
|
|
2875
|
+
try {
|
|
2876
|
+
const patternsPath = path_1.default.join(__dirname, '..', '..', 'data', 'workflow-patterns.json');
|
|
2877
|
+
if ((0, fs_1.existsSync)(patternsPath)) {
|
|
2878
|
+
this.workflowPatternsCache = JSON.parse((0, fs_1.readFileSync)(patternsPath, 'utf-8'));
|
|
2879
|
+
}
|
|
2880
|
+
else {
|
|
2881
|
+
return { error: 'Workflow patterns not generated yet. Run: npm run mine:patterns' };
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
catch (e) {
|
|
2885
|
+
return { error: `Failed to load workflow patterns: ${e instanceof Error ? e.message : String(e)}` };
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
const patterns = this.workflowPatternsCache;
|
|
2889
|
+
if (category) {
|
|
2890
|
+
const categoryData = patterns.categories[category];
|
|
2891
|
+
if (!categoryData) {
|
|
2892
|
+
const available = Object.keys(patterns.categories);
|
|
2893
|
+
return { error: `Unknown category "${category}". Available: ${available.join(', ')}` };
|
|
2894
|
+
}
|
|
2895
|
+
return {
|
|
2896
|
+
category,
|
|
2897
|
+
...categoryData,
|
|
2898
|
+
nodes: categoryData.nodes?.slice(0, limit),
|
|
2899
|
+
commonChains: categoryData.commonChains?.slice(0, limit),
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
const overview = Object.entries(patterns.categories).map(([name, data]) => ({
|
|
2903
|
+
category: name,
|
|
2904
|
+
templateCount: data.templateCount,
|
|
2905
|
+
pattern: data.pattern,
|
|
2906
|
+
topNodes: data.nodes?.slice(0, 5).map(n => n.displayName || n.type),
|
|
2907
|
+
}));
|
|
2908
|
+
return {
|
|
2909
|
+
templateCount: patterns.templateCount,
|
|
2910
|
+
generatedAt: patterns.generatedAt,
|
|
2911
|
+
categories: overview,
|
|
2912
|
+
tip: 'Use search_templates({searchMode: "patterns", task: "category_name"}) for full pattern data with nodes, chains, and tips.',
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2801
2915
|
async getTemplatesForTask(task, limit = 10, offset = 0) {
|
|
2802
2916
|
await this.ensureInitialized();
|
|
2803
2917
|
if (!this.templateService)
|