n8n-workflow-builder-mcp 0.1.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/.cursor/rules/cursor_rules.mdc +53 -0
- package/.cursor/rules/dev_workflow.mdc +219 -0
- package/.cursor/rules/mcp.mdc +430 -0
- package/.cursor/rules/self_improve.mdc +72 -0
- package/.cursor/rules/taskmaster.mdc +382 -0
- package/.cursorignore +1 -0
- package/.cursorrules +4 -0
- package/.env.example +23 -0
- package/.eslintrc.json +38 -0
- package/.github/workflows/npm-publish-github-packages.yml +55 -0
- package/.prettierrc +9 -0
- package/.roo/rules/dev_workflow.md +219 -0
- package/.roo/rules/mcp.md +430 -0
- package/.roo/rules/roo_rules.md +53 -0
- package/.roo/rules/self_improve.md +72 -0
- package/.roo/rules/taskmaster.md +382 -0
- package/.roo/rules-architect/architect-rules +93 -0
- package/.roo/rules-ask/ask-rules +89 -0
- package/.roo/rules-boomerang/boomerang-rules +181 -0
- package/.roo/rules-code/code-rules +61 -0
- package/.roo/rules-debug/debug-rules +68 -0
- package/.roo/rules-test/test-rules +61 -0
- package/.roomodes +63 -0
- package/.taskmasterconfig +31 -0
- package/.windsurfrules +2382 -0
- package/LICENSE +21 -0
- package/README.md +210 -0
- package/config/credentials/credentials.json +1 -0
- package/config/default.js +41 -0
- package/package.json +56 -0
- package/scripts/demo-n8n-integration.js +161 -0
- package/scripts/demo-workflow-generator.js +102 -0
- package/scripts/init.sh +36 -0
- package/scripts/prd.txt +197 -0
- package/src/index.ts +1440 -0
- package/src/middleware/auth.js +273 -0
- package/src/middleware/authorize.js +183 -0
- package/src/middleware/logging.js +64 -0
- package/src/middleware/mcp.js +187 -0
- package/src/middleware/rateLimiter.js +82 -0
- package/src/middleware/validation.js +241 -0
- package/src/models/credential.js +359 -0
- package/src/models/llmService.js +236 -0
- package/src/models/n8nIntegration.js +542 -0
- package/src/models/storage.js +196 -0
- package/src/models/tool.js +148 -0
- package/src/models/user.js +164 -0
- package/src/models/workflow.js +229 -0
- package/src/routes/toolDefinitions.js +62 -0
- package/src/routes/toolExecution.js +79 -0
- package/src/tools/__index.js +242 -0
- package/src/tools/connectionManagement.js +500 -0
- package/src/tools/n8nIntegration.js +370 -0
- package/src/tools/nodeDiscovery.js +488 -0
- package/src/tools/nodeManagement.js +674 -0
- package/src/tools/toolDefinitions.js +660 -0
- package/src/tools/workflowCreation.js +100 -0
- package/src/tools/workflowGenerator.js +152 -0
- package/src/tools/workflowStorage.js +113 -0
- package/src/tools/workflowTesting.js +285 -0
- package/src/utils/encryption.js +164 -0
- package/src/utils/logger.js +84 -0
- package/src/utils/mcp.js +85 -0
- package/src/utils/securityLogger.js +109 -0
- package/tests/auth.test.js +402 -0
- package/tests/authorize.test.js +208 -0
- package/tests/run-memory-tests.js +55 -0
- package/tests/run-tests.js +55 -0
- package/tests/server.test.js +203 -0
- package/tests/unit/add-ai-connections.test.js +385 -0
- package/tests/unit/connectionManagement.test.js +309 -0
- package/tests/unit/langchain-llm-format.test.js +259 -0
- package/tests/unit/memory-connection.test.js +140 -0
- package/tests/unit/memory-integration.test.js +253 -0
- package/tests/unit/n8nIntegration.test.js +291 -0
- package/tests/unit/nodeDiscovery.test.js +270 -0
- package/tests/unit/nodeManagement.test.js +522 -0
- package/tests/unit/utils/mcp-test-utils.js +94 -0
- package/tests/unit/workflowCreation.test.js +110 -0
- package/tests/unit/workflowTesting.test.js +269 -0
- package/tests/user.test.js +181 -0
- package/tsconfig.json +20 -0
- package/workflow_nodes/Brandfetch.json +85 -0
- package/workflow_nodes/WorkflowTrigger.json +28 -0
- package/workflow_nodes/actionNetwork.json +218 -0
- package/workflow_nodes/activeCampaign.json +722 -0
- package/workflow_nodes/activeCampaignTrigger.json +52 -0
- package/workflow_nodes/acuitySchedulingTrigger.json +8 -0
- package/workflow_nodes/adalo.json +123 -0
- package/workflow_nodes/affinity.json +203 -0
- package/workflow_nodes/affinityTrigger.json +124 -0
- package/workflow_nodes/aggregate.json +119 -0
- package/workflow_nodes/agileCrm.json +503 -0
- package/workflow_nodes/aiTransform.json +17 -0
- package/workflow_nodes/airtable.json +226 -0
- package/workflow_nodes/airtableTrigger.json +120 -0
- package/workflow_nodes/airtop.json +10 -0
- package/workflow_nodes/amqp.json +62 -0
- package/workflow_nodes/amqpTrigger.json +8 -0
- package/workflow_nodes/apiTemplateIo.json +147 -0
- package/workflow_nodes/asana.json +446 -0
- package/workflow_nodes/asanaTrigger.json +52 -0
- package/workflow_nodes/automizy.json +195 -0
- package/workflow_nodes/autopilot.json +287 -0
- package/workflow_nodes/autopilotTrigger.json +8 -0
- package/workflow_nodes/awsCertificateManager.json +223 -0
- package/workflow_nodes/awsComprehend.json +125 -0
- package/workflow_nodes/awsDynamoDb.json +251 -0
- package/workflow_nodes/awsElb.json +174 -0
- package/workflow_nodes/awsLambda.json +69 -0
- package/workflow_nodes/awsRekognition.json +191 -0
- package/workflow_nodes/awsS3.json +32 -0
- package/workflow_nodes/awsSes.json +302 -0
- package/workflow_nodes/awsSns.json +110 -0
- package/workflow_nodes/awsSnsTrigger.json +47 -0
- package/workflow_nodes/awsSqs.json +140 -0
- package/workflow_nodes/awsTextract.json +43 -0
- package/workflow_nodes/awsTranscribe.json +217 -0
- package/workflow_nodes/azureCosmosDb.json +8 -0
- package/workflow_nodes/azureStorage.json +17 -0
- package/workflow_nodes/bambooHr.json +8 -0
- package/workflow_nodes/bannerbear.json +126 -0
- package/workflow_nodes/baserow.json +277 -0
- package/workflow_nodes/beeminder.json +146 -0
- package/workflow_nodes/bitbucketTrigger.json +62 -0
- package/workflow_nodes/bitly.json +130 -0
- package/workflow_nodes/bitwarden.json +224 -0
- package/workflow_nodes/box.json +457 -0
- package/workflow_nodes/boxTrigger.json +8 -0
- package/workflow_nodes/brevo.json +41 -0
- package/workflow_nodes/brevoTrigger.json +145 -0
- package/workflow_nodes/bubble.json +212 -0
- package/workflow_nodes/calTrigger.json +91 -0
- package/workflow_nodes/calendlyTrigger.json +71 -0
- package/workflow_nodes/chargebee.json +217 -0
- package/workflow_nodes/chargebeeTrigger.json +187 -0
- package/workflow_nodes/circleCi.json +89 -0
- package/workflow_nodes/ciscoWebex.json +593 -0
- package/workflow_nodes/ciscoWebexTrigger.json +159 -0
- package/workflow_nodes/clearbit.json +138 -0
- package/workflow_nodes/clickUp.json +793 -0
- package/workflow_nodes/clickUpTrigger.json +188 -0
- package/workflow_nodes/clockify.json +372 -0
- package/workflow_nodes/clockifyTrigger.json +26 -0
- package/workflow_nodes/cloudflare.json +103 -0
- package/workflow_nodes/cockpit.json +161 -0
- package/workflow_nodes/coda.json +242 -0
- package/workflow_nodes/code.json +40 -0
- package/workflow_nodes/coinGecko.json +363 -0
- package/workflow_nodes/compareDatasets.json +14 -0
- package/workflow_nodes/compression.json +66 -0
- package/workflow_nodes/contentful.json +29 -0
- package/workflow_nodes/convertKit.json +159 -0
- package/workflow_nodes/convertKitTrigger.json +109 -0
- package/workflow_nodes/convertToFile.json +64 -0
- package/workflow_nodes/copper.json +239 -0
- package/workflow_nodes/copperTrigger.json +8 -0
- package/workflow_nodes/cortex.json +348 -0
- package/workflow_nodes/crateDb.json +90 -0
- package/workflow_nodes/cron.json +23 -0
- package/workflow_nodes/crowdDev.json +8 -0
- package/workflow_nodes/crowdDevTrigger.json +8 -0
- package/workflow_nodes/crypto.json +147 -0
- package/workflow_nodes/customerIo.json +206 -0
- package/workflow_nodes/customerIoTrigger.json +185 -0
- package/workflow_nodes/dateTime.json +39 -0
- package/workflow_nodes/debughelper.json +162 -0
- package/workflow_nodes/deepL.json +103 -0
- package/workflow_nodes/demio.json +187 -0
- package/workflow_nodes/dhl.json +53 -0
- package/workflow_nodes/discord.json +81 -0
- package/workflow_nodes/discourse.json +319 -0
- package/workflow_nodes/disqus.json +254 -0
- package/workflow_nodes/drift.json +112 -0
- package/workflow_nodes/dropbox.json +258 -0
- package/workflow_nodes/dropcontact.json +154 -0
- package/workflow_nodes/e2eTest.json +70 -0
- package/workflow_nodes/editImage.json +132 -0
- package/workflow_nodes/egoi.json +220 -0
- package/workflow_nodes/elasticSecurity.json +401 -0
- package/workflow_nodes/elasticsearch.json +422 -0
- package/workflow_nodes/emailReadImap.json +88 -0
- package/workflow_nodes/emailSend.json +38 -0
- package/workflow_nodes/emelia.json +201 -0
- package/workflow_nodes/emeliaTrigger.json +57 -0
- package/workflow_nodes/erpNext.json +139 -0
- package/workflow_nodes/errorTrigger.json +15 -0
- package/workflow_nodes/evaluationMetrics.json +21 -0
- package/workflow_nodes/eventbriteTrigger.json +125 -0
- package/workflow_nodes/executeCommand.json +25 -0
- package/workflow_nodes/executeWorkflow.json +102 -0
- package/workflow_nodes/executeWorkflowTrigger.json +65 -0
- package/workflow_nodes/executionData.json +35 -0
- package/workflow_nodes/extractFromFile.json +71 -0
- package/workflow_nodes/facebookGraphApi.json +234 -0
- package/workflow_nodes/facebookLeadAdsTrigger.json +8 -0
- package/workflow_nodes/facebookTrigger.json +112 -0
- package/workflow_nodes/figmaTrigger.json +8 -0
- package/workflow_nodes/filemaker.json +268 -0
- package/workflow_nodes/filter.json +24 -0
- package/workflow_nodes/flow.json +323 -0
- package/workflow_nodes/flowTrigger.json +52 -0
- package/workflow_nodes/form.json +25 -0
- package/workflow_nodes/formIoTrigger.json +59 -0
- package/workflow_nodes/formTrigger.json +8 -0
- package/workflow_nodes/formstackTrigger.json +8 -0
- package/workflow_nodes/freshdesk.json +584 -0
- package/workflow_nodes/freshservice.json +899 -0
- package/workflow_nodes/freshworksCrm.json +772 -0
- package/workflow_nodes/ftp.json +127 -0
- package/workflow_nodes/function.json +22 -0
- package/workflow_nodes/functionItem.json +22 -0
- package/workflow_nodes/gSuiteAdmin.json +562 -0
- package/workflow_nodes/getResponse.json +310 -0
- package/workflow_nodes/getResponseTrigger.json +82 -0
- package/workflow_nodes/ghost.json +290 -0
- package/workflow_nodes/git.json +184 -0
- package/workflow_nodes/github.json +732 -0
- package/workflow_nodes/githubTrigger.json +317 -0
- package/workflow_nodes/gitlab.json +544 -0
- package/workflow_nodes/gitlabTrigger.json +61 -0
- package/workflow_nodes/gmail.json +62 -0
- package/workflow_nodes/gmailTrigger.json +127 -0
- package/workflow_nodes/goToWebinar.json +430 -0
- package/workflow_nodes/gong.json +22 -0
- package/workflow_nodes/googleAds.json +116 -0
- package/workflow_nodes/googleAnalytics.json +28 -0
- package/workflow_nodes/googleBigQuery.json +38 -0
- package/workflow_nodes/googleBooks.json +154 -0
- package/workflow_nodes/googleBusinessProfile.json +277 -0
- package/workflow_nodes/googleBusinessProfileTrigger.json +55 -0
- package/workflow_nodes/googleCalendar.json +474 -0
- package/workflow_nodes/googleCalendarTrigger.json +72 -0
- package/workflow_nodes/googleChat.json +187 -0
- package/workflow_nodes/googleCloudNaturalLanguage.json +171 -0
- package/workflow_nodes/googleCloudStorage.json +466 -0
- package/workflow_nodes/googleContacts.json +481 -0
- package/workflow_nodes/googleDocs.json +312 -0
- package/workflow_nodes/googleDrive.json +920 -0
- package/workflow_nodes/googleDriveTrigger.json +181 -0
- package/workflow_nodes/googleFirebaseCloudFirestore.json +156 -0
- package/workflow_nodes/googleFirebaseRealtimeDatabase.json +75 -0
- package/workflow_nodes/googlePerspective.json +94 -0
- package/workflow_nodes/googleSheets.json +98 -0
- package/workflow_nodes/googleSheetsTrigger.json +192 -0
- package/workflow_nodes/googleSlides.json +186 -0
- package/workflow_nodes/googleTasks.json +198 -0
- package/workflow_nodes/googleTranslate.json +80 -0
- package/workflow_nodes/gotify.json +110 -0
- package/workflow_nodes/grafana.json +155 -0
- package/workflow_nodes/graphql.json +165 -0
- package/workflow_nodes/grist.json +13 -0
- package/workflow_nodes/gumroadTrigger.json +8 -0
- package/workflow_nodes/hackerNews.json +100 -0
- package/workflow_nodes/haloPSA.json +286 -0
- package/workflow_nodes/harvest.json +699 -0
- package/workflow_nodes/helpScout.json +629 -0
- package/workflow_nodes/helpScoutTrigger.json +8 -0
- package/workflow_nodes/highLevel.json +8 -0
- package/workflow_nodes/homeAssistant.json +201 -0
- package/workflow_nodes/html.json +118 -0
- package/workflow_nodes/htmlExtract.json +87 -0
- package/workflow_nodes/httpRequest.json +472 -0
- package/workflow_nodes/hubspot.json +62 -0
- package/workflow_nodes/hubspotTrigger.json +138 -0
- package/workflow_nodes/humanticAi.json +82 -0
- package/workflow_nodes/hunter.json +168 -0
- package/workflow_nodes/iCal.json +20 -0
- package/workflow_nodes/if.json +24 -0
- package/workflow_nodes/intercom.json +335 -0
- package/workflow_nodes/interval.json +8 -0
- package/workflow_nodes/invoiceNinja.json +882 -0
- package/workflow_nodes/invoiceNinjaTrigger.json +11 -0
- package/workflow_nodes/itemLists.json +313 -0
- package/workflow_nodes/iterable.json +168 -0
- package/workflow_nodes/jenkins.json +172 -0
- package/workflow_nodes/jira.json +529 -0
- package/workflow_nodes/jiraTrigger.json +308 -0
- package/workflow_nodes/jotFormTrigger.json +44 -0
- package/workflow_nodes/jwt.json +195 -0
- package/workflow_nodes/kafka.json +132 -0
- package/workflow_nodes/kafkaTrigger.json +11 -0
- package/workflow_nodes/keap.json +915 -0
- package/workflow_nodes/keapTrigger.json +37 -0
- package/workflow_nodes/kitemaker.json +153 -0
- package/workflow_nodes/koBoToolbox.json +337 -0
- package/workflow_nodes/koBoToolboxTrigger.json +8 -0
- package/workflow_nodes/langchain_Summarization Chain.json +60 -0
- package/workflow_nodes/langchain_agent.json +145 -0
- package/workflow_nodes/langchain_allowFileUploads.json +180 -0
- package/workflow_nodes/langchain_chainLlm.json +16 -0
- package/workflow_nodes/langchain_chainSummarization.json +119 -0
- package/workflow_nodes/langchain_code.json +62 -0
- package/workflow_nodes/langchain_documentBinaryInputLoader.json +8 -0
- package/workflow_nodes/langchain_documentDefaultDataLoader.json +8 -0
- package/workflow_nodes/langchain_documentGithubLoader.json +8 -0
- package/workflow_nodes/langchain_documentJsonInputLoader.json +8 -0
- package/workflow_nodes/langchain_embeddingDimensions.json +17 -0
- package/workflow_nodes/langchain_embeddingsAwsBedrock.json +8 -0
- package/workflow_nodes/langchain_embeddingsAzureOpenAi.json +151 -0
- package/workflow_nodes/langchain_embeddingsCohere.json +8 -0
- package/workflow_nodes/langchain_embeddingsGoogleGemini.json +8 -0
- package/workflow_nodes/langchain_embeddingsGoogleVertex.json +8 -0
- package/workflow_nodes/langchain_embeddingsHuggingFaceInference.json +8 -0
- package/workflow_nodes/langchain_embeddingsMistralCloud.json +8 -0
- package/workflow_nodes/langchain_embeddingsOllama.json +8 -0
- package/workflow_nodes/langchain_informationExtractor.json +81 -0
- package/workflow_nodes/langchain_lmChatAwsBedrock.json +8 -0
- package/workflow_nodes/langchain_lmChatAzureOpenAi.json +151 -0
- package/workflow_nodes/langchain_lmChatDeepSeek.json +10 -0
- package/workflow_nodes/langchain_lmChatGoogleGemini.json +31 -0
- package/workflow_nodes/langchain_lmChatGoogleVertex.json +32 -0
- package/workflow_nodes/langchain_lmChatGroq.json +8 -0
- package/workflow_nodes/langchain_lmChatMistralCloud.json +8 -0
- package/workflow_nodes/langchain_lmChatOllama.json +8 -0
- package/workflow_nodes/langchain_lmChatOpenAi.json +155 -0
- package/workflow_nodes/langchain_lmChatOpenRouter.json +10 -0
- package/workflow_nodes/langchain_lmChatXAiGrok.json +10 -0
- package/workflow_nodes/langchain_lmCohere.json +8 -0
- package/workflow_nodes/langchain_lmOllama.json +8 -0
- package/workflow_nodes/langchain_lmOpenAi.json +251 -0
- package/workflow_nodes/langchain_lmOpenHuggingFaceInference.json +8 -0
- package/workflow_nodes/langchain_manualChatTrigger.json +11 -0
- package/workflow_nodes/langchain_mcpClientTool.json +86 -0
- package/workflow_nodes/langchain_mcpTrigger.json +8 -0
- package/workflow_nodes/langchain_memoryBufferWindow.json +13 -0
- package/workflow_nodes/langchain_memoryChatRetriever.json +22 -0
- package/workflow_nodes/langchain_memoryManager.json +106 -0
- package/workflow_nodes/langchain_memoryMongoDbChat.json +10 -0
- package/workflow_nodes/langchain_memoryMotorhead.json +13 -0
- package/workflow_nodes/langchain_memoryPostgresChat.json +13 -0
- package/workflow_nodes/langchain_memoryRedisChat.json +15 -0
- package/workflow_nodes/langchain_memoryXata.json +14 -0
- package/workflow_nodes/langchain_memoryZep.json +13 -0
- package/workflow_nodes/langchain_model.json +155 -0
- package/workflow_nodes/langchain_mongoCollection.json +16 -0
- package/workflow_nodes/langchain_notice.json +22 -0
- package/workflow_nodes/langchain_openAiAssistant.json +132 -0
- package/workflow_nodes/langchain_options.json +17 -0
- package/workflow_nodes/langchain_outputParserAutofixing.json +8 -0
- package/workflow_nodes/langchain_outputParserItemList.json +8 -0
- package/workflow_nodes/langchain_outputParserStructured.json +12 -0
- package/workflow_nodes/langchain_pineconeNamespace.json +16 -0
- package/workflow_nodes/langchain_queryName.json +16 -0
- package/workflow_nodes/langchain_retrieverContextualCompression.json +8 -0
- package/workflow_nodes/langchain_retrieverMultiQuery.json +8 -0
- package/workflow_nodes/langchain_retrieverVectorStore.json +8 -0
- package/workflow_nodes/langchain_retrieverWorkflow.json +103 -0
- package/workflow_nodes/langchain_sentimentAnalysis.json +52 -0
- package/workflow_nodes/langchain_systemPromptTemplate.json +47 -0
- package/workflow_nodes/langchain_tableName.json +23 -0
- package/workflow_nodes/langchain_textClassifier.json +66 -0
- package/workflow_nodes/langchain_textSplitterCharacterTextSplitter.json +8 -0
- package/workflow_nodes/langchain_textSplitterRecursiveCharacterTextSplitter.json +8 -0
- package/workflow_nodes/langchain_textSplitterTokenSplitter.json +8 -0
- package/workflow_nodes/langchain_toolCalculator.json +8 -0
- package/workflow_nodes/langchain_toolCode.json +12 -0
- package/workflow_nodes/langchain_toolHttpRequest.json +232 -0
- package/workflow_nodes/langchain_toolSearXng.json +8 -0
- package/workflow_nodes/langchain_toolSerpApi.json +8 -0
- package/workflow_nodes/langchain_toolThink.json +8 -0
- package/workflow_nodes/langchain_toolVectorStore.json +11 -0
- package/workflow_nodes/langchain_toolWikipedia.json +8 -0
- package/workflow_nodes/langchain_toolWolframAlpha.json +8 -0
- package/workflow_nodes/langchain_toolWorkflow.json +8 -0
- package/workflow_nodes/langchain_vectorStoreInMemoryInsert.json +29 -0
- package/workflow_nodes/langchain_vectorStoreInMemoryLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStorePineconeInsert.json +37 -0
- package/workflow_nodes/langchain_vectorStorePineconeLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStoreSupabaseInsert.json +32 -0
- package/workflow_nodes/langchain_vectorStoreSupabaseLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStoreZepInsert.json +46 -0
- package/workflow_nodes/langchain_vectorStoreZepLoad.json +8 -0
- package/workflow_nodes/ldap.json +182 -0
- package/workflow_nodes/lemlist.json +44 -0
- package/workflow_nodes/lemlistTrigger.json +45 -0
- package/workflow_nodes/limit.json +26 -0
- package/workflow_nodes/line.json +95 -0
- package/workflow_nodes/linear.json +151 -0
- package/workflow_nodes/linearTrigger.json +71 -0
- package/workflow_nodes/lingvaNex.json +66 -0
- package/workflow_nodes/linkedIn.json +142 -0
- package/workflow_nodes/localFileTrigger.json +120 -0
- package/workflow_nodes/lonescale.json +171 -0
- package/workflow_nodes/lonescaleTrigger.json +8 -0
- package/workflow_nodes/magento2.json +164 -0
- package/workflow_nodes/mailcheck.json +46 -0
- package/workflow_nodes/mailchimp.json +507 -0
- package/workflow_nodes/mailchimpTrigger.json +100 -0
- package/workflow_nodes/mailerLite.json +24 -0
- package/workflow_nodes/mailerLiteTrigger.json +74 -0
- package/workflow_nodes/mailgun.json +81 -0
- package/workflow_nodes/mailjet.json +201 -0
- package/workflow_nodes/mailjetTrigger.json +8 -0
- package/workflow_nodes/mandrill.json +372 -0
- package/workflow_nodes/manualTrigger.json +8 -0
- package/workflow_nodes/markdown.json +376 -0
- package/workflow_nodes/marketstack.json +126 -0
- package/workflow_nodes/matrix.json +264 -0
- package/workflow_nodes/mattermost.json +8 -0
- package/workflow_nodes/mautic.json +564 -0
- package/workflow_nodes/mauticTrigger.json +54 -0
- package/workflow_nodes/medium.json +209 -0
- package/workflow_nodes/merge.json +125 -0
- package/workflow_nodes/messageBird.json +182 -0
- package/workflow_nodes/metabase.json +175 -0
- package/workflow_nodes/microsoftDynamicsCrm.json +100 -0
- package/workflow_nodes/microsoftEntra.json +51 -0
- package/workflow_nodes/microsoftExcel.json +35 -0
- package/workflow_nodes/microsoftGraphSecurity.json +113 -0
- package/workflow_nodes/microsoftOneDrive.json +232 -0
- package/workflow_nodes/microsoftOneDriveTrigger.json +80 -0
- package/workflow_nodes/microsoftOutlook.json +40 -0
- package/workflow_nodes/microsoftOutlookTrigger.json +24 -0
- package/workflow_nodes/microsoftSql.json +81 -0
- package/workflow_nodes/microsoftTeams.json +36 -0
- package/workflow_nodes/microsoftToDo.json +181 -0
- package/workflow_nodes/mindee.json +86 -0
- package/workflow_nodes/misp.json +399 -0
- package/workflow_nodes/mocean.json +103 -0
- package/workflow_nodes/mondayCom.json +290 -0
- package/workflow_nodes/mongoDb.json +16 -0
- package/workflow_nodes/monicaCrm.json +543 -0
- package/workflow_nodes/moveBinaryData.json +121 -0
- package/workflow_nodes/mqtt.json +67 -0
- package/workflow_nodes/mqttTrigger.json +47 -0
- package/workflow_nodes/msg91.json +65 -0
- package/workflow_nodes/mySql.json +111 -0
- package/workflow_nodes/n8n.json +75 -0
- package/workflow_nodes/n8nTrigger.json +27 -0
- package/workflow_nodes/nasa.json +310 -0
- package/workflow_nodes/netlify.json +87 -0
- package/workflow_nodes/netlifyTrigger.json +68 -0
- package/workflow_nodes/netscalerAdc.json +243 -0
- package/workflow_nodes/nextCloud.json +312 -0
- package/workflow_nodes/noOp.json +8 -0
- package/workflow_nodes/nocoDb.json +276 -0
- package/workflow_nodes/notion.json +8 -0
- package/workflow_nodes/notionTrigger.json +75 -0
- package/workflow_nodes/npm.json +64 -0
- package/workflow_nodes/odoo.json +344 -0
- package/workflow_nodes/okta.json +97 -0
- package/workflow_nodes/oneSimpleApi.json +281 -0
- package/workflow_nodes/onfleet.json +316 -0
- package/workflow_nodes/onfleetTrigger.json +8 -0
- package/workflow_nodes/openAi.json +154 -0
- package/workflow_nodes/openThesaurus.json +81 -0
- package/workflow_nodes/openWeatherMap.json +129 -0
- package/workflow_nodes/orbit.json +375 -0
- package/workflow_nodes/oura.json +74 -0
- package/workflow_nodes/paddle.json +403 -0
- package/workflow_nodes/pagerDuty.json +351 -0
- package/workflow_nodes/payPal.json +196 -0
- package/workflow_nodes/payPalTrigger.json +40 -0
- package/workflow_nodes/peekalink.json +41 -0
- package/workflow_nodes/phantombuster.json +172 -0
- package/workflow_nodes/philipsHue.json +177 -0
- package/workflow_nodes/pipedrive.json +860 -0
- package/workflow_nodes/pipedriveTrigger.json +11 -0
- package/workflow_nodes/plivo.json +91 -0
- package/workflow_nodes/postHog.json +122 -0
- package/workflow_nodes/postbin.json +60 -0
- package/workflow_nodes/postgres.json +109 -0
- package/workflow_nodes/postgresTrigger.json +8 -0
- package/workflow_nodes/postmarkTrigger.json +72 -0
- package/workflow_nodes/profitWell.json +305 -0
- package/workflow_nodes/pushbullet.json +186 -0
- package/workflow_nodes/pushcut.json +75 -0
- package/workflow_nodes/pushcutTrigger.json +8 -0
- package/workflow_nodes/pushover.json +159 -0
- package/workflow_nodes/questDb.json +94 -0
- package/workflow_nodes/quickChart.json +188 -0
- package/workflow_nodes/quickbase.json +205 -0
- package/workflow_nodes/quickbooks.json +550 -0
- package/workflow_nodes/rabbitmq.json +165 -0
- package/workflow_nodes/rabbitmqTrigger.json +8 -0
- package/workflow_nodes/raindrop.json +216 -0
- package/workflow_nodes/readBinaryFile.json +26 -0
- package/workflow_nodes/readBinaryFiles.json +26 -0
- package/workflow_nodes/readPDF.json +31 -0
- package/workflow_nodes/readWriteFile.json +27 -0
- package/workflow_nodes/reddit.json +309 -0
- package/workflow_nodes/redis.json +183 -0
- package/workflow_nodes/redisTrigger.json +8 -0
- package/workflow_nodes/removeDuplicates.json +8 -0
- package/workflow_nodes/renameKeys.json +67 -0
- package/workflow_nodes/respondToWebhook.json +126 -0
- package/workflow_nodes/rocketchat.json +216 -0
- package/workflow_nodes/rssFeedRead.json +28 -0
- package/workflow_nodes/rssFeedReadTrigger.json +17 -0
- package/workflow_nodes/rundeck.json +79 -0
- package/workflow_nodes/s3.json +425 -0
- package/workflow_nodes/salesforce.json +1137 -0
- package/workflow_nodes/salesforceTrigger.json +122 -0
- package/workflow_nodes/salesmate.json +467 -0
- package/workflow_nodes/scheduleTrigger.json +270 -0
- package/workflow_nodes/seaTable.json +8 -0
- package/workflow_nodes/seaTableTrigger.json +87 -0
- package/workflow_nodes/securityScorecard.json +459 -0
- package/workflow_nodes/segment.json +219 -0
- package/workflow_nodes/sendGrid.json +359 -0
- package/workflow_nodes/sendy.json +225 -0
- package/workflow_nodes/sentryIo.json +426 -0
- package/workflow_nodes/serviceNow.json +544 -0
- package/workflow_nodes/set.json +124 -0
- package/workflow_nodes/shopify.json +707 -0
- package/workflow_nodes/shopifyTrigger.json +8 -0
- package/workflow_nodes/signl4.json +133 -0
- package/workflow_nodes/simulate.json +30 -0
- package/workflow_nodes/simulateTrigger.json +8 -0
- package/workflow_nodes/slack.json +62 -0
- package/workflow_nodes/slackTrigger.json +135 -0
- package/workflow_nodes/sms77.json +121 -0
- package/workflow_nodes/snowflake.json +65 -0
- package/workflow_nodes/sort.json +57 -0
- package/workflow_nodes/splitInBatches.json +30 -0
- package/workflow_nodes/splitOut.json +62 -0
- package/workflow_nodes/splunk.json +40 -0
- package/workflow_nodes/spontit.json +123 -0
- package/workflow_nodes/spotify.json +285 -0
- package/workflow_nodes/spreadsheetFile.json +8 -0
- package/workflow_nodes/sseTrigger.json +8 -0
- package/workflow_nodes/ssh.json +105 -0
- package/workflow_nodes/stackby.json +85 -0
- package/workflow_nodes/start.json +15 -0
- package/workflow_nodes/stickyNote.json +36 -0
- package/workflow_nodes/stopAndError.json +8 -0
- package/workflow_nodes/storyblok.json +138 -0
- package/workflow_nodes/strapi.json +138 -0
- package/workflow_nodes/strava.json +427 -0
- package/workflow_nodes/stravaTrigger.json +79 -0
- package/workflow_nodes/stripe.json +357 -0
- package/workflow_nodes/stripeTrigger.json +775 -0
- package/workflow_nodes/summarize.json +124 -0
- package/workflow_nodes/supabase.json +136 -0
- package/workflow_nodes/surveyMonkeyTrigger.json +160 -0
- package/workflow_nodes/switch.json +91 -0
- package/workflow_nodes/syncroMsp.json +8 -0
- package/workflow_nodes/taiga.json +340 -0
- package/workflow_nodes/taigaTrigger.json +81 -0
- package/workflow_nodes/tapfiliate.json +241 -0
- package/workflow_nodes/telegram.json +612 -0
- package/workflow_nodes/telegramTrigger.json +142 -0
- package/workflow_nodes/theHive.json +497 -0
- package/workflow_nodes/theHiveProject.json +8 -0
- package/workflow_nodes/theHiveProjectTrigger.json +162 -0
- package/workflow_nodes/theHiveTrigger.json +101 -0
- package/workflow_nodes/timescaleDb.json +95 -0
- package/workflow_nodes/todoist.json +285 -0
- package/workflow_nodes/togglTrigger.json +24 -0
- package/workflow_nodes/totp.json +86 -0
- package/workflow_nodes/travisCi.json +142 -0
- package/workflow_nodes/trello.json +609 -0
- package/workflow_nodes/trelloTrigger.json +8 -0
- package/workflow_nodes/twake.json +76 -0
- package/workflow_nodes/twilio.json +95 -0
- package/workflow_nodes/twilioTrigger.json +46 -0
- package/workflow_nodes/twist.json +376 -0
- package/workflow_nodes/twitter.json +40 -0
- package/workflow_nodes/typeformTrigger.json +62 -0
- package/workflow_nodes/unleashedSoftware.json +154 -0
- package/workflow_nodes/uplead.json +72 -0
- package/workflow_nodes/uproc.json +26 -0
- package/workflow_nodes/uptimeRobot.json +453 -0
- package/workflow_nodes/urlScanIo.json +113 -0
- package/workflow_nodes/venafiTlsProtectCloud.json +310 -0
- package/workflow_nodes/venafiTlsProtectCloudTrigger.json +38 -0
- package/workflow_nodes/venafiTlsProtectDatacenter.json +491 -0
- package/workflow_nodes/vero.json +158 -0
- package/workflow_nodes/vonage.json +125 -0
- package/workflow_nodes/wait.json +71 -0
- package/workflow_nodes/webflow.json +38 -0
- package/workflow_nodes/webflowTrigger.json +8 -0
- package/workflow_nodes/webhook.json +55 -0
- package/workflow_nodes/wekan.json +460 -0
- package/workflow_nodes/whatsApp.json +476 -0
- package/workflow_nodes/whatsAppTrigger.json +103 -0
- package/workflow_nodes/wise.json +330 -0
- package/workflow_nodes/wiseTrigger.json +8 -0
- package/workflow_nodes/wooCommerce.json +812 -0
- package/workflow_nodes/wooCommerceTrigger.json +8 -0
- package/workflow_nodes/wordpress.json +500 -0
- package/workflow_nodes/workableTrigger.json +51 -0
- package/workflow_nodes/writeBinaryFile.json +34 -0
- package/workflow_nodes/wufooTrigger.json +37 -0
- package/workflow_nodes/xero.json +530 -0
- package/workflow_nodes/xml.json +129 -0
- package/workflow_nodes/youTube.json +578 -0
- package/workflow_nodes/yourls.json +71 -0
- package/workflow_nodes/zammad.json +406 -0
- package/workflow_nodes/zendesk.json +526 -0
- package/workflow_nodes/zendeskTrigger.json +187 -0
- package/workflow_nodes/zohoCrm.json +721 -0
- package/workflow_nodes/zoom.json +507 -0
- package/workflow_nodes/zulip.json +371 -0
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node Discovery Tool
|
|
3
|
+
*
|
|
4
|
+
* Implements the search_nodes tool for discovering n8n nodes and their parameters.
|
|
5
|
+
*
|
|
6
|
+
* This tool allows AI agents to explore available n8n nodes by:
|
|
7
|
+
* 1. Scanning the workflow_nodes directory for node definition files
|
|
8
|
+
* 2. Extracting node information, parameters, and credentials
|
|
9
|
+
* 3. Categorizing nodes based on their functionality
|
|
10
|
+
* 4. Providing search capabilities with various filters
|
|
11
|
+
* 5. Ensuring secure handling of credential-related parameters
|
|
12
|
+
*
|
|
13
|
+
* Usage example:
|
|
14
|
+
* ```
|
|
15
|
+
* // Search for database-related nodes
|
|
16
|
+
* const result = await searchNodes({ category: 'database' });
|
|
17
|
+
*
|
|
18
|
+
* // Search for nodes by keyword
|
|
19
|
+
* const result = await searchNodes({ keyword: 'email' });
|
|
20
|
+
*
|
|
21
|
+
* // Combined search
|
|
22
|
+
* const result = await searchNodes({
|
|
23
|
+
* category: 'trigger',
|
|
24
|
+
* functionality: 'webhook'
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const fs = require('fs').promises;
|
|
30
|
+
const path = require('path');
|
|
31
|
+
const { createTool } = require('../models/tool');
|
|
32
|
+
const { logger } = require('../utils/logger');
|
|
33
|
+
|
|
34
|
+
// Cache for node information to improve performance
|
|
35
|
+
let nodeCache = null;
|
|
36
|
+
let cacheTimestamp = null;
|
|
37
|
+
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour cache TTL
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Scans and parses the n8n workflow_nodes directory
|
|
41
|
+
*
|
|
42
|
+
* This function reads all JSON files in the workflow_nodes directory,
|
|
43
|
+
* extracts node information, and returns a structured array of node data.
|
|
44
|
+
*
|
|
45
|
+
* @returns {Promise<Array>} Array of node information objects
|
|
46
|
+
*/
|
|
47
|
+
const scanWorkflowNodes = async () => {
|
|
48
|
+
const workflowNodesDir = path.join(process.cwd(), 'workflow_nodes');
|
|
49
|
+
try {
|
|
50
|
+
logger.debug('Scanning workflow_nodes directory for node definitions');
|
|
51
|
+
const files = await fs.readdir(workflowNodesDir);
|
|
52
|
+
|
|
53
|
+
// Filter for JSON files only
|
|
54
|
+
const jsonFiles = files.filter(file => file.endsWith('.json'));
|
|
55
|
+
logger.debug(`Found ${jsonFiles.length} node definition files`);
|
|
56
|
+
|
|
57
|
+
// Create a map of normalized filename -> actual filename with original casing
|
|
58
|
+
// This helps us find files with the correct casing based on lowercase lookups
|
|
59
|
+
const filenameMap = {};
|
|
60
|
+
jsonFiles.forEach(file => {
|
|
61
|
+
const baseId = file.replace('.json', '');
|
|
62
|
+
filenameMap[baseId.toLowerCase()] = baseId;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
logger.debug(`Built filename map with ${Object.keys(filenameMap).length} entries`);
|
|
66
|
+
|
|
67
|
+
// Process each file
|
|
68
|
+
const nodesPromises = jsonFiles.map(async (file) => {
|
|
69
|
+
try {
|
|
70
|
+
const filePath = path.join(workflowNodesDir, file);
|
|
71
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
72
|
+
const nodeData = JSON.parse(content);
|
|
73
|
+
|
|
74
|
+
// Get filename without extension for node identification
|
|
75
|
+
// Preserve the exact filename casing
|
|
76
|
+
const baseNodeId = file.replace('.json', '');
|
|
77
|
+
|
|
78
|
+
// For indexing and finding nodes, we need a lowercase version of the ID
|
|
79
|
+
const normalizedNodeId = baseNodeId.toLowerCase();
|
|
80
|
+
|
|
81
|
+
// Check if the node has a nodeType field (preferred way to identify the node)
|
|
82
|
+
let nodeType = null;
|
|
83
|
+
if (nodeData.nodeType) {
|
|
84
|
+
nodeType = nodeData.nodeType;
|
|
85
|
+
// Store the original node type format with exact casing for reference
|
|
86
|
+
nodeData.originalNodeType = nodeType; // Preserve the exact casing
|
|
87
|
+
|
|
88
|
+
// Normalize the node type for consistency in searching
|
|
89
|
+
if (nodeType.includes('n8n-nodes-base.')) {
|
|
90
|
+
// Extract just the node name part after the prefix
|
|
91
|
+
const nodeName = nodeType.split('n8n-nodes-base.')[1];
|
|
92
|
+
// Store both formats for lookup
|
|
93
|
+
nodeData.normalizedNodeType = nodeName.toLowerCase();
|
|
94
|
+
} else {
|
|
95
|
+
nodeData.normalizedNodeType = nodeType.toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
// If no nodeType is specified, derive it from the filename
|
|
99
|
+
// Use the original filename casing to construct the nodeType to preserve camelCase
|
|
100
|
+
const nodeIdWithOriginalCase = file.replace('.json', '');
|
|
101
|
+
nodeType = `n8n-nodes-base.${nodeIdWithOriginalCase}`;
|
|
102
|
+
nodeData.originalNodeType = nodeType; // Store with exact casing
|
|
103
|
+
nodeData.normalizedNodeType = baseNodeId.toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Extract node ID from the base name for consistent identification
|
|
107
|
+
const nodeId = baseNodeId;
|
|
108
|
+
|
|
109
|
+
// Extract node information, passing the full node data and file info
|
|
110
|
+
const nodeInfo = extractNodeInfo(nodeId, nodeData, file);
|
|
111
|
+
|
|
112
|
+
// Include the nodeType in the node info for reference
|
|
113
|
+
// Always use the original casing from the definition file
|
|
114
|
+
nodeInfo.type = nodeData.nodeType || nodeType;
|
|
115
|
+
nodeInfo.originalNodeType = nodeData.nodeType || nodeType; // Store the original nodeType with exact casing
|
|
116
|
+
nodeInfo.normalizedType = nodeData.normalizedNodeType;
|
|
117
|
+
|
|
118
|
+
// Log the node discovery for debugging
|
|
119
|
+
logger.debug(`Discovered node: ${nodeInfo.id}`, {
|
|
120
|
+
type: nodeInfo.type,
|
|
121
|
+
originalNodeType: nodeInfo.originalNodeType
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return nodeInfo;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
logger.error(`Error processing node file ${file}:`, error);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Filter out any failed node parsing
|
|
132
|
+
const nodes = (await Promise.all(nodesPromises)).filter(Boolean);
|
|
133
|
+
logger.debug(`Successfully parsed ${nodes.length} node definitions`);
|
|
134
|
+
|
|
135
|
+
// Add a filenames map to help with exact case matching
|
|
136
|
+
const result = nodes;
|
|
137
|
+
result.filenameMap = filenameMap;
|
|
138
|
+
|
|
139
|
+
return result;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
logger.error('Failed to scan workflow_nodes directory:', error);
|
|
142
|
+
throw new Error(`Failed to scan workflow nodes: ${error.message}`);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Extract relevant node information from node data
|
|
148
|
+
*
|
|
149
|
+
* Parses the raw JSON node data and extracts structured information
|
|
150
|
+
* about the node, including its parameters, categories, and credentials.
|
|
151
|
+
*
|
|
152
|
+
* @param {string} nodeId - The node identifier
|
|
153
|
+
* @param {Object} nodeData - Raw node data from JSON file
|
|
154
|
+
* @param {string} fileName - Original filename
|
|
155
|
+
* @returns {Object} Structured node information
|
|
156
|
+
*/
|
|
157
|
+
const extractNodeInfo = (nodeId, nodeData, fileName) => {
|
|
158
|
+
try {
|
|
159
|
+
// If there are no nodes in the file, return minimal info
|
|
160
|
+
if (!nodeData.nodes || !nodeData.nodes.length) {
|
|
161
|
+
logger.debug(`No node instance found in ${fileName}`);
|
|
162
|
+
return {
|
|
163
|
+
id: nodeId,
|
|
164
|
+
name: nodeId,
|
|
165
|
+
fileName,
|
|
166
|
+
description: 'Node information not available',
|
|
167
|
+
parameters: [],
|
|
168
|
+
categories: []
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const nodeInstance = nodeData.nodes[0];
|
|
173
|
+
|
|
174
|
+
// Determine node categories from file name and node structure
|
|
175
|
+
const categories = determineCategories(nodeId, nodeInstance);
|
|
176
|
+
|
|
177
|
+
// Extract parameters from the node instance
|
|
178
|
+
const parameters = extractParameters(nodeInstance.parameters);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
id: nodeId,
|
|
182
|
+
name: nodeInstance.name || nodeId,
|
|
183
|
+
fileName,
|
|
184
|
+
description: getNodeDescription(nodeId, nodeInstance),
|
|
185
|
+
parameters,
|
|
186
|
+
categories,
|
|
187
|
+
typeVersion: nodeInstance.typeVersion,
|
|
188
|
+
credentials: nodeInstance.credentials ? Object.keys(nodeInstance.credentials) : [],
|
|
189
|
+
// Store the nodeType directly from the JSON data with original casing
|
|
190
|
+
originalNodeType: nodeData.nodeType || null
|
|
191
|
+
};
|
|
192
|
+
} catch (error) {
|
|
193
|
+
logger.warn(`Error extracting node info for ${nodeId}:`, error);
|
|
194
|
+
return {
|
|
195
|
+
id: nodeId,
|
|
196
|
+
name: nodeId,
|
|
197
|
+
fileName,
|
|
198
|
+
description: 'Error extracting node information',
|
|
199
|
+
parameters: [],
|
|
200
|
+
categories: []
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Determine categories for a node based on its ID and structure
|
|
207
|
+
*
|
|
208
|
+
* Analyzes the node identifier and structure to categorize it
|
|
209
|
+
* according to its functionality (e.g., Trigger, HTTP, Database).
|
|
210
|
+
*
|
|
211
|
+
* @param {string} nodeId - The node identifier
|
|
212
|
+
* @param {Object} nodeInstance - Node instance data
|
|
213
|
+
* @returns {Array<string>} Categories for the node
|
|
214
|
+
*/
|
|
215
|
+
const determineCategories = (nodeId, nodeInstance) => {
|
|
216
|
+
const categories = new Set();
|
|
217
|
+
|
|
218
|
+
// Check for trigger nodes
|
|
219
|
+
if (nodeId.toLowerCase().includes('trigger')) {
|
|
220
|
+
categories.add('Trigger');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Check for common categories
|
|
224
|
+
if (nodeId.match(/^(http|rest|api|webhook)/i)) {
|
|
225
|
+
categories.add('HTTP');
|
|
226
|
+
} else if (nodeId.match(/^(gmail|email|smtp|mail)/i)) {
|
|
227
|
+
categories.add('Email');
|
|
228
|
+
} else if (nodeId.match(/^(postgres|mysql|mongodb|db|sql|database)/i)) {
|
|
229
|
+
categories.add('Database');
|
|
230
|
+
} else if (nodeId.match(/^(file|s3|storage)/i)) {
|
|
231
|
+
categories.add('File');
|
|
232
|
+
} else if (nodeId.match(/^(slack|telegram|discord|chat|message)/i)) {
|
|
233
|
+
categories.add('Communication');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check operation-based categories
|
|
237
|
+
if (nodeInstance.parameters) {
|
|
238
|
+
if (nodeInstance.parameters.operation) {
|
|
239
|
+
categories.add('Operation');
|
|
240
|
+
}
|
|
241
|
+
if (nodeInstance.parameters.resource) {
|
|
242
|
+
categories.add('Resource');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return Array.from(categories);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Generate a description for the node
|
|
251
|
+
*
|
|
252
|
+
* Creates a human-readable description of the node based on its
|
|
253
|
+
* identifier and category to help AI agents understand its purpose.
|
|
254
|
+
*
|
|
255
|
+
* @param {string} nodeId - The node identifier
|
|
256
|
+
* @param {Object} nodeInstance - Node instance data
|
|
257
|
+
* @returns {string} Node description
|
|
258
|
+
*/
|
|
259
|
+
const getNodeDescription = (nodeId, nodeInstance) => {
|
|
260
|
+
// Remove any 'Trigger' suffix for cleaner descriptions
|
|
261
|
+
const baseName = nodeId.replace(/Trigger$/, '');
|
|
262
|
+
|
|
263
|
+
if (nodeId.endsWith('Trigger')) {
|
|
264
|
+
return `Trigger node for ${baseName} events`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Generate description based on categories
|
|
268
|
+
const categories = determineCategories(nodeId, nodeInstance);
|
|
269
|
+
if (categories.includes('HTTP')) {
|
|
270
|
+
return `Make HTTP requests to ${baseName} API`;
|
|
271
|
+
} else if (categories.includes('Database')) {
|
|
272
|
+
return `Interact with ${baseName} database`;
|
|
273
|
+
} else if (categories.includes('Email')) {
|
|
274
|
+
return `Send or process emails with ${baseName}`;
|
|
275
|
+
} else if (categories.includes('File')) {
|
|
276
|
+
return `Handle file operations with ${baseName}`;
|
|
277
|
+
} else if (categories.includes('Communication')) {
|
|
278
|
+
return `Send or receive messages with ${baseName}`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Default description
|
|
282
|
+
return `${baseName} integration node`;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Extract parameters from node instance
|
|
287
|
+
*
|
|
288
|
+
* Processes the raw parameter data from a node and converts it
|
|
289
|
+
* into a structured format, identifying credential parameters.
|
|
290
|
+
*
|
|
291
|
+
* @param {Object} paramData - Raw parameter data
|
|
292
|
+
* @returns {Array} Structured parameter information
|
|
293
|
+
*/
|
|
294
|
+
const extractParameters = (paramData) => {
|
|
295
|
+
if (!paramData) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const parameters = [];
|
|
300
|
+
|
|
301
|
+
for (const [key, value] of Object.entries(paramData)) {
|
|
302
|
+
// Skip null values and empty objects
|
|
303
|
+
if (value === null || (typeof value === 'object' && Object.keys(value).length === 0)) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Determine parameter type
|
|
308
|
+
let type = typeof value;
|
|
309
|
+
if (type === 'object') {
|
|
310
|
+
type = Array.isArray(value) ? 'array' : 'object';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Sanitize credential parameters
|
|
314
|
+
const sanitizedValue = key.toLowerCase().includes('credential') ?
|
|
315
|
+
{ type: 'credential', required: false } : value;
|
|
316
|
+
|
|
317
|
+
parameters.push({
|
|
318
|
+
name: key,
|
|
319
|
+
type,
|
|
320
|
+
value: sanitizedValue,
|
|
321
|
+
isCredential: key.toLowerCase().includes('credential')
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return parameters;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get node information from cache or source
|
|
330
|
+
*
|
|
331
|
+
* Retrieves node information from cache if available and valid,
|
|
332
|
+
* otherwise scans the workflow_nodes directory and updates the cache.
|
|
333
|
+
*
|
|
334
|
+
* @returns {Promise<Array>} Array of node information
|
|
335
|
+
*/
|
|
336
|
+
const getNodesFromSource = async () => {
|
|
337
|
+
// Check if cache is still valid
|
|
338
|
+
const now = Date.now();
|
|
339
|
+
if (nodeCache && cacheTimestamp && (now - cacheTimestamp < CACHE_TTL_MS)) {
|
|
340
|
+
logger.debug('Using cached node data');
|
|
341
|
+
return nodeCache;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
logger.debug('Cache invalid or expired, scanning for node data');
|
|
345
|
+
// Scan and cache the nodes
|
|
346
|
+
const nodes = await scanWorkflowNodes();
|
|
347
|
+
nodeCache = nodes;
|
|
348
|
+
cacheTimestamp = now;
|
|
349
|
+
|
|
350
|
+
return nodes;
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Sanitize credential parameters in node responses
|
|
355
|
+
*
|
|
356
|
+
* Processes parameters to ensure any credential-related information
|
|
357
|
+
* is properly sanitized before being included in responses.
|
|
358
|
+
*
|
|
359
|
+
* @param {Array} parameters - Array of parameters
|
|
360
|
+
* @returns {Array} Sanitized parameters
|
|
361
|
+
*/
|
|
362
|
+
const sanitizeCredentialParameters = (parameters) => {
|
|
363
|
+
if (!parameters) return [];
|
|
364
|
+
|
|
365
|
+
return parameters.map(param => {
|
|
366
|
+
if (param.isCredential) {
|
|
367
|
+
return {
|
|
368
|
+
...param,
|
|
369
|
+
value: { credentialType: param.name }
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
return param;
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Search nodes based on provided filters
|
|
378
|
+
*
|
|
379
|
+
* Allows searching for nodes based on various criteria including
|
|
380
|
+
* category, keyword, and functionality.
|
|
381
|
+
*
|
|
382
|
+
* @param {Object} params - Search parameters
|
|
383
|
+
* @param {string} [params.category] - Filter by node category
|
|
384
|
+
* @param {string} [params.keyword] - Search by keyword in name or description
|
|
385
|
+
* @param {string} [params.functionality] - Filter by node functionality
|
|
386
|
+
* @returns {Promise<Object>} Search results with count and nodes
|
|
387
|
+
*/
|
|
388
|
+
const searchNodes = async (params) => {
|
|
389
|
+
try {
|
|
390
|
+
const { category, keyword, functionality } = params;
|
|
391
|
+
logger.debug('Searching nodes with params:', { category, keyword, functionality });
|
|
392
|
+
|
|
393
|
+
// Get all nodes from cache or scan directory
|
|
394
|
+
let nodes = await getNodesFromSource();
|
|
395
|
+
|
|
396
|
+
// Apply filters if provided
|
|
397
|
+
if (category) {
|
|
398
|
+
nodes = nodes.filter(node =>
|
|
399
|
+
node.categories.some(cat =>
|
|
400
|
+
cat.toLowerCase().includes(category.toLowerCase())
|
|
401
|
+
)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (keyword) {
|
|
406
|
+
const keywordLower = keyword.toLowerCase();
|
|
407
|
+
nodes = nodes.filter(node =>
|
|
408
|
+
node.name.toLowerCase().includes(keywordLower) ||
|
|
409
|
+
node.description.toLowerCase().includes(keywordLower) ||
|
|
410
|
+
node.id.toLowerCase().includes(keywordLower) ||
|
|
411
|
+
// Also check normalized type and original type if available
|
|
412
|
+
(node.normalizedType && node.normalizedType.includes(keywordLower)) ||
|
|
413
|
+
(node.type && node.type.toLowerCase().includes(keywordLower))
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (functionality) {
|
|
418
|
+
const functionalityLower = functionality.toLowerCase();
|
|
419
|
+
nodes = nodes.filter(node =>
|
|
420
|
+
node.description.toLowerCase().includes(functionalityLower) ||
|
|
421
|
+
node.categories.some(cat => cat.toLowerCase().includes(functionalityLower))
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Sanitize any credential-related information in the response
|
|
426
|
+
const sanitizedNodes = nodes.map(node => ({
|
|
427
|
+
id: node.id,
|
|
428
|
+
name: node.name,
|
|
429
|
+
description: node.description,
|
|
430
|
+
parameters: sanitizeCredentialParameters(node.parameters),
|
|
431
|
+
categories: node.categories,
|
|
432
|
+
type: node.type, // Include the node type
|
|
433
|
+
originalNodeType: node.originalNodeType, // Include the original node type with exact casing
|
|
434
|
+
normalizedType: node.normalizedType // Include the normalized node type for reference
|
|
435
|
+
}));
|
|
436
|
+
|
|
437
|
+
logger.debug(`Search returned ${sanitizedNodes.length} results`);
|
|
438
|
+
return {
|
|
439
|
+
count: sanitizedNodes.length,
|
|
440
|
+
nodes: sanitizedNodes
|
|
441
|
+
};
|
|
442
|
+
} catch (error) {
|
|
443
|
+
logger.error('Error in searchNodes function:', error);
|
|
444
|
+
throw new Error(`Failed to search nodes: ${error.message}`);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Tool definition for the search_nodes MCP tool
|
|
450
|
+
*
|
|
451
|
+
* Registers the search_nodes tool with the MCP server, defining its
|
|
452
|
+
* parameters, description, and implementation.
|
|
453
|
+
*/
|
|
454
|
+
const searchNodesTool = createTool(
|
|
455
|
+
'Search for available n8n nodes and their parameters',
|
|
456
|
+
{
|
|
457
|
+
category: {
|
|
458
|
+
type: 'string',
|
|
459
|
+
description: 'Filter nodes by category (e.g., "trigger", "http", "database")',
|
|
460
|
+
optional: true
|
|
461
|
+
},
|
|
462
|
+
keyword: {
|
|
463
|
+
type: 'string',
|
|
464
|
+
description: 'Search by name or description',
|
|
465
|
+
optional: true
|
|
466
|
+
},
|
|
467
|
+
functionality: {
|
|
468
|
+
type: 'string',
|
|
469
|
+
description: 'Filter by node functionality/purpose',
|
|
470
|
+
optional: true
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
searchNodes
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
// Export the module's functions and tools
|
|
477
|
+
module.exports = {
|
|
478
|
+
searchNodesTool,
|
|
479
|
+
scanWorkflowNodes,
|
|
480
|
+
getNodesFromSource,
|
|
481
|
+
searchNodes,
|
|
482
|
+
sanitizeCredentialParameters, // Exported for testing
|
|
483
|
+
// Export cache reset function for testing
|
|
484
|
+
resetCache: () => {
|
|
485
|
+
nodeCache = null;
|
|
486
|
+
cacheTimestamp = null;
|
|
487
|
+
}
|
|
488
|
+
};
|