n8n-mcp 2.7.7

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.
Files changed (375) hide show
  1. package/.env.example +79 -0
  2. package/LICENSE +21 -0
  3. package/README.md +670 -0
  4. package/data/nodes.db +0 -0
  5. package/dist/config/n8n-api.d.ts +9 -0
  6. package/dist/config/n8n-api.d.ts.map +1 -0
  7. package/dist/config/n8n-api.js +41 -0
  8. package/dist/config/n8n-api.js.map +1 -0
  9. package/dist/database/database-adapter.d.ts +32 -0
  10. package/dist/database/database-adapter.d.ts.map +1 -0
  11. package/dist/database/database-adapter.js +328 -0
  12. package/dist/database/database-adapter.js.map +1 -0
  13. package/dist/database/node-repository.d.ts +11 -0
  14. package/dist/database/node-repository.d.ts.map +1 -0
  15. package/dist/database/node-repository.js +67 -0
  16. package/dist/database/node-repository.js.map +1 -0
  17. package/dist/http-server-single-session.d.ts +21 -0
  18. package/dist/http-server-single-session.d.ts.map +1 -0
  19. package/dist/http-server-single-session.js +279 -0
  20. package/dist/http-server-single-session.js.map +1 -0
  21. package/dist/http-server.d.ts +9 -0
  22. package/dist/http-server.d.ts.map +1 -0
  23. package/dist/http-server.js +342 -0
  24. package/dist/http-server.js.map +1 -0
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +17 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/loaders/node-loader.d.ts +11 -0
  30. package/dist/loaders/node-loader.d.ts.map +1 -0
  31. package/dist/loaders/node-loader.js +79 -0
  32. package/dist/loaders/node-loader.js.map +1 -0
  33. package/dist/mappers/docs-mapper.d.ts +6 -0
  34. package/dist/mappers/docs-mapper.d.ts.map +1 -0
  35. package/dist/mappers/docs-mapper.js +59 -0
  36. package/dist/mappers/docs-mapper.js.map +1 -0
  37. package/dist/mcp/absolute-minimal.d.ts +4 -0
  38. package/dist/mcp/absolute-minimal.d.ts.map +1 -0
  39. package/dist/mcp/absolute-minimal.js +34 -0
  40. package/dist/mcp/absolute-minimal.js.map +1 -0
  41. package/dist/mcp/fixed-protocol.d.ts +17 -0
  42. package/dist/mcp/fixed-protocol.d.ts.map +1 -0
  43. package/dist/mcp/fixed-protocol.js +162 -0
  44. package/dist/mcp/fixed-protocol.js.map +1 -0
  45. package/dist/mcp/handlers-documentation.d.ts +18 -0
  46. package/dist/mcp/handlers-documentation.d.ts.map +1 -0
  47. package/dist/mcp/handlers-documentation.js +113 -0
  48. package/dist/mcp/handlers-documentation.js.map +1 -0
  49. package/dist/mcp/handlers-n8n-manager.d.ts +21 -0
  50. package/dist/mcp/handlers-n8n-manager.d.ts.map +1 -0
  51. package/dist/mcp/handlers-n8n-manager.js +827 -0
  52. package/dist/mcp/handlers-n8n-manager.js.map +1 -0
  53. package/dist/mcp/handlers-workflow-diff.d.ts +3 -0
  54. package/dist/mcp/handlers-workflow-diff.d.ts.map +1 -0
  55. package/dist/mcp/handlers-workflow-diff.js +125 -0
  56. package/dist/mcp/handlers-workflow-diff.js.map +1 -0
  57. package/dist/mcp/index.d.ts +3 -0
  58. package/dist/mcp/index.d.ts.map +1 -0
  59. package/dist/mcp/index.js +106 -0
  60. package/dist/mcp/index.js.map +1 -0
  61. package/dist/mcp/minimal-test.d.ts +3 -0
  62. package/dist/mcp/minimal-test.d.ts.map +1 -0
  63. package/dist/mcp/minimal-test.js +83 -0
  64. package/dist/mcp/minimal-test.js.map +1 -0
  65. package/dist/mcp/server.d.ts +42 -0
  66. package/dist/mcp/server.d.ts.map +1 -0
  67. package/dist/mcp/server.js +1258 -0
  68. package/dist/mcp/server.js.map +1 -0
  69. package/dist/mcp/stderr-test.d.ts +2 -0
  70. package/dist/mcp/stderr-test.d.ts.map +1 -0
  71. package/dist/mcp/stderr-test.js +32 -0
  72. package/dist/mcp/stderr-test.js.map +1 -0
  73. package/dist/mcp/stdio-wrapper.d.ts +3 -0
  74. package/dist/mcp/stdio-wrapper.d.ts.map +1 -0
  75. package/dist/mcp/stdio-wrapper.js +52 -0
  76. package/dist/mcp/stdio-wrapper.js.map +1 -0
  77. package/dist/mcp/tools-documentation.d.ts +34 -0
  78. package/dist/mcp/tools-documentation.d.ts.map +1 -0
  79. package/dist/mcp/tools-documentation.js +609 -0
  80. package/dist/mcp/tools-documentation.js.map +1 -0
  81. package/dist/mcp/tools-n8n-manager.d.ts +3 -0
  82. package/dist/mcp/tools-n8n-manager.d.ts.map +1 -0
  83. package/dist/mcp/tools-n8n-manager.js +496 -0
  84. package/dist/mcp/tools-n8n-manager.js.map +1 -0
  85. package/dist/mcp/tools.d.ts +3 -0
  86. package/dist/mcp/tools.d.ts.map +1 -0
  87. package/dist/mcp/tools.js +405 -0
  88. package/dist/mcp/tools.js.map +1 -0
  89. package/dist/mcp/ultra-minimal.d.ts +8 -0
  90. package/dist/mcp/ultra-minimal.d.ts.map +1 -0
  91. package/dist/mcp/ultra-minimal.js +93 -0
  92. package/dist/mcp/ultra-minimal.js.map +1 -0
  93. package/dist/mcp/working-test.d.ts +3 -0
  94. package/dist/mcp/working-test.d.ts.map +1 -0
  95. package/dist/mcp/working-test.js +48 -0
  96. package/dist/mcp/working-test.js.map +1 -0
  97. package/dist/mcp/wrapper.sh +28 -0
  98. package/dist/mcp-engine.d.ts +32 -0
  99. package/dist/mcp-engine.d.ts.map +1 -0
  100. package/dist/mcp-engine.js +63 -0
  101. package/dist/mcp-engine.js.map +1 -0
  102. package/dist/n8n/MCPApi.credentials.d.ts +8 -0
  103. package/dist/n8n/MCPApi.credentials.d.ts.map +1 -0
  104. package/dist/n8n/MCPApi.credentials.js +53 -0
  105. package/dist/n8n/MCPApi.credentials.js.map +1 -0
  106. package/dist/n8n/MCPNode.node.d.ts +13 -0
  107. package/dist/n8n/MCPNode.node.d.ts.map +1 -0
  108. package/dist/n8n/MCPNode.node.js +260 -0
  109. package/dist/n8n/MCPNode.node.js.map +1 -0
  110. package/dist/parsers/node-parser.d.ts +30 -0
  111. package/dist/parsers/node-parser.d.ts.map +1 -0
  112. package/dist/parsers/node-parser.js +152 -0
  113. package/dist/parsers/node-parser.js.map +1 -0
  114. package/dist/parsers/property-extractor.d.ts +10 -0
  115. package/dist/parsers/property-extractor.d.ts.map +1 -0
  116. package/dist/parsers/property-extractor.js +155 -0
  117. package/dist/parsers/property-extractor.js.map +1 -0
  118. package/dist/parsers/simple-parser.d.ts +24 -0
  119. package/dist/parsers/simple-parser.d.ts.map +1 -0
  120. package/dist/parsers/simple-parser.js +160 -0
  121. package/dist/parsers/simple-parser.js.map +1 -0
  122. package/dist/scripts/debug-n8n-auth.d.ts +3 -0
  123. package/dist/scripts/debug-n8n-auth.d.ts.map +1 -0
  124. package/dist/scripts/debug-n8n-auth.js +97 -0
  125. package/dist/scripts/debug-n8n-auth.js.map +1 -0
  126. package/dist/scripts/debug-node.d.ts +3 -0
  127. package/dist/scripts/debug-node.d.ts.map +1 -0
  128. package/dist/scripts/debug-node.js +59 -0
  129. package/dist/scripts/debug-node.js.map +1 -0
  130. package/dist/scripts/extract-from-docker.d.ts +3 -0
  131. package/dist/scripts/extract-from-docker.d.ts.map +1 -0
  132. package/dist/scripts/extract-from-docker.js +210 -0
  133. package/dist/scripts/extract-from-docker.js.map +1 -0
  134. package/dist/scripts/fetch-templates-robust.d.ts +4 -0
  135. package/dist/scripts/fetch-templates-robust.d.ts.map +1 -0
  136. package/dist/scripts/fetch-templates-robust.js +126 -0
  137. package/dist/scripts/fetch-templates-robust.js.map +1 -0
  138. package/dist/scripts/fetch-templates.d.ts +4 -0
  139. package/dist/scripts/fetch-templates.d.ts.map +1 -0
  140. package/dist/scripts/fetch-templates.js +94 -0
  141. package/dist/scripts/fetch-templates.js.map +1 -0
  142. package/dist/scripts/rebuild-database.d.ts +4 -0
  143. package/dist/scripts/rebuild-database.d.ts.map +1 -0
  144. package/dist/scripts/rebuild-database.js +95 -0
  145. package/dist/scripts/rebuild-database.js.map +1 -0
  146. package/dist/scripts/rebuild-optimized.d.ts +3 -0
  147. package/dist/scripts/rebuild-optimized.d.ts.map +1 -0
  148. package/dist/scripts/rebuild-optimized.js +198 -0
  149. package/dist/scripts/rebuild-optimized.js.map +1 -0
  150. package/dist/scripts/rebuild.d.ts +3 -0
  151. package/dist/scripts/rebuild.d.ts.map +1 -0
  152. package/dist/scripts/rebuild.js +163 -0
  153. package/dist/scripts/rebuild.js.map +1 -0
  154. package/dist/scripts/sanitize-templates.d.ts +3 -0
  155. package/dist/scripts/sanitize-templates.d.ts.map +1 -0
  156. package/dist/scripts/sanitize-templates.js +56 -0
  157. package/dist/scripts/sanitize-templates.js.map +1 -0
  158. package/dist/scripts/test-ai-workflow-validation.d.ts +3 -0
  159. package/dist/scripts/test-ai-workflow-validation.d.ts.map +1 -0
  160. package/dist/scripts/test-ai-workflow-validation.js +191 -0
  161. package/dist/scripts/test-ai-workflow-validation.js.map +1 -0
  162. package/dist/scripts/test-api-headers.d.ts +3 -0
  163. package/dist/scripts/test-api-headers.d.ts.map +1 -0
  164. package/dist/scripts/test-api-headers.js +35 -0
  165. package/dist/scripts/test-api-headers.js.map +1 -0
  166. package/dist/scripts/test-docker-config-simulation.d.ts +3 -0
  167. package/dist/scripts/test-docker-config-simulation.d.ts.map +1 -0
  168. package/dist/scripts/test-docker-config-simulation.js +74 -0
  169. package/dist/scripts/test-docker-config-simulation.js.map +1 -0
  170. package/dist/scripts/test-enhanced-validation.d.ts +3 -0
  171. package/dist/scripts/test-enhanced-validation.d.ts.map +1 -0
  172. package/dist/scripts/test-enhanced-validation.js +117 -0
  173. package/dist/scripts/test-enhanced-validation.js.map +1 -0
  174. package/dist/scripts/test-lazy-config.d.ts +3 -0
  175. package/dist/scripts/test-lazy-config.d.ts.map +1 -0
  176. package/dist/scripts/test-lazy-config.js +60 -0
  177. package/dist/scripts/test-lazy-config.js.map +1 -0
  178. package/dist/scripts/test-limited-results.d.ts +3 -0
  179. package/dist/scripts/test-limited-results.d.ts.map +1 -0
  180. package/dist/scripts/test-limited-results.js +76 -0
  181. package/dist/scripts/test-limited-results.js.map +1 -0
  182. package/dist/scripts/test-mcp-n8n-update-partial.d.ts +3 -0
  183. package/dist/scripts/test-mcp-n8n-update-partial.d.ts.map +1 -0
  184. package/dist/scripts/test-mcp-n8n-update-partial.js +138 -0
  185. package/dist/scripts/test-mcp-n8n-update-partial.js.map +1 -0
  186. package/dist/scripts/test-mcp-tools.d.ts +3 -0
  187. package/dist/scripts/test-mcp-tools.d.ts.map +1 -0
  188. package/dist/scripts/test-mcp-tools.js +36 -0
  189. package/dist/scripts/test-mcp-tools.js.map +1 -0
  190. package/dist/scripts/test-n8n-manager-integration.d.ts +3 -0
  191. package/dist/scripts/test-n8n-manager-integration.d.ts.map +1 -0
  192. package/dist/scripts/test-n8n-manager-integration.js +122 -0
  193. package/dist/scripts/test-n8n-manager-integration.js.map +1 -0
  194. package/dist/scripts/test-n8n-validate-workflow.d.ts +3 -0
  195. package/dist/scripts/test-n8n-validate-workflow.d.ts.map +1 -0
  196. package/dist/scripts/test-n8n-validate-workflow.js +125 -0
  197. package/dist/scripts/test-n8n-validate-workflow.js.map +1 -0
  198. package/dist/scripts/test-nodes.d.ts +3 -0
  199. package/dist/scripts/test-nodes.d.ts.map +1 -0
  200. package/dist/scripts/test-nodes.js +91 -0
  201. package/dist/scripts/test-nodes.js.map +1 -0
  202. package/dist/scripts/test-single-workflow.d.ts +3 -0
  203. package/dist/scripts/test-single-workflow.d.ts.map +1 -0
  204. package/dist/scripts/test-single-workflow.js +112 -0
  205. package/dist/scripts/test-single-workflow.js.map +1 -0
  206. package/dist/scripts/test-template-validation.d.ts +3 -0
  207. package/dist/scripts/test-template-validation.d.ts.map +1 -0
  208. package/dist/scripts/test-template-validation.js +142 -0
  209. package/dist/scripts/test-template-validation.js.map +1 -0
  210. package/dist/scripts/test-templates.d.ts +4 -0
  211. package/dist/scripts/test-templates.d.ts.map +1 -0
  212. package/dist/scripts/test-templates.js +99 -0
  213. package/dist/scripts/test-templates.js.map +1 -0
  214. package/dist/scripts/test-transactional-diff.d.ts +2 -0
  215. package/dist/scripts/test-transactional-diff.d.ts.map +1 -0
  216. package/dist/scripts/test-transactional-diff.js +240 -0
  217. package/dist/scripts/test-transactional-diff.js.map +1 -0
  218. package/dist/scripts/test-update-partial-debug.d.ts +3 -0
  219. package/dist/scripts/test-update-partial-debug.d.ts.map +1 -0
  220. package/dist/scripts/test-update-partial-debug.js +92 -0
  221. package/dist/scripts/test-update-partial-debug.js.map +1 -0
  222. package/dist/scripts/test-version-extraction.d.ts +2 -0
  223. package/dist/scripts/test-version-extraction.d.ts.map +1 -0
  224. package/dist/scripts/test-version-extraction.js +74 -0
  225. package/dist/scripts/test-version-extraction.js.map +1 -0
  226. package/dist/scripts/test-workflow-diff.d.ts +3 -0
  227. package/dist/scripts/test-workflow-diff.d.ts.map +1 -0
  228. package/dist/scripts/test-workflow-diff.js +328 -0
  229. package/dist/scripts/test-workflow-diff.js.map +1 -0
  230. package/dist/scripts/test-workflow-validation.d.ts +3 -0
  231. package/dist/scripts/test-workflow-validation.d.ts.map +1 -0
  232. package/dist/scripts/test-workflow-validation.js +238 -0
  233. package/dist/scripts/test-workflow-validation.js.map +1 -0
  234. package/dist/scripts/validate.d.ts +3 -0
  235. package/dist/scripts/validate.d.ts.map +1 -0
  236. package/dist/scripts/validate.js +121 -0
  237. package/dist/scripts/validate.js.map +1 -0
  238. package/dist/scripts/validation-summary.d.ts +3 -0
  239. package/dist/scripts/validation-summary.d.ts.map +1 -0
  240. package/dist/scripts/validation-summary.js +135 -0
  241. package/dist/scripts/validation-summary.js.map +1 -0
  242. package/dist/services/config-validator.d.ts +39 -0
  243. package/dist/services/config-validator.d.ts.map +1 -0
  244. package/dist/services/config-validator.js +376 -0
  245. package/dist/services/config-validator.js.map +1 -0
  246. package/dist/services/enhanced-config-validator.d.ts +38 -0
  247. package/dist/services/enhanced-config-validator.d.ts.map +1 -0
  248. package/dist/services/enhanced-config-validator.js +300 -0
  249. package/dist/services/enhanced-config-validator.js.map +1 -0
  250. package/dist/services/example-generator.d.ts +14 -0
  251. package/dist/services/example-generator.d.ts.map +1 -0
  252. package/dist/services/example-generator.js +556 -0
  253. package/dist/services/example-generator.js.map +1 -0
  254. package/dist/services/expression-validator.d.ts +27 -0
  255. package/dist/services/expression-validator.d.ts.map +1 -0
  256. package/dist/services/expression-validator.js +163 -0
  257. package/dist/services/expression-validator.js.map +1 -0
  258. package/dist/services/n8n-api-client.d.ts +39 -0
  259. package/dist/services/n8n-api-client.d.ts.map +1 -0
  260. package/dist/services/n8n-api-client.js +326 -0
  261. package/dist/services/n8n-api-client.js.map +1 -0
  262. package/dist/services/n8n-validation.d.ts +127 -0
  263. package/dist/services/n8n-validation.d.ts.map +1 -0
  264. package/dist/services/n8n-validation.js +238 -0
  265. package/dist/services/n8n-validation.js.map +1 -0
  266. package/dist/services/node-documentation-service.d.ts +70 -0
  267. package/dist/services/node-documentation-service.d.ts.map +1 -0
  268. package/dist/services/node-documentation-service.js +518 -0
  269. package/dist/services/node-documentation-service.js.map +1 -0
  270. package/dist/services/node-specific-validators.d.ts +28 -0
  271. package/dist/services/node-specific-validators.d.ts.map +1 -0
  272. package/dist/services/node-specific-validators.js +666 -0
  273. package/dist/services/node-specific-validators.js.map +1 -0
  274. package/dist/services/property-dependencies.d.ts +36 -0
  275. package/dist/services/property-dependencies.d.ts.map +1 -0
  276. package/dist/services/property-dependencies.js +168 -0
  277. package/dist/services/property-dependencies.js.map +1 -0
  278. package/dist/services/property-filter.d.ts +39 -0
  279. package/dist/services/property-filter.d.ts.map +1 -0
  280. package/dist/services/property-filter.js +362 -0
  281. package/dist/services/property-filter.js.map +1 -0
  282. package/dist/services/task-templates.d.ts +26 -0
  283. package/dist/services/task-templates.d.ts.map +1 -0
  284. package/dist/services/task-templates.js +555 -0
  285. package/dist/services/task-templates.js.map +1 -0
  286. package/dist/services/workflow-diff-engine.d.ts +31 -0
  287. package/dist/services/workflow-diff-engine.d.ts.map +1 -0
  288. package/dist/services/workflow-diff-engine.js +478 -0
  289. package/dist/services/workflow-diff-engine.js.map +1 -0
  290. package/dist/services/workflow-validator.d.ts +87 -0
  291. package/dist/services/workflow-validator.d.ts.map +1 -0
  292. package/dist/services/workflow-validator.js +656 -0
  293. package/dist/services/workflow-validator.js.map +1 -0
  294. package/dist/templates/template-fetcher.d.ts +41 -0
  295. package/dist/templates/template-fetcher.d.ts.map +1 -0
  296. package/dist/templates/template-fetcher.js +94 -0
  297. package/dist/templates/template-fetcher.js.map +1 -0
  298. package/dist/templates/template-repository.d.ts +34 -0
  299. package/dist/templates/template-repository.d.ts.map +1 -0
  300. package/dist/templates/template-repository.js +121 -0
  301. package/dist/templates/template-repository.js.map +1 -0
  302. package/dist/templates/template-service.d.ts +31 -0
  303. package/dist/templates/template-service.d.ts.map +1 -0
  304. package/dist/templates/template-service.js +131 -0
  305. package/dist/templates/template-service.js.map +1 -0
  306. package/dist/types/index.d.ts +31 -0
  307. package/dist/types/index.d.ts.map +1 -0
  308. package/dist/types/index.js +3 -0
  309. package/dist/types/index.js.map +1 -0
  310. package/dist/types/n8n-api.d.ts +241 -0
  311. package/dist/types/n8n-api.d.ts.map +1 -0
  312. package/dist/types/n8n-api.js +10 -0
  313. package/dist/types/n8n-api.js.map +1 -0
  314. package/dist/types/workflow-diff.d.ts +113 -0
  315. package/dist/types/workflow-diff.d.ts.map +1 -0
  316. package/dist/types/workflow-diff.js +15 -0
  317. package/dist/types/workflow-diff.js.map +1 -0
  318. package/dist/utils/auth.d.ts +12 -0
  319. package/dist/utils/auth.d.ts.map +1 -0
  320. package/dist/utils/auth.js +66 -0
  321. package/dist/utils/auth.js.map +1 -0
  322. package/dist/utils/bridge.d.ts +12 -0
  323. package/dist/utils/bridge.d.ts.map +1 -0
  324. package/dist/utils/bridge.js +127 -0
  325. package/dist/utils/bridge.js.map +1 -0
  326. package/dist/utils/console-manager.d.ts +10 -0
  327. package/dist/utils/console-manager.d.ts.map +1 -0
  328. package/dist/utils/console-manager.js +63 -0
  329. package/dist/utils/console-manager.js.map +1 -0
  330. package/dist/utils/documentation-fetcher.d.ts +2 -0
  331. package/dist/utils/documentation-fetcher.d.ts.map +1 -0
  332. package/dist/utils/documentation-fetcher.js +18 -0
  333. package/dist/utils/documentation-fetcher.js.map +1 -0
  334. package/dist/utils/enhanced-documentation-fetcher.d.ts +73 -0
  335. package/dist/utils/enhanced-documentation-fetcher.d.ts.map +1 -0
  336. package/dist/utils/enhanced-documentation-fetcher.js +397 -0
  337. package/dist/utils/enhanced-documentation-fetcher.js.map +1 -0
  338. package/dist/utils/error-handler.d.ts +24 -0
  339. package/dist/utils/error-handler.d.ts.map +1 -0
  340. package/dist/utils/error-handler.js +84 -0
  341. package/dist/utils/error-handler.js.map +1 -0
  342. package/dist/utils/example-generator.d.ts +8 -0
  343. package/dist/utils/example-generator.d.ts.map +1 -0
  344. package/dist/utils/example-generator.js +106 -0
  345. package/dist/utils/example-generator.js.map +1 -0
  346. package/dist/utils/logger.d.ts +32 -0
  347. package/dist/utils/logger.d.ts.map +1 -0
  348. package/dist/utils/logger.js +97 -0
  349. package/dist/utils/logger.js.map +1 -0
  350. package/dist/utils/mcp-client.d.ts +21 -0
  351. package/dist/utils/mcp-client.d.ts.map +1 -0
  352. package/dist/utils/mcp-client.js +96 -0
  353. package/dist/utils/mcp-client.js.map +1 -0
  354. package/dist/utils/n8n-errors.d.ts +25 -0
  355. package/dist/utils/n8n-errors.d.ts.map +1 -0
  356. package/dist/utils/n8n-errors.js +129 -0
  357. package/dist/utils/n8n-errors.js.map +1 -0
  358. package/dist/utils/node-source-extractor.d.ts +21 -0
  359. package/dist/utils/node-source-extractor.d.ts.map +1 -0
  360. package/dist/utils/node-source-extractor.js +377 -0
  361. package/dist/utils/node-source-extractor.js.map +1 -0
  362. package/dist/utils/simple-cache.d.ts +8 -0
  363. package/dist/utils/simple-cache.d.ts.map +1 -0
  364. package/dist/utils/simple-cache.js +34 -0
  365. package/dist/utils/simple-cache.js.map +1 -0
  366. package/dist/utils/template-sanitizer.d.ts +21 -0
  367. package/dist/utils/template-sanitizer.d.ts.map +1 -0
  368. package/dist/utils/template-sanitizer.js +108 -0
  369. package/dist/utils/template-sanitizer.js.map +1 -0
  370. package/dist/utils/version.d.ts +2 -0
  371. package/dist/utils/version.d.ts.map +1 -0
  372. package/dist/utils/version.js +18 -0
  373. package/dist/utils/version.js.map +1 -0
  374. package/package.json +100 -0
  375. package/package.runtime.json +19 -0
