n8n-mcp 2.23.0 → 2.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -13
- package/data/nodes.db +0 -0
- package/dist/http-server-single-session.d.ts +4 -0
- package/dist/http-server-single-session.d.ts.map +1 -1
- package/dist/http-server-single-session.js +123 -0
- package/dist/http-server-single-session.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +233 -5
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools-documentation.d.ts.map +1 -1
- package/dist/mcp/tools-documentation.js +14 -9
- package/dist/mcp/tools-documentation.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +29 -18
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp-engine.d.ts +3 -0
- package/dist/mcp-engine.d.ts.map +1 -1
- package/dist/mcp-engine.js +16 -2
- package/dist/mcp-engine.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/session-state.d.ts +15 -0
- package/dist/types/session-state.d.ts.map +1 -0
- package/dist/types/session-state.js +3 -0
- package/dist/types/session-state.js.map +1 -0
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -53,6 +53,7 @@ const property_filter_1 = require("../services/property-filter");
|
|
|
53
53
|
const task_templates_1 = require("../services/task-templates");
|
|
54
54
|
const enhanced_config_validator_1 = require("../services/enhanced-config-validator");
|
|
55
55
|
const property_dependencies_1 = require("../services/property-dependencies");
|
|
56
|
+
const type_structure_service_1 = require("../services/type-structure-service");
|
|
56
57
|
const simple_cache_1 = require("../utils/simple-cache");
|
|
57
58
|
const template_service_1 = require("../templates/template-service");
|
|
58
59
|
const workflow_validator_1 = require("../services/workflow-validator");
|
|
@@ -727,9 +728,6 @@ class N8NDocumentationMCPServer {
|
|
|
727
728
|
return this.getToolsDocumentation(args.topic, args.depth);
|
|
728
729
|
case 'list_nodes':
|
|
729
730
|
return this.listNodes(args);
|
|
730
|
-
case 'get_node_info':
|
|
731
|
-
this.validateToolParams(name, args, ['nodeType']);
|
|
732
|
-
return this.getNodeInfo(args.nodeType);
|
|
733
731
|
case 'search_nodes':
|
|
734
732
|
this.validateToolParams(name, args, ['query']);
|
|
735
733
|
const limit = args.limit !== undefined ? Number(args.limit) || 20 : 20;
|
|
@@ -741,9 +739,9 @@ class N8NDocumentationMCPServer {
|
|
|
741
739
|
return this.getNodeDocumentation(args.nodeType);
|
|
742
740
|
case 'get_database_statistics':
|
|
743
741
|
return this.getDatabaseStatistics();
|
|
744
|
-
case '
|
|
742
|
+
case 'get_node':
|
|
745
743
|
this.validateToolParams(name, args, ['nodeType']);
|
|
746
|
-
return this.
|
|
744
|
+
return this.getNode(args.nodeType, args.detail, args.mode, args.includeTypeInfo, args.includeExamples, args.fromVersion, args.toVersion);
|
|
747
745
|
case 'search_node_properties':
|
|
748
746
|
this.validateToolParams(name, args, ['nodeType', 'query']);
|
|
749
747
|
const maxResults = args.maxResults !== undefined ? Number(args.maxResults) || 20 : 20;
|
|
@@ -1723,6 +1721,236 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
1723
1721
|
this.cache.set(cacheKey, result, 3600);
|
|
1724
1722
|
return result;
|
|
1725
1723
|
}
|
|
1724
|
+
async getNode(nodeType, detail = 'standard', mode = 'info', includeTypeInfo, includeExamples, fromVersion, toVersion) {
|
|
1725
|
+
await this.ensureInitialized();
|
|
1726
|
+
if (!this.repository)
|
|
1727
|
+
throw new Error('Repository not initialized');
|
|
1728
|
+
const validDetailLevels = ['minimal', 'standard', 'full'];
|
|
1729
|
+
const validModes = ['info', 'versions', 'compare', 'breaking', 'migrations'];
|
|
1730
|
+
if (!validDetailLevels.includes(detail)) {
|
|
1731
|
+
throw new Error(`get_node: Invalid detail level "${detail}". Valid options: ${validDetailLevels.join(', ')}`);
|
|
1732
|
+
}
|
|
1733
|
+
if (!validModes.includes(mode)) {
|
|
1734
|
+
throw new Error(`get_node: Invalid mode "${mode}". Valid options: ${validModes.join(', ')}`);
|
|
1735
|
+
}
|
|
1736
|
+
const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType);
|
|
1737
|
+
if (mode !== 'info') {
|
|
1738
|
+
return this.handleVersionMode(normalizedType, mode, fromVersion, toVersion);
|
|
1739
|
+
}
|
|
1740
|
+
return this.handleInfoMode(normalizedType, detail, includeTypeInfo, includeExamples);
|
|
1741
|
+
}
|
|
1742
|
+
async handleInfoMode(nodeType, detail, includeTypeInfo, includeExamples) {
|
|
1743
|
+
switch (detail) {
|
|
1744
|
+
case 'minimal': {
|
|
1745
|
+
let node = this.repository.getNode(nodeType);
|
|
1746
|
+
if (!node) {
|
|
1747
|
+
const alternatives = (0, node_utils_1.getNodeTypeAlternatives)(nodeType);
|
|
1748
|
+
for (const alt of alternatives) {
|
|
1749
|
+
const found = this.repository.getNode(alt);
|
|
1750
|
+
if (found) {
|
|
1751
|
+
node = found;
|
|
1752
|
+
break;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
if (!node) {
|
|
1757
|
+
throw new Error(`Node ${nodeType} not found`);
|
|
1758
|
+
}
|
|
1759
|
+
return {
|
|
1760
|
+
nodeType: node.nodeType,
|
|
1761
|
+
workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType),
|
|
1762
|
+
displayName: node.displayName,
|
|
1763
|
+
description: node.description,
|
|
1764
|
+
category: node.category,
|
|
1765
|
+
package: node.package,
|
|
1766
|
+
isAITool: node.isAITool,
|
|
1767
|
+
isTrigger: node.isTrigger,
|
|
1768
|
+
isWebhook: node.isWebhook
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
case 'standard': {
|
|
1772
|
+
const essentials = await this.getNodeEssentials(nodeType, includeExamples);
|
|
1773
|
+
const versionSummary = this.getVersionSummary(nodeType);
|
|
1774
|
+
if (includeTypeInfo) {
|
|
1775
|
+
essentials.requiredProperties = this.enrichPropertiesWithTypeInfo(essentials.requiredProperties);
|
|
1776
|
+
essentials.commonProperties = this.enrichPropertiesWithTypeInfo(essentials.commonProperties);
|
|
1777
|
+
}
|
|
1778
|
+
return {
|
|
1779
|
+
...essentials,
|
|
1780
|
+
versionInfo: versionSummary
|
|
1781
|
+
};
|
|
1782
|
+
}
|
|
1783
|
+
case 'full': {
|
|
1784
|
+
const fullInfo = await this.getNodeInfo(nodeType);
|
|
1785
|
+
const versionSummary = this.getVersionSummary(nodeType);
|
|
1786
|
+
if (includeTypeInfo && fullInfo.properties) {
|
|
1787
|
+
fullInfo.properties = this.enrichPropertiesWithTypeInfo(fullInfo.properties);
|
|
1788
|
+
}
|
|
1789
|
+
return {
|
|
1790
|
+
...fullInfo,
|
|
1791
|
+
versionInfo: versionSummary
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
default:
|
|
1795
|
+
throw new Error(`Unknown detail level: ${detail}`);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
async handleVersionMode(nodeType, mode, fromVersion, toVersion) {
|
|
1799
|
+
switch (mode) {
|
|
1800
|
+
case 'versions':
|
|
1801
|
+
return this.getVersionHistory(nodeType);
|
|
1802
|
+
case 'compare':
|
|
1803
|
+
if (!fromVersion) {
|
|
1804
|
+
throw new Error(`get_node: fromVersion is required for compare mode (nodeType: ${nodeType})`);
|
|
1805
|
+
}
|
|
1806
|
+
return this.compareVersions(nodeType, fromVersion, toVersion);
|
|
1807
|
+
case 'breaking':
|
|
1808
|
+
if (!fromVersion) {
|
|
1809
|
+
throw new Error(`get_node: fromVersion is required for breaking mode (nodeType: ${nodeType})`);
|
|
1810
|
+
}
|
|
1811
|
+
return this.getBreakingChanges(nodeType, fromVersion, toVersion);
|
|
1812
|
+
case 'migrations':
|
|
1813
|
+
if (!fromVersion || !toVersion) {
|
|
1814
|
+
throw new Error(`get_node: Both fromVersion and toVersion are required for migrations mode (nodeType: ${nodeType})`);
|
|
1815
|
+
}
|
|
1816
|
+
return this.getMigrations(nodeType, fromVersion, toVersion);
|
|
1817
|
+
default:
|
|
1818
|
+
throw new Error(`get_node: Unknown mode: ${mode} (nodeType: ${nodeType})`);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
getVersionSummary(nodeType) {
|
|
1822
|
+
const cacheKey = `version-summary:${nodeType}`;
|
|
1823
|
+
const cached = this.cache.get(cacheKey);
|
|
1824
|
+
if (cached) {
|
|
1825
|
+
return cached;
|
|
1826
|
+
}
|
|
1827
|
+
const versions = this.repository.getNodeVersions(nodeType);
|
|
1828
|
+
const latest = this.repository.getLatestNodeVersion(nodeType);
|
|
1829
|
+
const summary = {
|
|
1830
|
+
currentVersion: latest?.version || 'unknown',
|
|
1831
|
+
totalVersions: versions.length,
|
|
1832
|
+
hasVersionHistory: versions.length > 0
|
|
1833
|
+
};
|
|
1834
|
+
this.cache.set(cacheKey, summary, 86400000);
|
|
1835
|
+
return summary;
|
|
1836
|
+
}
|
|
1837
|
+
getVersionHistory(nodeType) {
|
|
1838
|
+
const versions = this.repository.getNodeVersions(nodeType);
|
|
1839
|
+
return {
|
|
1840
|
+
nodeType,
|
|
1841
|
+
totalVersions: versions.length,
|
|
1842
|
+
versions: versions.map(v => ({
|
|
1843
|
+
version: v.version,
|
|
1844
|
+
isCurrent: v.isCurrentMax,
|
|
1845
|
+
minimumN8nVersion: v.minimumN8nVersion,
|
|
1846
|
+
releasedAt: v.releasedAt,
|
|
1847
|
+
hasBreakingChanges: (v.breakingChanges || []).length > 0,
|
|
1848
|
+
breakingChangesCount: (v.breakingChanges || []).length,
|
|
1849
|
+
deprecatedProperties: v.deprecatedProperties || [],
|
|
1850
|
+
addedProperties: v.addedProperties || []
|
|
1851
|
+
})),
|
|
1852
|
+
available: versions.length > 0,
|
|
1853
|
+
message: versions.length === 0 ?
|
|
1854
|
+
'No version history available. Version tracking may not be enabled for this node.' :
|
|
1855
|
+
undefined
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
compareVersions(nodeType, fromVersion, toVersion) {
|
|
1859
|
+
const latest = this.repository.getLatestNodeVersion(nodeType);
|
|
1860
|
+
const targetVersion = toVersion || latest?.version;
|
|
1861
|
+
if (!targetVersion) {
|
|
1862
|
+
throw new Error('No target version available');
|
|
1863
|
+
}
|
|
1864
|
+
const changes = this.repository.getPropertyChanges(nodeType, fromVersion, targetVersion);
|
|
1865
|
+
return {
|
|
1866
|
+
nodeType,
|
|
1867
|
+
fromVersion,
|
|
1868
|
+
toVersion: targetVersion,
|
|
1869
|
+
totalChanges: changes.length,
|
|
1870
|
+
breakingChanges: changes.filter(c => c.isBreaking).length,
|
|
1871
|
+
changes: changes.map(c => ({
|
|
1872
|
+
property: c.propertyName,
|
|
1873
|
+
changeType: c.changeType,
|
|
1874
|
+
isBreaking: c.isBreaking,
|
|
1875
|
+
severity: c.severity,
|
|
1876
|
+
oldValue: c.oldValue,
|
|
1877
|
+
newValue: c.newValue,
|
|
1878
|
+
migrationHint: c.migrationHint,
|
|
1879
|
+
autoMigratable: c.autoMigratable
|
|
1880
|
+
}))
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
getBreakingChanges(nodeType, fromVersion, toVersion) {
|
|
1884
|
+
const breakingChanges = this.repository.getBreakingChanges(nodeType, fromVersion, toVersion);
|
|
1885
|
+
return {
|
|
1886
|
+
nodeType,
|
|
1887
|
+
fromVersion,
|
|
1888
|
+
toVersion: toVersion || 'latest',
|
|
1889
|
+
totalBreakingChanges: breakingChanges.length,
|
|
1890
|
+
changes: breakingChanges.map(c => ({
|
|
1891
|
+
fromVersion: c.fromVersion,
|
|
1892
|
+
toVersion: c.toVersion,
|
|
1893
|
+
property: c.propertyName,
|
|
1894
|
+
changeType: c.changeType,
|
|
1895
|
+
severity: c.severity,
|
|
1896
|
+
migrationHint: c.migrationHint,
|
|
1897
|
+
oldValue: c.oldValue,
|
|
1898
|
+
newValue: c.newValue
|
|
1899
|
+
})),
|
|
1900
|
+
upgradeSafe: breakingChanges.length === 0
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
getMigrations(nodeType, fromVersion, toVersion) {
|
|
1904
|
+
const migrations = this.repository.getAutoMigratableChanges(nodeType, fromVersion, toVersion);
|
|
1905
|
+
const allChanges = this.repository.getPropertyChanges(nodeType, fromVersion, toVersion);
|
|
1906
|
+
return {
|
|
1907
|
+
nodeType,
|
|
1908
|
+
fromVersion,
|
|
1909
|
+
toVersion,
|
|
1910
|
+
autoMigratableChanges: migrations.length,
|
|
1911
|
+
totalChanges: allChanges.length,
|
|
1912
|
+
migrations: migrations.map(m => ({
|
|
1913
|
+
property: m.propertyName,
|
|
1914
|
+
changeType: m.changeType,
|
|
1915
|
+
migrationStrategy: m.migrationStrategy,
|
|
1916
|
+
severity: m.severity
|
|
1917
|
+
})),
|
|
1918
|
+
requiresManualMigration: migrations.length < allChanges.length
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
enrichPropertyWithTypeInfo(property) {
|
|
1922
|
+
if (!property || !property.type)
|
|
1923
|
+
return property;
|
|
1924
|
+
const structure = type_structure_service_1.TypeStructureService.getStructure(property.type);
|
|
1925
|
+
if (!structure)
|
|
1926
|
+
return property;
|
|
1927
|
+
return {
|
|
1928
|
+
...property,
|
|
1929
|
+
typeInfo: {
|
|
1930
|
+
category: structure.type,
|
|
1931
|
+
jsType: structure.jsType,
|
|
1932
|
+
description: structure.description,
|
|
1933
|
+
isComplex: type_structure_service_1.TypeStructureService.isComplexType(property.type),
|
|
1934
|
+
isPrimitive: type_structure_service_1.TypeStructureService.isPrimitiveType(property.type),
|
|
1935
|
+
allowsExpressions: structure.validation?.allowExpressions ?? true,
|
|
1936
|
+
allowsEmpty: structure.validation?.allowEmpty ?? false,
|
|
1937
|
+
...(structure.structure && {
|
|
1938
|
+
structureHints: {
|
|
1939
|
+
hasProperties: !!structure.structure.properties,
|
|
1940
|
+
hasItems: !!structure.structure.items,
|
|
1941
|
+
isFlexible: structure.structure.flexible ?? false,
|
|
1942
|
+
requiredFields: structure.structure.required ?? []
|
|
1943
|
+
}
|
|
1944
|
+
}),
|
|
1945
|
+
...(structure.notes && { notes: structure.notes })
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
enrichPropertiesWithTypeInfo(properties) {
|
|
1950
|
+
if (!properties || !Array.isArray(properties))
|
|
1951
|
+
return properties;
|
|
1952
|
+
return properties.map((prop) => this.enrichPropertyWithTypeInfo(prop));
|
|
1953
|
+
}
|
|
1726
1954
|
async searchNodeProperties(nodeType, query, maxResults = 20) {
|
|
1727
1955
|
await this.ensureInitialized();
|
|
1728
1956
|
if (!this.repository)
|