#
tokens: 40487/50000 2/614 files (page 42/59)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 42 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

--------------------------------------------------------------------------------
/docs/local/P0_IMPLEMENTATION_PLAN.md:
--------------------------------------------------------------------------------

```markdown
   1 | # P0 Priorities Implementation Plan
   2 | ## Critical Fixes for n8n-mcp Based on Production Telemetry Data
   3 | 
   4 | **Date:** October 2, 2025
   5 | **Analysis Period:** September 26 - October 2, 2025
   6 | **Data Volume:** 212,375 events | 5,751 workflows | 2,119 users
   7 | **Target:** Reduce error rate from 5-10% to <2%
   8 | 
   9 | ---
  10 | 
  11 | ## Executive Summary
  12 | 
  13 | This document provides a comprehensive implementation plan for the three P0 (Priority 0 - Critical) issues identified through deep analysis of production telemetry data. These fixes will eliminate **80% of all validation errors** and significantly improve the AI agent experience.
  14 | 
  15 | ### Impact Summary
  16 | 
  17 | | Issue | Current Failure Rate | Post-Fix Target | Affected Users | Estimated Effort |
  18 | |-------|---------------------|-----------------|----------------|------------------|
  19 | | **P0-R1**: Node Type Prefix Normalization | 80% of validation errors | <1% | Hundreds | 2 days |
  20 | | **P0-R2**: Null-Safety Audit | 10-18% TypeError rate | <1% | 30+ | 2 days |
  21 | | **P0-R3**: Pre-extract Template Configs + Remove get_node_for_task | 28% failure rate, 5.9% coverage | N/A (tool removed), 100% coverage | 197 (migrated) | 5 days |
  22 | 
  23 | **Total Effort:** 2 weeks (v2.15.0 release)
  24 | 
  25 | ---
  26 | 
  27 | ## Table of Contents
  28 | 
  29 | 1. [P0-R1: Auto-Normalize Node Type Prefixes](#p0-r1-auto-normalize-node-type-prefixes)
  30 | 2. [P0-R2: Complete Null-Safety Audit](#p0-r2-complete-null-safety-audit)
  31 | 3. [P0-R3: Pre-extract Template Configurations + Remove get_node_for_task](#p0-r3-pre-extract-template-configurations--remove-get_node_for_task)
  32 | 4. [Implementation Order & Timeline](#implementation-order--timeline)
  33 | 5. [Testing Strategy](#testing-strategy)
  34 | 6. [Rollback Plan](#rollback-plan)
  35 | 7. [Success Metrics](#success-metrics)
  36 | 
  37 | ---
  38 | 
  39 | ## P0-R1: Auto-Normalize Node Type Prefixes
  40 | 
  41 | ### Problem Statement
  42 | 
  43 | **Impact:** 4,800+ validation errors (80% of all validation errors) from a single root cause
  44 | 
  45 | AI agents frequently produce `nodes-base.X` instead of `n8n-nodes-base.X`, causing validation failures. This is the single largest source of user frustration.
  46 | 
  47 | **Example Error:**
  48 | ```
  49 | Error: Invalid node type: "nodes-base.set". Use "n8n-nodes-base.set" instead.
  50 | ```
  51 | 
  52 | ### Root Cause Analysis
  53 | 
  54 | **Current Implementation Issues:**
  55 | 
  56 | 1. **Existing normalization is BACKWARD:**
  57 |    - `src/utils/node-type-utils.ts` normalizes TO short form (`nodes-base.`)
  58 |    - But validation expects full form (`n8n-nodes-base.`)
  59 |    - This is the **opposite** of what we need
  60 | 
  61 | 2. **Location of the bug:**
  62 |    ```typescript
  63 |    // src/utils/node-type-utils.ts:18-20
  64 |    return type
  65 |      .replace(/^n8n-nodes-base\./, 'nodes-base.')  // ❌ WRONG DIRECTION
  66 |      .replace(/^@n8n\/n8n-nodes-langchain\./, 'nodes-langchain.');
  67 |    ```
  68 | 
  69 | 3. **Why AI agents produce short form:**
  70 |    - Token efficiency (LLMs abbreviate to save tokens)
  71 |    - Pattern learning from examples
  72 |    - Natural language preference for concise names
  73 | 
  74 | ### Solution Architecture
  75 | 
  76 | **Strategy:** Normalize ALL node types to FULL form before validation
  77 | 
  78 | #### 1. Create Universal Node Type Normalizer
  79 | 
  80 | **File:** `src/utils/node-type-normalizer.ts` (NEW)
  81 | 
  82 | ```typescript
  83 | /**
  84 |  * Universal Node Type Normalizer
  85 |  *
  86 |  * Converts ANY node type variation to the canonical full form expected by n8n
  87 |  *
  88 |  * Handles:
  89 |  * - Short form → Full form (nodes-base.X → n8n-nodes-base.X)
  90 |  * - Already full form → Unchanged
  91 |  * - LangChain nodes → Proper @n8n/ prefix
  92 |  */
  93 | 
  94 | export interface NodeTypeNormalizationResult {
  95 |   original: string;
  96 |   normalized: string;
  97 |   wasNormalized: boolean;
  98 |   package: 'base' | 'langchain' | 'community' | 'unknown';
  99 | }
 100 | 
 101 | export class NodeTypeNormalizer {
 102 | 
 103 |   /**
 104 |    * Normalize node type to canonical full form
 105 |    *
 106 |    * @example
 107 |    * normalizeToFullForm('nodes-base.webhook')
 108 |    * // → 'n8n-nodes-base.webhook'
 109 |    *
 110 |    * normalizeToFullForm('n8n-nodes-base.webhook')
 111 |    * // → 'n8n-nodes-base.webhook' (unchanged)
 112 |    *
 113 |    * normalizeToFullForm('nodes-langchain.agent')
 114 |    * // → '@n8n/n8n-nodes-langchain.agent'
 115 |    */
 116 |   static normalizeToFullForm(type: string): string {
 117 |     if (!type || typeof type !== 'string') {
 118 |       return type;
 119 |     }
 120 | 
 121 |     // Already in full form - return unchanged
 122 |     if (type.startsWith('n8n-nodes-base.')) {
 123 |       return type;
 124 |     }
 125 |     if (type.startsWith('@n8n/n8n-nodes-langchain.')) {
 126 |       return type;
 127 |     }
 128 | 
 129 |     // Normalize short forms to full form
 130 |     if (type.startsWith('nodes-base.')) {
 131 |       return type.replace(/^nodes-base\./, 'n8n-nodes-base.');
 132 |     }
 133 |     if (type.startsWith('nodes-langchain.')) {
 134 |       return type.replace(/^nodes-langchain\./, '@n8n/n8n-nodes-langchain.');
 135 |     }
 136 |     if (type.startsWith('n8n-nodes-langchain.')) {
 137 |       return type.replace(/^n8n-nodes-langchain\./, '@n8n/n8n-nodes-langchain.');
 138 |     }
 139 | 
 140 |     // No prefix - might be community node or error
 141 |     return type;
 142 |   }
 143 | 
 144 |   /**
 145 |    * Normalize with detailed result
 146 |    */
 147 |   static normalizeWithDetails(type: string): NodeTypeNormalizationResult {
 148 |     const original = type;
 149 |     const normalized = this.normalizeToFullForm(type);
 150 | 
 151 |     return {
 152 |       original,
 153 |       normalized,
 154 |       wasNormalized: original !== normalized,
 155 |       package: this.detectPackage(normalized)
 156 |     };
 157 |   }
 158 | 
 159 |   /**
 160 |    * Detect package type from node type
 161 |    */
 162 |   private static detectPackage(type: string): 'base' | 'langchain' | 'community' | 'unknown' {
 163 |     if (type.startsWith('n8n-nodes-base.')) return 'base';
 164 |     if (type.startsWith('@n8n/n8n-nodes-langchain.')) return 'langchain';
 165 |     if (type.includes('.')) return 'community';
 166 |     return 'unknown';
 167 |   }
 168 | 
 169 |   /**
 170 |    * Batch normalize multiple node types
 171 |    */
 172 |   static normalizeBatch(types: string[]): Map<string, string> {
 173 |     const result = new Map<string, string>();
 174 |     for (const type of types) {
 175 |       result.set(type, this.normalizeToFullForm(type));
 176 |     }
 177 |     return result;
 178 |   }
 179 | 
 180 |   /**
 181 |    * Normalize all node types in a workflow
 182 |    */
 183 |   static normalizeWorkflowNodeTypes(workflow: any): any {
 184 |     if (!workflow?.nodes || !Array.isArray(workflow.nodes)) {
 185 |       return workflow;
 186 |     }
 187 | 
 188 |     return {
 189 |       ...workflow,
 190 |       nodes: workflow.nodes.map((node: any) => ({
 191 |         ...node,
 192 |         type: this.normalizeToFullForm(node.type)
 193 |       }))
 194 |     };
 195 |   }
 196 | }
 197 | ```
 198 | 
 199 | #### 2. Apply Normalization in All Entry Points
 200 | 
 201 | **File:** `src/services/workflow-validator.ts`
 202 | 
 203 | **Change at line 250:** (validateWorkflowStructure method)
 204 | 
 205 | ```typescript
 206 | // BEFORE (line 250-252):
 207 | const normalizedType = normalizeNodeType(singleNode.type);
 208 | const isWebhook = normalizedType === 'nodes-base.webhook' ||
 209 |                  normalizedType === 'nodes-base.webhookTrigger';
 210 | 
 211 | // AFTER:
 212 | import { NodeTypeNormalizer } from '../utils/node-type-normalizer';
 213 | 
 214 | const normalizedType = NodeTypeNormalizer.normalizeToFullForm(singleNode.type);
 215 | const isWebhook = normalizedType === 'n8n-nodes-base.webhook' ||
 216 |                  normalizedType === 'n8n-nodes-base.webhookTrigger';
 217 | ```
 218 | 
 219 | **Change at line 368-376:** (validateAllNodes method)
 220 | 
 221 | ```typescript
 222 | // BEFORE:
 223 | // Get node definition - try multiple formats
 224 | let nodeInfo = this.nodeRepository.getNode(node.type);
 225 | 
 226 | // If not found, try with normalized type
 227 | if (!nodeInfo) {
 228 |   const normalizedType = normalizeNodeType(node.type);
 229 |   if (normalizedType !== node.type) {
 230 |     nodeInfo = this.nodeRepository.getNode(normalizedType);
 231 |   }
 232 | }
 233 | 
 234 | // AFTER:
 235 | // Normalize node type FIRST
 236 | const normalizedType = NodeTypeNormalizer.normalizeToFullForm(node.type);
 237 | const nodeInfo = this.nodeRepository.getNode(normalizedType);
 238 | 
 239 | // Update node type in place if normalized
 240 | if (normalizedType !== node.type) {
 241 |   node.type = normalizedType;
 242 | }
 243 | ```
 244 | 
 245 | **File:** `src/mcp/handlers-n8n-manager.ts`
 246 | 
 247 | **Add normalization in handleCreateWorkflow (line 281-310):**
 248 | 
 249 | ```typescript
 250 | // BEFORE validation:
 251 | const input = createWorkflowSchema.parse(args);
 252 | 
 253 | // AFTER: Add normalization
 254 | const input = createWorkflowSchema.parse(args);
 255 | 
 256 | // Normalize all node types before validation
 257 | const normalizedInput = NodeTypeNormalizer.normalizeWorkflowNodeTypes(input);
 258 | 
 259 | // Validate workflow structure
 260 | const errors = validateWorkflowStructure(normalizedInput);
 261 | ```
 262 | 
 263 | **Apply same pattern to:**
 264 | - `handleUpdateWorkflow` (line 520)
 265 | - `validateWorkflow` tool handler
 266 | - Any other workflow creation/update entry points
 267 | 
 268 | #### 3. Update Node Repository for Flexible Lookups
 269 | 
 270 | **File:** `src/database/node-repository.ts`
 271 | 
 272 | **Enhance getNode method (line 54):**
 273 | 
 274 | ```typescript
 275 | /**
 276 |  * Get node with automatic type normalization
 277 |  */
 278 | getNode(nodeType: string): any {
 279 |   // Try normalized type first
 280 |   const normalizedType = NodeTypeNormalizer.normalizeToFullForm(nodeType);
 281 | 
 282 |   const row = this.db.prepare(`
 283 |     SELECT * FROM nodes WHERE node_type = ?
 284 |   `).get(normalizedType) as any;
 285 | 
 286 |   if (!row) {
 287 |     // Fallback: try original type if normalization didn't help
 288 |     if (normalizedType !== nodeType) {
 289 |       const originalRow = this.db.prepare(`
 290 |         SELECT * FROM nodes WHERE node_type = ?
 291 |       `).get(nodeType) as any;
 292 | 
 293 |       if (originalRow) return this.parseNodeRow(originalRow);
 294 |     }
 295 |     return null;
 296 |   }
 297 | 
 298 |   return this.parseNodeRow(row);
 299 | }
 300 | ```
 301 | 
 302 | ### Testing Requirements
 303 | 
 304 | **File:** `tests/unit/utils/node-type-normalizer.test.ts` (NEW)
 305 | 
 306 | ```typescript
 307 | describe('NodeTypeNormalizer', () => {
 308 |   describe('normalizeToFullForm', () => {
 309 |     it('should normalize short base form to full form', () => {
 310 |       expect(NodeTypeNormalizer.normalizeToFullForm('nodes-base.webhook'))
 311 |         .toBe('n8n-nodes-base.webhook');
 312 |     });
 313 | 
 314 |     it('should normalize short langchain form to full form', () => {
 315 |       expect(NodeTypeNormalizer.normalizeToFullForm('nodes-langchain.agent'))
 316 |         .toBe('@n8n/n8n-nodes-langchain.agent');
 317 |     });
 318 | 
 319 |     it('should leave full forms unchanged', () => {
 320 |       expect(NodeTypeNormalizer.normalizeToFullForm('n8n-nodes-base.webhook'))
 321 |         .toBe('n8n-nodes-base.webhook');
 322 |     });
 323 | 
 324 |     it('should handle edge cases', () => {
 325 |       expect(NodeTypeNormalizer.normalizeToFullForm('')).toBe('');
 326 |       expect(NodeTypeNormalizer.normalizeToFullForm(null as any)).toBe(null);
 327 |     });
 328 |   });
 329 | 
 330 |   describe('normalizeWorkflowNodeTypes', () => {
 331 |     it('should normalize all nodes in workflow', () => {
 332 |       const workflow = {
 333 |         nodes: [
 334 |           { type: 'nodes-base.webhook', id: '1', name: 'Webhook' },
 335 |           { type: 'nodes-base.set', id: '2', name: 'Set' }
 336 |         ],
 337 |         connections: {}
 338 |       };
 339 | 
 340 |       const result = NodeTypeNormalizer.normalizeWorkflowNodeTypes(workflow);
 341 | 
 342 |       expect(result.nodes[0].type).toBe('n8n-nodes-base.webhook');
 343 |       expect(result.nodes[1].type).toBe('n8n-nodes-base.set');
 344 |     });
 345 |   });
 346 | });
 347 | ```
 348 | 
 349 | ### Success Criteria
 350 | 
 351 | - [x] All workflow validation tests pass with both short and full node type forms
 352 | - [x] 0 "Invalid node type" errors for variations of core nodes
 353 | - [x] Telemetry shows <1% validation errors related to node type prefixes
 354 | - [x] No breaking changes to existing workflows
 355 | 
 356 | **Status:** ✅ COMPLETED (October 2, 2025)
 357 | **Commit:** ed7de10
 358 | 
 359 | ### Estimated Effort
 360 | 
 361 | **Total: 2-4 hours**
 362 | 
 363 | - Implementation: 1-2 hours
 364 | - Testing: 1 hour
 365 | - Documentation: 30 minutes
 366 | - Code review: 30 minutes
 367 | 
 368 | ---
 369 | 
 370 | ## P0-R2: Complete Null-Safety Audit
 371 | 
 372 | ### Problem Statement
 373 | 
 374 | **Impact:** 10-18% TypeError failures in node information tools affecting 1,000+ calls
 375 | 
 376 | ```
 377 | TypeError: Cannot read property 'text' of undefined
 378 | ```
 379 | 
 380 | **Affected Tools:**
 381 | - `get_node_essentials`: 483 failures (10% of 4,909 calls)
 382 | - `get_node_info`: 352 failures (18% of 1,988 calls)
 383 | - `get_node_documentation`: 136 failures (7% of 1,919 calls)
 384 | 
 385 | ### Root Cause Analysis
 386 | 
 387 | **From CHANGELOG 2.14.0:**
 388 | > "Fixed TypeErrors in get_node_info, get_node_essentials, and get_node_documentation tools"
 389 | > "Added null safety checks for undefined node properties"
 390 | 
 391 | **The fix was incomplete.** Residual issues remain in:
 392 | 
 393 | 1. Nested property access without guards
 394 | 2. Edge cases with unusual/legacy node structures
 395 | 3. Missing properties in database
 396 | 4. Assumptions about property structure
 397 | 
 398 | ### Current Implementation Analysis
 399 | 
 400 | **File:** `src/database/node-repository.ts`
 401 | 
 402 | **Problem areas identified:**
 403 | 
 404 | ```typescript
 405 | // Line 73-78: Good - has safeJsonParse
 406 | properties: this.safeJsonParse(row.properties_schema, []),
 407 | operations: this.safeJsonParse(row.operations, []),
 408 | credentials: this.safeJsonParse(row.credentials_required, []),
 409 | 
 410 | // But doesn't protect against:
 411 | // - properties being null after parse
 412 | // - Nested properties like properties[0].description.text
 413 | // - Missing fields in properties array
 414 | ```
 415 | 
 416 | **handlers for get_node_essentials/info need to be found and audited**
 417 | 
 418 | ### Solution Architecture
 419 | 
 420 | #### 1. Enhanced Safe Property Access Utilities
 421 | 
 422 | **File:** `src/utils/safe-property-access.ts` (NEW)
 423 | 
 424 | ```typescript
 425 | /**
 426 |  * Safe Property Access Utilities
 427 |  *
 428 |  * Provides defensive property access with fallbacks
 429 |  */
 430 | 
 431 | export class SafePropertyAccess {
 432 |   /**
 433 |    * Safely get nested property with default
 434 |    */
 435 |   static get<T>(obj: any, path: string, defaultValue: T): T {
 436 |     if (!obj || typeof obj !== 'object') return defaultValue;
 437 | 
 438 |     const keys = path.split('.');
 439 |     let current = obj;
 440 | 
 441 |     for (const key of keys) {
 442 |       if (current === null || current === undefined) {
 443 |         return defaultValue;
 444 |       }
 445 |       if (typeof current !== 'object') {
 446 |         return defaultValue;
 447 |       }
 448 |       current = current[key];
 449 |     }
 450 | 
 451 |     return current !== undefined ? current : defaultValue;
 452 |   }
 453 | 
 454 |   /**
 455 |    * Safely get array with default
 456 |    */
 457 |   static getArray<T>(obj: any, path: string, defaultValue: T[] = []): T[] {
 458 |     const value = this.get(obj, path, defaultValue);
 459 |     return Array.isArray(value) ? value : defaultValue;
 460 |   }
 461 | 
 462 |   /**
 463 |    * Safely get string with default
 464 |    */
 465 |   static getString(obj: any, path: string, defaultValue: string = ''): string {
 466 |     const value = this.get(obj, path, defaultValue);
 467 |     return typeof value === 'string' ? value : defaultValue;
 468 |   }
 469 | 
 470 |   /**
 471 |    * Safely get number with default
 472 |    */
 473 |   static getNumber(obj: any, path: string, defaultValue: number = 0): number {
 474 |     const value = this.get(obj, path, defaultValue);
 475 |     return typeof value === 'number' && !isNaN(value) ? value : defaultValue;
 476 |   }
 477 | 
 478 |   /**
 479 |    * Safely get boolean with default
 480 |    */
 481 |   static getBoolean(obj: any, path: string, defaultValue: boolean = false): boolean {
 482 |     const value = this.get(obj, path, defaultValue);
 483 |     return typeof value === 'boolean' ? value : defaultValue;
 484 |   }
 485 | 
 486 |   /**
 487 |    * Extract description from multiple possible locations
 488 |    */
 489 |   static extractDescription(obj: any): string {
 490 |     // Try common description locations
 491 |     const locations = [
 492 |       'description',
 493 |       'properties.description',
 494 |       'properties.description.text',
 495 |       'subtitle',
 496 |       'displayName'
 497 |     ];
 498 | 
 499 |     for (const location of locations) {
 500 |       const value = this.getString(obj, location);
 501 |       if (value) return value;
 502 |     }
 503 | 
 504 |     return 'No description available';
 505 |   }
 506 | 
 507 |   /**
 508 |    * Extract display name from multiple possible locations
 509 |    */
 510 |   static extractDisplayName(obj: any, fallback: string = 'Unknown'): string {
 511 |     const locations = [
 512 |       'displayName',
 513 |       'name',
 514 |       'label',
 515 |       'title'
 516 |     ];
 517 | 
 518 |     for (const location of locations) {
 519 |       const value = this.getString(obj, location);
 520 |       if (value) return value;
 521 |     }
 522 | 
 523 |     return fallback;
 524 |   }
 525 | }
 526 | ```
 527 | 
 528 | #### 2. Null-Safe Node Repository Methods
 529 | 
 530 | **File:** `src/database/node-repository.ts`
 531 | 
 532 | **Refactor getNode method (line 54):**
 533 | 
 534 | ```typescript
 535 | import { SafePropertyAccess } from '../utils/safe-property-access';
 536 | 
 537 | /**
 538 |  * Get node with comprehensive null-safety
 539 |  */
 540 | getNode(nodeType: string): any | null {
 541 |   try {
 542 |     // Normalize type first
 543 |     const normalizedType = NodeTypeNormalizer.normalizeToFullForm(nodeType);
 544 | 
 545 |     const row = this.db.prepare(`
 546 |       SELECT * FROM nodes WHERE node_type = ?
 547 |     `).get(normalizedType) as any;
 548 | 
 549 |     if (!row) return null;
 550 | 
 551 |     // Use safe property access for all fields
 552 |     return {
 553 |       nodeType: SafePropertyAccess.getString(row, 'node_type', normalizedType),
 554 |       displayName: SafePropertyAccess.extractDisplayName(row,
 555 |         SafePropertyAccess.getString(row, 'display_name', 'Unknown Node')),
 556 |       description: SafePropertyAccess.extractDescription(row),
 557 |       category: SafePropertyAccess.getString(row, 'category', 'Uncategorized'),
 558 |       developmentStyle: SafePropertyAccess.getString(row, 'development_style', 'declarative'),
 559 |       package: SafePropertyAccess.getString(row, 'package_name', 'unknown'),
 560 |       isAITool: SafePropertyAccess.getBoolean(row, 'is_ai_tool', false),
 561 |       isTrigger: SafePropertyAccess.getBoolean(row, 'is_trigger', false),
 562 |       isWebhook: SafePropertyAccess.getBoolean(row, 'is_webhook', false),
 563 |       isVersioned: SafePropertyAccess.getBoolean(row, 'is_versioned', false),
 564 |       version: SafePropertyAccess.getNumber(row, 'version', 1),
 565 |       properties: this.safeParseProperties(row.properties_schema),
 566 |       operations: this.safeParseArray(row.operations),
 567 |       credentials: this.safeParseArray(row.credentials_required),
 568 |       hasDocumentation: !!row.documentation,
 569 |       outputs: row.outputs ? this.safeJsonParse(row.outputs, null) : null,
 570 |       outputNames: row.output_names ? this.safeJsonParse(row.output_names, null) : null
 571 |     };
 572 |   } catch (error) {
 573 |     console.error(`Error getting node ${nodeType}:`, error);
 574 |     return null;
 575 |   }
 576 | }
 577 | 
 578 | /**
 579 |  * Safely parse properties with validation
 580 |  */
 581 | private safeParseProperties(json: string): any[] {
 582 |   try {
 583 |     const parsed = JSON.parse(json);
 584 |     if (!Array.isArray(parsed)) return [];
 585 | 
 586 |     // Validate each property has minimum required fields
 587 |     return parsed.map(prop => ({
 588 |       name: SafePropertyAccess.getString(prop, 'name', 'unknown'),
 589 |       displayName: SafePropertyAccess.extractDisplayName(prop),
 590 |       type: SafePropertyAccess.getString(prop, 'type', 'string'),
 591 |       required: SafePropertyAccess.getBoolean(prop, 'required', false),
 592 |       default: prop.default !== undefined ? prop.default : null,
 593 |       description: SafePropertyAccess.extractDescription(prop),
 594 |       options: SafePropertyAccess.getArray(prop, 'options', []),
 595 |       displayOptions: prop.displayOptions || null
 596 |     }));
 597 |   } catch {
 598 |     return [];
 599 |   }
 600 | }
 601 | 
 602 | /**
 603 |  * Safely parse array field
 604 |  */
 605 | private safeParseArray(json: string): any[] {
 606 |   try {
 607 |     const parsed = JSON.parse(json);
 608 |     return Array.isArray(parsed) ? parsed : [];
 609 |   } catch {
 610 |     return [];
 611 |   }
 612 | }
 613 | ```
 614 | 
 615 | #### 3. Find and Fix Handler Functions
 616 | 
 617 | **Action Required:** Search for handler functions that call getNode and add null checks
 618 | 
 619 | **Pattern to search for:**
 620 | ```bash
 621 | grep -r "getNode\|getNodeEssentials\|getNodeInfo" src/mcp/ --include="*.ts"
 622 | ```
 623 | 
 624 | **Add null checks like:**
 625 | ```typescript
 626 | const node = repository.getNode(nodeType);
 627 | if (!node) {
 628 |   return {
 629 |     success: false,
 630 |     error: `Node type "${nodeType}" not found. Use search_nodes to find available nodes.`
 631 |   };
 632 | }
 633 | ```
 634 | 
 635 | ### Testing Requirements
 636 | 
 637 | **File:** `tests/unit/database/node-repository-null-safety.test.ts` (NEW)
 638 | 
 639 | ```typescript
 640 | describe('NodeRepository - Null Safety', () => {
 641 |   it('should handle node with missing description', () => {
 642 |     // Insert node with minimal data
 643 |     const node = { type: 'test.node', name: 'Test' };
 644 |     db.prepare('INSERT INTO nodes (node_type, display_name) VALUES (?, ?)').run(node.type, node.name);
 645 | 
 646 |     const result = repository.getNode('test.node');
 647 |     expect(result).not.toBeNull();
 648 |     expect(result.description).toBe('No description available');
 649 |     expect(result.properties).toEqual([]);
 650 |   });
 651 | 
 652 |   it('should handle node with malformed JSON', () => {
 653 |     db.prepare('INSERT INTO nodes (node_type, properties_schema) VALUES (?, ?)').run('test.node', 'invalid json');
 654 | 
 655 |     const result = repository.getNode('test.node');
 656 |     expect(result).not.toBeNull();
 657 |     expect(result.properties).toEqual([]);
 658 |   });
 659 | 
 660 |   it('should handle non-existent node gracefully', () => {
 661 |     const result = repository.getNode('non.existent');
 662 |     expect(result).toBeNull();
 663 |   });
 664 | 
 665 |   it('should handle null database row', () => {
 666 |     // Simulate database returning null
 667 |     const result = repository.getNode('null.node');
 668 |     expect(result).toBeNull();
 669 |   });
 670 | });
 671 | ```
 672 | 
 673 | ### Success Criteria
 674 | 
 675 | - [ ] get_node_essentials failure rate: 10% → <1%
 676 | - [ ] get_node_info failure rate: 18% → <1%
 677 | - [ ] get_node_documentation failure rate: 7% → <1%
 678 | - [ ] 100% test coverage for null cases
 679 | - [ ] No TypeErrors in production logs
 680 | 
 681 | ### Estimated Effort
 682 | 
 683 | **Total: 1 day (8 hours)**
 684 | 
 685 | - Safe property access utility: 2 hours
 686 | - Repository refactoring: 3 hours
 687 | - Handler updates: 2 hours
 688 | - Testing: 1 hour
 689 | 
 690 | ---
 691 | 
 692 | ## P0-R3: Pre-extract Template Configurations + Remove get_node_for_task
 693 | 
 694 | ### Problem Statement
 695 | 
 696 | **Impact:** 28% failure rate (worst-performing tool) + redundant with better alternatives
 697 | 
 698 | `get_node_for_task` failing 109 times out of 392 calls (27.8%)
 699 | 
 700 | **Current State:**
 701 | - Only 31 predefined tasks in `task-templates.ts` (5.9% node coverage)
 702 | - 22.5:1 usage ratio favoring `search_nodes` (8,839 calls vs 392)
 703 | - Hardcoded configurations require manual maintenance
 704 | - Tool provides no unique value over `search_nodes`
 705 | 
 706 | **Discovery:** We have 2,646 real production workflow templates from n8n.io with:
 707 | - 3,820 httpRequest configurations
 708 | - 1,700 googleSheets configurations
 709 | - 466 webhook configurations
 710 | - 100% AI-generated metadata coverage
 711 | - Real-world best practices and patterns
 712 | 
 713 | ### Architectural Decision: Pre-extraction
 714 | 
 715 | **Analysis:** On-the-fly vs Pre-extraction (see `/docs/local/TEMPLATE_MINING_ANALYSIS.md`)
 716 | 
 717 | **Decision:** Pre-extract node configurations into separate table
 718 | 
 719 | **Rationale:**
 720 | - **Performance:** 1ms vs 30-60ms (30-60x faster)
 721 | - **Storage:** Only 513 KB for 2,625 configs (negligible)
 722 | - **Simplicity:** No cache management, TTL, or eviction logic
 723 | - **Features:** Enables filtering by complexity, auth (indexed queries)
 724 | - **Scalability:** Handles 10,000+ templates without degradation
 725 | - **Predictability:** Consistent sub-millisecond response times
 726 | 
 727 | **Trade-offs (acceptable):**
 728 | - +30-60 seconds rebuild time (rare operation)
 729 | - Incremental updates needed when templates change
 730 | 
 731 | ### Solution Architecture
 732 | 
 733 | **Strategy:**
 734 | 1. Pre-extract top 10 node configurations per node type into new table
 735 | 2. Enhance `get_node_essentials` with optional examples
 736 | 3. Enhance `search_nodes` with optional examples
 737 | 4. **Remove** `get_node_for_task` entirely (no redirect)
 738 | 
 739 | See `/docs/local/TEMPLATE_MINING_ANALYSIS.md` for complete analysis
 740 | 
 741 | #### 1. Add Database Schema for Pre-extracted Configurations
 742 | 
 743 | **File:** `src/database/schema.sql`
 744 | 
 745 | Add new table after `templates` table:
 746 | 
 747 | ```sql
 748 | -- Pre-extracted node configurations from templates
 749 | CREATE TABLE template_node_configs (
 750 |   id INTEGER PRIMARY KEY,
 751 |   node_type TEXT NOT NULL,
 752 |   template_id INTEGER NOT NULL,
 753 |   template_name TEXT NOT NULL,
 754 |   template_views INTEGER DEFAULT 0,
 755 | 
 756 |   -- Node configuration (extracted from workflow)
 757 |   node_name TEXT,                  -- Node name in workflow (e.g., "HTTP Request")
 758 |   parameters_json TEXT NOT NULL,   -- JSON: node.parameters
 759 |   credentials_json TEXT,            -- JSON: node.credentials (if present)
 760 | 
 761 |   -- Pre-calculated metadata for filtering
 762 |   has_credentials INTEGER DEFAULT 0,
 763 |   has_expressions INTEGER DEFAULT 0,  -- Contains {{...}} or $json/$node
 764 |   complexity TEXT CHECK(complexity IN ('simple', 'medium', 'complex')),
 765 |   use_cases TEXT,                   -- JSON array from template.metadata.use_cases
 766 | 
 767 |   -- Pre-calculated ranking (1 = best, 2 = second best, etc.)
 768 |   rank INTEGER DEFAULT 0,
 769 | 
 770 |   created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
 771 |   FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE
 772 | );
 773 | 
 774 | -- Indexes for fast queries
 775 | CREATE INDEX idx_config_node_type_rank
 776 |   ON template_node_configs(node_type, rank);
 777 | 
 778 | CREATE INDEX idx_config_complexity
 779 |   ON template_node_configs(node_type, complexity, rank);
 780 | 
 781 | CREATE INDEX idx_config_auth
 782 |   ON template_node_configs(node_type, has_credentials, rank);
 783 | 
 784 | -- View for easy querying of top configs
 785 | CREATE VIEW ranked_node_configs AS
 786 | SELECT
 787 |   node_type,
 788 |   template_name,
 789 |   template_views,
 790 |   parameters_json,
 791 |   credentials_json,
 792 |   has_credentials,
 793 |   has_expressions,
 794 |   complexity,
 795 |   use_cases,
 796 |   rank
 797 | FROM template_node_configs
 798 | WHERE rank <= 5  -- Top 5 per node type
 799 | ORDER BY node_type, rank;
 800 | ```
 801 | 
 802 | **Migration Script:** `src/database/migrations/add-template-node-configs.sql`
 803 | 
 804 | ```sql
 805 | -- Migration for existing databases
 806 | -- Run during `npm run rebuild` or `npm run fetch:templates`
 807 | 
 808 | -- Check if table exists
 809 | CREATE TABLE IF NOT EXISTS template_node_configs (
 810 |   -- ... schema as above
 811 | );
 812 | 
 813 | -- Populate from existing templates
 814 | -- (handled by extraction logic in fetch:templates script)
 815 | ```
 816 | 
 817 | #### 2. Add Extraction Logic to fetch:templates Script
 818 | 
 819 | **File:** `src/scripts/fetch-templates.ts`
 820 | 
 821 | Add extraction function:
 822 | 
 823 | ```typescript
 824 | import gzip from 'zlib';
 825 | 
 826 | /**
 827 |  * Extract node configurations from a template workflow
 828 |  */
 829 | function extractNodeConfigs(
 830 |   templateId: number,
 831 |   templateName: string,
 832 |   templateViews: number,
 833 |   workflowCompressed: string,
 834 |   metadata: any
 835 | ): Array<{
 836 |   node_type: string;
 837 |   template_id: number;
 838 |   template_name: string;
 839 |   template_views: number;
 840 |   node_name: string;
 841 |   parameters_json: string;
 842 |   credentials_json: string | null;
 843 |   has_credentials: number;
 844 |   has_expressions: number;
 845 |   complexity: string;
 846 |   use_cases: string;
 847 | }> {
 848 |   try {
 849 |     // Decompress workflow
 850 |     const decompressed = gzip.gunzipSync(Buffer.from(workflowCompressed, 'base64'));
 851 |     const workflow = JSON.parse(decompressed.toString('utf-8'));
 852 | 
 853 |     const configs: any[] = [];
 854 | 
 855 |     for (const node of workflow.nodes || []) {
 856 |       // Skip UI-only nodes
 857 |       if (node.type.includes('stickyNote') || !node.parameters) {
 858 |         continue;
 859 |       }
 860 | 
 861 |       configs.push({
 862 |         node_type: node.type,
 863 |         template_id: templateId,
 864 |         template_name: templateName,
 865 |         template_views: templateViews,
 866 |         node_name: node.name,
 867 |         parameters_json: JSON.stringify(node.parameters),
 868 |         credentials_json: node.credentials ? JSON.stringify(node.credentials) : null,
 869 |         has_credentials: node.credentials ? 1 : 0,
 870 |         has_expressions: detectExpressions(node.parameters) ? 1 : 0,
 871 |         complexity: metadata?.complexity || 'medium',
 872 |         use_cases: JSON.stringify(metadata?.use_cases || [])
 873 |       });
 874 |     }
 875 | 
 876 |     return configs;
 877 |   } catch (error) {
 878 |     console.error(`Error extracting configs from template ${templateId}:`, error);
 879 |     return [];
 880 |   }
 881 | }
 882 | 
 883 | /**
 884 |  * Detect n8n expressions in parameters
 885 |  */
 886 | function detectExpressions(params: any): boolean {
 887 |   const json = JSON.stringify(params);
 888 |   return json.includes('={{') || json.includes('$json') || json.includes('$node');
 889 | }
 890 | 
 891 | /**
 892 |  * Insert extracted configs into database and rank them
 893 |  */
 894 | function insertAndRankConfigs(db: Database, configs: any[]) {
 895 |   // Clear old configs for these templates
 896 |   const templateIds = [...new Set(configs.map(c => c.template_id))];
 897 |   db.prepare(`DELETE FROM template_node_configs WHERE template_id IN (${templateIds.join(',')})`).run();
 898 | 
 899 |   // Insert new configs
 900 |   const insertStmt = db.prepare(`
 901 |     INSERT INTO template_node_configs (
 902 |       node_type, template_id, template_name, template_views,
 903 |       node_name, parameters_json, credentials_json,
 904 |       has_credentials, has_expressions, complexity, use_cases
 905 |     ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 906 |   `);
 907 | 
 908 |   for (const config of configs) {
 909 |     insertStmt.run(
 910 |       config.node_type,
 911 |       config.template_id,
 912 |       config.template_name,
 913 |       config.template_views,
 914 |       config.node_name,
 915 |       config.parameters_json,
 916 |       config.credentials_json,
 917 |       config.has_credentials,
 918 |       config.has_expressions,
 919 |       config.complexity,
 920 |       config.use_cases
 921 |     );
 922 |   }
 923 | 
 924 |   // Rank configs per node_type by template popularity
 925 |   db.exec(`
 926 |     UPDATE template_node_configs
 927 |     SET rank = (
 928 |       SELECT COUNT(*) + 1
 929 |       FROM template_node_configs AS t2
 930 |       WHERE t2.node_type = template_node_configs.node_type
 931 |         AND t2.template_views > template_node_configs.template_views
 932 |     )
 933 |   `);
 934 | 
 935 |   // Keep only top 10 per node_type
 936 |   db.exec(`
 937 |     DELETE FROM template_node_configs
 938 |     WHERE id NOT IN (
 939 |       SELECT id FROM template_node_configs
 940 |       WHERE rank <= 10
 941 |     )
 942 |   `);
 943 | 
 944 |   console.log(`Extracted and ranked ${configs.length} node configurations`);
 945 | }
 946 | ```
 947 | 
 948 | #### 3. Enhance get_node_essentials with Examples
 949 | 
 950 | **File:** `src/mcp/handlers-*.ts` or `src/mcp/server.ts`
 951 | 
 952 | Update `get_node_essentials` handler:
 953 | 
 954 | ```typescript
 955 | async function getNodeEssentials(
 956 |   nodeType: string,
 957 |   options?: { includeExamples?: boolean }
 958 | ): Promise<any> {
 959 |   const node = repository.getNode(nodeType);
 960 |   if (!node) {
 961 |     return {
 962 |       success: false,
 963 |       error: `Node type "${nodeType}" not found. Use search_nodes to find available nodes.`
 964 |     };
 965 |   }
 966 | 
 967 |   const result = {
 968 |     nodeType,
 969 |     displayName: node.displayName,
 970 |     description: node.description,
 971 |     category: node.category,
 972 |     // ... existing essentials fields ...
 973 |   };
 974 | 
 975 |   // NEW: Add real-world examples if requested
 976 |   if (options?.includeExamples) {
 977 |     const examples = db.prepare(`
 978 |       SELECT
 979 |         parameters_json,
 980 |         template_name,
 981 |         template_views,
 982 |         complexity,
 983 |         use_cases,
 984 |         has_credentials,
 985 |         has_expressions
 986 |       FROM template_node_configs
 987 |       WHERE node_type = ?
 988 |       ORDER BY rank
 989 |       LIMIT 3
 990 |     `).all(nodeType);
 991 | 
 992 |     result.examples = examples.map(ex => ({
 993 |       config: JSON.parse(ex.parameters_json),
 994 |       source: `${ex.template_name} (${(ex.template_views / 1000).toFixed(0)}k views)`,
 995 |       complexity: ex.complexity,
 996 |       useCases: JSON.parse(ex.use_cases).slice(0, 2),
 997 |       hasAuth: ex.has_credentials === 1,
 998 |       hasExpressions: ex.has_expressions === 1
 999 |     }));
1000 |   }
1001 | 
1002 |   return result;
1003 | }
1004 | ```
1005 | 
1006 | **Tool definition update:**
1007 | 
1008 | ```typescript
1009 | {
1010 |   name: 'get_node_essentials',
1011 |   description: 'Get essential information about a specific n8n node type...',
1012 |   inputSchema: {
1013 |     type: 'object',
1014 |     properties: {
1015 |       nodeType: {
1016 |         type: 'string',
1017 |         description: 'Full node type (e.g., "n8n-nodes-base.httpRequest")'
1018 |       },
1019 |       includeExamples: {  // NEW
1020 |         type: 'boolean',
1021 |         description: 'Include 2-3 real configuration examples from popular templates',
1022 |         default: false
1023 |       }
1024 |     },
1025 |     required: ['nodeType']
1026 |   }
1027 | }
1028 | ```
1029 | 
1030 | #### 4. Enhance search_nodes with Examples
1031 | 
1032 | **File:** `src/mcp/handlers-*.ts` or `src/mcp/server.ts`
1033 | 
1034 | Update `search_nodes` handler:
1035 | 
1036 | ```typescript
1037 | async function searchNodes(
1038 |   query: string,
1039 |   options?: {
1040 |     limit?: number;
1041 |     includeExamples?: boolean;
1042 |   }
1043 | ): Promise<any> {
1044 |   const nodes = repository.searchNodes(query, 'OR', options?.limit || 20);
1045 | 
1046 |   const results = nodes.map(node => {
1047 |     const result = {
1048 |       nodeType: node.nodeType,
1049 |       displayName: node.displayName,
1050 |       description: node.description,
1051 |       category: node.category
1052 |     };
1053 | 
1054 |     // NEW: Add examples if requested
1055 |     if (options?.includeExamples) {
1056 |       const examples = db.prepare(`
1057 |         SELECT parameters_json, template_name, complexity
1058 |         FROM template_node_configs
1059 |         WHERE node_type = ?
1060 |         ORDER BY rank
1061 |         LIMIT 2
1062 |       `).all(node.nodeType);
1063 | 
1064 |       result.examples = examples.map(ex => ({
1065 |         config: JSON.parse(ex.parameters_json),
1066 |         source: ex.template_name,
1067 |         complexity: ex.complexity
1068 |       }));
1069 |     }
1070 | 
1071 |     return result;
1072 |   });
1073 | 
1074 |   return results;
1075 | }
1076 | ```
1077 | 
1078 | **Tool definition update:**
1079 | 
1080 | ```typescript
1081 | {
1082 |   name: 'search_nodes',
1083 |   description: 'Search for n8n nodes by keyword...',
1084 |   inputSchema: {
1085 |     type: 'object',
1086 |     properties: {
1087 |       query: { type: 'string', description: 'Search query' },
1088 |       limit: { type: 'number', default: 20 },
1089 |       includeExamples: {  // NEW
1090 |         type: 'boolean',
1091 |         description: 'Include 2 real configuration examples per node',
1092 |         default: false
1093 |       }
1094 |     },
1095 |     required: ['query']
1096 |   }
1097 | }
1098 | ```
1099 | 
1100 | #### 5. Remove get_node_for_task Tool Entirely
1101 | 
1102 | **Files to modify:**
1103 | 
1104 | 1. **`src/mcp/server.ts`** - Remove handler function
1105 | 2. **`src/mcp/tools.ts`** - Remove tool definition
1106 | 3. **`src/mcp/tools-documentation.ts`** - Remove from documentation
1107 | 4. **`src/services/task-templates.ts`** - Can be deprecated (keep for now, remove in v2.16.0)
1108 | 5. **`README.md`** - Remove from available tools list
1109 | 6. **`CHANGELOG.md`** - Document removal
1110 | 
1111 | **Steps:**
1112 | 
1113 | ```bash
1114 | # Search for all references
1115 | grep -r "get_node_for_task" src/
1116 | grep -r "getNodeForTask" src/
1117 | 
1118 | # Remove handler
1119 | # Remove tool definition
1120 | # Remove from documentation
1121 | # Update README
1122 | ```
1123 | 
1124 | **Migration note for users (add to CHANGELOG):**
1125 | 
1126 | ```markdown
1127 | ### BREAKING CHANGES in v2.15.0
1128 | 
1129 | - **Removed:** `get_node_for_task` tool
1130 |   - **Replacement:** Use `search_nodes` with `includeExamples: true`
1131 |   - **Migration:** `get_node_for_task({task: "webhook"})` → `search_nodes({query: "webhook", includeExamples: true})`
1132 |   - **Benefit:** Access to 2,646 real templates vs 31 hardcoded tasks
1133 | ```
1134 | 
1135 | ### Testing Requirements
1136 | 
1137 | **File:** `tests/unit/services/template-config-extraction.test.ts` (NEW)
1138 | 
1139 | ```typescript
1140 | describe('Template Config Extraction', () => {
1141 |   it('should extract node configs from workflow', () => {
1142 |     const workflow = {
1143 |       nodes: [
1144 |         {
1145 |           type: 'n8n-nodes-base.httpRequest',
1146 |           name: 'HTTP Request',
1147 |           parameters: { url: 'https://api.example.com', method: 'GET' }
1148 |         }
1149 |       ]
1150 |     };
1151 | 
1152 |     const configs = extractNodeConfigs(1, 'Test', 1000, compressWorkflow(workflow), {});
1153 |     expect(configs).toHaveLength(1);
1154 |     expect(configs[0].node_type).toBe('n8n-nodes-base.httpRequest');
1155 |   });
1156 | 
1157 |   it('should detect expressions in parameters', () => {
1158 |     const params = { url: '={{$json.api_url}}' };
1159 |     expect(detectExpressions(params)).toBe(true);
1160 |   });
1161 | 
1162 |   it('should rank configs by popularity', () => {
1163 |     // Insert configs with different views
1164 |     // Verify ranking order
1165 |   });
1166 | });
1167 | ```
1168 | 
1169 | **File:** `tests/integration/enhanced-tools.test.ts` (NEW)
1170 | 
1171 | ```typescript
1172 | describe('Enhanced Tools with Examples', () => {
1173 |   it('get_node_essentials should return examples when requested', async () => {
1174 |     const result = await getNodeEssentials('n8n-nodes-base.httpRequest', {
1175 |       includeExamples: true
1176 |     });
1177 | 
1178 |     expect(result.examples).toBeDefined();
1179 |     expect(result.examples.length).toBeGreaterThan(0);
1180 |     expect(result.examples[0].config).toHaveProperty('url');
1181 |   });
1182 | 
1183 |   it('search_nodes should return examples when requested', async () => {
1184 |     const result = await searchNodes('webhook', { includeExamples: true });
1185 | 
1186 |     expect(result.length).toBeGreaterThan(0);
1187 |     expect(result[0].examples).toBeDefined();
1188 |   });
1189 | 
1190 |   it('get_node_for_task should not exist', async () => {
1191 |     expect(toolRegistry.has('get_node_for_task')).toBe(false);
1192 |   });
1193 | });
1194 | ```
1195 | 
1196 | ### Success Criteria
1197 | 
1198 | - [ ] Extract 2,000+ node configurations from templates
1199 | - [ ] Query performance: <1ms for pre-extracted configs
1200 | - [ ] `get_node_essentials` with examples: <5ms total
1201 | - [ ] `search_nodes` with examples: <10ms total
1202 | - [ ] Database size increase: <1 MB
1203 | - [ ] `get_node_for_task` completely removed from codebase
1204 | - [ ] All documentation updated
1205 | 
1206 | ### Estimated Effort
1207 | 
1208 | **Total: 1 week (5 days)**
1209 | 
1210 | - **Day 1:** Database schema + migration (8 hours)
1211 |   - Design schema
1212 |   - Create migration script
1213 |   - Test with existing database
1214 | 
1215 | - **Day 2:** Extraction logic in fetch:templates (8 hours)
1216 |   - Write extraction function
1217 |   - Write ranking logic
1218 |   - Test with 2,646 templates
1219 | 
1220 | - **Day 3:** Enhance get_node_essentials + search_nodes (8 hours)
1221 |   - Add includeExamples parameter
1222 |   - Update tool definitions
1223 |   - Integration testing
1224 | 
1225 | - **Day 4:** Remove get_node_for_task + documentation (8 hours)
1226 |   - Remove from all files
1227 |   - Update README, CHANGELOG
1228 |   - Update tools_documentation
1229 |   - Migration guide
1230 | 
1231 | - **Day 5:** Testing + optimization (8 hours)
1232 |   - Unit tests
1233 |   - Integration tests
1234 |   - Performance testing
1235 |   - Bug fixes
1236 | 
1237 | ---
1238 | 
1239 | ## Implementation Order & Timeline
1240 | 
1241 | ### Version 2.15.0 - All P0 Fixes in One Release
1242 | 
1243 | **Total Timeline:** 2 weeks (10 working days)
1244 | 
1245 | ### Week 1: Foundation + P0-R1 + P0-R2
1246 | 
1247 | **Monday (Day 1-2): P0-R1 - Node Type Normalization**
1248 | - AM: Create NodeTypeNormalizer utility
1249 | - PM: Apply to workflow validator, handlers, and repository
1250 | - Testing and validation
1251 | - **Deliverable:** 80% of validation errors eliminated
1252 | 
1253 | **Tuesday (Day 3): P0-R2 - Null-Safety Audit (Part 1)**
1254 | - AM: Create SafePropertyAccess utility
1255 | - PM: Refactor node repository methods
1256 | - **Deliverable:** Safe property access framework
1257 | 
1258 | **Wednesday (Day 4): P0-R2 - Null-Safety Audit (Part 2)**
1259 | - AM: Find and fix all handlers
1260 | - PM: Comprehensive null-safety testing
1261 | - **Deliverable:** 10-18% TypeError rate → <1%
1262 | 
1263 | **Thursday (Day 5): P0-R3 - Database Schema**
1264 | - AM: Design and implement template_node_configs table
1265 | - PM: Create migration script and test with existing database
1266 | - **Deliverable:** Schema ready for extraction
1267 | 
1268 | **Friday (Day 6): P0-R3 - Extraction Logic**
1269 | - AM: Write extraction function in fetch:templates
1270 | - PM: Write ranking logic and test with 2,646 templates
1271 | - **Deliverable:** 2,000+ configs extracted and ranked
1272 | 
1273 | ### Week 2: P0-R3 Integration + Testing + Documentation
1274 | 
1275 | **Monday (Day 7): Tool Enhancements**
1276 | - AM: Enhance get_node_essentials with includeExamples
1277 | - PM: Enhance search_nodes with includeExamples
1278 | - **Deliverable:** Both tools return real examples
1279 | 
1280 | **Tuesday (Day 8): Tool Removal + Documentation**
1281 | - AM: Remove get_node_for_task from all files
1282 | - PM: Update README, CHANGELOG, tools_documentation
1283 | - **Deliverable:** Clean removal, migration guide complete
1284 | 
1285 | **Wednesday (Day 9): Comprehensive Testing**
1286 | - AM: Unit tests for extraction and enhanced tools
1287 | - PM: Integration tests for all P0 fixes
1288 | - **Deliverable:** 95%+ test coverage
1289 | 
1290 | **Thursday (Day 10): Performance + Final Testing**
1291 | - AM: Performance testing and optimization
1292 | - PM: E2E testing and bug fixes
1293 | - **Deliverable:** All success criteria met
1294 | 
1295 | **Friday (Day 11): Release Preparation**
1296 | - AM: Code review and documentation review
1297 | - PM: Prepare release notes, tag v2.15.0
1298 | - **Deliverable:** Ready for release
1299 | 
1300 | ### Parallel Activities
1301 | 
1302 | - **Documentation updates:** Days 1-11
1303 | - **Code reviews:** End of Days 2, 4, 6, 8, 10
1304 | - **Telemetry preparation:** Day 10-11 (prepare monitoring dashboard)
1305 | 
1306 | ---
1307 | 
1308 | ## Testing Strategy
1309 | 
1310 | ### Unit Tests
1311 | 
1312 | **Coverage Target:** 95% for new code
1313 | 
1314 | - **Node Type Normalizer:** 20+ test cases
1315 | - **Safe Property Access:** 30+ test cases
1316 | - **Task Discovery Service:** 40+ test cases
1317 | 
1318 | ### Integration Tests
1319 | 
1320 | - Workflow validation with mixed node type forms
1321 | - Node repository with edge case data
1322 | - Task discovery with real node database
1323 | 
1324 | ### E2E Tests
1325 | 
1326 | - Create workflow with short-form node types → Should succeed
1327 | - Get node info for nodes with missing properties → Should return safe defaults
1328 | - Query task discovery with variations → Should find matches
1329 | 
1330 | ### Regression Tests
1331 | 
1332 | - All existing tests must pass
1333 | - No breaking changes to public APIs
1334 | 
1335 | ### Performance Tests
1336 | 
1337 | - Normalization overhead: <1ms per workflow
1338 | - Safe property access: <0.1ms per node
1339 | - Task discovery: <50ms average
1340 | 
1341 | ---
1342 | 
1343 | ## Rollback Plan
1344 | 
1345 | ### If P0-R1 Causes Issues
1346 | 
1347 | 1. **Symptom:** Workflows fail validation after normalization
1348 | 2. **Action:** Revert node-type-normalizer changes
1349 | 3. **Fallback:** Use original normalizeNodeType
1350 | 4. **Recovery time:** 15 minutes
1351 | 
1352 | ### If P0-R2 Causes Performance Issues
1353 | 
1354 | 1. **Symptom:** Node lookup becomes slow
1355 | 2. **Action:** Cache safe property access results
1356 | 3. **Fallback:** Keep safe parsing but reduce validation
1357 | 4. **Recovery time:** 1 hour
1358 | 
1359 | ### If P0-R3 Template Extraction Causes Issues
1360 | 
1361 | 1. **Symptom:** Database bloat or slow queries
1362 | 2. **Action:** Reduce rank limit from 10 to 5 per node
1363 | 3. **Fallback:** Disable includeExamples parameter temporarily
1364 | 4. **Recovery time:** 15 minutes (just disable parameter)
1365 | 
1366 | ### If get_node_for_task Removal Causes User Issues
1367 | 
1368 | 1. **Symptom:** Users report missing tool
1369 | 2. **Action:** Add prominent migration guide to error messages
1370 | 3. **Fallback:** N/A (breaking change, users must migrate)
1371 | 4. **Communication:** Update docs, add migration examples
1372 | 
1373 | ---
1374 | 
1375 | ## Success Metrics
1376 | 
1377 | ### Overall Goals
1378 | 
1379 | | Metric | Current | Target | How to Measure |
1380 | |--------|---------|--------|----------------|
1381 | | Overall error rate | 5-10% | <2% | Telemetry events |
1382 | | Validation errors | 4,800/week | <100/week | Error logs |
1383 | | TypeError rate | 10-18% | <1% | Tool execution logs |
1384 | | Node configs extracted | 0 | 2,000+ | Database count |
1385 | | Config query performance | N/A | <1ms | Performance tests |
1386 | | get_node_for_task usage | 392 calls | 0 (removed) | Tool usage stats |
1387 | | search_nodes w/ examples | 0 | Monitored | New feature adoption |
1388 | 
1389 | ### Telemetry Monitoring
1390 | 
1391 | After deployment, monitor for 1 week:
1392 | 
1393 | - Error rate by tool (should decrease 80-90%)
1394 | - User success rate (should increase 5-10%)
1395 | - Average errors per user (should decrease from 2.5 to <0.5)
1396 | 
1397 | ---
1398 | 
1399 | ## Dependencies
1400 | 
1401 | ### NPM Packages
1402 | 
1403 | No new NPM packages required - all functionality uses existing dependencies.
1404 | 
1405 | ### Internal Dependencies
1406 | 
1407 | - **P0-R3** requires database schema update (template_node_configs table)
1408 | - **P0-R3** requires migration script for existing databases
1409 | - All changes are backward compatible except removal of `get_node_for_task`
1410 | 
1411 | ---
1412 | 
1413 | ## Documentation Updates
1414 | 
1415 | ### Files to Update
1416 | 
1417 | 1. **CHANGELOG.md** - Add entries for each P0 fix + breaking changes
1418 | 2. **README.md** - Remove get_node_for_task, add includeExamples parameter
1419 | 3. **src/mcp/tools-documentation.ts** - Remove get_node_for_task documentation
1420 | 4. **API.md** - Document enhanced tool parameters
1421 | 5. **MIGRATION.md** - Add migration guide from get_node_for_task to search_nodes (NEW)
1422 | 
1423 | ### Example CHANGELOG Entry
1424 | 
1425 | ```markdown
1426 | ## [2.15.0] - 2025-10-09
1427 | 
1428 | ### BREAKING CHANGES
1429 | - **Removed:** `get_node_for_task` tool
1430 |   - **Replacement:** Use `search_nodes` with `includeExamples: true`
1431 |   - **Migration:** `get_node_for_task({task: "webhook"})` → `search_nodes({query: "webhook", includeExamples: true})`
1432 |   - **Benefit:** Access to 2,646 real templates vs 31 hardcoded tasks
1433 | 
1434 | ### Fixed
1435 | - **P0-R1:** Auto-normalize node type prefixes (eliminates 80% of validation errors)
1436 | - **P0-R2:** Complete null-safety audit for node information tools (reduces TypeError failures from 10-18% to <1%)
1437 | 
1438 | ### Added
1439 | - `NodeTypeNormalizer` utility for universal node type normalization
1440 | - `SafePropertyAccess` utility for defensive property access
1441 | - `template_node_configs` table with 2,000+ pre-extracted configurations
1442 | - `includeExamples` parameter for `get_node_essentials` (returns 2-3 real configs)
1443 | - `includeExamples` parameter for `search_nodes` (returns 2 real configs per node)
1444 | - Real-world configuration examples from popular n8n templates
1445 | 
1446 | ### Performance
1447 | - Node configuration queries: <1ms (30-60x faster than on-the-fly extraction)
1448 | - Sub-millisecond response time for configuration examples
1449 | ```
1450 | 
1451 | ---
1452 | 
1453 | ## Conclusion
1454 | 
1455 | These P0 fixes represent the highest-impact improvements we can make to n8n-mcp based on real production telemetry data. By implementing all three fixes in v2.15.0, we will:
1456 | 
1457 | 1. **Eliminate 80% of validation errors** (P0-R1: Node type normalization)
1458 | 2. **Fix the majority of TypeError failures** (P0-R2: Null-safety audit)
1459 | 3. **Replace inferior tool with superior alternative** (P0-R3: Template-based configs + remove get_node_for_task)
1460 | 
1461 | **Expected Overall Impact:**
1462 | - Error rate: 5-10% → <2%
1463 | - Configuration examples: 31 hardcoded → 2,000+ real templates
1464 | - Query performance: 30-60ms → <1ms (30-60x faster)
1465 | - User experience: Significant improvement across all tools
1466 | - Support burden: Reduced by 50%+
1467 | 
1468 | **Key Innovation (P0-R3):**
1469 | - Pre-extraction delivers 30-60x performance improvement
1470 | - 2,646 real templates provide richer context than hardcoded tasks
1471 | - Breaking change justified by superior replacement
1472 | - Database increase: Only +513 KB for 2,625 configurations
1473 | 
1474 | The implementation is well-architected, delivers exceptional value, and sets up future enhancements.
1475 | 
1476 | ---
1477 | 
1478 | **Next Steps:**
1479 | 
1480 | 1. ✅ Review implementation plan with team (COMPLETED)
1481 | 2. ✅ Finalize architectural decisions (COMPLETED - pre-extraction chosen)
1482 | 3. ✅ Create feature branch: `feature/p0-priorities-fixes` (COMPLETED)
1483 | 4. ✅ **P0-R1**: Auto-Normalize Node Type Prefixes (COMPLETED - commit ed7de10)
1484 | 5. ⏳ **P0-R2**: Complete Null-Safety Audit (PENDING)
1485 | 6. ⏳ **P0-R3**: Pre-extract Template Configs + Remove get_node_for_task (PENDING)
1486 | 7. ⏳ Deploy v2.15.0 with monitoring and telemetry analysis
1487 | 
1488 | **Target Release:** v2.15.0 (estimated 1.5 weeks remaining)
1489 | 
1490 | 
```