@@ -0,0 +1,1258 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.N8NDocumentationMCPServer = void 0;
40
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
41
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
42
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
43
+ const fs_1 = require("fs");
44
+ const path_1 = __importDefault(require("path"));
45
+ const tools_1 = require("./tools");
46
+ const tools_n8n_manager_1 = require("./tools-n8n-manager");
47
+ const logger_1 = require("../utils/logger");
48
+ const node_repository_1 = require("../database/node-repository");
49
+ const database_adapter_1 = require("../database/database-adapter");
50
+ const property_filter_1 = require("../services/property-filter");
51
+ const example_generator_1 = require("../services/example-generator");
52
+ const task_templates_1 = require("../services/task-templates");
53
+ const enhanced_config_validator_1 = require("../services/enhanced-config-validator");
54
+ const property_dependencies_1 = require("../services/property-dependencies");
55
+ const simple_cache_1 = require("../utils/simple-cache");
56
+ const template_service_1 = require("../templates/template-service");
57
+ const workflow_validator_1 = require("../services/workflow-validator");
58
+ const n8n_api_1 = require("../config/n8n-api");
59
+ const n8nHandlers = __importStar(require("./handlers-n8n-manager"));
60
+ const handlers_workflow_diff_1 = require("./handlers-workflow-diff");
61
+ const tools_documentation_1 = require("./tools-documentation");
62
+ const version_1 = require("../utils/version");
63
+ class N8NDocumentationMCPServer {
64
+ constructor() {
65
+ this.db = null;
66
+ this.repository = null;
67
+ this.templateService = null;
68
+ this.cache = new simple_cache_1.SimpleCache();
69
+ const possiblePaths = [
70
+ path_1.default.join(process.cwd(), 'data', 'nodes.db'),
71
+ path_1.default.join(__dirname, '../../data', 'nodes.db'),
72
+ './data/nodes.db'
73
+ ];
74
+ let dbPath = null;
75
+ for (const p of possiblePaths) {
76
+ if ((0, fs_1.existsSync)(p)) {
77
+ dbPath = p;
78
+ break;
79
+ }
80
+ }
81
+ if (!dbPath) {
82
+ logger_1.logger.error('Database not found in any of the expected locations:', possiblePaths);
83
+ throw new Error('Database nodes.db not found. Please run npm run rebuild first.');
84
+ }
85
+ this.initialized = this.initializeDatabase(dbPath);
86
+ logger_1.logger.info('Initializing n8n Documentation MCP server');
87
+ const apiConfigured = (0, n8n_api_1.isN8nApiConfigured)();
88
+ const totalTools = apiConfigured ?
89
+ tools_1.n8nDocumentationToolsFinal.length + tools_n8n_manager_1.n8nManagementTools.length :
90
+ tools_1.n8nDocumentationToolsFinal.length;
91
+ logger_1.logger.info(`MCP server initialized with ${totalTools} tools (n8n API: ${apiConfigured ? 'configured' : 'not configured'})`);
92
+ this.server = new index_js_1.Server({
93
+ name: 'n8n-documentation-mcp',
94
+ version: '1.0.0',
95
+ }, {
96
+ capabilities: {
97
+ tools: {},
98
+ },
99
+ });
100
+ this.setupHandlers();
101
+ }
102
+ async initializeDatabase(dbPath) {
103
+ try {
104
+ this.db = await (0, database_adapter_1.createDatabaseAdapter)(dbPath);
105
+ this.repository = new node_repository_1.NodeRepository(this.db);
106
+ this.templateService = new template_service_1.TemplateService(this.db);
107
+ logger_1.logger.info(`Initialized database from: ${dbPath}`);
108
+ }
109
+ catch (error) {
110
+ logger_1.logger.error('Failed to initialize database:', error);
111
+ throw new Error(`Failed to open database: ${error instanceof Error ? error.message : 'Unknown error'}`);
112
+ }
113
+ }
114
+ async ensureInitialized() {
115
+ await this.initialized;
116
+ if (!this.db || !this.repository) {
117
+ throw new Error('Database not initialized');
118
+ }
119
+ }
120
+ setupHandlers() {
121
+ this.server.setRequestHandler(types_js_1.InitializeRequestSchema, async () => {
122
+ const response = {
123
+ protocolVersion: '2024-11-05',
124
+ capabilities: {
125
+ tools: {},
126
+ },
127
+ serverInfo: {
128
+ name: 'n8n-documentation-mcp',
129
+ version: version_1.PROJECT_VERSION,
130
+ },
131
+ };
132
+ if (process.env.DEBUG_MCP === 'true') {
133
+ logger_1.logger.debug('Initialize handler called', { response });
134
+ }
135
+ return response;
136
+ });
137
+ this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
138
+ const tools = [...tools_1.n8nDocumentationToolsFinal];
139
+ const isConfigured = (0, n8n_api_1.isN8nApiConfigured)();
140
+ if (isConfigured) {
141
+ tools.push(...tools_n8n_manager_1.n8nManagementTools);
142
+ logger_1.logger.debug(`Tool listing: ${tools.length} tools available (${tools_1.n8nDocumentationToolsFinal.length} documentation + ${tools_n8n_manager_1.n8nManagementTools.length} management)`);
143
+ }
144
+ else {
145
+ logger_1.logger.debug(`Tool listing: ${tools.length} tools available (documentation only)`);
146
+ }
147
+ return { tools };
148
+ });
149
+ this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
150
+ const { name, arguments: args } = request.params;
151
+ try {
152
+ logger_1.logger.debug(`Executing tool: ${name}`, { args });
153
+ const result = await this.executeTool(name, args);
154
+ logger_1.logger.debug(`Tool ${name} executed successfully`);
155
+ return {
156
+ content: [
157
+ {
158
+ type: 'text',
159
+ text: JSON.stringify(result, null, 2),
160
+ },
161
+ ],
162
+ };
163
+ }
164
+ catch (error) {
165
+ logger_1.logger.error(`Error executing tool ${name}`, error);
166
+ return {
167
+ content: [
168
+ {
169
+ type: 'text',
170
+ text: `Error executing tool ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`,
171
+ },
172
+ ],
173
+ isError: true,
174
+ };
175
+ }
176
+ });
177
+ }
178
+ async executeTool(name, args) {
179
+ switch (name) {
180
+ case 'tools_documentation':
181
+ return this.getToolsDocumentation(args.topic, args.depth);
182
+ case 'list_nodes':
183
+ return this.listNodes(args);
184
+ case 'get_node_info':
185
+ return this.getNodeInfo(args.nodeType);
186
+ case 'search_nodes':
187
+ return this.searchNodes(args.query, args.limit);
188
+ case 'list_ai_tools':
189
+ return this.listAITools();
190
+ case 'get_node_documentation':
191
+ return this.getNodeDocumentation(args.nodeType);
192
+ case 'get_database_statistics':
193
+ return this.getDatabaseStatistics();
194
+ case 'get_node_essentials':
195
+ return this.getNodeEssentials(args.nodeType);
196
+ case 'search_node_properties':
197
+ return this.searchNodeProperties(args.nodeType, args.query, args.maxResults);
198
+ case 'get_node_for_task':
199
+ return this.getNodeForTask(args.task);
200
+ case 'list_tasks':
201
+ return this.listTasks(args.category);
202
+ case 'validate_node_operation':
203
+ return this.validateNodeConfig(args.nodeType, args.config, 'operation', args.profile);
204
+ case 'validate_node_minimal':
205
+ return this.validateNodeMinimal(args.nodeType, args.config);
206
+ case 'get_property_dependencies':
207
+ return this.getPropertyDependencies(args.nodeType, args.config);
208
+ case 'get_node_as_tool_info':
209
+ return this.getNodeAsToolInfo(args.nodeType);
210
+ case 'list_node_templates':
211
+ return this.listNodeTemplates(args.nodeTypes, args.limit);
212
+ case 'get_template':
213
+ return this.getTemplate(args.templateId);
214
+ case 'search_templates':
215
+ return this.searchTemplates(args.query, args.limit);
216
+ case 'get_templates_for_task':
217
+ return this.getTemplatesForTask(args.task);
218
+ case 'validate_workflow':
219
+ return this.validateWorkflow(args.workflow, args.options);
220
+ case 'validate_workflow_connections':
221
+ return this.validateWorkflowConnections(args.workflow);
222
+ case 'validate_workflow_expressions':
223
+ return this.validateWorkflowExpressions(args.workflow);
224
+ case 'n8n_create_workflow':
225
+ return n8nHandlers.handleCreateWorkflow(args);
226
+ case 'n8n_get_workflow':
227
+ return n8nHandlers.handleGetWorkflow(args);
228
+ case 'n8n_get_workflow_details':
229
+ return n8nHandlers.handleGetWorkflowDetails(args);
230
+ case 'n8n_get_workflow_structure':
231
+ return n8nHandlers.handleGetWorkflowStructure(args);
232
+ case 'n8n_get_workflow_minimal':
233
+ return n8nHandlers.handleGetWorkflowMinimal(args);
234
+ case 'n8n_update_full_workflow':
235
+ return n8nHandlers.handleUpdateWorkflow(args);
236
+ case 'n8n_update_partial_workflow':
237
+ return (0, handlers_workflow_diff_1.handleUpdatePartialWorkflow)(args);
238
+ case 'n8n_delete_workflow':
239
+ return n8nHandlers.handleDeleteWorkflow(args);
240
+ case 'n8n_list_workflows':
241
+ return n8nHandlers.handleListWorkflows(args);
242
+ case 'n8n_validate_workflow':
243
+ await this.ensureInitialized();
244
+ if (!this.repository)
245
+ throw new Error('Repository not initialized');
246
+ return n8nHandlers.handleValidateWorkflow(args, this.repository);
247
+ case 'n8n_trigger_webhook_workflow':
248
+ return n8nHandlers.handleTriggerWebhookWorkflow(args);
249
+ case 'n8n_get_execution':
250
+ return n8nHandlers.handleGetExecution(args);
251
+ case 'n8n_list_executions':
252
+ return n8nHandlers.handleListExecutions(args);
253
+ case 'n8n_delete_execution':
254
+ return n8nHandlers.handleDeleteExecution(args);
255
+ case 'n8n_health_check':
256
+ return n8nHandlers.handleHealthCheck();
257
+ case 'n8n_list_available_tools':
258
+ return n8nHandlers.handleListAvailableTools();
259
+ case 'n8n_diagnostic':
260
+ return n8nHandlers.handleDiagnostic({ params: { arguments: args } });
261
+ default:
262
+ throw new Error(`Unknown tool: ${name}`);
263
+ }
264
+ }
265
+ async listNodes(filters = {}) {
266
+ await this.ensureInitialized();
267
+ let query = 'SELECT * FROM nodes WHERE 1=1';
268
+ const params = [];
269
+ if (filters.package) {
270
+ const packageVariants = [
271
+ filters.package,
272
+ `@n8n/${filters.package}`,
273
+ filters.package.replace('@n8n/', '')
274
+ ];
275
+ query += ' AND package_name IN (' + packageVariants.map(() => '?').join(',') + ')';
276
+ params.push(...packageVariants);
277
+ }
278
+ if (filters.category) {
279
+ query += ' AND category = ?';
280
+ params.push(filters.category);
281
+ }
282
+ if (filters.developmentStyle) {
283
+ query += ' AND development_style = ?';
284
+ params.push(filters.developmentStyle);
285
+ }
286
+ if (filters.isAITool !== undefined) {
287
+ query += ' AND is_ai_tool = ?';
288
+ params.push(filters.isAITool ? 1 : 0);
289
+ }
290
+ query += ' ORDER BY display_name';
291
+ if (filters.limit) {
292
+ query += ' LIMIT ?';
293
+ params.push(filters.limit);
294
+ }
295
+ const nodes = this.db.prepare(query).all(...params);
296
+ return {
297
+ nodes: nodes.map(node => ({
298
+ nodeType: node.node_type,
299
+ displayName: node.display_name,
300
+ description: node.description,
301
+ category: node.category,
302
+ package: node.package_name,
303
+ developmentStyle: node.development_style,
304
+ isAITool: Number(node.is_ai_tool) === 1,
305
+ isTrigger: Number(node.is_trigger) === 1,
306
+ isVersioned: Number(node.is_versioned) === 1,
307
+ })),
308
+ totalCount: nodes.length,
309
+ };
310
+ }
311
+ async getNodeInfo(nodeType) {
312
+ await this.ensureInitialized();
313
+ if (!this.repository)
314
+ throw new Error('Repository not initialized');
315
+ let node = this.repository.getNode(nodeType);
316
+ if (!node) {
317
+ const alternatives = [
318
+ nodeType,
319
+ nodeType.replace('n8n-nodes-base.', ''),
320
+ `n8n-nodes-base.${nodeType}`,
321
+ nodeType.toLowerCase()
322
+ ];
323
+ for (const alt of alternatives) {
324
+ const found = this.repository.getNode(alt);
325
+ if (found) {
326
+ node = found;
327
+ break;
328
+ }
329
+ }
330
+ if (!node) {
331
+ throw new Error(`Node ${nodeType} not found`);
332
+ }
333
+ }
334
+ const aiToolCapabilities = {
335
+ canBeUsedAsTool: true,
336
+ hasUsableAsToolProperty: node.isAITool,
337
+ requiresEnvironmentVariable: !node.isAITool && node.package !== 'n8n-nodes-base',
338
+ toolConnectionType: 'ai_tool',
339
+ commonToolUseCases: this.getCommonAIToolUseCases(node.nodeType),
340
+ environmentRequirement: node.package !== 'n8n-nodes-base' ?
341
+ 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true' :
342
+ null
343
+ };
344
+ return {
345
+ ...node,
346
+ aiToolCapabilities
347
+ };
348
+ }
349
+ async searchNodes(query, limit = 20) {
350
+ await this.ensureInitialized();
351
+ if (!this.db)
352
+ throw new Error('Database not initialized');
353
+ if (query.startsWith('"') && query.endsWith('"')) {
354
+ const exactPhrase = query.slice(1, -1);
355
+ const nodes = this.db.prepare(`
356
+ SELECT * FROM nodes
357
+ WHERE node_type LIKE ? OR display_name LIKE ? OR description LIKE ?
358
+ ORDER BY display_name
359
+ LIMIT ?
360
+ `).all(`%${exactPhrase}%`, `%${exactPhrase}%`, `%${exactPhrase}%`, limit);
361
+ return {
362
+ query,
363
+ results: nodes.map(node => ({
364
+ nodeType: node.node_type,
365
+ displayName: node.display_name,
366
+ description: node.description,
367
+ category: node.category,
368
+ package: node.package_name
369
+ })),
370
+ totalCount: nodes.length
371
+ };
372
+ }
373
+ const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0);
374
+ if (words.length === 0) {
375
+ return { query, results: [], totalCount: 0 };
376
+ }
377
+ const conditions = words.map(() => '(node_type LIKE ? OR display_name LIKE ? OR description LIKE ?)').join(' OR ');
378
+ const params = words.flatMap(w => [`%${w}%`, `%${w}%`, `%${w}%`]);
379
+ params.push(limit);
380
+ const nodes = this.db.prepare(`
381
+ SELECT DISTINCT * FROM nodes
382
+ WHERE ${conditions}
383
+ ORDER BY display_name
384
+ LIMIT ?
385
+ `).all(...params);
386
+ return {
387
+ query,
388
+ results: nodes.map(node => ({
389
+ nodeType: node.node_type,
390
+ displayName: node.display_name,
391
+ description: node.description,
392
+ category: node.category,
393
+ package: node.package_name
394
+ })),
395
+ totalCount: nodes.length
396
+ };
397
+ }
398
+ calculateRelevance(node, query) {
399
+ const lowerQuery = query.toLowerCase();
400
+ if (node.node_type.toLowerCase().includes(lowerQuery))
401
+ return 'high';
402
+ if (node.display_name.toLowerCase().includes(lowerQuery))
403
+ return 'high';
404
+ if (node.description?.toLowerCase().includes(lowerQuery))
405
+ return 'medium';
406
+ return 'low';
407
+ }
408
+ async listAITools() {
409
+ await this.ensureInitialized();
410
+ if (!this.repository)
411
+ throw new Error('Repository not initialized');
412
+ const tools = this.repository.getAITools();
413
+ const aiCount = this.db.prepare('SELECT COUNT(*) as ai_count FROM nodes WHERE is_ai_tool = 1').get();
414
+ return {
415
+ tools,
416
+ totalCount: tools.length,
417
+ requirements: {
418
+ environmentVariable: 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true',
419
+ nodeProperty: 'usableAsTool: true',
420
+ },
421
+ usage: {
422
+ description: 'These nodes have the usableAsTool property set to true, making them optimized for AI agent usage.',
423
+ note: 'ANY node in n8n can be used as an AI tool by connecting it to the ai_tool port of an AI Agent node.',
424
+ examples: [
425
+ 'Regular nodes like Slack, Google Sheets, or HTTP Request can be used as tools',
426
+ 'Connect any node to an AI Agent\'s tool port to make it available for AI-driven automation',
427
+ 'Community nodes require the environment variable to be set'
428
+ ]
429
+ }
430
+ };
431
+ }
432
+ async getNodeDocumentation(nodeType) {
433
+ await this.ensureInitialized();
434
+ if (!this.db)
435
+ throw new Error('Database not initialized');
436
+ const node = this.db.prepare(`
437
+ SELECT node_type, display_name, documentation, description
438
+ FROM nodes
439
+ WHERE node_type = ?
440
+ `).get(nodeType);
441
+ if (!node) {
442
+ throw new Error(`Node ${nodeType} not found`);
443
+ }
444
+ if (!node.documentation) {
445
+ const essentials = await this.getNodeEssentials(nodeType);
446
+ return {
447
+ nodeType: node.node_type,
448
+ displayName: node.display_name,
449
+ documentation: `
450
+ # ${node.display_name}
451
+
452
+ ${node.description || 'No description available.'}
453
+
454
+ ## Common Properties
455
+
456
+ ${essentials.commonProperties.map((p) => `### ${p.displayName}\n${p.description || `Type: ${p.type}`}`).join('\n\n')}
457
+
458
+ ## Note
459
+ Full documentation is being prepared. For now, use get_node_essentials for configuration help.
460
+ `,
461
+ hasDocumentation: false
462
+ };
463
+ }
464
+ return {
465
+ nodeType: node.node_type,
466
+ displayName: node.display_name,
467
+ documentation: node.documentation,
468
+ hasDocumentation: true,
469
+ };
470
+ }
471
+ async getDatabaseStatistics() {
472
+ await this.ensureInitialized();
473
+ if (!this.db)
474
+ throw new Error('Database not initialized');
475
+ const stats = this.db.prepare(`
476
+ SELECT
477
+ COUNT(*) as total,
478
+ SUM(is_ai_tool) as ai_tools,
479
+ SUM(is_trigger) as triggers,
480
+ SUM(is_versioned) as versioned,
481
+ SUM(CASE WHEN documentation IS NOT NULL THEN 1 ELSE 0 END) as with_docs,
482
+ COUNT(DISTINCT package_name) as packages,
483
+ COUNT(DISTINCT category) as categories
484
+ FROM nodes
485
+ `).get();
486
+ const packages = this.db.prepare(`
487
+ SELECT package_name, COUNT(*) as count
488
+ FROM nodes
489
+ GROUP BY package_name
490
+ `).all();
491
+ return {
492
+ totalNodes: stats.total,
493
+ statistics: {
494
+ aiTools: stats.ai_tools,
495
+ triggers: stats.triggers,
496
+ versionedNodes: stats.versioned,
497
+ nodesWithDocumentation: stats.with_docs,
498
+ documentationCoverage: Math.round((stats.with_docs / stats.total) * 100) + '%',
499
+ uniquePackages: stats.packages,
500
+ uniqueCategories: stats.categories,
501
+ },
502
+ packageBreakdown: packages.map(pkg => ({
503
+ package: pkg.package_name,
504
+ nodeCount: pkg.count,
505
+ })),
506
+ };
507
+ }
508
+ async getNodeEssentials(nodeType) {
509
+ await this.ensureInitialized();
510
+ if (!this.repository)
511
+ throw new Error('Repository not initialized');
512
+ const cacheKey = `essentials:${nodeType}`;
513
+ const cached = this.cache.get(cacheKey);
514
+ if (cached)
515
+ return cached;
516
+ let node = this.repository.getNode(nodeType);
517
+ if (!node) {
518
+ const alternatives = [
519
+ nodeType,
520
+ nodeType.replace('n8n-nodes-base.', ''),
521
+ `n8n-nodes-base.${nodeType}`,
522
+ nodeType.toLowerCase()
523
+ ];
524
+ for (const alt of alternatives) {
525
+ const found = this.repository.getNode(alt);
526
+ if (found) {
527
+ node = found;
528
+ break;
529
+ }
530
+ }
531
+ if (!node) {
532
+ throw new Error(`Node ${nodeType} not found`);
533
+ }
534
+ }
535
+ const allProperties = node.properties || [];
536
+ const essentials = property_filter_1.PropertyFilter.getEssentials(allProperties, node.nodeType);
537
+ const examples = example_generator_1.ExampleGenerator.getExamples(node.nodeType, essentials);
538
+ const operations = node.operations || [];
539
+ const result = {
540
+ nodeType: node.nodeType,
541
+ displayName: node.displayName,
542
+ description: node.description,
543
+ category: node.category,
544
+ version: node.version || '1',
545
+ isVersioned: node.isVersioned || false,
546
+ requiredProperties: essentials.required,
547
+ commonProperties: essentials.common,
548
+ operations: operations.map((op) => ({
549
+ name: op.name || op.operation,
550
+ description: op.description,
551
+ action: op.action,
552
+ resource: op.resource
553
+ })),
554
+ examples,
555
+ metadata: {
556
+ totalProperties: allProperties.length,
557
+ isAITool: node.isAITool,
558
+ isTrigger: node.isTrigger,
559
+ isWebhook: node.isWebhook,
560
+ hasCredentials: node.credentials ? true : false,
561
+ package: node.package,
562
+ developmentStyle: node.developmentStyle || 'programmatic'
563
+ }
564
+ };
565
+ this.cache.set(cacheKey, result, 3600);
566
+ return result;
567
+ }
568
+ async searchNodeProperties(nodeType, query, maxResults = 20) {
569
+ await this.ensureInitialized();
570
+ if (!this.repository)
571
+ throw new Error('Repository not initialized');
572
+ let node = this.repository.getNode(nodeType);
573
+ if (!node) {
574
+ const alternatives = [
575
+ nodeType,
576
+ nodeType.replace('n8n-nodes-base.', ''),
577
+ `n8n-nodes-base.${nodeType}`,
578
+ nodeType.toLowerCase()
579
+ ];
580
+ for (const alt of alternatives) {
581
+ const found = this.repository.getNode(alt);
582
+ if (found) {
583
+ node = found;
584
+ break;
585
+ }
586
+ }
587
+ if (!node) {
588
+ throw new Error(`Node ${nodeType} not found`);
589
+ }
590
+ }
591
+ const allProperties = node.properties || [];
592
+ const matches = property_filter_1.PropertyFilter.searchProperties(allProperties, query, maxResults);
593
+ return {
594
+ nodeType: node.nodeType,
595
+ query,
596
+ matches: matches.map((match) => ({
597
+ name: match.name,
598
+ displayName: match.displayName,
599
+ type: match.type,
600
+ description: match.description,
601
+ path: match.path || match.name,
602
+ required: match.required,
603
+ default: match.default,
604
+ options: match.options,
605
+ showWhen: match.showWhen
606
+ })),
607
+ totalMatches: matches.length,
608
+ searchedIn: allProperties.length + ' properties'
609
+ };
610
+ }
611
+ async getNodeForTask(task) {
612
+ const template = task_templates_1.TaskTemplates.getTaskTemplate(task);
613
+ if (!template) {
614
+ const similar = task_templates_1.TaskTemplates.searchTasks(task);
615
+ throw new Error(`Unknown task: ${task}. ` +
616
+ (similar.length > 0
617
+ ? `Did you mean: ${similar.slice(0, 3).join(', ')}?`
618
+ : `Use 'list_tasks' to see available tasks.`));
619
+ }
620
+ return {
621
+ task: template.task,
622
+ description: template.description,
623
+ nodeType: template.nodeType,
624
+ configuration: template.configuration,
625
+ userMustProvide: template.userMustProvide,
626
+ optionalEnhancements: template.optionalEnhancements || [],
627
+ notes: template.notes || [],
628
+ example: {
629
+ node: {
630
+ type: template.nodeType,
631
+ parameters: template.configuration
632
+ },
633
+ userInputsNeeded: template.userMustProvide.map(p => ({
634
+ property: p.property,
635
+ currentValue: this.getPropertyValue(template.configuration, p.property),
636
+ description: p.description,
637
+ example: p.example
638
+ }))
639
+ }
640
+ };
641
+ }
642
+ getPropertyValue(config, path) {
643
+ const parts = path.split('.');
644
+ let value = config;
645
+ for (const part of parts) {
646
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
647
+ if (arrayMatch) {
648
+ value = value?.[arrayMatch[1]]?.[parseInt(arrayMatch[2])];
649
+ }
650
+ else {
651
+ value = value?.[part];
652
+ }
653
+ }
654
+ return value;
655
+ }
656
+ async listTasks(category) {
657
+ if (category) {
658
+ const categories = task_templates_1.TaskTemplates.getTaskCategories();
659
+ const tasks = categories[category];
660
+ if (!tasks) {
661
+ throw new Error(`Unknown category: ${category}. Available categories: ${Object.keys(categories).join(', ')}`);
662
+ }
663
+ return {
664
+ category,
665
+ tasks: tasks.map(task => {
666
+ const template = task_templates_1.TaskTemplates.getTaskTemplate(task);
667
+ return {
668
+ task,
669
+ description: template?.description || '',
670
+ nodeType: template?.nodeType || ''
671
+ };
672
+ })
673
+ };
674
+ }
675
+ const categories = task_templates_1.TaskTemplates.getTaskCategories();
676
+ const result = {
677
+ totalTasks: task_templates_1.TaskTemplates.getAllTasks().length,
678
+ categories: {}
679
+ };
680
+ for (const [cat, tasks] of Object.entries(categories)) {
681
+ result.categories[cat] = tasks.map(task => {
682
+ const template = task_templates_1.TaskTemplates.getTaskTemplate(task);
683
+ return {
684
+ task,
685
+ description: template?.description || '',
686
+ nodeType: template?.nodeType || ''
687
+ };
688
+ });
689
+ }
690
+ return result;
691
+ }
692
+ async validateNodeConfig(nodeType, config, mode = 'operation', profile = 'ai-friendly') {
693
+ await this.ensureInitialized();
694
+ if (!this.repository)
695
+ throw new Error('Repository not initialized');
696
+ let node = this.repository.getNode(nodeType);
697
+ if (!node) {
698
+ const alternatives = [
699
+ nodeType,
700
+ nodeType.replace('n8n-nodes-base.', ''),
701
+ `n8n-nodes-base.${nodeType}`,
702
+ nodeType.toLowerCase()
703
+ ];
704
+ for (const alt of alternatives) {
705
+ const found = this.repository.getNode(alt);
706
+ if (found) {
707
+ node = found;
708
+ break;
709
+ }
710
+ }
711
+ if (!node) {
712
+ throw new Error(`Node ${nodeType} not found`);
713
+ }
714
+ }
715
+ const properties = node.properties || [];
716
+ const validationResult = enhanced_config_validator_1.EnhancedConfigValidator.validateWithMode(node.nodeType, config, properties, mode, profile);
717
+ return {
718
+ nodeType: node.nodeType,
719
+ displayName: node.displayName,
720
+ ...validationResult,
721
+ summary: {
722
+ hasErrors: !validationResult.valid,
723
+ errorCount: validationResult.errors.length,
724
+ warningCount: validationResult.warnings.length,
725
+ suggestionCount: validationResult.suggestions.length
726
+ }
727
+ };
728
+ }
729
+ async getPropertyDependencies(nodeType, config) {
730
+ await this.ensureInitialized();
731
+ if (!this.repository)
732
+ throw new Error('Repository not initialized');
733
+ let node = this.repository.getNode(nodeType);
734
+ if (!node) {
735
+ const alternatives = [
736
+ nodeType,
737
+ nodeType.replace('n8n-nodes-base.', ''),
738
+ `n8n-nodes-base.${nodeType}`,
739
+ nodeType.toLowerCase()
740
+ ];
741
+ for (const alt of alternatives) {
742
+ const found = this.repository.getNode(alt);
743
+ if (found) {
744
+ node = found;
745
+ break;
746
+ }
747
+ }
748
+ if (!node) {
749
+ throw new Error(`Node ${nodeType} not found`);
750
+ }
751
+ }
752
+ const properties = node.properties || [];
753
+ const analysis = property_dependencies_1.PropertyDependencies.analyze(properties);
754
+ let visibilityImpact = null;
755
+ if (config) {
756
+ visibilityImpact = property_dependencies_1.PropertyDependencies.getVisibilityImpact(properties, config);
757
+ }
758
+ return {
759
+ nodeType: node.nodeType,
760
+ displayName: node.displayName,
761
+ ...analysis,
762
+ currentConfig: config ? {
763
+ providedValues: config,
764
+ visibilityImpact
765
+ } : undefined
766
+ };
767
+ }
768
+ async getNodeAsToolInfo(nodeType) {
769
+ await this.ensureInitialized();
770
+ if (!this.repository)
771
+ throw new Error('Repository not initialized');
772
+ let node = this.repository.getNode(nodeType);
773
+ if (!node) {
774
+ const alternatives = [
775
+ nodeType,
776
+ nodeType.replace('n8n-nodes-base.', ''),
777
+ `n8n-nodes-base.${nodeType}`,
778
+ nodeType.toLowerCase()
779
+ ];
780
+ for (const alt of alternatives) {
781
+ const found = this.repository.getNode(alt);
782
+ if (found) {
783
+ node = found;
784
+ break;
785
+ }
786
+ }
787
+ if (!node) {
788
+ throw new Error(`Node ${nodeType} not found`);
789
+ }
790
+ }
791
+ const commonUseCases = this.getCommonAIToolUseCases(node.nodeType);
792
+ const aiToolCapabilities = {
793
+ canBeUsedAsTool: true,
794
+ hasUsableAsToolProperty: node.isAITool,
795
+ requiresEnvironmentVariable: !node.isAITool && node.package !== 'n8n-nodes-base',
796
+ connectionType: 'ai_tool',
797
+ commonUseCases,
798
+ requirements: {
799
+ connection: 'Connect to the "ai_tool" port of an AI Agent node',
800
+ environment: node.package !== 'n8n-nodes-base' ?
801
+ 'Set N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true for community nodes' :
802
+ 'No special environment variables needed for built-in nodes'
803
+ },
804
+ examples: this.getAIToolExamples(node.nodeType),
805
+ tips: [
806
+ 'Give the tool a clear, descriptive name in the AI Agent settings',
807
+ 'Write a detailed tool description to help the AI understand when to use it',
808
+ 'Test the node independently before connecting it as a tool',
809
+ node.isAITool ?
810
+ 'This node is optimized for AI tool usage' :
811
+ 'This is a regular node that can be used as an AI tool'
812
+ ]
813
+ };
814
+ return {
815
+ nodeType: node.nodeType,
816
+ displayName: node.displayName,
817
+ description: node.description,
818
+ package: node.package,
819
+ isMarkedAsAITool: node.isAITool,
820
+ aiToolCapabilities
821
+ };
822
+ }
823
+ getCommonAIToolUseCases(nodeType) {
824
+ const useCaseMap = {
825
+ 'nodes-base.slack': [
826
+ 'Send notifications about task completion',
827
+ 'Post updates to channels',
828
+ 'Send direct messages',
829
+ 'Create alerts and reminders'
830
+ ],
831
+ 'nodes-base.googleSheets': [
832
+ 'Read data for analysis',
833
+ 'Log results and outputs',
834
+ 'Update spreadsheet records',
835
+ 'Create reports'
836
+ ],
837
+ 'nodes-base.gmail': [
838
+ 'Send email notifications',
839
+ 'Read and process emails',
840
+ 'Send reports and summaries',
841
+ 'Handle email-based workflows'
842
+ ],
843
+ 'nodes-base.httpRequest': [
844
+ 'Call external APIs',
845
+ 'Fetch data from web services',
846
+ 'Send webhooks',
847
+ 'Integrate with any REST API'
848
+ ],
849
+ 'nodes-base.postgres': [
850
+ 'Query database for information',
851
+ 'Store analysis results',
852
+ 'Update records based on AI decisions',
853
+ 'Generate reports from data'
854
+ ],
855
+ 'nodes-base.webhook': [
856
+ 'Receive external triggers',
857
+ 'Create callback endpoints',
858
+ 'Handle incoming data',
859
+ 'Integrate with external systems'
860
+ ]
861
+ };
862
+ for (const [key, useCases] of Object.entries(useCaseMap)) {
863
+ if (nodeType.includes(key)) {
864
+ return useCases;
865
+ }
866
+ }
867
+ return [
868
+ 'Perform automated actions',
869
+ 'Integrate with external services',
870
+ 'Process and transform data',
871
+ 'Extend AI agent capabilities'
872
+ ];
873
+ }
874
+ getAIToolExamples(nodeType) {
875
+ const exampleMap = {
876
+ 'nodes-base.slack': {
877
+ toolName: 'Send Slack Message',
878
+ toolDescription: 'Sends a message to a specified Slack channel or user. Use this to notify team members about important events or results.',
879
+ nodeConfig: {
880
+ resource: 'message',
881
+ operation: 'post',
882
+ channel: '={{ $fromAI("channel", "The Slack channel to send to, e.g. #general") }}',
883
+ text: '={{ $fromAI("message", "The message content to send") }}'
884
+ }
885
+ },
886
+ 'nodes-base.googleSheets': {
887
+ toolName: 'Update Google Sheet',
888
+ toolDescription: 'Reads or updates data in a Google Sheets spreadsheet. Use this to log information, retrieve data, or update records.',
889
+ nodeConfig: {
890
+ operation: 'append',
891
+ sheetId: 'your-sheet-id',
892
+ range: 'A:Z',
893
+ dataMode: 'autoMap'
894
+ }
895
+ },
896
+ 'nodes-base.httpRequest': {
897
+ toolName: 'Call API',
898
+ toolDescription: 'Makes HTTP requests to external APIs. Use this to fetch data, trigger webhooks, or integrate with any web service.',
899
+ nodeConfig: {
900
+ method: '={{ $fromAI("method", "HTTP method: GET, POST, PUT, DELETE") }}',
901
+ url: '={{ $fromAI("url", "The complete API endpoint URL") }}',
902
+ sendBody: true,
903
+ bodyContentType: 'json',
904
+ jsonBody: '={{ $fromAI("body", "Request body as JSON object") }}'
905
+ }
906
+ }
907
+ };
908
+ for (const [key, example] of Object.entries(exampleMap)) {
909
+ if (nodeType.includes(key)) {
910
+ return example;
911
+ }
912
+ }
913
+ return {
914
+ toolName: 'Custom Tool',
915
+ toolDescription: 'Performs specific operations. Describe what this tool does and when to use it.',
916
+ nodeConfig: {
917
+ note: 'Configure the node based on its specific requirements'
918
+ }
919
+ };
920
+ }
921
+ async validateNodeMinimal(nodeType, config) {
922
+ await this.ensureInitialized();
923
+ if (!this.repository)
924
+ throw new Error('Repository not initialized');
925
+ let node = this.repository.getNode(nodeType);
926
+ if (!node) {
927
+ const alternatives = [
928
+ nodeType,
929
+ nodeType.replace('n8n-nodes-base.', ''),
930
+ `n8n-nodes-base.${nodeType}`,
931
+ nodeType.toLowerCase()
932
+ ];
933
+ for (const alt of alternatives) {
934
+ const found = this.repository.getNode(alt);
935
+ if (found) {
936
+ node = found;
937
+ break;
938
+ }
939
+ }
940
+ if (!node) {
941
+ throw new Error(`Node ${nodeType} not found`);
942
+ }
943
+ }
944
+ const properties = node.properties || [];
945
+ const operationContext = {
946
+ resource: config.resource,
947
+ operation: config.operation,
948
+ action: config.action,
949
+ mode: config.mode
950
+ };
951
+ const missingFields = [];
952
+ for (const prop of properties) {
953
+ if (!prop.required)
954
+ continue;
955
+ if (prop.displayOptions) {
956
+ let isVisible = true;
957
+ if (prop.displayOptions.show) {
958
+ for (const [key, values] of Object.entries(prop.displayOptions.show)) {
959
+ const configValue = config[key];
960
+ const expectedValues = Array.isArray(values) ? values : [values];
961
+ if (!expectedValues.includes(configValue)) {
962
+ isVisible = false;
963
+ break;
964
+ }
965
+ }
966
+ }
967
+ if (isVisible && prop.displayOptions.hide) {
968
+ for (const [key, values] of Object.entries(prop.displayOptions.hide)) {
969
+ const configValue = config[key];
970
+ const expectedValues = Array.isArray(values) ? values : [values];
971
+ if (expectedValues.includes(configValue)) {
972
+ isVisible = false;
973
+ break;
974
+ }
975
+ }
976
+ }
977
+ if (!isVisible)
978
+ continue;
979
+ }
980
+ if (!(prop.name in config)) {
981
+ missingFields.push(prop.displayName || prop.name);
982
+ }
983
+ }
984
+ return {
985
+ nodeType: node.nodeType,
986
+ displayName: node.displayName,
987
+ valid: missingFields.length === 0,
988
+ missingRequiredFields: missingFields
989
+ };
990
+ }
991
+ async getToolsDocumentation(topic, depth = 'essentials') {
992
+ if (!topic || topic === 'overview') {
993
+ return (0, tools_documentation_1.getToolsOverview)(depth);
994
+ }
995
+ return (0, tools_documentation_1.getToolDocumentation)(topic, depth);
996
+ }
997
+ async connect(transport) {
998
+ await this.ensureInitialized();
999
+ await this.server.connect(transport);
1000
+ logger_1.logger.info('MCP Server connected', {
1001
+ transportType: transport.constructor.name
1002
+ });
1003
+ }
1004
+ async listNodeTemplates(nodeTypes, limit = 10) {
1005
+ await this.ensureInitialized();
1006
+ if (!this.templateService)
1007
+ throw new Error('Template service not initialized');
1008
+ const templates = await this.templateService.listNodeTemplates(nodeTypes, limit);
1009
+ if (templates.length === 0) {
1010
+ return {
1011
+ message: `No templates found using nodes: ${nodeTypes.join(', ')}`,
1012
+ tip: "Try searching with more common nodes or run 'npm run fetch:templates' to update template database",
1013
+ templates: []
1014
+ };
1015
+ }
1016
+ return {
1017
+ templates,
1018
+ count: templates.length,
1019
+ tip: `Use get_template(templateId) to get the full workflow JSON for any template`
1020
+ };
1021
+ }
1022
+ async getTemplate(templateId) {
1023
+ await this.ensureInitialized();
1024
+ if (!this.templateService)
1025
+ throw new Error('Template service not initialized');
1026
+ const template = await this.templateService.getTemplate(templateId);
1027
+ if (!template) {
1028
+ return {
1029
+ error: `Template ${templateId} not found`,
1030
+ tip: "Use list_node_templates or search_templates to find available templates"
1031
+ };
1032
+ }
1033
+ return {
1034
+ template,
1035
+ usage: "Import this workflow JSON directly into n8n or use it as a reference for building workflows"
1036
+ };
1037
+ }
1038
+ async searchTemplates(query, limit = 20) {
1039
+ await this.ensureInitialized();
1040
+ if (!this.templateService)
1041
+ throw new Error('Template service not initialized');
1042
+ const templates = await this.templateService.searchTemplates(query, limit);
1043
+ if (templates.length === 0) {
1044
+ return {
1045
+ message: `No templates found matching: "${query}"`,
1046
+ tip: "Try different keywords or run 'npm run fetch:templates' to update template database",
1047
+ templates: []
1048
+ };
1049
+ }
1050
+ return {
1051
+ templates,
1052
+ count: templates.length,
1053
+ query
1054
+ };
1055
+ }
1056
+ async getTemplatesForTask(task) {
1057
+ await this.ensureInitialized();
1058
+ if (!this.templateService)
1059
+ throw new Error('Template service not initialized');
1060
+ const templates = await this.templateService.getTemplatesForTask(task);
1061
+ const availableTasks = this.templateService.listAvailableTasks();
1062
+ if (templates.length === 0) {
1063
+ return {
1064
+ message: `No templates found for task: ${task}`,
1065
+ availableTasks,
1066
+ tip: "Try a different task or use search_templates for custom searches"
1067
+ };
1068
+ }
1069
+ return {
1070
+ task,
1071
+ templates,
1072
+ count: templates.length,
1073
+ description: this.getTaskDescription(task)
1074
+ };
1075
+ }
1076
+ getTaskDescription(task) {
1077
+ const descriptions = {
1078
+ 'ai_automation': 'AI-powered workflows using OpenAI, LangChain, and other AI tools',
1079
+ 'data_sync': 'Synchronize data between databases, spreadsheets, and APIs',
1080
+ 'webhook_processing': 'Process incoming webhooks and trigger automated actions',
1081
+ 'email_automation': 'Send, receive, and process emails automatically',
1082
+ 'slack_integration': 'Integrate with Slack for notifications and bot interactions',
1083
+ 'data_transformation': 'Transform, clean, and manipulate data',
1084
+ 'file_processing': 'Handle file uploads, downloads, and transformations',
1085
+ 'scheduling': 'Schedule recurring tasks and time-based automations',
1086
+ 'api_integration': 'Connect to external APIs and web services',
1087
+ 'database_operations': 'Query, insert, update, and manage database records'
1088
+ };
1089
+ return descriptions[task] || 'Workflow templates for this task';
1090
+ }
1091
+ async validateWorkflow(workflow, options) {
1092
+ await this.ensureInitialized();
1093
+ if (!this.repository)
1094
+ throw new Error('Repository not initialized');
1095
+ const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator);
1096
+ try {
1097
+ const result = await validator.validateWorkflow(workflow, options);
1098
+ const response = {
1099
+ valid: result.valid,
1100
+ summary: {
1101
+ totalNodes: result.statistics.totalNodes,
1102
+ enabledNodes: result.statistics.enabledNodes,
1103
+ triggerNodes: result.statistics.triggerNodes,
1104
+ validConnections: result.statistics.validConnections,
1105
+ invalidConnections: result.statistics.invalidConnections,
1106
+ expressionsValidated: result.statistics.expressionsValidated,
1107
+ errorCount: result.errors.length,
1108
+ warningCount: result.warnings.length
1109
+ }
1110
+ };
1111
+ if (result.errors.length > 0) {
1112
+ response.errors = result.errors.map(e => ({
1113
+ node: e.nodeName || 'workflow',
1114
+ message: e.message,
1115
+ details: e.details
1116
+ }));
1117
+ }
1118
+ if (result.warnings.length > 0) {
1119
+ response.warnings = result.warnings.map(w => ({
1120
+ node: w.nodeName || 'workflow',
1121
+ message: w.message,
1122
+ details: w.details
1123
+ }));
1124
+ }
1125
+ if (result.suggestions.length > 0) {
1126
+ response.suggestions = result.suggestions;
1127
+ }
1128
+ return response;
1129
+ }
1130
+ catch (error) {
1131
+ logger_1.logger.error('Error validating workflow:', error);
1132
+ return {
1133
+ valid: false,
1134
+ error: error instanceof Error ? error.message : 'Unknown error validating workflow',
1135
+ tip: 'Ensure the workflow JSON includes nodes array and connections object'
1136
+ };
1137
+ }
1138
+ }
1139
+ async validateWorkflowConnections(workflow) {
1140
+ await this.ensureInitialized();
1141
+ if (!this.repository)
1142
+ throw new Error('Repository not initialized');
1143
+ const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator);
1144
+ try {
1145
+ const result = await validator.validateWorkflow(workflow, {
1146
+ validateNodes: false,
1147
+ validateConnections: true,
1148
+ validateExpressions: false
1149
+ });
1150
+ const response = {
1151
+ valid: result.errors.length === 0,
1152
+ statistics: {
1153
+ totalNodes: result.statistics.totalNodes,
1154
+ triggerNodes: result.statistics.triggerNodes,
1155
+ validConnections: result.statistics.validConnections,
1156
+ invalidConnections: result.statistics.invalidConnections
1157
+ }
1158
+ };
1159
+ const connectionErrors = result.errors.filter(e => e.message.includes('connection') ||
1160
+ e.message.includes('cycle') ||
1161
+ e.message.includes('orphaned'));
1162
+ const connectionWarnings = result.warnings.filter(w => w.message.includes('connection') ||
1163
+ w.message.includes('orphaned') ||
1164
+ w.message.includes('trigger'));
1165
+ if (connectionErrors.length > 0) {
1166
+ response.errors = connectionErrors.map(e => ({
1167
+ node: e.nodeName || 'workflow',
1168
+ message: e.message
1169
+ }));
1170
+ }
1171
+ if (connectionWarnings.length > 0) {
1172
+ response.warnings = connectionWarnings.map(w => ({
1173
+ node: w.nodeName || 'workflow',
1174
+ message: w.message
1175
+ }));
1176
+ }
1177
+ return response;
1178
+ }
1179
+ catch (error) {
1180
+ logger_1.logger.error('Error validating workflow connections:', error);
1181
+ return {
1182
+ valid: false,
1183
+ error: error instanceof Error ? error.message : 'Unknown error validating connections'
1184
+ };
1185
+ }
1186
+ }
1187
+ async validateWorkflowExpressions(workflow) {
1188
+ await this.ensureInitialized();
1189
+ if (!this.repository)
1190
+ throw new Error('Repository not initialized');
1191
+ const validator = new workflow_validator_1.WorkflowValidator(this.repository, enhanced_config_validator_1.EnhancedConfigValidator);
1192
+ try {
1193
+ const result = await validator.validateWorkflow(workflow, {
1194
+ validateNodes: false,
1195
+ validateConnections: false,
1196
+ validateExpressions: true
1197
+ });
1198
+ const response = {
1199
+ valid: result.errors.length === 0,
1200
+ statistics: {
1201
+ totalNodes: result.statistics.totalNodes,
1202
+ expressionsValidated: result.statistics.expressionsValidated
1203
+ }
1204
+ };
1205
+ const expressionErrors = result.errors.filter(e => e.message.includes('Expression') ||
1206
+ e.message.includes('$') ||
1207
+ e.message.includes('{{'));
1208
+ const expressionWarnings = result.warnings.filter(w => w.message.includes('Expression') ||
1209
+ w.message.includes('$') ||
1210
+ w.message.includes('{{'));
1211
+ if (expressionErrors.length > 0) {
1212
+ response.errors = expressionErrors.map(e => ({
1213
+ node: e.nodeName || 'workflow',
1214
+ message: e.message
1215
+ }));
1216
+ }
1217
+ if (expressionWarnings.length > 0) {
1218
+ response.warnings = expressionWarnings.map(w => ({
1219
+ node: w.nodeName || 'workflow',
1220
+ message: w.message
1221
+ }));
1222
+ }
1223
+ if (expressionErrors.length > 0 || expressionWarnings.length > 0) {
1224
+ response.tips = [
1225
+ 'Use {{ }} to wrap expressions',
1226
+ 'Reference data with $json.propertyName',
1227
+ 'Reference other nodes with $node["Node Name"].json',
1228
+ 'Use $input.item for input data in loops'
1229
+ ];
1230
+ }
1231
+ return response;
1232
+ }
1233
+ catch (error) {
1234
+ logger_1.logger.error('Error validating workflow expressions:', error);
1235
+ return {
1236
+ valid: false,
1237
+ error: error instanceof Error ? error.message : 'Unknown error validating expressions'
1238
+ };
1239
+ }
1240
+ }
1241
+ async run() {
1242
+ await this.ensureInitialized();
1243
+ const transport = new stdio_js_1.StdioServerTransport();
1244
+ await this.server.connect(transport);
1245
+ if (!process.stdout.isTTY || process.env.IS_DOCKER) {
1246
+ const originalWrite = process.stdout.write.bind(process.stdout);
1247
+ process.stdout.write = function (chunk, encoding, callback) {
1248
+ const result = originalWrite(chunk, encoding, callback);
1249
+ process.stdout.emit('drain');
1250
+ return result;
1251
+ };
1252
+ }
1253
+ logger_1.logger.info('n8n Documentation MCP Server running on stdio transport');
1254
+ process.stdin.resume();
1255
+ }
1256
+ }
1257
+ exports.N8NDocumentationMCPServer = N8NDocumentationMCPServer;
1258
+ //# sourceMappingURL=server.js.map