--------------------------------------------------------------------------------
/docs/local/DEEP_DIVE_ANALYSIS_2025-10-02.md:
--------------------------------------------------------------------------------

```markdown
   1 | # **N8N-MCP DEEP DIVE ANALYSIS**
   2 | ## **Usage Patterns & Refactoring Recommendations**
   3 | 
   4 | **Analysis Period:** September 26 - October 2, 2025 (6 days)
   5 | **Data Volume:** 212,375 events | 5,751 workflows | 2,119 unique users
   6 | **Database:** Supabase telemetry with 15 analytical views
   7 | **Analyst:** Claude Code with Supabase MCP integration
   8 | **Date:** October 2, 2025
   9 | 
  10 | ---
  11 | 
  12 | ## **EXECUTIVE SUMMARY**
  13 | 
  14 | n8n-mcp has achieved **strong adoption** with 2,119 users generating 212K+ events in 6 days. The system demonstrates **excellent reliability** (96-100% success rates for most tools) but has **critical pain points** that are blocking users and degrading the AI agent experience. The upcoming refactor should focus on:
  15 | 
  16 | 1. **Fixing the "node type prefix" validation catastrophe** (5,000+ validation errors from a single root cause)
  17 | 2. **Resolving TypeError issues** in node information tools (1,000+ failures affecting 10% of calls)
  18 | 3. **Streamlining the workflow update experience** (iterative updates dominate usage)
  19 | 4. **Improving node discovery** (search is the #2 most-used tool but has UX gaps)
  20 | 5. **Optimizing for power users** who drive 60% of activity
  21 | 
  22 | **Key Metrics:**
  23 | - **Overall Success Rate:** 96-98% across all user segments
  24 | - **Daily Event Growth:** 16K → 40K events (2.5x growth in 3 days)
  25 | - **Power User Concentration:** Top 3% of users generate 27% of events
  26 | - **Most Used Tools:** update_partial_workflow (10,177), search_nodes (8,839), create_workflow (6,046)
  27 | - **Critical Failure Rates:** get_node_for_task (28%), get_node_info (18%), get_node_essentials (10%)
  28 | 
  29 | ---
  30 | 
  31 | ## **TABLE OF CONTENTS**
  32 | 
  33 | 1. [Tool Performance Analysis](#1-tool-performance-analysis)
  34 | 2. [Validation Catastrophe](#2-validation-catastrophe)
  35 | 3. [Usage Patterns & User Segmentation](#3-usage-patterns--user-segmentation)
  36 | 4. [Tool Sequence Analysis](#4-tool-sequence-analysis)
  37 | 5. [Workflow Creation Patterns](#5-workflow-creation-patterns)
  38 | 6. [Platform & Version Distribution](#6-platform--version-distribution)
  39 | 7. [Error Patterns & Root Causes](#7-error-patterns--root-causes)
  40 | 8. [Prioritized Refactoring Recommendations](#8-prioritized-refactoring-recommendations)
  41 | 9. [Architectural Recommendations](#9-architectural-recommendations)
  42 | 10. [Telemetry Enhancements](#10-telemetry-enhancements)
  43 | 11. [Specific Code Changes](#11-specific-code-changes)
  44 | 12. [CHANGELOG Integration](#12-changelog-integration)
  45 | 13. [Final Recommendations Summary](#13-final-recommendations-summary)
  46 | 
  47 | ---
  48 | 
  49 | ## **1. TOOL PERFORMANCE ANALYSIS**
  50 | 
  51 | ### **1.1 Success Rate Tiers**
  52 | 
  53 | **EXCELLENT (95-100% success):**
  54 | - ✅ `n8n_update_partial_workflow` - 10,177 calls, 98.7% success, 846 users
  55 | - ✅ `search_nodes` - 8,839 calls, 99.8% success, 1,283 users
  56 | - ✅ `n8n_create_workflow` - 6,046 calls, 96.1% success, 1,305 users
  57 | - ✅ `n8n_validate_workflow` - 3,222 calls, 99.8% success, 597 users
  58 | - ✅ `n8n_get_workflow` - 3,368 calls, 99.8% success, 790 users
  59 | - ✅ `n8n_update_full_workflow` - 2,640 calls, 99.4% success, 486 users
  60 | - ✅ `tools_documentation` - 1,886 calls, 100% success, 879 users
  61 | - ✅ `validate_workflow` - 1,667 calls, 95.4% success, 472 users
  62 | - ✅ All n8n workflow management tools (list/delete/health) - 100% success
  63 | 
  64 | **GOOD (80-95% success):**
  65 | - ⚠️ `get_node_essentials` - 4,909 calls, **90.2% success**, 921 users (**9.8% failure**)
  66 | - ⚠️ `get_node_documentation` - 1,919 calls, 92.9% success, 657 users (**7.1% failure**)
  67 | - ⚠️ `validate_node_operation` - 998 calls, 88.6% success, 240 users (**11.4% failure**)
  68 | - ⚠️ `list_ai_tools` - 234 calls, 84.2% success, 184 users (**15.8% failure**)
  69 | - ⚠️ `get_node_info` - 1,988 calls, **82.3% success**, 677 users (**17.7% failure**)
  70 | 
  71 | **POOR (50-80% success):**
  72 | - 🔴 `get_node_for_task` - 392 calls, **72.2% success**, 197 users (**27.8% failure**)
  73 | 
  74 | ### **1.2 Performance Metrics**
  75 | 
  76 | **Ultra-Fast (<10ms avg):**
  77 | - `get_node_essentials`: 3.27ms avg (median: 1ms)
  78 | - `get_node_info`: 4.78ms avg (median: 1ms)
  79 | - `get_node_documentation`: 2.16ms avg (median: 1ms)
  80 | - `tools_documentation`: 3.42ms avg (median: 1ms)
  81 | - `validate_node_minimal`: 1.79ms avg (median: 1ms)
  82 | 
  83 | **Fast (10-100ms avg):**
  84 | - `search_nodes`: 20.47ms avg (median: 5ms, p95: 84ms)
  85 | - `validate_workflow`: 31.59ms avg (median: 12ms, p95: 103ms)
  86 | - `list_nodes`: 41.86ms avg (median: 11ms, p95: 196ms)
  87 | 
  88 | **Acceptable (100-500ms avg):**
  89 | - `n8n_get_workflow`: 248.79ms avg (median: 111ms, p95: 830ms)
  90 | - `n8n_validate_workflow`: 229.37ms avg (median: 106ms, p95: 722ms)
  91 | - `n8n_update_full_workflow`: 302.70ms avg (median: 119ms, p95: 1,069ms)
  92 | - `n8n_delete_workflow`: 308.85ms avg (median: 166ms, p95: 950ms)
  93 | - `n8n_create_workflow`: 333.37ms avg (median: 85ms, p95: 1,251ms)
  94 | - `n8n_list_workflows`: 476.05ms avg (median: 231ms, p95: 1,465ms)
  95 | - `n8n_autofix_workflow`: 486.49ms avg (median: 174ms, p95: 1,152ms)
  96 | 
  97 | **Slow (>500ms avg):**
  98 | - `n8n_get_execution`: 670.35ms avg (median: 121ms, p95: 1,166ms)
  99 | - `n8n_trigger_webhook_workflow`: 1,884.67ms avg (median: 157ms, p95: 4,865ms)
 100 | 
 101 | ### **1.3 Critical Findings**
 102 | 
 103 | **FINDING #1: Node information tools have systematic TypeError issues**
 104 | - `get_node_essentials`: 483 failures (10% of calls)
 105 | - `get_node_info`: 352 failures (18% of calls)
 106 | - `get_node_documentation`: 136 failures (7% of calls)
 107 | - **Root cause**: Accessing undefined properties on node objects (from CHANGELOG 2.14.0 fix)
 108 | - **Impact**: AI agents cannot get basic node information, blocking workflow creation
 109 | - **Evidence**: 400+ TypeError occurrences from error logs
 110 | 
 111 | **FINDING #2: Task-based node discovery is failing 28% of the time**
 112 | - `get_node_for_task` has the worst success rate (72%)
 113 | - **Impact**: When AI agents ask "which node should I use for X task?", they fail 1 in 4 times
 114 | - **Likely cause**: Limited task library or poor task-to-node mapping
 115 | - **Usage pattern**: 392 calls, 197 users → high demand but low reliability
 116 | 
 117 | **FINDING #3: Performance is excellent across the board**
 118 | - Node lookup tools: <5ms average (ultra-fast SQLite queries)
 119 | - Search operations: ~20ms average (efficient FTS5 indexing)
 120 | - Network operations (n8n API): 200-500ms average (acceptable for HTTP calls)
 121 | - Webhook triggers: 1,885ms average (expected for workflow execution)
 122 | - **Conclusion**: Performance is NOT a bottleneck; reliability is
 123 | 
 124 | **FINDING #4: Workflow management tools have perfect reliability**
 125 | - `n8n_list_workflows`: 100% success (1,489 calls)
 126 | - `n8n_health_check`: 100% success (1,304 calls)
 127 | - `n8n_list_executions`: 100% success (1,297 calls)
 128 | - `n8n_delete_workflow`: 100% success (1,230 calls)
 129 | - **Takeaway**: The n8n API integration layer is rock-solid
 130 | 
 131 | ---
 132 | 
 133 | ## **2. VALIDATION CATASTROPHE**
 134 | 
 135 | ### **2.1 The "Node Type Prefix" Disaster**
 136 | 
 137 | **CRITICAL ISSUE:** 5,000+ validation errors from a single root cause
 138 | 
 139 | ```
 140 | Error: Invalid node type: "nodes-base.set". Use "n8n-nodes-base.set" instead.
 141 | ```
 142 | 
 143 | **Breakdown by error type:**
 144 | 1. **4,800 occurrences**: "Invalid node type" prefix errors across Node0-Node19
 145 |    - Pattern: `nodes-base.X` instead of `n8n-nodes-base.X`
 146 |    - Affected nodes: ALL node types (Set, HTTP Request, Code, etc.)
 147 |    - **Impact**: 1 affected user with systematic errors across entire workflow
 148 | 
 149 | 2. **2,500 occurrences**: "Multi-node workflow has no connections"
 150 |    - Likely same 2 users testing/debugging
 151 |    - Message: "Multi-node workflow has no connections. Nodes must be connected..."
 152 |    - **Pattern**: Valid validation but high repetition suggests test loops
 153 | 
 154 | 3. **58 occurrences**: "Single-node workflows are only valid for webhook endpoints"
 155 |    - 42 affected users
 156 |    - **This is good validation** - appropriate message
 157 | 
 158 | 4. **22 occurrences**: Duplicate node ID: "undefined"
 159 |    - 5 affected users
 160 |    - **Likely bug**: Nodes being created without IDs
 161 | 
 162 | ### **2.2 Root Cause Analysis**
 163 | 
 164 | **Why AI agents produce `nodes-base.X` instead of `n8n-nodes-base.X`:**
 165 | 
 166 | 1. **Token efficiency**: LLMs may abbreviate to save tokens
 167 | 2. **Pattern learning**: AI may see shortened versions in docs/examples
 168 | 3. **Natural language**: "nodes-base" is more concise than "n8n-nodes-base"
 169 | 4. **Inconsistency**: Some tools may accept both formats, creating confusion
 170 | 
 171 | **Why the system doesn't auto-correct:**
 172 | 
 173 | From CHANGELOG 2.14.2:
 174 | > "Fixed validation false positives for Google Drive nodes with 'fileFolder' resource
 175 | > - Added node type normalization to handle both `n8n-nodes-base.` and `nodes-base.` prefixes correctly"
 176 | 
 177 | **Analysis**: A fix was attempted in 2.14.2, but it's **incomplete or not applied universally**. The normalization logic exists but isn't being called in all validation paths.
 178 | 
 179 | ### **2.3 Impact Assessment**
 180 | 
 181 | **User Experience:**
 182 | - **Frustration**: AI agents receive validation errors requiring manual intervention
 183 | - **Token waste**: Multiple retry attempts with failed validations
 184 | - **Broken flow**: Interrupts the natural workflow creation process
 185 | 
 186 | **Quantitative Impact:**
 187 | - **80% of all validation errors** stem from this single issue
 188 | - **Affects ALL node types**, not specific to certain nodes
 189 | - **Systematic pattern**: Once a user hits this, they hit it repeatedly
 190 | 
 191 | **Why This Is Critical:**
 192 | - Easy to fix (normalization helper already exists)
 193 | - Massive impact (eliminates 4,800+ errors)
 194 | - Improves AI agent experience significantly
 195 | 
 196 | ### **2.4 Other Validation Issues**
 197 | 
 198 | **Connection Validation:**
 199 | - "Connection uses node ID instead of node name" - 1 occurrence
 200 | - Good error message with clear guidance
 201 | - Not a systemic issue
 202 | 
 203 | **Node Configuration:**
 204 | - Various property-specific validation errors (low frequency)
 205 | - Generally well-handled with actionable messages
 206 | 
 207 | ---
 208 | 
 209 | ## **3. USAGE PATTERNS & USER SEGMENTATION**
 210 | 
 211 | ### **3.1 User Distribution**
 212 | 
 213 | | Segment | Users | % | Events | Avg Events | Workflows | Success Rate |
 214 | |---------|-------|---|--------|------------|-----------|--------------|
 215 | | **Power Users (1000+)** | 12 | 0.6% | 25,346 | 2,112 | 33 | 97.1% |
 216 | | **Heavy Users (500-999)** | 47 | 2.2% | 31,608 | 673 | 18 | 98.0% |
 217 | | **Regular Users (100-499)** | 516 | 24.3% | 102,931 | 199 | 7 | 96.5% |
 218 | | **Active Users (20-99)** | 919 | 43.4% | 47,768 | 52 | 2 | 97.0% |
 219 | | **Casual Users (<20)** | 625 | 29.5% | 4,958 | 8 | 1 | 97.6% |
 220 | | **TOTAL** | 2,119 | 100% | 212,611 | 100 | - | 97.0% |
 221 | 
 222 | ### **3.2 Key Insights**
 223 | 
 224 | **INSIGHT #1: Extreme power law distribution**
 225 | - **Top 59 users (3%)** generate **27% of all events** (57K events)
 226 | - **Top 575 users (27%)** generate **76% of all events** (160K events)
 227 | - **Bottom 625 users (30%)** generate only **2% of events** (5K events)
 228 | 
 229 | **Implications:**
 230 | - Optimize for power users → 3x impact per feature
 231 | - Onboarding is good (casual users have 97.6% success rate)
 232 | - Need enterprise features for heavy users (monitoring, analytics, team features)
 233 | 
 234 | **INSIGHT #2: Regular users (516) are the core audience**
 235 | - 103K events total (48% of all activity)
 236 | - 7 workflows/user average (meaningful engagement)
 237 | - 96.5% success rate (room for improvement)
 238 | - **This is the growth segment** - convert to heavy users
 239 | 
 240 | **INSIGHT #3: Consistent success rates across segments**
 241 | - All segments: 96-98% success rate
 242 | - **Paradox**: Power users have LOWER success rate (97.1% vs 97.6% casual)
 243 | - **Explanation**: Power users attempt harder tasks → more edge cases
 244 | - **Opportunity**: Focus reliability improvements on advanced features
 245 | 
 246 | **INSIGHT #4: Workflow creation correlates with engagement**
 247 | - Power users: 33 workflows
 248 | - Heavy users: 18 workflows
 249 | - Regular users: 7 workflows
 250 | - Active users: 2 workflows
 251 | - **Metric**: Workflows created = proxy for value delivered
 252 | 
 253 | ### **3.3 Daily Usage Trends**
 254 | 
 255 | | Date | Events | Users | Events/User | Growth |
 256 | |------|--------|-------|-------------|--------|
 257 | | Sep 26 | 16,334 | 958 | 17.0 | baseline |
 258 | | Sep 27 | 26,042 | 2,075 | 12.6 | +59% events |
 259 | | Sep 28 | 35,687 | 2,655 | 13.4 | +37% events |
 260 | | **Sep 29** | **40,361** | **3,039** | **13.3** | **+13% events (peak)** |
 261 | | Sep 30 | 39,833 | 3,319 | 12.0 | -1% events |
 262 | | Oct 1 | 39,854 | 3,528 | 11.3 | 0% events |
 263 | | Oct 2 | 14,500 | 1,057 | 13.7 | partial day |
 264 | 
 265 | **Growth Analysis:**
 266 | - **Rapid adoption**: 16K → 40K daily events (2.5x in 3 days)
 267 | - **Plateau**: Sep 29-Oct 1 stable at ~40K events/day
 268 | - **User growth**: 958 → 3,528 users (3.7x growth)
 269 | - **Efficiency**: Events per user declining (17 → 11) as user base broadens
 270 | 
 271 | **Interpretation:**
 272 | - System reached **initial scale** (~40K events/day, ~3K users/day)
 273 | - Now in **consolidation phase** - need to improve retention
 274 | - **Next growth phase** requires solving reliability issues (see P0 recommendations)
 275 | 
 276 | ---
 277 | 
 278 | ## **4. TOOL SEQUENCE ANALYSIS**
 279 | 
 280 | ### **4.1 Most Common Patterns**
 281 | 
 282 | **Top 15 Tool Sequences (all show 300s = 5 min time delta):**
 283 | 
 284 | | Rank | Sequence | Count | Users | Pattern |
 285 | |------|----------|-------|-------|---------|
 286 | | 1 | `update_partial_workflow` → `update_partial_workflow` | 549 | 153 | Iterative refinement |
 287 | | 2 | `create_workflow` → `update_partial_workflow` | 297 | 118 | Create then refine |
 288 | | 3 | `update_partial_workflow` → `get_workflow` | 265 | 91 | Update then verify |
 289 | | 4 | `create_workflow` → `create_workflow` | 237 | 97 | Multiple attempts |
 290 | | 5 | `create_workflow` → `get_workflow` | 185 | 81 | Create then inspect |
 291 | | 6 | `create_workflow` → `search_nodes` | 166 | 72 | Create then discover |
 292 | | 7 | `validate_workflow` → `update_partial_workflow` | 161 | 63 | Validate then fix |
 293 | | 8 | `validate_workflow` → `validate_workflow` | 152 | 44 | Re-validation |
 294 | | 9 | `validate_workflow` → `get_workflow` | 134 | 53 | Validate then inspect |
 295 | | 10 | `update_partial_workflow` → `create_workflow` | 130 | 59 | Update then recreate |
 296 | | 11 | `get_workflow` → `update_partial_workflow` | 117 | 50 | Inspect then update |
 297 | | 12 | `update_full_workflow` → `update_partial_workflow` | 98 | 41 | Full to partial update |
 298 | | 13 | `update_partial_workflow` → `search_nodes` | 94 | 42 | Update then discover |
 299 | | 14 | `get_workflow` → `create_workflow` | 87 | 42 | Inspect then recreate |
 300 | | 15 | `create_workflow` → `tools_documentation` | 85 | 36 | Create then learn |
 301 | 
 302 | ### **4.2 Critical Insights**
 303 | 
 304 | **INSIGHT #1: AI agents iterate heavily on workflows**
 305 | - **#1 sequence**: `update → update → update` (549 occurrences)
 306 | - **Pattern**: Create → Validate → Update → Validate → Update (feedback loop)
 307 | - **Workflow**:
 308 |   1. AI creates initial workflow
 309 |   2. Validates it (finds issues)
 310 |   3. Updates to fix issues
 311 |   4. Validates again (finds more issues)
 312 |   5. Continues iterating until success
 313 | 
 314 | **Implication**: The diff-based update system (v2.7.0) is **CRUCIAL** for token efficiency
 315 | - Without diff updates: Would need full workflow JSON each time (~10-50KB)
 316 | - With diff updates: Only send changed operations (~1-5KB)
 317 | - **Token savings**: 80-90% per update iteration
 318 | 
 319 | **INSIGHT #2: All transitions show 5-minute time deltas**
 320 | - **This is NOT actual elapsed time** - it's the telemetry "slow transition" threshold
 321 | - All sequences are marked as `is_slow_transition: true`
 322 | - **Actual insight**: AI agents take thinking time between tool calls (expected for LLMs)
 323 | - **Limitation**: Cannot determine real workflow creation speed with current data
 324 | 
 325 | **Recommendation**: Add fine-grained timing (see T1 in Telemetry Enhancements)
 326 | 
 327 | **INSIGHT #3: Node discovery happens AFTER workflow creation**
 328 | - `create_workflow → search_nodes` (166 occurrences)
 329 | - **Flow**:
 330 |   1. AI creates workflow with known nodes
 331 |   2. Realizes it needs additional nodes
 332 |   3. Searches for them
 333 |   4. Updates workflow with new nodes
 334 | 
 335 | **Opportunity**: Proactive node suggestions during creation (see P1-R5)
 336 | 
 337 | **INSIGHT #4: Validation drives updates**
 338 | - `validate_workflow → update_partial_workflow` (161 occurrences)
 339 | - `validate_workflow → validate_workflow` (152 occurrences)
 340 | - **Pattern**: Validation → Fix → Re-validate loop
 341 | 
 342 | **Quality**: This is GOOD behavior (AI agents using validation to improve)
 343 | **Optimization**: Better validation error messages → fewer iterations (see P1-R6)
 344 | 
 345 | ### **4.3 Common Workflow Patterns**
 346 | 
 347 | **Pattern A: Create-Update-Validate Loop**
 348 | ```
 349 | create_workflow → update_partial_workflow → validate_workflow → update_partial_workflow
 350 | ```
 351 | - Most common for new workflows
 352 | - 3-5 iterations average before success
 353 | 
 354 | **Pattern B: Inspect-Modify-Deploy**
 355 | ```
 356 | get_workflow → update_partial_workflow → validate_workflow → get_workflow
 357 | ```
 358 | - Common for modifying existing workflows
 359 | - "Get" used to verify final state
 360 | 
 361 | **Pattern C: Search-Create-Refine**
 362 | ```
 363 | search_nodes → create_workflow → update_partial_workflow → validate_workflow
 364 | ```
 365 | - Discovery-driven workflow creation
 366 | - Users explore capabilities before creating
 367 | 
 368 | ### **4.4 Tools Leading to Workflow Creation**
 369 | 
 370 | **Tools used within 5 minutes BEFORE workflow creation:**
 371 | 
 372 | | Tool | Occurrences | Users | Conversion Rate |
 373 | |------|-------------|-------|-----------------|
 374 | | `update_partial_workflow` | 6,271 | 547 | High |
 375 | | `search_nodes` | 6,099 | 901 | High |
 376 | | `get_node_essentials` | 3,361 | 649 | Medium |
 377 | | `create_workflow` | 2,810 | 742 | Medium (re-creation) |
 378 | | `get_workflow` | 2,057 | 512 | Medium |
 379 | | `validate_workflow` | 2,014 | 417 | Medium |
 380 | | `get_node_documentation` | 1,301 | 456 | Low |
 381 | | `tools_documentation` | 1,290 | 596 | Low |
 382 | 
 383 | **Interpretation:**
 384 | - **Discovery tools** (search_nodes, get_node_essentials) → high workflow creation
 385 | - **Documentation tools** → lower conversion (learning/exploring phase)
 386 | - **Workflow management** (update/validate) → iterative creation process
 387 | 
 388 | ---
 389 | 
 390 | ## **5. WORKFLOW CREATION PATTERNS**
 391 | 
 392 | ### **5.1 Complexity Distribution**
 393 | 
 394 | | Complexity | Count | % | Avg Nodes | Median | Triggers | Webhooks |
 395 | |------------|-------|---|-----------|--------|----------|----------|
 396 | | **Simple** | 4,290 | 75% | 5.5 | 5 | 1,330 (31%) | 1,330 (31%) |
 397 | | **Medium** | 1,282 | 22% | 14.0 | 13 | 424 (33%) | 424 (33%) |
 398 | | **Complex** | 187 | 3% | 27.5 | 23 | 71 (38%) | 71 (38%) |
 399 | | **TOTAL** | 5,759 | 100% | 8.2 | 6 | 1,825 (32%) | 1,825 (32%) |
 400 | 
 401 | **Complexity Definitions:**
 402 | - **Simple**: ≤8 nodes
 403 | - **Medium**: 9-20 nodes
 404 | - **Complex**: 21+ nodes
 405 | 
 406 | ### **5.2 Key Findings**
 407 | 
 408 | **FINDING #1: 75% of workflows are simple**
 409 | - AI agents prefer minimalism (5-6 nodes average)
 410 | - Small workflows are easier to reason about
 411 | - Faster creation and debugging
 412 | - **Implication**: Optimize for simple workflow creation experience
 413 | 
 414 | **FINDING #2: Complex workflows are rare but important**
 415 | - Only 3% of workflows (187 total)
 416 | - Average 27.5 nodes (large automation)
 417 | - 38% have triggers/webhooks (production use)
 418 | - **User profile**: Likely power users building production systems
 419 | 
 420 | **FINDING #3: Webhook usage is consistent across complexity**
 421 | - Simple: 31% have webhooks
 422 | - Medium: 33% have webhooks
 423 | - Complex: 38% have webhooks
 424 | - **Insight**: Webhooks are a fundamental pattern, not correlated with complexity
 425 | 
 426 | ### **5.3 Most Popular Nodes**
 427 | 
 428 | **Top 20 Nodes by Workflow Count:**
 429 | 
 430 | | Rank | Node Type | Workflows | % | Users | Avg Workflow Size |
 431 | |------|-----------|-----------|---|-------|-------------------|
 432 | | 1 | `n8n-nodes-base.code` | 3,051 | 53% | 1,056 | 9.4 |
 433 | | 2 | `n8n-nodes-base.httpRequest` | 2,686 | 47% | 1,033 | 9.6 |
 434 | | 3 | `n8n-nodes-base.webhook` | 1,812 | 32% | 750 | 8.5 |
 435 | | 4 | `n8n-nodes-base.set` | 1,738 | 30% | 742 | 9.2 |
 436 | | 5 | `n8n-nodes-base.if` | 1,400 | 24% | 653 | 12.2 |
 437 | | 6 | `n8n-nodes-base.manualTrigger` | 1,391 | 24% | 590 | 7.9 |
 438 | | 7 | `n8n-nodes-base.respondToWebhook` | 1,113 | 19% | 484 | 8.7 |
 439 | | 8 | `@n8n/n8n-nodes-langchain.agent` | 884 | 15% | 403 | 9.7 |
 440 | | 9 | `n8n-nodes-base.scheduleTrigger` | 825 | 14% | 412 | 9.5 |
 441 | | 10 | `n8n-nodes-base.googleSheets` | 732 | 13% | 324 | 10.5 |
 442 | | 11 | `n8n-nodes-base.merge` | 599 | 10% | 311 | 13.8 |
 443 | | 12 | `@n8n/n8n-nodes-langchain.lmChatOpenAi` | 564 | 10% | 268 | 10.6 |
 444 | | 13 | `n8n-nodes-base.switch` | 534 | 9% | 262 | 13.7 |
 445 | | 14 | `n8n-nodes-base.openAi` | 486 | 8% | 261 | 10.1 |
 446 | | 15 | `n8n-nodes-base.splitInBatches` | 457 | 8% | 229 | 13.2 |
 447 | | 16 | `n8n-nodes-base.telegram` | 416 | 7% | 168 | 10.0 |
 448 | | 17 | `n8n-nodes-base.function` | 414 | 7% | 162 | 9.6 |
 449 | | 18 | `n8n-nodes-base.gmail` | 400 | 7% | 212 | 9.5 |
 450 | | 19 | `n8n-nodes-base.cron` | 380 | 7% | 182 | 9.2 |
 451 | | 20 | `n8n-nodes-base.noOp` | 322 | 6% | 174 | 10.9 |
 452 | 
 453 | ### **5.4 Critical Insights**
 454 | 
 455 | **INSIGHT #1: Code node dominates (53% of workflows)**
 456 | - AI agents LOVE programmatic control
 457 | - Code node enables custom logic that other nodes can't provide
 458 | - **Implication**: Ensure code node documentation and examples are excellent
 459 | 
 460 | **INSIGHT #2: HTTP Request is in nearly half of workflows (47%)**
 461 | - Integration-heavy usage pattern
 462 | - Most workflows interact with external APIs
 463 | - **Synergy**: Code + HTTP Request (see co-occurrence analysis)
 464 | 
 465 | **INSIGHT #3: LangChain nodes show strong adoption (15%)**
 466 | - AI-on-AI workflows
 467 | - `langchain.agent` in 884 workflows
 468 | - `lmChatOpenAi` in 564 workflows
 469 | - **Trend**: AI-building-AI-workflows is a real use case
 470 | 
 471 | **INSIGHT #4: Average workflow size correlates with node type**
 472 | - Control flow nodes (if/switch): 12-14 nodes average (complex workflows)
 473 | - Data nodes (set/code): 9-10 nodes average (medium workflows)
 474 | - Trigger nodes (manualTrigger): 7-8 nodes average (simple workflows)
 475 | 
 476 | ### **5.5 Node Co-occurrence Patterns**
 477 | 
 478 | **Top 20 Node Pairs:**
 479 | 
 480 | | Rank | Node 1 | Node 2 | Co-occurrence | Users | Avg Size | Pattern |
 481 | |------|--------|--------|---------------|-------|----------|---------|
 482 | | 1 | `code` | `httpRequest` | 1,646 | 686 | 10.4 | Data transformation + API |
 483 | | 2 | `webhook` | `respondToWebhook` | 1,043 | 452 | 8.8 | Standard webhook pattern |
 484 | | 3 | `code` | `webhook` | 1,008 | 442 | 9.6 | Custom webhook logic |
 485 | | 4 | `code` | `if` | 894 | 437 | 12.9 | Conditional with custom logic |
 486 | | 5 | `httpRequest` | `webhook` | 845 | 404 | 10.5 | Webhook-triggered API calls |
 487 | | 6 | `httpRequest` | `set` | 841 | 431 | 10.7 | API response processing |
 488 | | 7 | `httpRequest` | `if` | 815 | 420 | 13.4 | Conditional API logic |
 489 | | 8 | `code` | `manualTrigger` | 731 | 321 | 9.7 | Manual testing workflows |
 490 | | 9 | `httpRequest` | `manualTrigger` | 706 | 328 | 9.1 | Manual API testing |
 491 | | 10 | `code` | `set` | 677 | 339 | 11.6 | Data manipulation |
 492 | | 11 | `code` | `respondToWebhook` | 617 | 285 | 9.8 | Webhook responses |
 493 | | 12 | `code` | `scheduleTrigger` | 585 | 290 | 10.3 | Scheduled automation |
 494 | | 13 | `manualTrigger` | `set` | 569 | 290 | 8.6 | Simple manual workflows |
 495 | | 14 | `if` | `set` | 545 | 291 | 13.0 | Conditional data setting |
 496 | | 15 | `httpRequest` | `respondToWebhook` | 534 | 263 | 10.0 | API-based webhooks |
 497 | | 16 | `webhook` | `set` | 516 | 289 | 9.9 | Webhook data processing |
 498 | | 17 | `httpRequest` | `scheduleTrigger` | 511 | 270 | 10.4 | Scheduled API calls |
 499 | | 18 | `webhook` | `if` | 477 | 277 | 12.7 | Conditional webhooks |
 500 | | 19 | `code` | `googleSheets` | 475 | 212 | 11.4 | Sheets data processing |
 501 | | 20 | `agent` | `lmChatOpenAi` | 475 | 222 | 10.1 | AI agent workflows |
 502 | 
 503 | ### **5.6 Pattern Recognition**
 504 | 
 505 | **Pattern A: The "Transform-and-Call" Pattern**
 506 | - `code + httpRequest` (1,646 workflows)
 507 | - **Flow**: Prepare data → Call API → Process response
 508 | - **Use cases**: Integration automation, data synchronization
 509 | 
 510 | **Pattern B: The "Webhook Handler" Pattern**
 511 | - `webhook + respondToWebhook` (1,043 workflows)
 512 | - **Flow**: Receive webhook → Process → Respond
 513 | - **Use cases**: Event-driven automation, API endpoints
 514 | 
 515 | **Pattern C: The "Conditional Integration" Pattern**
 516 | - `httpRequest + if + set` (combined ~2,000 workflows)
 517 | - **Flow**: Call API → Check response → Transform data
 518 | - **Use cases**: Smart integrations, error handling
 519 | 
 520 | **Pattern D: The "AI Agent" Pattern**
 521 | - `agent + lmChatOpenAi + memoryBufferWindow` (475 workflows)
 522 | - **Flow**: AI agent with memory and LLM
 523 | - **Use cases**: Conversational AI, intelligent automation
 524 | 
 525 | ### **5.7 Node Usage in Complex Workflows**
 526 | 
 527 | **Top nodes in complex workflows (21+ nodes):**
 528 | 
 529 | | Rank | Node Type | Count | Avg Size |
 530 | |------|-----------|-------|----------|
 531 | | 1 | `code` | 139 | 26.7 |
 532 | | 2 | `httpRequest` | 125 | 27.6 |
 533 | | 3 | `if` | 111 | 27.4 |
 534 | | 4 | `set` | 87 | 28.0 |
 535 | | 5 | `switch` | 74 | 27.9 |
 536 | | 6 | `webhook` | 68 | 29.5 |
 537 | | 7 | `merge` | 62 | 27.1 |
 538 | | 8 | `splitInBatches` | 50 | 25.6 |
 539 | 
 540 | **Insight**: Complex workflows use the same core nodes, just more of them
 541 | - Control flow (if/switch) for complex logic
 542 | - Data manipulation (code/set) for transformations
 543 | - Integration (httpRequest) for external systems
 544 | 
 545 | ---
 546 | 
 547 | ## **6. PLATFORM & VERSION DISTRIBUTION**
 548 | 
 549 | ### **6.1 Platform Breakdown**
 550 | 
 551 | **Top 20 Configurations:**
 552 | 
 553 | | Platform | Arch | Version | Sessions | Users | % |
 554 | |----------|------|---------|----------|-------|---|
 555 | | **Linux** | x64 | 2.14.0 | 1,488 | 242 | 34% |
 556 | | Linux | arm64 | 2.14.0 | 190 | 135 | 4% |
 557 | | **Windows** | x64 | 2.14.1 | 115 | 79 | 3% |
 558 | | Windows | x64 | 2.14.1 | 95 | 53 | 2% |
 559 | | **macOS** | arm64 | 2.14.1 | 77 | 51 | 2% |
 560 | | Windows | x64 | 2.14.1 | 70 | 41 | 2% |
 561 | | macOS | arm64 | 2.14.1 | 68 | 43 | 2% |
 562 | | Windows | x64 | 2.14.1 | 60 | 46 | 1% |
 563 | | Linux | x64 | 2.14.5 | 54 | 30 | 1% |
 564 | | macOS | arm64 | 2.14.1 | 51 | 26 | 1% |
 565 | 
 566 | **Aggregated by Platform:**
 567 | - **Linux**: ~40% (1,678 sessions) - Docker, cloud VMs, CI/CD
 568 | - **Windows**: ~25% (multiple versions)
 569 | - **macOS**: ~15% (mostly M1/M2 Macs)
 570 | - **Other/Unknown**: ~20%
 571 | 
 572 | ### **6.2 Version Distribution**
 573 | 
 574 | | Version | Total Sessions | Estimated Users | Release Date |
 575 | |---------|----------------|-----------------|--------------|
 576 | | 2.14.0 | 1,678 | 377 | Sep 26 |
 577 | | 2.14.1 | 780+ | 500+ | Sep 26 |
 578 | | 2.14.2 | ~50 | ~40 | Sep 29 |
 579 | | 2.14.3 | ~30 | ~25 | Sep 29 |
 580 | | 2.14.4 | 29 | 27 | Sep 30 |
 581 | | 2.14.5 | 54 | 30 | Sep 30 |
 582 | | 2.14.6 | 74 | 56 | Oct 1 |
 583 | 
 584 | ### **6.3 Critical Findings**
 585 | 
 586 | **FINDING #1: Majority stuck on 2.14.0 (37% of sessions)**
 587 | - 1,678 sessions on v2.14.0
 588 | - **Problem**: This version has known issues:
 589 |   - TypeError fixes incomplete (CHANGELOG 2.14.0)
 590 |   - Validation false positives (fixed in 2.14.2)
 591 |   - Template sanitization issues (fixed in 2.14.3)
 592 | 
 593 | **FINDING #2: Slow version adoption**
 594 | - Only 74 sessions on latest v2.14.6 (Oct 1 release)
 595 | - Only 54 sessions on v2.14.5 (Sep 30 release)
 596 | - **Gap**: Users not upgrading despite bug fixes
 597 | 
 598 | **FINDING #3: Linux dominates (40% of sessions)**
 599 | - Likely Docker deployments
 600 | - CI/CD integration
 601 | - Cloud VMs (AWS, GCP, Azure)
 602 | - **Implication**: Containerization is working well
 603 | 
 604 | **FINDING #4: Node.js version fragmentation**
 605 | - v22.20.0: Most common
 606 | - v22.19.0: Second most common
 607 | - v22.18.0, v22.17.0, v22.14.0: Long tail
 608 | - **No compatibility issues reported** (good)
 609 | 
 610 | ### **6.4 Recommendations**
 611 | 
 612 | **R1: Version update notifications**
 613 | - Add update checker to MCP server
 614 | - Notify users of critical fixes
 615 | - Show CHANGELOG diff between versions
 616 | 
 617 | **R2: Docker image optimization**
 618 | - Pre-build for Linux x64 + arm64
 619 | - Multi-stage builds for smaller images
 620 | - Automatic version pinning
 621 | 
 622 | **R3: Breaking change policy**
 623 | - Clear migration guides for version updates
 624 | - Deprecation warnings before breaking changes
 625 | - Backward compatibility period (2 releases minimum)
 626 | 
 627 | ---
 628 | 
 629 | ## **7. ERROR PATTERNS & ROOT CAUSES**
 630 | 
 631 | ### **7.1 TypeError Cascade in Node Tools**
 632 | 
 633 | **Error Distribution (from error logs):**
 634 | 
 635 | | Tool | TypeError Count | Affected Users | % Failure |
 636 | |------|-----------------|----------------|-----------|
 637 | | `get_node_essentials` | ~350 | 10+ | 9.8% |
 638 | | `get_node_info` | ~250 | 12+ | 17.7% |
 639 | | `get_node_documentation` | ~100 | 8+ | 7.1% |
 640 | | **TOTAL** | ~700 | ~30 | **varies** |
 641 | 
 642 | **From CHANGELOG 2.14.0:**
 643 | > "Fixed TypeErrors in `get_node_info`, `get_node_essentials`, and `get_node_documentation` tools that were affecting 50% of calls"
 644 | > "Added null safety checks for undefined node properties"
 645 | 
 646 | **Analysis:**
 647 | - Fix in 2.14.0 reduced failures from **50% → 10-18%**
 648 | - **Residual issues remain** (700+ errors in 6 days)
 649 | - **Root causes**:
 650 |   1. Incomplete null safety for edge cases
 651 |   2. Nodes with unusual/legacy structure
 652 |   3. Missing properties in database
 653 |   4. Nested property access without guards
 654 | 
 655 | **Example Error Pattern:**
 656 | ```javascript
 657 | // Fails when node.properties.description is undefined
 658 | const description = node.properties.description.text;
 659 | 
 660 | // Should be:
 661 | const description = node?.properties?.description?.text ?? 'No description';
 662 | ```
 663 | 
 664 | ### **7.2 ValidationError in Workflow Creation**
 665 | 
 666 | **Pattern:**
 667 | - `n8n_create_workflow`: 237 failures (3.9% failure rate)
 668 | - Error type: `ValidationError`
 669 | - Context: `tool_execution`
 670 | 
 671 | **Root causes (from validation analysis):**
 672 | 1. **Node type prefix errors** (80% of validation errors)
 673 |    - `nodes-base.X` vs `n8n-nodes-base.X`
 674 |    - See Section 2 for full analysis
 675 | 
 676 | 2. **Missing connections** (10% of validation errors)
 677 |    - "Multi-node workflow has no connections"
 678 |    - Valid error, but could provide better guidance
 679 | 
 680 | 3. **Duplicate node IDs** (5% of validation errors)
 681 |    - "Duplicate node ID: 'undefined'"
 682 |    - Likely bug in node generation
 683 | 
 684 | 4. **Other validation issues** (5%)
 685 |    - Missing required properties
 686 |    - Invalid property values
 687 |    - Connection reference errors
 688 | 
 689 | ### **7.3 Task Discovery Failures**
 690 | 
 691 | **Pattern:**
 692 | - `get_node_for_task`: 109 failures (27.8% failure rate)
 693 | - Error type: Not specified (likely "No matching task found")
 694 | - **Highest failure rate of any tool**
 695 | 
 696 | **Probable causes:**
 697 | 1. **Limited task library** - Only ~30-40 predefined tasks
 698 | 2. **No fuzzy matching** - Exact task name required
 699 | 3. **Poor task descriptions** - AI agents can't guess correct task name
 700 | 4. **Missing fallback** - Doesn't suggest alternatives
 701 | 
 702 | **Example failing queries (inferred):**
 703 | - "send email notification" (might need "email_send" task)
 704 | - "process json data" (might need "json_parse" task)
 705 | - "schedule workflow" (might need "cron_trigger" task)
 706 | 
 707 | ### **7.4 Other Error Patterns**
 708 | 
 709 | **Low-frequency errors (<10 occurrences):**
 710 | - Tool not found errors (misspelled tool names)
 711 | - Invalid parameters (wrong types, missing required fields)
 712 | - Network timeouts (n8n API unavailable)
 713 | - Database errors (SQLite lock issues)
 714 | 
 715 | **These are expected in production and handled gracefully**
 716 | 
 717 | ---
 718 | 
 719 | ## **8. PRIORITIZED REFACTORING RECOMMENDATIONS**
 720 | 
 721 | ### **P0 - CRITICAL (Fix Immediately)**
 722 | 
 723 | ---
 724 | 
 725 | #### **P0-R1: Auto-normalize node type prefixes**
 726 | 
 727 | **Problem**: 4,800+ validation errors from `nodes-base.X` vs `n8n-nodes-base.X`
 728 | 
 729 | **Impact**:
 730 | - Eliminates **80% of all validation errors**
 731 | - Improves AI agent experience significantly
 732 | - Reduces token waste from retry attempts
 733 | - Unblocks hundreds of users
 734 | 
 735 | **Solution**:
 736 | ```typescript
 737 | // src/services/workflow-validator.ts
 738 | 
 739 | export function normalizeNodeTypes(workflow: any): any {
 740 |   const normalized = { ...workflow };
 741 | 
 742 |   if (normalized.nodes) {
 743 |     normalized.nodes = normalized.nodes.map((node: any) => ({
 744 |       ...node,
 745 |       type: normalizeNodeType(node.type)
 746 |     }));
 747 |   }
 748 | 
 749 |   return normalized;
 750 | }
 751 | 
 752 | function normalizeNodeType(type: string): string {
 753 |   // Fix common AI-generated abbreviations
 754 |   const prefixMap: Record<string, string> = {
 755 |     'nodes-base.': 'n8n-nodes-base.',
 756 |     'nodes-langchain.': '@n8n/n8n-nodes-langchain.',
 757 |     'n8n-nodes-langchain.': '@n8n/n8n-nodes-langchain.'
 758 |   };
 759 | 
 760 |   for (const [short, full] of Object.entries(prefixMap)) {
 761 |     if (type.startsWith(short)) {
 762 |       return type.replace(short, full);
 763 |     }
 764 |   }
 765 | 
 766 |   return type;
 767 | }
 768 | ```
 769 | 
 770 | **Apply in handlers**:
 771 | ```typescript
 772 | // src/mcp/handlers-n8n-manager.ts
 773 | 
 774 | export async function handleCreateWorkflow(params: any): Promise<McpToolResponse> {
 775 |   // Normalize before validation
 776 |   const normalizedWorkflow = normalizeNodeTypes(params);
 777 | 
 778 |   const validation = await validateWorkflow(normalizedWorkflow);
 779 |   if (!validation.valid) {
 780 |     return { success: false, error: validation.errors };
 781 |   }
 782 | 
 783 |   // Use normalized workflow
 784 |   return await createWorkflow(normalizedWorkflow);
 785 | }
 786 | 
 787 | export async function handleUpdateFullWorkflow(params: any): Promise<McpToolResponse> {
 788 |   const normalizedWorkflow = normalizeNodeTypes(params);
 789 |   // ... rest of handler
 790 | }
 791 | ```
 792 | 
 793 | **Testing**:
 794 | ```typescript
 795 | // tests/unit/services/workflow-normalizer.test.ts
 796 | 
 797 | describe('normalizeNodeTypes', () => {
 798 |   it('should normalize nodes-base prefix', () => {
 799 |     const workflow = {
 800 |       nodes: [
 801 |         { id: '1', type: 'nodes-base.set', parameters: {} }
 802 |       ]
 803 |     };
 804 | 
 805 |     const result = normalizeNodeTypes(workflow);
 806 |     expect(result.nodes[0].type).toBe('n8n-nodes-base.set');
 807 |   });
 808 | 
 809 |   it('should handle already-normalized types', () => {
 810 |     const workflow = {
 811 |       nodes: [
 812 |         { id: '1', type: 'n8n-nodes-base.set', parameters: {} }
 813 |       ]
 814 |     };
 815 | 
 816 |     const result = normalizeNodeTypes(workflow);
 817 |     expect(result.nodes[0].type).toBe('n8n-nodes-base.set');
 818 |   });
 819 | 
 820 |   it('should normalize langchain nodes', () => {
 821 |     const workflow = {
 822 |       nodes: [
 823 |         { id: '1', type: 'nodes-langchain.agent', parameters: {} }
 824 |       ]
 825 |     };
 826 | 
 827 |     const result = normalizeNodeTypes(workflow);
 828 |     expect(result.nodes[0].type).toBe('@n8n/n8n-nodes-langchain.agent');
 829 |   });
 830 | });
 831 | ```
 832 | 
 833 | **Effort**: 2-4 hours
 834 | **Risk**: Low (only adds normalization, doesn't change validation logic)
 835 | **Files**:
 836 | - `src/services/workflow-validator.ts` (new helper)
 837 | - `src/mcp/handlers-n8n-manager.ts` (apply in handlers)
 838 | - `tests/unit/services/workflow-normalizer.test.ts` (new tests)
 839 | 
 840 | ---
 841 | 
 842 | #### **P0-R2: Complete null-safety audit of node information tools**
 843 | 
 844 | **Problem**: 10-18% failure rate for `get_node_essentials`, `get_node_info`, `get_node_documentation`
 845 | 
 846 | **Impact**:
 847 | - Reduce TypeError failures from **10-18% → <1%**
 848 | - Improve reliability of most-used tools
 849 | - Prevent AI agent blocking on node discovery
 850 | 
 851 | **Solution**: Comprehensive null-safety refactor
 852 | 
 853 | **Step 1: Update repository methods**
 854 | ```typescript
 855 | // src/database/node-repository.ts
 856 | 
 857 | export class NodeRepository {
 858 |   getNodeEssentials(nodeType: string): NodeEssentials | null {
 859 |     try {
 860 |       const node = this.db.prepare(`
 861 |         SELECT * FROM nodes WHERE type = ?
 862 |       `).get(nodeType);
 863 | 
 864 |       if (!node) {
 865 |         return null;
 866 |       }
 867 | 
 868 |       // Safe property access with defaults
 869 |       return {
 870 |         type: node.type ?? 'unknown',
 871 |         displayName: node.displayName ?? node.name ?? 'Unknown Node',
 872 |         description: this.extractDescription(node),
 873 |         category: node.category ?? 'Uncategorized',
 874 |         icon: node.icon ?? 'fa:question',
 875 |         inputs: this.parseJSON(node.inputs, []),
 876 |         outputs: this.parseJSON(node.outputs, []),
 877 |         properties: this.extractEssentialProperties(node)
 878 |       };
 879 |     } catch (error) {
 880 |       this.logger.error('Error getting node essentials', { nodeType, error });
 881 |       return null;
 882 |     }
 883 |   }
 884 | 
 885 |   private extractDescription(node: any): string {
 886 |     // Try multiple possible locations for description
 887 |     if (node.description) return node.description;
 888 |     if (node.properties?.description?.text) return node.properties.description.text;
 889 |     if (node.properties?.description) return node.properties.description;
 890 |     if (node.subtitle) return node.subtitle;
 891 |     return 'No description available';
 892 |   }
 893 | 
 894 |   private parseJSON<T>(value: any, defaultValue: T): T {
 895 |     if (!value) return defaultValue;
 896 |     try {
 897 |       return typeof value === 'string' ? JSON.parse(value) : value;
 898 |     } catch {
 899 |       return defaultValue;
 900 |     }
 901 |   }
 902 | 
 903 |   private extractEssentialProperties(node: any): any[] {
 904 |     try {
 905 |       const props = this.parseJSON(node.properties, []);
 906 |       return props.map((prop: any) => ({
 907 |         name: prop.name ?? 'unknown',
 908 |         displayName: prop.displayName ?? prop.name ?? 'Unknown',
 909 |         type: prop.type ?? 'string',
 910 |         required: prop.required ?? false,
 911 |         default: prop.default ?? null,
 912 |         description: prop.description ?? ''
 913 |       }));
 914 |     } catch {
 915 |       return [];
 916 |     }
 917 |   }
 918 | }
 919 | ```
 920 | 
 921 | **Step 2: Update handlers with error handling**
 922 | ```typescript
 923 | // src/mcp/handlers.ts
 924 | 
 925 | export async function handleGetNodeEssentials(params: { nodeType: string }): Promise<McpToolResponse> {
 926 |   const { nodeType } = params;
 927 | 
 928 |   // Validate input
 929 |   if (!nodeType || typeof nodeType !== 'string') {
 930 |     return {
 931 |       success: false,
 932 |       error: 'Invalid nodeType parameter'
 933 |     };
 934 |   }
 935 | 
 936 |   try {
 937 |     const essentials = await nodeRepository.getNodeEssentials(nodeType);
 938 | 
 939 |     if (!essentials) {
 940 |       return {
 941 |         success: false,
 942 |         error: `Node type "${nodeType}" not found. Use search_nodes to find available nodes.`
 943 |       };
 944 |     }
 945 | 
 946 |     return {
 947 |       success: true,
 948 |       data: essentials
 949 |     };
 950 |   } catch (error) {
 951 |     return {
 952 |       success: false,
 953 |       error: `Failed to get node essentials: ${error.message}`
 954 |     };
 955 |   }
 956 | }
 957 | ```
 958 | 
 959 | **Step 3: Add comprehensive tests**
 960 | ```typescript
 961 | // tests/unit/database/node-repository.test.ts
 962 | 
 963 | describe('NodeRepository - Null Safety', () => {
 964 |   it('should handle node with missing description', () => {
 965 |     const node = { type: 'test.node', name: 'Test' };
 966 |     db.prepare('INSERT INTO nodes VALUES (?, ?, NULL)').run(node.type, node.name);
 967 | 
 968 |     const result = repository.getNodeEssentials('test.node');
 969 |     expect(result).not.toBeNull();
 970 |     expect(result.description).toBe('No description available');
 971 |   });
 972 | 
 973 |   it('should handle node with malformed JSON properties', () => {
 974 |     const node = { type: 'test.node', properties: 'invalid json' };
 975 |     db.prepare('INSERT INTO nodes VALUES (?, ?, ?)').run(node.type, node.name, node.properties);
 976 | 
 977 |     const result = repository.getNodeEssentials('test.node');
 978 |     expect(result).not.toBeNull();
 979 |     expect(result.properties).toEqual([]);
 980 |   });
 981 | 
 982 |   it('should return null for non-existent node', () => {
 983 |     const result = repository.getNodeEssentials('non.existent');
 984 |     expect(result).toBeNull();
 985 |   });
 986 | });
 987 | ```
 988 | 
 989 | **Effort**: 1 day (8 hours)
 990 | **Risk**: Medium (changes core repository methods, needs thorough testing)
 991 | **Files**:
 992 | - `src/database/node-repository.ts` (refactor)
 993 | - `src/mcp/handlers.ts` (update error handling)
 994 | - `tests/unit/database/node-repository.test.ts` (comprehensive tests)
 995 | - `tests/unit/mcp/handlers.test.ts` (update tests)
 996 | 
 997 | **Success Criteria**:
 998 | - `get_node_essentials` failure rate: 10% → <1%
 999 | - `get_node_info` failure rate: 18% → <1%
1000 | - `get_node_documentation` failure rate: 7% → <1%
1001 | - 100% test coverage for null cases
1002 | 
1003 | ---
1004 | 
1005 | #### **P0-R3: Improve `get_node_for_task` success rate**
1006 | 
1007 | **Problem**: 27.8% failure rate (worst-performing tool)
1008 | 
1009 | **Impact**:
1010 | - Improve from **72% → 95%+ success rate**
1011 | - Enable AI agents to discover nodes by task description
1012 | - Reduce frustration when agents don't know exact node names
1013 | 
1014 | **Solution**: Multi-pronged enhancement
1015 | 
1016 | **Step 1: Expand task library**
1017 | ```typescript
1018 | // src/services/task-templates.ts
1019 | 
1020 | export const TASK_LIBRARY = {
1021 |   // HTTP & API
1022 |   'http_request': { node: 'n8n-nodes-base.httpRequest', priority: 1 },
1023 |   'api_call': { node: 'n8n-nodes-base.httpRequest', priority: 1 },
1024 |   'make_http_request': { node: 'n8n-nodes-base.httpRequest', priority: 1 },
1025 |   'fetch_data': { node: 'n8n-nodes-base.httpRequest', priority: 2 },
1026 | 
1027 |   // Data transformation
1028 |   'transform_data': { node: 'n8n-nodes-base.code', priority: 1 },
1029 |   'process_json': { node: 'n8n-nodes-base.code', priority: 1 },
1030 |   'manipulate_data': { node: 'n8n-nodes-base.set', priority: 2 },
1031 |   'set_values': { node: 'n8n-nodes-base.set', priority: 1 },
1032 | 
1033 |   // Email
1034 |   'send_email': { node: 'n8n-nodes-base.emailSend', priority: 1 },
1035 |   'email_notification': { node: 'n8n-nodes-base.emailSend', priority: 1 },
1036 |   'receive_email': { node: 'n8n-nodes-base.emailReadImap', priority: 1 },
1037 | 
1038 |   // Webhooks
1039 |   'webhook': { node: 'n8n-nodes-base.webhook', priority: 1 },
1040 |   'receive_webhook': { node: 'n8n-nodes-base.webhook', priority: 1 },
1041 |   'respond_to_webhook': { node: 'n8n-nodes-base.respondToWebhook', priority: 1 },
1042 | 
1043 |   // ... expand to 100+ tasks
1044 | };
1045 | ```
1046 | 
1047 | **Step 2: Add fuzzy matching**
1048 | ```typescript
1049 | // src/services/discovery-service.ts
1050 | 
1051 | import Fuse from 'fuse.js';
1052 | 
1053 | export class DiscoveryService {
1054 |   private taskIndex: Fuse<TaskDefinition>;
1055 | 
1056 |   constructor() {
1057 |     // Build fuzzy search index
1058 |     this.taskIndex = new Fuse(Object.entries(TASK_LIBRARY), {
1059 |       keys: ['0'], // Task name
1060 |       threshold: 0.4, // Allow some typos
1061 |       distance: 100
1062 |     });
1063 |   }
1064 | 
1065 |   getNodeForTask(taskDescription: string): TaskMatch[] {
1066 |     // 1. Try exact match
1067 |     const exactMatch = TASK_LIBRARY[taskDescription.toLowerCase()];
1068 |     if (exactMatch) {
1069 |       return [{
1070 |         node: exactMatch.node,
1071 |         confidence: 1.0,
1072 |         reason: 'Exact task match'
1073 |       }];
1074 |     }
1075 | 
1076 |     // 2. Try fuzzy match
1077 |     const fuzzyMatches = this.taskIndex.search(taskDescription);
1078 |     if (fuzzyMatches.length > 0) {
1079 |       return fuzzyMatches.slice(0, 3).map(match => ({
1080 |         node: match.item[1].node,
1081 |         confidence: 1 - match.score,
1082 |         reason: `Similar to "${match.item[0]}"`
1083 |       }));
1084 |     }
1085 | 
1086 |     // 3. Fallback to keyword search in node descriptions
1087 |     return this.searchNodesByKeywords(taskDescription);
1088 |   }
1089 | 
1090 |   private searchNodesByKeywords(query: string): TaskMatch[] {
1091 |     // Use existing search_nodes functionality
1092 |     const results = nodeRepository.searchNodes(query, { limit: 3 });
1093 |     return results.map(node => ({
1094 |       node: node.type,
1095 |       confidence: 0.5,
1096 |       reason: `Found by keyword search: "${query}"`
1097 |     }));
1098 |   }
1099 | }
1100 | ```
1101 | 
1102 | **Step 3: Return multiple suggestions**
1103 | ```typescript
1104 | // src/mcp/handlers.ts
1105 | 
1106 | export async function handleGetNodeForTask(params: { task: string }): Promise<McpToolResponse> {
1107 |   const { task } = params;
1108 | 
1109 |   try {
1110 |     const matches = discoveryService.getNodeForTask(task);
1111 | 
1112 |     if (matches.length === 0) {
1113 |       return {
1114 |         success: false,
1115 |         error: `No node found for task "${task}". Try search_nodes with keywords instead.`,
1116 |         suggestions: [
1117 |           'Use search_nodes to explore available nodes',
1118 |           'Check list_tasks to see predefined task names'
1119 |         ]
1120 |       };
1121 |     }
1122 | 
1123 |     return {
1124 |       success: true,
1125 |       data: {
1126 |         primaryMatch: matches[0],
1127 |         alternativeMatches: matches.slice(1),
1128 |         totalMatches: matches.length
1129 |       }
1130 |     };
1131 |   } catch (error) {
1132 |     return {
1133 |       success: false,
1134 |       error: `Failed to find node for task: ${error.message}`
1135 |     };
1136 |   }
1137 | }
1138 | ```
1139 | 
1140 | **Step 4: Testing**
1141 | ```typescript
1142 | // tests/unit/services/discovery-service.test.ts
1143 | 
1144 | describe('DiscoveryService - Task Matching', () => {
1145 |   it('should find exact task match', () => {
1146 |     const result = service.getNodeForTask('send_email');
1147 |     expect(result[0].node).toBe('n8n-nodes-base.emailSend');
1148 |     expect(result[0].confidence).toBe(1.0);
1149 |   });
1150 | 
1151 |   it('should handle typos with fuzzy matching', () => {
1152 |     const result = service.getNodeForTask('send emial'); // typo
1153 |     expect(result[0].node).toBe('n8n-nodes-base.emailSend');
1154 |     expect(result[0].confidence).toBeGreaterThan(0.7);
1155 |   });
1156 | 
1157 |   it('should return multiple suggestions', () => {
1158 |     const result = service.getNodeForTask('process data');
1159 |     expect(result.length).toBeGreaterThan(1);
1160 |     expect(result).toContainEqual(
1161 |       expect.objectContaining({ node: 'n8n-nodes-base.code' })
1162 |     );
1163 |   });
1164 | 
1165 |   it('should fallback to keyword search', () => {
1166 |     const result = service.getNodeForTask('sheets manipulation');
1167 |     expect(result.some(r => r.node.includes('googleSheets'))).toBe(true);
1168 |   });
1169 | });
1170 | ```
1171 | 
1172 | **Effort**: 3 days (24 hours)
1173 | - Day 1: Expand task library (100+ tasks)
1174 | - Day 2: Implement fuzzy matching
1175 | - Day 3: Testing and refinement
1176 | 
1177 | **Risk**: Low (enhances existing functionality)
1178 | **Dependencies**: `fuse.js` (fuzzy search library)
1179 | **Files**:
1180 | - `src/services/task-templates.ts` (expand library)
1181 | - `src/services/discovery-service.ts` (new service)
1182 | - `src/mcp/handlers.ts` (update handler)
1183 | - `tests/unit/services/discovery-service.test.ts` (comprehensive tests)
1184 | 
1185 | **Success Criteria**:
1186 | - `get_node_for_task` success rate: 72% → 95%
1187 | - Average confidence score: >0.8
1188 | - Multiple suggestions returned for ambiguous queries
1189 | 
1190 | ### **Immediate Actions (This Week) - P0**
1191 | 
1192 | **1. Auto-normalize node type prefixes (P0-R1)**
1193 | - **Impact**: Eliminate 4,800 validation errors (80% of all errors)
1194 | - **Effort**: 2-4 hours
1195 | - **Files**: `workflow-validator.ts`, `handlers-n8n-manager.ts`
1196 | - **ROI**: ⭐⭐⭐⭐⭐ (Massive impact, minimal effort)
1197 | 
1198 | **2. Complete null-safety audit (P0-R2)**
1199 | - **Impact**: Fix 10-18% TypeError failures
1200 | - **Effort**: 1 day (8 hours)
1201 | - **Files**: `node-repository.ts`, `handlers.ts`
1202 | - **ROI**: ⭐⭐⭐⭐⭐ (Critical reliability improvement)
1203 | 
1204 | **3. Expand task discovery library (P0-R3)**
1205 | - **Impact**: Improve 72% → 95% success rate
1206 | - **Effort**: 3 days (24 hours)
1207 | - **Files**: `task-templates.ts`, `discovery-service.ts`
1208 | - **ROI**: ⭐⭐⭐⭐ (High value for task-based workflows)
1209 | 
1210 | **Expected Overall Impact**:
1211 | - Error rate: 5-10% → <2%
1212 | - User satisfaction: Significant improvement
1213 | - Support burden: Reduced by 50%
1214 | 
```
Page 42/59FirstPrevNextLast