Compare commits

..

1 Commits

Author SHA1 Message Date
Romuald Członkowski
32f63c64a5 fix: memory leak in session removal - close MCP server properly (#471)
- Add close() method to N8NDocumentationMCPServer that:
  - Calls server.close() (MCP SDK cleanup)
  - Clears internal cache
  - Nullifies service references to help GC
- Update removeSession() to call server.close() before releasing references

Root cause: removeSession() deleted server from map but didn't call cleanup
Evidence: Production server memory grew ~1GB in 43 minutes (10% to 35%)

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 18:18:56 +01:00
117 changed files with 4732 additions and 7578 deletions

View File

@@ -311,14 +311,14 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
@@ -396,7 +396,7 @@ jobs:
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Clean up
if: always()
run: rm -rf npm-publish-temp

View File

@@ -7,315 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [2.31.2] - 2025-12-24
### Changed
- Updated n8n from 2.0.2 to 2.1.4
- Updated n8n-core from 2.0.1 to 2.1.3
- Updated n8n-workflow from 2.0.1 to 2.1.1
- Updated @n8n/n8n-nodes-langchain from 2.0.1 to 2.1.3
- Rebuilt node database with 540 nodes (434 from n8n-nodes-base, 106 from @n8n/n8n-nodes-langchain)
- Refreshed template database with 2,737 workflow templates from n8n.io
## [2.31.1] - 2025-12-23
### Fixed
**mcpTrigger Nodes No Longer Incorrectly Flagged as "Disconnected" (Issue #503)**
Fixed a validation bug where `mcpTrigger` nodes were incorrectly flagged as "disconnected nodes" when using `n8n_update_partial_workflow` or `n8n_update_full_workflow`. This blocked ALL updates to MCP server workflows.
**Root Cause:**
The `validateWorkflowStructure()` function only checked `main` connections when building the connected nodes set, ignoring AI connection types (`ai_tool`, `ai_languageModel`, `ai_memory`, `ai_embedding`, `ai_vectorStore`). Additionally, trigger nodes were only checked for outgoing connections, but `mcpTrigger` only receives inbound `ai_tool` connections.
**Changes:**
- Extended connection validation to check all 7 connection types (main, error, ai_tool, ai_languageModel, ai_memory, ai_embedding, ai_vectorStore)
- Updated trigger node validation to accept either outgoing OR inbound connections
- Added 7 new tests covering all AI connection types
**Impact:**
- MCP server workflows can now be updated, renamed, and deactivated normally
- All `n8n_update_*` operations work correctly for AI workflows
- No breaking changes for existing workflows
## [2.31.0] - 2025-12-23
### Added
**New `error` Mode for Execution Debugging**
Added a new `mode='error'` option to `n8n_executions` action=get that's optimized for AI agents debugging workflow failures. This mode provides intelligent error extraction with 80-99% token savings compared to `mode='full'`.
**Key Features:**
- **Error Analysis**: Extracts error message, type, node name, and relevant parameters
- **Upstream Context**: Samples input data from the node feeding into the error node (configurable limit)
- **Execution Path**: Shows the node execution sequence from trigger to error
- **AI Suggestions**: Pattern-based fix suggestions for common errors (missing fields, auth issues, rate limits, etc.)
- **Workflow Fetch**: Optionally fetches workflow structure for accurate upstream detection
**New Parameters for `mode='error'`:**
- `errorItemsLimit` (default: 2) - Number of sample items from upstream node
- `includeStackTrace` (default: false) - Include full vs truncated stack trace
- `includeExecutionPath` (default: true) - Include node execution path
- `fetchWorkflow` (default: true) - Fetch workflow for accurate upstream detection
**Token Efficiency:**
| Execution Size | Full Mode | Error Mode | Savings |
|----------------|-----------|------------|---------|
| 11 items | ~11KB | ~3KB | 73% |
| 1001 items | ~354KB | ~3KB | 99% |
**AI Suggestion Patterns Detected:**
- Missing required fields
- Authentication/authorization issues
- Rate limiting
- Network/connection errors
- Invalid JSON format
- Missing data fields
- Type mismatches
- Timeouts
- Permission denied
**Usage Examples:**
```javascript
// Basic error debugging
n8n_executions({action: "get", id: "exec_123", mode: "error"})
// With more sample data
n8n_executions({action: "get", id: "exec_123", mode: "error", errorItemsLimit: 5})
// With full stack trace
n8n_executions({action: "get", id: "exec_123", mode: "error", includeStackTrace: true})
```
## [2.30.2] - 2025-12-21
### Fixed
**Restored Template Database**
Fixed missing templates in the database by restoring 2,768 workflow templates from git history while preserving compatibility with latest n8n 2.0.2 node definitions.
**Key Changes:**
- Restored templates table with 2,768 curated workflow templates
- Updated nodes table schema to include `is_tool_variant`, `has_tool_variant`, and `tool_variant_of` columns
- Database now contains 803 nodes (updated for n8n 2.0.2) and 2,768 templates
## [2.30.1] - 2025-12-17
### Added
**Support for `_cnd` Conditional Operators in displayOptions Validation**
Added comprehensive support for n8n's `_cnd` conditional operators in displayOptions, enabling proper validation of versioned nodes like Execute Workflow Trigger.
**Supported Operators (12 total):**
- `eq` - Equal
- `not` - Not equal
- `gte` - Greater than or equal
- `lte` - Less than or equal
- `gt` - Greater than
- `lt` - Less than
- `between` - Range check (from/to)
- `startsWith` - String prefix match
- `endsWith` - String suffix match
- `includes` - String contains
- `regex` - Regular expression match
- `exists` - Field existence check
**Key Features:**
- **Version-Based Visibility**: Properties with `displayOptions: { show: { '@version': [{ _cnd: { gte: 1.1 } }] } }` are now correctly evaluated
- **No More False Positives**: Eliminates incorrect "not visible with current settings" warnings for versioned nodes
- **Full Operator Support**: All 12 n8n conditional operators implemented
- **Backward Compatible**: Plain value matching continues to work unchanged
- **Hardened Operators**: Regex and between operators include validation for edge cases
**Files Changed:**
- `src/services/config-validator.ts` - Added `evaluateCondition()`, `valueMatches()`, updated `isPropertyVisible()` to public
- `src/mcp/server.ts` - Pass `@version` to validators in `validateNodeConfig()` and `validateNodeMinimal()`
- `src/services/workflow-validator.ts` - Pass `@version` in workflow validation
- `tests/unit/services/config-validator-cnd.test.ts` - **NEW** 47 unit tests for all operators including edge cases
### Fixed
**n8n 2.0+ Execute Workflow Trigger Activation**
Fixed a breaking change introduced in n8n 2.0 where Execute Workflow Trigger workflows must now be activated to work.
**What Changed:**
- `executeWorkflowTrigger` is now recognized as an activatable trigger
- Removed outdated validation that blocked active workflows with only Execute Workflow Trigger
- Updated error messages to include executeWorkflowTrigger in the list of valid triggers
**Files Changed:**
- `src/utils/node-type-utils.ts` - Updated `isActivatableTrigger()` to return `true` for executeWorkflowTrigger
- `src/services/n8n-validation.ts` - Removed specific check blocking Execute Workflow Trigger
- `src/services/workflow-diff-engine.ts` - Updated error message
- `tests/unit/utils/node-type-utils.test.ts` - Updated tests for n8n 2.0+ behavior
**Conceived by Romuald Czlonkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.30.0] - 2025-12-15
### Changed
**Major n8n 2.0 Update**
Updated to n8n 2.0, a major version upgrade with significant improvements.
**Dependency Updates:**
- n8n: 1.123.4 → 2.0.2
- n8n-core: 1.122.1 → 2.0.1
- n8n-workflow: 1.120.0 → 2.0.1
- @n8n/n8n-nodes-langchain: 1.122.1 → 2.0.1
**Database:**
- Rebuilt node database with 541 nodes (435 from n8n-nodes-base, 106 from @n8n/n8n-nodes-langchain)
- Updated README badge with new n8n version
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.29.2] - 2025-12-12
### Added
**Tool Variant Validation and Auto-Fix**
Added validation to detect when base nodes are incorrectly used as AI tools when Tool variants should be used instead, with automatic fix capability.
**Key Features:**
- **New Validation**: `validateAIToolSource()` detects base nodes (e.g., `n8n-nodes-base.supabase`) connected via `ai_tool` output when a Tool variant exists
- **Clear Error Messages**: Returns actionable error with `WRONG_NODE_TYPE_FOR_AI_TOOL` code explaining which Tool variant to use
- **Auto-Fix Support**: New `tool-variant-correction` fix type in `n8n_autofix_workflow` automatically replaces base nodes with their Tool variants
- **High Confidence Fixes**: Tool variant corrections are marked as high confidence since the correct type is known
**New Utility Method:**
- `NodeTypeNormalizer.toWorkflowFormat()` - Converts database format (short) back to n8n API format (full)
**Test Coverage:**
- 83 new unit tests covering Tool variant validation, auto-fix, and type normalization
- Tests for edge cases: langchain tools, unknown nodes, multiple errors, community nodes
**Files Changed:**
- `src/services/workflow-validator.ts` - Added `validateAIToolSource()` method
- `src/services/workflow-auto-fixer.ts` - Added `tool-variant-correction` fix type
- `src/utils/node-type-normalizer.ts` - Added `toWorkflowFormat()` method
- `tests/unit/services/workflow-validator-tool-variants.test.ts` - **NEW** 12 tests
- `tests/unit/services/workflow-auto-fixer-tool-variants.test.ts` - **NEW** 13 tests
- `tests/unit/utils/node-type-normalizer.test.ts` - Added 19 tests for `toWorkflowFormat()`
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.29.1] - 2025-12-12
### Added
**Tool Variant Support for AI Agent Integration**
Added comprehensive support for n8n Tool variants - specialized node versions created for AI Agent tool connections (e.g., `nodes-base.supabaseTool` from `nodes-base.supabase`).
**Key Features:**
- **266 Tool Variants Generated**: During database rebuild, Tool variants are automatically created for all nodes with `usableAsTool: true`
- **Bidirectional Cross-References**:
- Base nodes show `toolVariantInfo.hasToolVariant: true` with guidance to use Tool variant
- Tool variants show `toolVariantInfo.isToolVariant: true` with reference to base node
- **Clear AI Guidance**: Contextual messages help AI assistants choose the correct node type:
- Base node guidance: "To use this node with AI Agents, use the Tool variant: nodes-base.supabaseTool"
- Tool variant guidance: "This is the Tool variant for AI Agent integration"
- **Tool Description Property**: Tool variants include `toolDescription` property for AI context
- **ai_tool Output Type**: Tool variants output `ai_tool` instead of `main` for proper Agent connections
**Database Schema Changes:**
- Added `is_tool_variant` column (1 if Tool variant)
- Added `tool_variant_of` column (base node type reference)
- Added `has_tool_variant` column (1 if base node has Tool variant)
- Added indexes for efficient Tool variant queries
**Files Changed:**
- `src/database/schema.sql` - New columns and indexes
- `src/parsers/node-parser.ts` - Extended ParsedNode interface
- `src/services/tool-variant-generator.ts` - **NEW** Tool variant generation service
- `src/database/node-repository.ts` - Store/retrieve Tool variant fields
- `src/scripts/rebuild.ts` - Generate Tool variants during rebuild
- `src/mcp/server.ts` - Add `toolVariantInfo` to get_node responses
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.29.0] - 2025-12-09
### Performance
**Token-Efficient Workflow Tool Responses (#479)**
Optimized 4 workflow management tools to return minimal responses instead of full workflow objects, reducing token usage by 75-90%:
- **n8n_update_partial_workflow**: Returns `{id, name, active, nodeCount, operationsApplied}` instead of full workflow
- **n8n_create_workflow**: Returns `{id, name, active, nodeCount}` instead of full workflow
- **n8n_update_full_workflow**: Returns `{id, name, active, nodeCount}` instead of full workflow
- **n8n_delete_workflow**: Returns `{id, name, deleted: true}` instead of full deleted workflow
**Impact**:
- ~75-90% reduction in response token usage per operation
- Messages now guide AI agents to use `n8n_get_workflow` with mode 'structure' if verification needed
- No functional changes - full workflow data still available via `n8n_get_workflow`
**Files Modified**:
- `src/mcp/handlers-workflow-diff.ts` - Optimized partial update response
- `src/mcp/handlers-n8n-manager.ts` - Optimized create, full update, and delete responses
- `src/mcp/tool-docs/workflow_management/*.ts` - Updated documentation
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.28.9] - 2025-12-08
### Dependencies
**Updated n8n to 1.123.4**
- Updated n8n from 1.122.4 to 1.123.4
- Updated n8n-core from 1.121.1 to 1.122.1
- Updated n8n-workflow from 1.119.1 to 1.120.0
- Updated @n8n/n8n-nodes-langchain from 1.121.1 to 1.122.1
- Rebuilt node database with 545 nodes (439 from n8n-nodes-base, 106 from @n8n/n8n-nodes-langchain)
- Updated README badge with new n8n version
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.28.8] - 2025-12-07
### Bug Fixes
**Multi-tenant: handleValidateWorkflow missing context parameter (#474)**
Fixed `n8n_validate_workflow` tool failing in multi-tenant mode with error:
`"n8n API not configured. Please set N8N_API_URL and N8N_API_KEY environment variables."`
- **Root Cause**: `handleValidateWorkflow` called `handleGetWorkflow` without passing the `context` parameter
- **Impact**: Multi-tenant deployments could not use the `n8n_validate_workflow` tool
- **Solution**: Pass `context` parameter to `handleGetWorkflow` call (line 987)
**Conceived by Romuald Członkowski - [AiAdvisors](https://www.aiadvisors.pl/en)**
## [2.28.7] - 2025-12-05
### Bug Fixes

View File

@@ -5,7 +5,7 @@
[![npm version](https://img.shields.io/npm/v/n8n-mcp.svg)](https://www.npmjs.com/package/n8n-mcp)
[![codecov](https://codecov.io/gh/czlonkowski/n8n-mcp/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/czlonkowski/n8n-mcp)
[![Tests](https://img.shields.io/badge/tests-3336%20passing-brightgreen.svg)](https://github.com/czlonkowski/n8n-mcp/actions)
[![n8n version](https://img.shields.io/badge/n8n-2.1.4-orange.svg)](https://github.com/n8n-io/n8n)
[![n8n version](https://img.shields.io/badge/n8n-1.122.4-orange.svg)](https://github.com/n8n-io/n8n)
[![Docker](https://img.shields.io/badge/docker-ghcr.io%2Fczlonkowski%2Fn8n--mcp-green.svg)](https://github.com/czlonkowski/n8n-mcp/pkgs/container/n8n-mcp)
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/n8n-mcp?referralCode=n8n-mcp)

Binary file not shown.

View File

@@ -15,10 +15,6 @@ export declare class NodeRepository {
getAllNodes(limit?: number): any[];
getNodeCount(): number;
getAIToolNodes(): any[];
getToolVariant(baseNodeType: string): any | null;
getBaseNodeForToolVariant(toolNodeType: string): any | null;
getToolVariants(): any[];
getToolVariantCount(): number;
getNodesByPackage(packageName: string): any[];
searchNodeProperties(nodeType: string, query: string, maxResults?: number): any[];
private parseNodeRow;

View File

@@ -1 +1 @@
{"version":3,"file":"node-repository.d.ts","sourceRoot":"","sources":["../../src/database/node-repository.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"node-repository.d.ts","sourceRoot":"","sources":["../../src/database/node-repository.ts"],"names":[],"mappings":"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"}

View File

@@ -16,13 +16,12 @@ class NodeRepository {
INSERT OR REPLACE INTO nodes (
node_type, package_name, display_name, description,
category, development_style, is_ai_tool, is_trigger,
is_webhook, is_versioned, is_tool_variant, tool_variant_of,
has_tool_variant, version, documentation,
is_webhook, is_versioned, version, documentation,
properties_schema, operations, credentials_required,
outputs, output_names
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(node.nodeType, node.packageName, node.displayName, node.description, node.category, node.style, node.isAITool ? 1 : 0, node.isTrigger ? 1 : 0, node.isWebhook ? 1 : 0, node.isVersioned ? 1 : 0, node.isToolVariant ? 1 : 0, node.toolVariantOf || null, node.hasToolVariant ? 1 : 0, node.version, node.documentation || null, JSON.stringify(node.properties, null, 2), JSON.stringify(node.operations, null, 2), JSON.stringify(node.credentials, null, 2), node.outputs ? JSON.stringify(node.outputs, null, 2) : null, node.outputNames ? JSON.stringify(node.outputNames, null, 2) : null);
stmt.run(node.nodeType, node.packageName, node.displayName, node.description, node.category, node.style, node.isAITool ? 1 : 0, node.isTrigger ? 1 : 0, node.isWebhook ? 1 : 0, node.isVersioned ? 1 : 0, node.version, node.documentation || null, JSON.stringify(node.properties, null, 2), JSON.stringify(node.operations, null, 2), JSON.stringify(node.credentials, null, 2), node.outputs ? JSON.stringify(node.outputs, null, 2) : null, node.outputNames ? JSON.stringify(node.outputNames, null, 2) : null);
}
getNode(nodeType) {
const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType);
@@ -123,40 +122,6 @@ class NodeRepository {
getAIToolNodes() {
return this.getAITools();
}
getToolVariant(baseNodeType) {
if (!baseNodeType || typeof baseNodeType !== 'string' || !baseNodeType.includes('.')) {
return null;
}
const toolNodeType = `${baseNodeType}Tool`;
return this.getNode(toolNodeType);
}
getBaseNodeForToolVariant(toolNodeType) {
const row = this.db.prepare(`
SELECT tool_variant_of FROM nodes WHERE node_type = ?
`).get(toolNodeType);
if (!row?.tool_variant_of)
return null;
return this.getNode(row.tool_variant_of);
}
getToolVariants() {
const rows = this.db.prepare(`
SELECT node_type, display_name, description, package_name, tool_variant_of
FROM nodes
WHERE is_tool_variant = 1
ORDER BY display_name
`).all();
return rows.map(row => ({
nodeType: row.node_type,
displayName: row.display_name,
description: row.description,
package: row.package_name,
toolVariantOf: row.tool_variant_of
}));
}
getToolVariantCount() {
const result = this.db.prepare('SELECT COUNT(*) as count FROM nodes WHERE is_tool_variant = 1').get();
return result.count;
}
getNodesByPackage(packageName) {
const rows = this.db.prepare(`
SELECT * FROM nodes WHERE package_name = ?
@@ -205,9 +170,6 @@ class NodeRepository {
isTrigger: Number(row.is_trigger) === 1,
isWebhook: Number(row.is_webhook) === 1,
isVersioned: Number(row.is_versioned) === 1,
isToolVariant: Number(row.is_tool_variant) === 1,
toolVariantOf: row.tool_variant_of || null,
hasToolVariant: Number(row.has_tool_variant) === 1,
version: row.version,
properties: this.safeJsonParse(row.properties_schema, []),
operations: this.safeJsonParse(row.operations, []),

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"http-server-single-session.d.ts","sourceRoot":"","sources":["../src/http-server-single-session.ts"],"names":[],"mappings":";AAMA,OAAO,OAAO,MAAM,SAAS,CAAC;AAoB9B,OAAO,EAAE,eAAe,EAA2B,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAuErD,qBAAa,uBAAuB;IAElC,OAAO,CAAC,UAAU,CAA8D;IAChF,OAAO,CAAC,OAAO,CAA0D;IACzE,OAAO,CAAC,eAAe,CAAsE;IAC7F,OAAO,CAAC,eAAe,CAA4D;IACnF,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA+B;;IAcnD,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,sBAAsB;YAqChB,aAAa;IAuC3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,sBAAsB;IAkC9B,OAAO,CAAC,mBAAmB;YASb,oBAAoB;YAwBpB,oBAAoB;IAwBlC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,mBAAmB;IAoDrB,aAAa,CACjB,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC;YAmOF,eAAe;IA8C7B,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,gBAAgB;IASlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgnBtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD/B,cAAc,IAAI;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE;YACT,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,GAAG,EAAE,MAAM,CAAC;YACZ,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;KACH;IAmDM,kBAAkB,IAAI,YAAY,EAAE;IAoEpC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM;CAsG7D"}
{"version":3,"file":"http-server-single-session.d.ts","sourceRoot":"","sources":["../src/http-server-single-session.ts"],"names":[],"mappings":";AAMA,OAAO,OAAO,MAAM,SAAS,CAAC;AAoB9B,OAAO,EAAE,eAAe,EAA2B,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAuErD,qBAAa,uBAAuB;IAElC,OAAO,CAAC,UAAU,CAA8D;IAChF,OAAO,CAAC,OAAO,CAA0D;IACzE,OAAO,CAAC,eAAe,CAAsE;IAC7F,OAAO,CAAC,eAAe,CAA4D;IACnF,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA+B;;IAcnD,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,sBAAsB;YAqChB,aAAa;IAkC3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,sBAAsB;IAkC9B,OAAO,CAAC,mBAAmB;YASb,oBAAoB;YAwBpB,oBAAoB;IAwBlC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,mBAAmB;IAoDrB,aAAa,CACjB,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC;YAmOF,eAAe;IA8C7B,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,gBAAgB;IASlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgnBtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD/B,cAAc,IAAI;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE;YACT,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,GAAG,EAAE,MAAM,CAAC;YACZ,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;KACH;IAmDM,kBAAkB,IAAI,YAAY,EAAE;IAoEpC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM;CAsG7D"}

View File

@@ -106,13 +106,8 @@ class SingleSessionHTTPServer {
delete this.servers[sessionId];
delete this.sessionMetadata[sessionId];
delete this.sessionContexts[sessionId];
if (server && typeof server.close === 'function') {
try {
await server.close();
}
catch (serverError) {
logger_1.logger.warn('Error closing server', { sessionId, error: serverError });
}
if (server) {
await server.close();
}
if (transport) {
await transport.close();

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"handlers-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAML,eAAe,EAGhB,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAA2B,MAAM,2BAA2B,CAAC;AAOrF,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAqNhE,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAMD,wBAAgB,uBAAuB,gDAEtC;AAKD,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAgF9E;AAqHD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAmF7G;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC1G;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAoDjH;AAED,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAmDnH;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyCjH;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA8H1B;AAeD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC7G;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiE5G;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA0F1B;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAoK1B;AAQD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwJ3G;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA8H3G;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAgD7G;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC9G;AAID,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwG3F;AAkLD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAkQxG;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAsL1B;AA+BD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAoM1B;AAQD,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyErH"}
{"version":3,"file":"handlers-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-n8n-manager.ts"],"names":[],"mappings":"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"}

View File

@@ -285,13 +285,8 @@ async function handleCreateWorkflow(args, context) {
telemetry_1.telemetry.trackWorkflowCreation(workflow, true);
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
nodeCount: workflow.nodes?.length || 0
},
message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}. Use n8n_get_workflow with mode 'structure' to verify current state.`
data: workflow,
message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}`
};
}
catch (error) {
@@ -542,13 +537,8 @@ async function handleUpdateWorkflow(args, repository, context) {
}
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
nodeCount: workflow.nodes?.length || 0
},
message: `Workflow "${workflow.name}" updated successfully. Use n8n_get_workflow with mode 'structure' to verify current state.`
data: workflow,
message: `Workflow "${workflow.name}" updated successfully`
};
}
catch (error) {
@@ -604,12 +594,8 @@ async function handleDeleteWorkflow(args, context) {
const deleted = await client.deleteWorkflow(id);
return {
success: true,
data: {
id: deleted?.id || id,
name: deleted?.name,
deleted: true
},
message: `Workflow "${deleted?.name || id}" deleted successfully.`
data: deleted,
message: `Workflow ${id} deleted successfully`
};
}
catch (error) {
@@ -696,7 +682,7 @@ async function handleValidateWorkflow(args, repository, context) {
try {
const client = ensureApiConfigured(context);
const input = validateWorkflowSchema.parse(args);
const workflowResponse = await handleGetWorkflow({ id: input.id }, context);
const workflowResponse = await handleGetWorkflow({ id: input.id });
if (!workflowResponse.success) {
return workflowResponse;
}
@@ -1024,18 +1010,14 @@ async function handleGetExecution(args, context) {
const client = ensureApiConfigured(context);
const schema = zod_1.z.object({
id: zod_1.z.string(),
mode: zod_1.z.enum(['preview', 'summary', 'filtered', 'full', 'error']).optional(),
mode: zod_1.z.enum(['preview', 'summary', 'filtered', 'full']).optional(),
nodeNames: zod_1.z.array(zod_1.z.string()).optional(),
itemsLimit: zod_1.z.number().optional(),
includeInputData: zod_1.z.boolean().optional(),
includeData: zod_1.z.boolean().optional(),
errorItemsLimit: zod_1.z.number().min(0).max(100).optional(),
includeStackTrace: zod_1.z.boolean().optional(),
includeExecutionPath: zod_1.z.boolean().optional(),
fetchWorkflow: zod_1.z.boolean().optional()
includeData: zod_1.z.boolean().optional()
});
const params = schema.parse(args);
const { id, mode, nodeNames, itemsLimit, includeInputData, includeData, errorItemsLimit, includeStackTrace, includeExecutionPath, fetchWorkflow } = params;
const { id, mode, nodeNames, itemsLimit, includeInputData, includeData } = params;
let effectiveMode = mode;
if (!effectiveMode && includeData !== undefined) {
effectiveMode = includeData ? 'summary' : undefined;
@@ -1048,28 +1030,13 @@ async function handleGetExecution(args, context) {
data: execution
};
}
let workflow;
if (effectiveMode === 'error' && fetchWorkflow !== false && execution.workflowId) {
try {
workflow = await client.getWorkflow(execution.workflowId);
}
catch (e) {
logger_1.logger.debug('Could not fetch workflow for error analysis', {
workflowId: execution.workflowId,
error: e instanceof Error ? e.message : 'Unknown error'
});
}
}
const filterOptions = {
mode: effectiveMode,
nodeNames,
itemsLimit,
includeInputData,
errorItemsLimit,
includeStackTrace,
includeExecutionPath
includeInputData
};
const processedExecution = (0, execution_processor_1.processExecution)(execution, filterOptions, workflow);
const processedExecution = (0, execution_processor_1.processExecution)(execution, filterOptions);
return {
success: true,
data: processedExecution

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"handlers-workflow-diff.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-workflow-diff.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AA0D7D,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA6V1B"}
{"version":3,"file":"handlers-workflow-diff.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers-workflow-diff.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AA0D7D,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CA2V1B"}

View File

@@ -329,15 +329,13 @@ async function handleUpdatePartialWorkflow(args, repository, context) {
}
return {
success: true,
data: {
id: finalWorkflow.id,
name: finalWorkflow.name,
active: finalWorkflow.active,
nodeCount: finalWorkflow.nodes?.length || 0,
operationsApplied: diffResult.operationsApplied
},
message: `Workflow "${finalWorkflow.name}" updated successfully. Applied ${diffResult.operationsApplied} operations.${activationMessage} Use n8n_get_workflow with mode 'structure' to verify current state.`,
data: finalWorkflow,
message: `Workflow "${finalWorkflow.name}" updated successfully. Applied ${diffResult.operationsApplied} operations.${activationMessage}`,
details: {
operationsApplied: diffResult.operationsApplied,
workflowId: finalWorkflow.id,
workflowName: finalWorkflow.name,
active: finalWorkflow.active,
applied: diffResult.applied,
failed: diffResult.failed,
errors: diffResult.errors,

File diff suppressed because one or more lines are too long

View File

@@ -60,7 +60,6 @@ export declare class N8NDocumentationMCPServer {
private getNodeAsToolInfo;
private getOutputDescriptions;
private getCommonAIToolUseCases;
private buildToolVariantGuidance;
private getAIToolExamples;
private validateNodeMinimal;
private getToolsDocumentation;

View File

@@ -1 +1 @@
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAgGnE,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,qBAAqB,CAAsB;IACnD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,eAAe,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,gBAAgB;IAiGvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA6Bd,kBAAkB;YAwClB,wBAAwB;IA0BtC,OAAO,CAAC,kBAAkB;YA6CZ,iBAAiB;IAa/B,OAAO,CAAC,eAAe,CAAkB;YAE3B,sBAAsB;IAgDpC,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAoTrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IAqE1B,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,qBAAqB;YAgTf,SAAS;YA2DT,WAAW;YAkFX,WAAW;YAyCX,cAAc;YAyKd,gBAAgB;IAqD9B,OAAO,CAAC,mBAAmB;IAwE3B,OAAO,CAAC,eAAe;YAsBT,eAAe;IAqI7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,uBAAuB;IA0D/B,OAAO,CAAC,iBAAiB;YAqFX,WAAW;YAgCX,oBAAoB;YA2EpB,qBAAqB;YAwDrB,iBAAiB;YAiKjB,OAAO;YAgDP,cAAc;YAwFd,iBAAiB;IAqC/B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,4BAA4B;YAKtB,oBAAoB;IAsDlC,OAAO,CAAC,gBAAgB;YAiBV,SAAS;YA6CT,kBAAkB;YAqElB,uBAAuB;YAsDvB,iBAAiB;IAqE/B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IA4D/B,OAAO,CAAC,wBAAwB;IAkChC,OAAO,CAAC,iBAAiB;YAoDX,mBAAmB;YAoEnB,qBAAqB;IAS7B,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAS9B,aAAa;YAcb,iBAAiB;YAoBjB,WAAW;YAwBX,eAAe;YAqBf,mBAAmB;YAwBnB,yBAAyB;IA4CvC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6HhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAkFnE,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,qBAAqB,CAAsB;IACnD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,eAAe,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,gBAAgB;IA2FvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAed,kBAAkB;YAwClB,wBAAwB;IA0BtC,OAAO,CAAC,kBAAkB;YA6CZ,iBAAiB;IAa/B,OAAO,CAAC,eAAe,CAAkB;YAE3B,sBAAsB;IAgDpC,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAoTrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IAqE1B,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,qBAAqB;YAgTf,SAAS;YA2DT,WAAW;YA0EX,WAAW;YAyCX,cAAc;YAyKd,gBAAgB;IAqD9B,OAAO,CAAC,mBAAmB;IAwE3B,OAAO,CAAC,eAAe;YAsBT,eAAe;IAqI7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,uBAAuB;IA0D/B,OAAO,CAAC,iBAAiB;YAqFX,WAAW;YAgCX,oBAAoB;YA2EpB,qBAAqB;YAwDrB,iBAAiB;YA2JjB,OAAO;YAgDP,cAAc;YAgFd,iBAAiB;IAqC/B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,4BAA4B;YAKtB,oBAAoB;IAsDlC,OAAO,CAAC,gBAAgB;YAiBV,SAAS;YA6CT,kBAAkB;YA+DlB,uBAAuB;YAsDvB,iBAAiB;IAqE/B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IAwD/B,OAAO,CAAC,iBAAiB;YAoDX,mBAAmB;YAkGnB,qBAAqB;IAS7B,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAS9B,aAAa;YAcb,iBAAiB;YAoBjB,WAAW;YAwBX,eAAe;YAqBf,mBAAmB;YAwBnB,yBAAyB;IA4CvC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6HhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}

97
dist/mcp/server.js vendored
View File

@@ -51,7 +51,6 @@ const node_repository_1 = require("../database/node-repository");
const database_adapter_1 = require("../database/database-adapter");
const property_filter_1 = require("../services/property-filter");
const task_templates_1 = require("../services/task-templates");
const config_validator_1 = require("../services/config-validator");
const enhanced_config_validator_1 = require("../services/enhanced-config-validator");
const property_dependencies_1 = require("../services/property-dependencies");
const type_structure_service_1 = require("../services/type-structure-service");
@@ -151,17 +150,7 @@ class N8NDocumentationMCPServer {
async close() {
try {
await this.server.close();
this.cache.destroy();
if (this.db) {
try {
this.db.close();
}
catch (dbError) {
logger_1.logger.warn('Error closing database', {
error: dbError instanceof Error ? dbError.message : String(dbError)
});
}
}
this.cache.clear();
this.db = null;
this.repository = null;
this.templateService = null;
@@ -1026,17 +1015,12 @@ class N8NDocumentationMCPServer {
};
});
}
const result = {
return {
...node,
workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType),
aiToolCapabilities,
outputs
};
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
return result;
}
async searchNodes(query, limit = 20, options) {
await this.ensureInitialized();
@@ -1709,10 +1693,6 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
developmentStyle: node.developmentStyle ?? 'programmatic'
}
};
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
if (includeExamples) {
try {
const examples = this.db.prepare(`
@@ -1794,7 +1774,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
if (!node) {
throw new Error(`Node ${nodeType} not found`);
}
const result = {
return {
nodeType: node.nodeType,
workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package ?? 'n8n-nodes-base', node.nodeType),
displayName: node.displayName,
@@ -1805,11 +1785,6 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
isTrigger: node.isTrigger,
isWebhook: node.isWebhook
};
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
return result;
}
case 'standard': {
const essentials = await this.getNodeEssentials(nodeType, includeExamples);
@@ -2109,11 +2084,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
throw new Error(`Node ${nodeType} not found`);
}
const properties = node.properties || [];
const configWithVersion = {
'@version': node.version || 1,
...config
};
const validationResult = enhanced_config_validator_1.EnhancedConfigValidator.validateWithMode(node.nodeType, configWithVersion, properties, mode, profile);
const validationResult = enhanced_config_validator_1.EnhancedConfigValidator.validateWithMode(node.nodeType, config, properties, mode, profile);
return {
nodeType: node.nodeType,
workflowNodeType: (0, node_utils_1.getWorkflowNodeType)(node.package, node.nodeType),
@@ -2311,32 +2282,6 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
'Extend AI agent capabilities'
];
}
buildToolVariantGuidance(node) {
const isToolVariant = !!node.isToolVariant;
const hasToolVariant = !!node.hasToolVariant;
const toolVariantOf = node.toolVariantOf;
if (!isToolVariant && !hasToolVariant) {
return undefined;
}
if (isToolVariant) {
return {
isToolVariant: true,
toolVariantOf,
hasToolVariant: false,
guidance: `This is the Tool variant for AI Agent integration. Use this node type when connecting to AI Agents. The base node is: ${toolVariantOf}`
};
}
if (hasToolVariant && node.nodeType) {
const toolVariantNodeType = `${node.nodeType}Tool`;
return {
isToolVariant: false,
hasToolVariant: true,
toolVariantNodeType,
guidance: `To use this node with AI Agents, use the Tool variant: ${toolVariantNodeType}. The Tool variant has an additional 'toolDescription' property and outputs 'ai_tool' instead of 'main'.`
};
}
return undefined;
}
getAIToolExamples(nodeType) {
const exampleMap = {
'nodes-base.slack': {
@@ -2407,16 +2352,40 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
throw new Error(`Node ${nodeType} not found`);
}
const properties = node.properties || [];
const configWithVersion = {
'@version': node.version || 1,
...(config || {})
const operationContext = {
resource: config?.resource,
operation: config?.operation,
action: config?.action,
mode: config?.mode
};
const missingFields = [];
for (const prop of properties) {
if (!prop.required)
continue;
if (prop.displayOptions && !config_validator_1.ConfigValidator.isPropertyVisible(prop, configWithVersion)) {
continue;
if (prop.displayOptions) {
let isVisible = true;
if (prop.displayOptions.show) {
for (const [key, values] of Object.entries(prop.displayOptions.show)) {
const configValue = config?.[key];
const expectedValues = Array.isArray(values) ? values : [values];
if (!expectedValues.includes(configValue)) {
isVisible = false;
break;
}
}
}
if (isVisible && prop.displayOptions.hide) {
for (const [key, values] of Object.entries(prop.displayOptions.hide)) {
const configValue = config?.[key];
const expectedValues = Array.isArray(values) ? values : [values];
if (expectedValues.includes(configValue)) {
isVisible = false;
break;
}
}
}
if (!isVisible)
continue;
}
if (!config || !(prop.name in config)) {
missingFields.push(prop.displayName || prop.name);

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,7 @@ exports.n8nCreateWorkflowDoc = {
connections: { type: 'object', required: true, description: 'Node connections. Keys are source node IDs' },
settings: { type: 'object', description: 'Optional workflow settings (timezone, error handling, etc.)' }
},
returns: 'Minimal summary (id, name, active, nodeCount) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed.',
returns: 'Created workflow object with id, name, nodes, connections, active status',
examples: [
`// Basic webhook to Slack workflow
n8n_create_workflow({

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-create-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;QAC/C,OAAO,EAAE,0EAA0E;QACnF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2BAA2B;YAC3B,+BAA+B;YAC/B,uCAAuC;YACvC,kFAAkF;SACnF;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,uLAAuL;QACpM,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE;YACtE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uEAAuE,EAAE;YAC9H,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4CAA4C,EAAE;YAC1G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;SACzG;QACD,OAAO,EAAE,mJAAmJ;QAC5J,QAAQ,EAAE;YACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCH;YACG;;;;;;;;;;;GAWH;SACE;QACD,QAAQ,EAAE;YACR,4BAA4B;YAC5B,4BAA4B;YAC5B,2BAA2B;YAC3B,qBAAqB;SACtB;QACD,WAAW,EAAE,oEAAoE;QACjF,aAAa,EAAE;YACb,uCAAuC;YACvC,qBAAqB;YACrB,gCAAgC;YAChC,6BAA6B;SAC9B;QACD,QAAQ,EAAE;YACR,0GAA0G;YAC1G,gEAAgE;YAChE,yCAAyC;YACzC,kDAAkD;YAClD,4EAA4E;YAC5E,yIAAyI;YACzI,uIAAuI;SACxI;QACD,YAAY,EAAE,CAAC,mBAAmB,EAAE,6BAA6B,EAAE,mBAAmB,CAAC;KACxF;CACF,CAAC"}
{"version":3,"file":"n8n-create-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;QAC/C,OAAO,EAAE,0EAA0E;QACnF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2BAA2B;YAC3B,+BAA+B;YAC/B,uCAAuC;YACvC,kFAAkF;SACnF;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,uLAAuL;QACpM,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE;YACtE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uEAAuE,EAAE;YAC9H,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4CAA4C,EAAE;YAC1G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;SACzG;QACD,OAAO,EAAE,0EAA0E;QACnF,QAAQ,EAAE;YACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCH;YACG;;;;;;;;;;;GAWH;SACE;QACD,QAAQ,EAAE;YACR,4BAA4B;YAC5B,4BAA4B;YAC5B,2BAA2B;YAC3B,qBAAqB;SACtB;QACD,WAAW,EAAE,oEAAoE;QACjF,aAAa,EAAE;YACb,uCAAuC;YACvC,qBAAqB;YACrB,gCAAgC;YAChC,6BAA6B;SAC9B;QACD,QAAQ,EAAE;YACR,0GAA0G;YAC1G,gEAAgE;YAChE,yCAAyC;YACzC,kDAAkD;YAClD,4EAA4E;YAC5E,yIAAyI;YACzI,uIAAuI;SACxI;QACD,YAAY,EAAE,CAAC,mBAAmB,EAAE,6BAA6B,EAAE,mBAAmB,CAAC;KACxF;CACF,CAAC"}

View File

@@ -20,7 +20,7 @@ exports.n8nDeleteWorkflowDoc = {
parameters: {
id: { type: 'string', required: true, description: 'Workflow ID to delete permanently' }
},
returns: 'Minimal confirmation (id, name, deleted: true) for token efficiency.',
returns: 'Success confirmation or error if workflow not found/cannot be deleted',
examples: [
'n8n_delete_workflow({id: "abc123"}) - Delete specific workflow',
'if (confirm) { n8n_delete_workflow({id: wf.id}); } // With confirmation'

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-delete-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,8DAA8D;QAC3E,aAAa,EAAE,CAAC,IAAI,CAAC;QACrB,OAAO,EAAE,2CAA2C;QACpD,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,wBAAwB;YACxB,+BAA+B;YAC/B,+DAA+D;SAChE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,qPAAqP;QAClQ,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mCAAmC,EAAE;SACzF;QACD,OAAO,EAAE,sEAAsE;QAC/E,QAAQ,EAAE;YACR,gEAAgE;YAChE,yEAAyE;SAC1E;QACD,QAAQ,EAAE;YACR,2BAA2B;YAC3B,yBAAyB;YACzB,2BAA2B;YAC3B,wBAAwB;YACxB,mBAAmB;SACpB;QACD,WAAW,EAAE,mGAAmG;QAChH,aAAa,EAAE;YACb,gCAAgC;YAChC,+DAA+D;YAC/D,2CAA2C;YAC3C,4CAA4C;SAC7C;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,uCAAuC;YACvC,+BAA+B;YAC/B,iCAAiC;YACjC,0BAA0B;SAC3B;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,gBAAgB,CAAC;KAC1G;CACF,CAAC"}
{"version":3,"file":"n8n-delete-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAsB;IACrD,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,8DAA8D;QAC3E,aAAa,EAAE,CAAC,IAAI,CAAC;QACrB,OAAO,EAAE,2CAA2C;QACpD,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,wBAAwB;YACxB,+BAA+B;YAC/B,+DAA+D;SAChE;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,qPAAqP;QAClQ,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mCAAmC,EAAE;SACzF;QACD,OAAO,EAAE,uEAAuE;QAChF,QAAQ,EAAE;YACR,gEAAgE;YAChE,yEAAyE;SAC1E;QACD,QAAQ,EAAE;YACR,2BAA2B;YAC3B,yBAAyB;YACzB,2BAA2B;YAC3B,wBAAwB;YACxB,mBAAmB;SACpB;QACD,WAAW,EAAE,mGAAmG;QAChH,aAAa,EAAE;YACb,gCAAgC;YAChC,+DAA+D;YAC/D,2CAA2C;YAC3C,4CAA4C;SAC7C;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,uCAAuC;YACvC,+BAA+B;YAC/B,iCAAiC;YACjC,0BAA0B;SAC3B;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,gBAAgB,CAAC;KAC1G;CACF,CAAC"}

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-executions.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,gBAAgB,EAAE,iBAwG9B,CAAC"}
{"version":3,"file":"n8n-executions.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,gBAAgB,EAAE,iBA+E9B,CAAC"}

View File

@@ -6,14 +6,13 @@ exports.n8nExecutionsDoc = {
category: 'workflow_management',
essentials: {
description: 'Manage workflow executions: get details, list, or delete. Unified tool for all execution operations.',
keyParameters: ['action', 'id', 'workflowId', 'status', 'mode'],
example: 'n8n_executions({action: "get", id: "exec_456", mode: "error"})',
keyParameters: ['action', 'id', 'workflowId', 'status'],
example: 'n8n_executions({action: "list", workflowId: "abc123", status: "error"})',
performance: 'Fast (50-200ms)',
tips: [
'action="get": Get execution details by ID',
'action="list": List executions with filters',
'action="delete": Delete execution record',
'Use mode="error" for efficient failure debugging (80-90% token savings)',
'Use mode parameter for action=get to control detail level'
]
},
@@ -27,26 +26,14 @@ exports.n8nExecutionsDoc = {
- preview: Structure only, no data
- summary: 2 items per node (default)
- filtered: Custom items limit, optionally filter by node names
- full: All execution data (can be very large)
- error: Optimized for debugging failures - extracts error info, upstream context, and AI suggestions
**Error Mode Features:**
- Extracts error message, type, and node configuration
- Samples input data from upstream node (configurable limit)
- Shows execution path leading to error
- Provides AI-friendly fix suggestions based on error patterns
- Token-efficient (80-90% smaller than full mode)`,
- full: All execution data (can be very large)`,
parameters: {
action: { type: 'string', required: true, description: 'Operation: "get", "list", or "delete"' },
id: { type: 'string', required: false, description: 'Execution ID (required for action=get or action=delete)' },
mode: { type: 'string', required: false, description: 'For action=get: "preview", "summary" (default), "filtered", "full", "error"' },
mode: { type: 'string', required: false, description: 'For action=get: "preview", "summary" (default), "filtered", "full"' },
nodeNames: { type: 'array', required: false, description: 'For action=get with mode=filtered: Filter to specific nodes by name' },
itemsLimit: { type: 'number', required: false, description: 'For action=get with mode=filtered: Items per node (0=structure, 2=default, -1=unlimited)' },
includeInputData: { type: 'boolean', required: false, description: 'For action=get: Include input data in addition to output (default: false)' },
errorItemsLimit: { type: 'number', required: false, description: 'For action=get with mode=error: Sample items from upstream (default: 2, max: 100)' },
includeStackTrace: { type: 'boolean', required: false, description: 'For action=get with mode=error: Include full stack trace (default: false, shows truncated)' },
includeExecutionPath: { type: 'boolean', required: false, description: 'For action=get with mode=error: Include execution path (default: true)' },
fetchWorkflow: { type: 'boolean', required: false, description: 'For action=get with mode=error: Fetch workflow for accurate upstream detection (default: true)' },
workflowId: { type: 'string', required: false, description: 'For action=list: Filter by workflow ID' },
status: { type: 'string', required: false, description: 'For action=list: Filter by status ("success", "error", "waiting")' },
limit: { type: 'number', required: false, description: 'For action=list: Number of results (1-100, default: 100)' },
@@ -55,15 +42,10 @@ exports.n8nExecutionsDoc = {
includeData: { type: 'boolean', required: false, description: 'For action=list: Include execution data (default: false)' }
},
returns: `Depends on action:
- get (error mode): { errorInfo: { primaryError, upstreamContext, executionPath, suggestions }, summary }
- get (other modes): Execution object with data based on mode
- get: Execution object with data based on mode
- list: { data: [...executions], nextCursor?: string }
- delete: { success: boolean, message: string }`,
examples: [
'// Debug a failed execution (recommended for errors)\nn8n_executions({action: "get", id: "exec_456", mode: "error"})',
'// Debug with more sample data from upstream\nn8n_executions({action: "get", id: "exec_456", mode: "error", errorItemsLimit: 5})',
'// Debug with full stack trace\nn8n_executions({action: "get", id: "exec_456", mode: "error", includeStackTrace: true})',
'// Debug without workflow fetch (faster but less accurate)\nn8n_executions({action: "get", id: "exec_456", mode: "error", fetchWorkflow: false})',
'// List recent executions for a workflow\nn8n_executions({action: "list", workflowId: "abc123", limit: 10})',
'// List failed executions\nn8n_executions({action: "list", status: "error"})',
'// Get execution summary\nn8n_executions({action: "get", id: "exec_456"})',
@@ -72,10 +54,7 @@ exports.n8nExecutionsDoc = {
'// Delete an execution\nn8n_executions({action: "delete", id: "exec_456"})'
],
useCases: [
'Debug workflow failures efficiently (mode=error) - 80-90% token savings',
'Get AI suggestions for fixing common errors',
'Analyze input data that caused failure',
'Debug workflow failures with full data (mode=full)',
'Debug workflow failures (get with mode=full)',
'Monitor workflow health (list with status filter)',
'Audit execution history',
'Clean up old execution records',
@@ -84,22 +63,18 @@ exports.n8nExecutionsDoc = {
performance: `Response times:
- list: 50-150ms depending on filters
- get (preview/summary): 30-100ms
- get (error): 50-200ms (includes optional workflow fetch)
- get (full): 100-500ms+ depending on data size
- delete: 30-80ms`,
bestPractices: [
'Use mode="error" for debugging failed executions - 80-90% token savings vs full',
'Use mode="summary" (default) for quick inspection',
'Use mode="summary" (default) for debugging - shows enough data',
'Use mode="filtered" with nodeNames for large workflows',
'Filter by workflowId when listing to reduce results',
'Use cursor for pagination through large result sets',
'Set fetchWorkflow=false if you already know the workflow structure',
'Delete old executions to save storage'
],
pitfalls: [
'Requires N8N_API_URL and N8N_API_KEY configured',
'mode="full" can return very large responses for complex workflows',
'mode="error" fetches workflow by default (adds ~50-100ms), disable with fetchWorkflow=false',
'Execution must exist or returns 404',
'Delete is permanent - cannot undo'
],

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-executions.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"n8n-executions.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-executions.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAsB;IACjD,IAAI,EAAE,gBAAgB;IACtB,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,aAAa,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC;QACvD,OAAO,EAAE,yEAAyE;QAClF,WAAW,EAAE,iBAAiB;QAC9B,IAAI,EAAE;YACJ,2CAA2C;YAC3C,6CAA6C;YAC7C,0CAA0C;YAC1C,2DAA2D;SAC5D;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE;;;;;;;;;+CAS8B;QAC3C,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uCAAuC,EAAE;YAChG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,yDAAyD,EAAE;YAC/G,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,oEAAoE,EAAE;YAC5H,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,qEAAqE,EAAE;YACjI,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0FAA0F,EAAE;YACxJ,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,2EAA2E,EAAE;YAChJ,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE;YACtG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,mEAAmE,EAAE;YAC7H,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0DAA0D,EAAE;YACnH,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,2DAA2D,EAAE;YACrH,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,oDAAoD,EAAE;YACjH,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0DAA0D,EAAE;SAC3H;QACD,OAAO,EAAE;;;gDAGmC;QAC5C,QAAQ,EAAE;YACR,6GAA6G;YAC7G,8EAA8E;YAC9E,2EAA2E;YAC3E,2FAA2F;YAC3F,+IAA+I;YAC/I,4EAA4E;SAC7E;QACD,QAAQ,EAAE;YACR,8CAA8C;YAC9C,mDAAmD;YACnD,yBAAyB;YACzB,gCAAgC;YAChC,+BAA+B;SAChC;QACD,WAAW,EAAE;;;;kBAIC;QACd,aAAa,EAAE;YACb,gEAAgE;YAChE,wDAAwD;YACxD,qDAAqD;YACrD,qDAAqD;YACrD,uCAAuC;SACxC;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,mEAAmE;YACnE,qCAAqC;YACrC,mCAAmC;SACpC;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,uBAAuB,CAAC;KACjF;CACF,CAAC"}

View File

@@ -26,7 +26,7 @@ exports.n8nUpdateFullWorkflowDoc = {
settings: { type: 'object', description: 'Workflow settings to update (timezone, error handling, etc.)' },
intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Migrate workflow to new node versions".' }
},
returns: 'Minimal summary (id, name, active, nodeCount) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed.',
returns: 'Updated workflow object with all fields including the changes applied',
examples: [
'n8n_update_full_workflow({id: "abc", intent: "Rename workflow for clarity", name: "New Name"}) - Rename with intent',
'n8n_update_full_workflow({id: "abc", name: "New Name"}) - Rename only',

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-update-full-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAsB;IACzD,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,qHAAqH;QAClI,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC;QAC7C,OAAO,EAAE,4EAA4E;QACrF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2EAA2E;YAC3E,gCAAgC;YAChC,sCAAsC;YACtC,0BAA0B;SAC3B;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,4QAA4Q;QACzR,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uBAAuB,EAAE;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;YACrE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,oEAAoE,EAAE;YAC3G,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;YAC7G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;YACzG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uIAAuI,EAAE;SACjL;QACD,OAAO,EAAE,mJAAmJ;QAC5J,QAAQ,EAAE;YACR,qHAAqH;YACrH,uEAAuE;YACvE,qIAAqI;YACrI,+IAA+I;SAChJ;QACD,QAAQ,EAAE;YACR,8BAA8B;YAC9B,mBAAmB;YACnB,0BAA0B;YAC1B,+BAA+B;YAC/B,kBAAkB;SACnB;QACD,WAAW,EAAE,wHAAwH;QACrI,aAAa,EAAE;YACb,qEAAqE;YACrE,yCAAyC;YACzC,iDAAiD;YACjD,sCAAsC;YACtC,sCAAsC;SACvC;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,oCAAoC;YACpC,+BAA+B;YAC/B,4BAA4B;YAC5B,iDAAiD;SAClD;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,qBAAqB,CAAC;KAC9G;CACF,CAAC"}
{"version":3,"file":"n8n-update-full-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAsB;IACzD,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,qBAAqB;IAC/B,UAAU,EAAE;QACV,WAAW,EAAE,qHAAqH;QAClI,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC;QAC7C,OAAO,EAAE,4EAA4E;QACrF,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE;YACJ,2EAA2E;YAC3E,gCAAgC;YAChC,sCAAsC;YACtC,0BAA0B;SAC3B;KACF;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,4QAA4Q;QACzR,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uBAAuB,EAAE;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;YACrE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,oEAAoE,EAAE;YAC3G,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;YAC7G,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;YACzG,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uIAAuI,EAAE;SACjL;QACD,OAAO,EAAE,uEAAuE;QAChF,QAAQ,EAAE;YACR,qHAAqH;YACrH,uEAAuE;YACvE,qIAAqI;YACrI,+IAA+I;SAChJ;QACD,QAAQ,EAAE;YACR,8BAA8B;YAC9B,mBAAmB;YACnB,0BAA0B;YAC1B,+BAA+B;YAC/B,kBAAkB;SACnB;QACD,WAAW,EAAE,wHAAwH;QACrI,aAAa,EAAE;YACb,qEAAqE;YACrE,yCAAyC;YACzC,iDAAiD;YACjD,sCAAsC;YACtC,sCAAsC;SACvC;QACD,QAAQ,EAAE;YACR,iDAAiD;YACjD,oCAAoC;YACpC,+BAA+B;YAC/B,4BAA4B;YAC5B,iDAAiD;SAClD;QACD,YAAY,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,qBAAqB,CAAC;KAC9G;CACF,CAAC"}

View File

@@ -313,7 +313,7 @@ n8n_update_partial_workflow({
continueOnError: { type: 'boolean', description: 'If true, apply valid operations even if some fail (best-effort mode). Returns applied and failed operation indices. Default: false (atomic)' },
intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Add error handling for API failures".' }
},
returns: 'Minimal summary (id, name, active, nodeCount, operationsApplied) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed. Returns validation results if validateOnly=true.',
returns: 'Updated workflow object or validation results if validateOnly=true',
examples: [
'// Include intent parameter for better responses\nn8n_update_partial_workflow({id: "abc", intent: "Add error handling for API failures", operations: [{type: "addConnection", source: "HTTP Request", target: "Error Handler"}]})',
'// Add a basic node (minimal configuration)\nn8n_update_partial_workflow({id: "abc", operations: [{type: "addNode", node: {name: "Process Data", type: "n8n-nodes-base.set", position: [400, 300], parameters: {}}}]})',

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-update-partial-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"n8n-update-partial-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts"],"names":[],"mappings":"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"}

View File

@@ -1 +1 @@
{"version":3,"file":"tools-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAogB9C,CAAC"}
{"version":3,"file":"tools-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAmf9C,CAAC"}

View File

@@ -336,8 +336,8 @@ exports.n8nManagementTools = [
},
mode: {
type: 'string',
enum: ['preview', 'summary', 'filtered', 'full', 'error'],
description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data, error=optimized error debugging'
enum: ['preview', 'summary', 'filtered', 'full'],
description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data'
},
nodeNames: {
type: 'array',
@@ -352,22 +352,6 @@ exports.n8nManagementTools = [
type: 'boolean',
description: 'For action=get: include input data in addition to output (default: false)'
},
errorItemsLimit: {
type: 'number',
description: 'For action=get with mode=error: sample items from upstream node (default: 2, max: 100)'
},
includeStackTrace: {
type: 'boolean',
description: 'For action=get with mode=error: include full stack trace (default: false, shows truncated)'
},
includeExecutionPath: {
type: 'boolean',
description: 'For action=get with mode=error: include execution path leading to error (default: true)'
},
fetchWorkflow: {
type: 'boolean',
description: 'For action=get with mode=error: fetch workflow for accurate upstream detection (default: true)'
},
limit: {
type: 'number',
description: 'For action=list: number of executions to return (1-100, default: 100)'

File diff suppressed because one or more lines are too long

View File

@@ -17,9 +17,6 @@ export interface ParsedNode {
documentation?: string;
outputs?: any[];
outputNames?: string[];
isToolVariant?: boolean;
toolVariantOf?: string;
hasToolVariant?: boolean;
}
export declare class NodeParser {
private propertyExtractor;

View File

@@ -1 +1 @@
{"version":3,"file":"node-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/node-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,GAAG,cAAc,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,gBAAgB,CAA0B;IAElD,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU;IA0B5D,OAAO,CAAC,kBAAkB;IAoD1B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,cAAc;IA0FtB,OAAO,CAAC,eAAe;IA2CvB,OAAO,CAAC,cAAc;CAsDvB"}
{"version":3,"file":"node-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/node-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,GAAG,cAAc,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,gBAAgB,CAA0B;IAElD,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU;IA0B5D,OAAO,CAAC,kBAAkB;IAoD1B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,cAAc;IA0FtB,OAAO,CAAC,eAAe;IA2CvB,OAAO,CAAC,cAAc;CAsDvB"}

File diff suppressed because one or more lines are too long

View File

@@ -39,7 +39,6 @@ const node_loader_1 = require("../loaders/node-loader");
const node_parser_1 = require("../parsers/node-parser");
const docs_mapper_1 = require("../mappers/docs-mapper");
const node_repository_1 = require("../database/node-repository");
const tool_variant_generator_1 = require("../services/tool-variant-generator");
const template_sanitizer_1 = require("../utils/template-sanitizer");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
@@ -51,7 +50,6 @@ async function rebuild() {
const parser = new node_parser_1.NodeParser();
const mapper = new docs_mapper_1.DocsMapper();
const repository = new node_repository_1.NodeRepository(db);
const toolVariantGenerator = new tool_variant_generator_1.ToolVariantGenerator();
const schema = fs.readFileSync(path.join(__dirname, '../../src/database/schema.sql'), 'utf8');
db.exec(schema);
db.exec('DELETE FROM nodes');
@@ -66,8 +64,7 @@ async function rebuild() {
webhooks: 0,
withProperties: 0,
withOperations: 0,
withDocs: 0,
toolVariants: 0
withDocs: 0
};
console.log('🔄 Processing nodes...');
const processedNodes = [];
@@ -82,18 +79,6 @@ async function rebuild() {
}
const docs = await mapper.fetchDocumentation(parsed.nodeType);
parsed.documentation = docs || undefined;
if (parsed.isAITool && !parsed.isTrigger) {
const toolVariant = toolVariantGenerator.generateToolVariant(parsed);
if (toolVariant) {
parsed.hasToolVariant = true;
processedNodes.push({
parsed: toolVariant,
docs: undefined,
nodeName: `${nodeName}Tool`
});
stats.toolVariants++;
}
}
processedNodes.push({ parsed, docs: docs || undefined, nodeName });
}
catch (error) {
@@ -150,7 +135,6 @@ async function rebuild() {
console.log(` Successful: ${stats.successful}`);
console.log(` Failed: ${stats.failed}`);
console.log(` AI Tools: ${stats.aiTools}`);
console.log(` Tool Variants: ${stats.toolVariants}`);
console.log(` Triggers: ${stats.triggers}`);
console.log(` Webhooks: ${stats.webhooks}`);
console.log(` With Properties: ${stats.withProperties}`);
@@ -181,7 +165,6 @@ async function rebuild() {
console.log('\n✨ Rebuild complete!');
db.close();
}
const MIN_EXPECTED_TOOL_VARIANTS = 200;
function validateDatabase(repository) {
const issues = [];
try {
@@ -209,13 +192,6 @@ function validateDatabase(repository) {
if (aiTools.length === 0) {
issues.push('No AI tools found - check detection logic');
}
const toolVariantCount = repository.getToolVariantCount();
if (toolVariantCount === 0) {
issues.push('No Tool variants found - check ToolVariantGenerator');
}
else if (toolVariantCount < MIN_EXPECTED_TOOL_VARIANTS) {
issues.push(`Only ${toolVariantCount} Tool variants found - expected at least ${MIN_EXPECTED_TOOL_VARIANTS}`);
}
const ftsTableCheck = db.prepare(`
SELECT name FROM sqlite_master
WHERE type='table' AND name='nodes_fts'

File diff suppressed because one or more lines are too long

View File

@@ -30,9 +30,7 @@ export declare class ConfigValidator {
}>): ValidationResult[];
private static checkRequiredProperties;
private static getPropertyVisibility;
private static evaluateCondition;
private static valueMatches;
static isPropertyVisible(prop: any, config: Record<string, any>): boolean;
protected static isPropertyVisible(prop: any, config: Record<string, any>): boolean;
private static validatePropertyTypes;
private static performNodeSpecificValidation;
private static validateHttpRequest;

View File

@@ -1 +1 @@
{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../../src/services/config-validator.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,GAAG,uBAAuB,GAAG,cAAc,CAAC;IACxH,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG,eAAe,CAAC;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,eAAe;IAI1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAA4C;IAKjF,MAAM,CAAC,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,EAAE,GAAG,EAAE,EACjB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,gBAAgB;IAsDnB,MAAM,CAAC,aAAa,CAClB,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,UAAU,EAAE,GAAG,EAAE,CAAC;KACnB,CAAC,GACD,gBAAgB,EAAE;IASrB,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0CtC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgDhC,OAAO,CAAC,MAAM,CAAC,YAAY;WAab,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IA2ChF,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAoIpC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA+B5C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAoElC,OAAO,CAAC,MAAM,CAAC,eAAe;IAc9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAoC/B,OAAO,CAAC,MAAM,CAAC,YAAY;IAyC3B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgEhC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAmCpC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA6BvC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA4CvC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgEnC,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAmOvC"}
{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../../src/services/config-validator.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,GAAG,uBAAuB,GAAG,cAAc,CAAC;IACxH,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG,eAAe,CAAC;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,eAAe;IAI1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAA4C;IAKjF,MAAM,CAAC,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,EAAE,GAAG,EAAE,EACjB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,gBAAgB;IAsDnB,MAAM,CAAC,aAAa,CAClB,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,UAAU,EAAE,GAAG,EAAE,CAAC;KACnB,CAAC,GACD,gBAAgB,EAAE;IASrB,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0CtC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAqBpC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAiCnF,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAoIpC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA+B5C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAoElC,OAAO,CAAC,MAAM,CAAC,eAAe;IAc9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAoC/B,OAAO,CAAC,MAAM,CAAC,YAAY;IAyC3B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgEhC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAmCpC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA6BvC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IA4CvC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgEnC,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAmOvC"}

View File

@@ -83,57 +83,6 @@ class ConfigValidator {
}
return { visible, hidden };
}
static evaluateCondition(condition, configValue) {
const cnd = condition._cnd;
if ('eq' in cnd)
return configValue === cnd.eq;
if ('not' in cnd)
return configValue !== cnd.not;
if ('gte' in cnd)
return configValue >= cnd.gte;
if ('lte' in cnd)
return configValue <= cnd.lte;
if ('gt' in cnd)
return configValue > cnd.gt;
if ('lt' in cnd)
return configValue < cnd.lt;
if ('between' in cnd) {
const between = cnd.between;
if (!between || typeof between.from === 'undefined' || typeof between.to === 'undefined') {
return false;
}
return configValue >= between.from && configValue <= between.to;
}
if ('startsWith' in cnd) {
return typeof configValue === 'string' && configValue.startsWith(cnd.startsWith);
}
if ('endsWith' in cnd) {
return typeof configValue === 'string' && configValue.endsWith(cnd.endsWith);
}
if ('includes' in cnd) {
return typeof configValue === 'string' && configValue.includes(cnd.includes);
}
if ('regex' in cnd) {
if (typeof configValue !== 'string')
return false;
try {
return new RegExp(cnd.regex).test(configValue);
}
catch {
return false;
}
}
if ('exists' in cnd) {
return configValue !== undefined && configValue !== null;
}
return false;
}
static valueMatches(expectedValue, configValue) {
if (expectedValue && typeof expectedValue === 'object' && '_cnd' in expectedValue) {
return this.evaluateCondition(expectedValue, configValue);
}
return configValue === expectedValue;
}
static isPropertyVisible(prop, config) {
if (!prop.displayOptions)
return true;
@@ -141,8 +90,7 @@ class ConfigValidator {
for (const [key, values] of Object.entries(prop.displayOptions.show)) {
const configValue = config[key];
const expectedValues = Array.isArray(values) ? values : [values];
const anyMatch = expectedValues.some(expected => this.valueMatches(expected, configValue));
if (!anyMatch) {
if (!expectedValues.includes(configValue)) {
return false;
}
}
@@ -151,8 +99,7 @@ class ConfigValidator {
for (const [key, values] of Object.entries(prop.displayOptions.hide)) {
const configValue = config[key];
const expectedValues = Array.isArray(values) ? values : [values];
const anyMatch = expectedValues.some(expected => this.valueMatches(expected, configValue));
if (anyMatch) {
if (expectedValues.includes(configValue)) {
return false;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,8 @@
import { Execution, ExecutionPreview, ExecutionRecommendation, ExecutionFilterOptions, FilteredExecutionResponse, Workflow } from '../types/n8n-api';
import { Execution, ExecutionPreview, ExecutionRecommendation, ExecutionFilterOptions, FilteredExecutionResponse } from '../types/n8n-api';
export declare function generatePreview(execution: Execution): {
preview: ExecutionPreview;
recommendation: ExecutionRecommendation;
};
export declare function filterExecutionData(execution: Execution, options: ExecutionFilterOptions, workflow?: Workflow): FilteredExecutionResponse;
export declare function processExecution(execution: Execution, options?: ExecutionFilterOptions, workflow?: Workflow): FilteredExecutionResponse | Execution;
export declare function filterExecutionData(execution: Execution, options: ExecutionFilterOptions): FilteredExecutionResponse;
export declare function processExecution(execution: Execution, options?: ExecutionFilterOptions): FilteredExecutionResponse | Execution;
//# sourceMappingURL=execution-processor.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"execution-processor.d.ts","sourceRoot":"","sources":["../../src/services/execution-processor.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,EAET,gBAAgB,EAEhB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EAGzB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAgH1B,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG;IACrD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,uBAAuB,CAAC;CACzC,CA2EA;AAoID,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,CAAC,EAAE,QAAQ,GAClB,yBAAyB,CAsL3B;AAMD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,sBAA2B,EACpC,QAAQ,CAAC,EAAE,QAAQ,GAClB,yBAAyB,GAAG,SAAS,CAOvC"}
{"version":3,"file":"execution-processor.d.ts","sourceRoot":"","sources":["../../src/services/execution-processor.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,EAET,gBAAgB,EAEhB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EAG1B,MAAM,kBAAkB,CAAC;AA+G1B,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG;IACrD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,uBAAuB,CAAC;CACzC,CA2EA;AAoID,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,sBAAsB,GAC9B,yBAAyB,CA2J3B;AAMD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,sBAA2B,GACnC,yBAAyB,GAAG,SAAS,CAOvC"}

View File

@@ -4,7 +4,6 @@ exports.generatePreview = generatePreview;
exports.filterExecutionData = filterExecutionData;
exports.processExecution = processExecution;
const logger_1 = require("../utils/logger");
const error_execution_processor_1 = require("./error-execution-processor");
const THRESHOLDS = {
CHAR_SIZE_BYTES: 2,
OVERHEAD_PER_OBJECT: 50,
@@ -232,7 +231,7 @@ function truncateItems(items, limit) {
},
};
}
function filterExecutionData(execution, options, workflow) {
function filterExecutionData(execution, options) {
const mode = options.mode || 'summary';
let itemsLimit = options.itemsLimit !== undefined ? options.itemsLimit : 2;
if (itemsLimit !== -1) {
@@ -266,27 +265,6 @@ function filterExecutionData(execution, options, workflow) {
response.recommendation = recommendation;
return response;
}
if (mode === 'error') {
const errorAnalysis = (0, error_execution_processor_1.processErrorExecution)(execution, {
itemsLimit: options.errorItemsLimit ?? 2,
includeStackTrace: options.includeStackTrace ?? false,
includeExecutionPath: options.includeExecutionPath !== false,
workflow
});
const runData = execution.data?.resultData?.runData || {};
const executedNodes = Object.keys(runData).length;
response.errorInfo = errorAnalysis;
response.summary = {
totalNodes: executedNodes,
executedNodes,
totalItems: 0,
hasMoreData: false
};
if (execution.data?.resultData?.error) {
response.error = execution.data.resultData.error;
}
return response;
}
if (!execution.data?.resultData?.runData) {
response.summary = {
totalNodes: 0,
@@ -372,10 +350,10 @@ function filterExecutionData(execution, options, workflow) {
}
return response;
}
function processExecution(execution, options = {}, workflow) {
function processExecution(execution, options = {}) {
if (!options.mode && !options.nodeNames && options.itemsLimit === undefined) {
return execution;
}
return filterExecutionData(execution, options, workflow);
return filterExecutionData(execution, options);
}
//# sourceMappingURL=execution-processor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"n8n-validation.d.ts","sourceRoot":"","sources":["../../src/services/n8n-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM9E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AAkBH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWjC,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;CAMnC,CAAC;AAGF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAEhE;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,OAAO,GAAG,kBAAkB,CAEpF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAElG;AAGD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBrF;AAiBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoE5E;AAGD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CA6P/E;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAK7D;AAMD,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CA+F5E;AAMD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0D/E;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAmB/D;AAGD,wBAAgB,2BAA2B,IAAI,MAAM,CA6CpD;AAGD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmBpE"}
{"version":3,"file":"n8n-validation.d.ts","sourceRoot":"","sources":["../../src/services/n8n-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM9E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AAkBH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWjC,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;CAMnC,CAAC;AAGF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAEhE;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,OAAO,GAAG,kBAAkB,CAEpF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAElG;AAGD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBrF;AAiBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoE5E;AAGD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAyP/E;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAK7D;AAMD,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CA+F5E;AAMD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0D/E;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAmB/D;AAGD,wBAAgB,2BAA2B,IAAI,MAAM,CA6CpD;AAGD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmBpE"}

View File

@@ -152,23 +152,17 @@ function validateWorkflowStructure(workflow) {
}
else if (connectionCount > 0 || executableNodes.length > 1) {
const connectedNodes = new Set();
const ALL_CONNECTION_TYPES = ['main', 'error', 'ai_tool', 'ai_languageModel', 'ai_memory', 'ai_embedding', 'ai_vectorStore'];
Object.entries(workflow.connections).forEach(([sourceName, connection]) => {
connectedNodes.add(sourceName);
ALL_CONNECTION_TYPES.forEach(connType => {
const connData = connection[connType];
if (connData && Array.isArray(connData)) {
connData.forEach((outputs) => {
if (Array.isArray(outputs)) {
outputs.forEach((target) => {
if (target?.node) {
connectedNodes.add(target.node);
}
});
}
});
}
});
if (connection.main && Array.isArray(connection.main)) {
connection.main.forEach((outputs) => {
if (Array.isArray(outputs)) {
outputs.forEach((target) => {
connectedNodes.add(target.node);
});
}
});
}
});
const disconnectedNodes = workflow.nodes.filter(node => {
if ((0, node_classification_1.isNonExecutableNode)(node.type)) {
@@ -177,9 +171,7 @@ function validateWorkflowStructure(workflow) {
const isConnected = connectedNodes.has(node.name);
const isNodeTrigger = (0, node_type_utils_1.isTriggerNode)(node.type);
if (isNodeTrigger) {
const hasOutgoingConnections = !!workflow.connections?.[node.name];
const hasInboundConnections = isConnected;
return !hasOutgoingConnections && !hasInboundConnections;
return !workflow.connections?.[node.name];
}
return !isConnected;
});
@@ -225,9 +217,12 @@ function validateWorkflowStructure(workflow) {
}
if (workflow.active === true && workflow.nodes && workflow.nodes.length > 0) {
const activatableTriggers = workflow.nodes.filter(node => !node.disabled && (0, node_type_utils_1.isActivatableTrigger)(node.type));
if (activatableTriggers.length === 0) {
errors.push('Cannot activate workflow: No activatable trigger nodes found. ' +
'Workflows must have at least one enabled trigger node (webhook, schedule, executeWorkflowTrigger, etc.).');
const executeWorkflowTriggers = workflow.nodes.filter(node => !node.disabled && node.type.toLowerCase().includes('executeworkflow'));
if (activatableTriggers.length === 0 && executeWorkflowTriggers.length > 0) {
const triggerNames = executeWorkflowTriggers.map(n => n.name).join(', ');
errors.push(`Cannot activate workflow with only Execute Workflow Trigger nodes (${triggerNames}). ` +
'Execute Workflow Trigger can only be invoked by other workflows, not activated. ' +
'Either deactivate the workflow or add a webhook/schedule/polling trigger.');
}
}
if (workflow.nodes && workflow.connections) {

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@ import { WorkflowDiffOperation } from '../types/workflow-diff';
import { Workflow } from '../types/n8n-api';
import { PostUpdateGuidance } from './post-update-validator';
export type FixConfidenceLevel = 'high' | 'medium' | 'low';
export type FixType = 'expression-format' | 'typeversion-correction' | 'error-output-config' | 'node-type-correction' | 'webhook-missing-path' | 'typeversion-upgrade' | 'version-migration' | 'tool-variant-correction';
export type FixType = 'expression-format' | 'typeversion-correction' | 'error-output-config' | 'node-type-correction' | 'webhook-missing-path' | 'typeversion-upgrade' | 'version-migration';
export interface AutoFixConfig {
applyFixes: boolean;
fixTypes?: FixType[];
@@ -62,7 +62,6 @@ export declare class WorkflowAutoFixer {
private processErrorOutputFixes;
private processNodeTypeFixes;
private processWebhookPathFixes;
private processToolVariantFixes;
private setNestedValue;
private filterByConfidence;
private filterOperationsByFixes;

View File

@@ -1 +1 @@
{"version":3,"file":"workflow-auto-fixer.d.ts","sourceRoot":"","sources":["../../src/services/workflow-auto-fixer.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"workflow-auto-fixer.d.ts","sourceRoot":"","sources":["../../src/services/workflow-auto-fixer.ts"],"names":[],"mappings":"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"}

View File

@@ -63,9 +63,6 @@ class WorkflowAutoFixer {
if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('webhook-missing-path')) {
this.processWebhookPathFixes(validationResult, nodeMap, operations, fixes);
}
if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('tool-variant-correction')) {
this.processToolVariantFixes(validationResult, nodeMap, workflow, operations, fixes);
}
if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('typeversion-upgrade')) {
await this.processVersionUpgradeFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance);
}
@@ -270,41 +267,6 @@ class WorkflowAutoFixer {
}
}
}
processToolVariantFixes(validationResult, nodeMap, _workflow, operations, fixes) {
for (const error of validationResult.errors) {
if (error.code !== 'WRONG_NODE_TYPE_FOR_AI_TOOL' || !error.fix) {
continue;
}
const fix = error.fix;
if (fix.type !== 'tool-variant-correction') {
continue;
}
const nodeName = error.nodeName || error.nodeId;
if (!nodeName)
continue;
const node = nodeMap.get(nodeName);
if (!node)
continue;
fixes.push({
node: nodeName,
field: 'type',
type: 'tool-variant-correction',
before: fix.currentType,
after: fix.suggestedType,
confidence: 'high',
description: fix.description || `Replace "${fix.currentType}" with Tool variant "${fix.suggestedType}"`
});
const operation = {
type: 'updateNode',
nodeId: nodeName,
updates: {
type: fix.suggestedType
}
};
operations.push(operation);
logger.info(`Generated tool variant correction for ${nodeName}: ${fix.currentType}${fix.suggestedType}`);
}
}
setNestedValue(obj, path, value) {
if (!obj || typeof obj !== 'object') {
throw new Error('Cannot set value on non-object');
@@ -410,8 +372,7 @@ class WorkflowAutoFixer {
'node-type-correction': 0,
'webhook-missing-path': 0,
'typeversion-upgrade': 0,
'version-migration': 0,
'tool-variant-correction': 0
'version-migration': 0
},
byConfidence: {
'high': 0,
@@ -451,9 +412,6 @@ class WorkflowAutoFixer {
if (stats.byType['version-migration'] > 0) {
parts.push(`${stats.byType['version-migration']} version ${stats.byType['version-migration'] === 1 ? 'migration' : 'migrations'}`);
}
if (stats.byType['tool-variant-correction'] > 0) {
parts.push(`${stats.byType['tool-variant-correction']} tool variant ${stats.byType['tool-variant-correction'] === 1 ? 'correction' : 'corrections'}`);
}
if (parts.length === 0) {
return `Fixed ${stats.total} ${stats.total === 1 ? 'issue' : 'issues'}`;
}

File diff suppressed because one or more lines are too long

View File

@@ -651,7 +651,7 @@ class WorkflowDiffEngine {
validateActivateWorkflow(workflow, operation) {
const activatableTriggers = workflow.nodes.filter(node => !node.disabled && (0, node_type_utils_1.isActivatableTrigger)(node.type));
if (activatableTriggers.length === 0) {
return 'Cannot activate workflow: No activatable trigger nodes found. Workflows must have at least one enabled trigger node (webhook, schedule, executeWorkflowTrigger, etc.).';
return 'Cannot activate workflow: No activatable trigger nodes found. Workflows must have at least one enabled trigger node (webhook, schedule, email, etc.). Note: executeWorkflowTrigger cannot activate workflows as they can only be invoked by other workflows.';
}
return null;
}

File diff suppressed because one or more lines are too long

View File

@@ -47,19 +47,12 @@ interface WorkflowJson {
pinData?: any;
meta?: any;
}
export interface ValidationIssue {
interface ValidationIssue {
type: 'error' | 'warning';
nodeId?: string;
nodeName?: string;
message: string;
details?: any;
code?: string;
fix?: {
type: string;
currentType?: string;
suggestedType?: string;
description?: string;
};
}
export interface WorkflowValidationResult {
valid: boolean;
@@ -93,7 +86,6 @@ export declare class WorkflowValidator {
private validateConnectionOutputs;
private validateErrorOutputConfiguration;
private validateAIToolConnection;
private validateAIToolSource;
private hasCycle;
private validateExpressions;
private countExpressionsInObject;

View File

@@ -1 +1 @@
{"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"}

View File

@@ -11,10 +11,8 @@ const node_similarity_service_1 = require("./node-similarity-service");
const node_type_normalizer_1 = require("../utils/node-type-normalizer");
const logger_1 = require("../utils/logger");
const ai_node_validator_1 = require("./ai-node-validator");
const ai_tool_validators_1 = require("./ai-tool-validators");
const node_type_utils_1 = require("../utils/node-type-utils");
const node_classification_1 = require("../utils/node-classification");
const tool_variant_generator_1 = require("./tool-variant-generator");
const logger = new logger_1.Logger({ prefix: '[WorkflowValidator]' });
class WorkflowValidator {
constructor(nodeRepository, nodeValidator) {
@@ -310,11 +308,7 @@ class WorkflowValidator {
if (normalizedType.startsWith('nodes-langchain.')) {
continue;
}
const paramsWithVersion = {
'@version': node.typeVersion || 1,
...node.parameters
};
const nodeValidation = this.nodeValidator.validateWithMode(node.type, paramsWithVersion, nodeInfo.properties || [], 'operation', profile);
const nodeValidation = this.nodeValidator.validateWithMode(node.type, node.parameters, nodeInfo.properties || [], 'operation', profile);
nodeValidation.errors.forEach((error) => {
result.errors.push({
type: 'error',
@@ -373,7 +367,6 @@ class WorkflowValidator {
this.validateConnectionOutputs(sourceName, outputs.error, nodeMap, nodeIdMap, result, 'error');
}
if (outputs.ai_tool) {
this.validateAIToolSource(sourceNode, result);
this.validateConnectionOutputs(sourceName, outputs.ai_tool, nodeMap, nodeIdMap, result, 'ai_tool');
}
}
@@ -562,51 +555,6 @@ class WorkflowValidator {
});
}
}
validateAIToolSource(sourceNode, result) {
const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(sourceNode.type);
if ((0, ai_tool_validators_1.isAIToolSubNode)(normalizedType)) {
return;
}
const nodeInfo = this.nodeRepository.getNode(normalizedType);
if (tool_variant_generator_1.ToolVariantGenerator.isToolVariantNodeType(normalizedType)) {
if (nodeInfo?.isToolVariant) {
return;
}
}
if (!nodeInfo) {
return;
}
if (nodeInfo.hasToolVariant) {
const toolVariantType = tool_variant_generator_1.ToolVariantGenerator.getToolVariantNodeType(normalizedType);
const workflowToolVariantType = node_type_normalizer_1.NodeTypeNormalizer.toWorkflowFormat(toolVariantType);
result.errors.push({
type: 'error',
nodeId: sourceNode.id,
nodeName: sourceNode.name,
message: `Node "${sourceNode.name}" uses "${sourceNode.type}" which cannot output ai_tool connections. ` +
`Use the Tool variant "${workflowToolVariantType}" instead for AI Agent integration.`,
code: 'WRONG_NODE_TYPE_FOR_AI_TOOL',
fix: {
type: 'tool-variant-correction',
currentType: sourceNode.type,
suggestedType: workflowToolVariantType,
description: `Change node type from "${sourceNode.type}" to "${workflowToolVariantType}"`
}
});
return;
}
if (nodeInfo.isAITool) {
return;
}
result.errors.push({
type: 'error',
nodeId: sourceNode.id,
nodeName: sourceNode.name,
message: `Node "${sourceNode.name}" of type "${sourceNode.type}" cannot output ai_tool connections. ` +
`Only AI tool nodes (e.g., Calculator, HTTP Request Tool) or Tool variants (e.g., *Tool suffix nodes) can be connected to AI Agents as tools.`,
code: 'INVALID_AI_TOOL_SOURCE'
});
}
hasCycle(workflow) {
const visited = new Set();
const recursionStack = new Set();

File diff suppressed because one or more lines are too long

View File

@@ -7,13 +7,13 @@ export declare const telemetryEventSchema: z.ZodObject<{
created_at: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
properties: Record<string, any>;
event: string;
user_id: string;
event: string;
created_at?: string | undefined;
}, {
properties: Record<string, unknown>;
event: string;
user_id: string;
event: string;
created_at?: string | undefined;
}>;
export declare const workflowTelemetrySchema: z.ZodObject<{

View File

@@ -267,7 +267,7 @@ export interface McpToolResponse {
executionId?: string;
workflowId?: string;
}
export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full' | 'error';
export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full';
export interface ExecutionPreview {
totalNodes: number;
executedNodes: number;
@@ -296,9 +296,6 @@ export interface ExecutionFilterOptions {
itemsLimit?: number;
includeInputData?: boolean;
fieldsToInclude?: string[];
errorItemsLimit?: number;
includeStackTrace?: boolean;
includeExecutionPath?: boolean;
}
export interface FilteredExecutionResponse {
id: string;
@@ -319,7 +316,6 @@ export interface FilteredExecutionResponse {
};
nodes?: Record<string, FilteredNodeData>;
error?: Record<string, unknown>;
errorInfo?: ErrorAnalysis;
}
export interface FilteredNodeData {
executionTime?: number;
@@ -337,39 +333,4 @@ export interface FilteredNodeData {
};
};
}
export interface ErrorAnalysis {
primaryError: {
message: string;
errorType: string;
nodeName: string;
nodeType: string;
nodeId?: string;
nodeParameters?: Record<string, unknown>;
stackTrace?: string;
};
upstreamContext?: {
nodeName: string;
nodeType: string;
itemCount: number;
sampleItems: unknown[];
dataStructure: Record<string, unknown>;
};
executionPath?: Array<{
nodeName: string;
status: 'success' | 'error' | 'skipped';
itemCount: number;
executionTime?: number;
}>;
additionalErrors?: Array<{
nodeName: string;
message: string;
}>;
suggestions?: ErrorSuggestion[];
}
export interface ErrorSuggestion {
type: 'fix' | 'investigate' | 'workaround';
title: string;
description: string;
confidence: 'high' | 'medium' | 'low';
}
//# sourceMappingURL=n8n-api.d.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -12,6 +12,5 @@ export declare class NodeTypeNormalizer {
static normalizeWorkflowNodeTypes(workflow: any): any;
static isFullForm(type: string): boolean;
static isShortForm(type: string): boolean;
static toWorkflowFormat(type: string): string;
}
//# sourceMappingURL=node-type-normalizer.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"node-type-normalizer.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"AA2CA,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CACzD;AAED,qBAAa,kBAAkB;IAyB7B,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAuChD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,2BAA2B;IAkBtE,OAAO,CAAC,MAAM,CAAC,aAAa;IAuB5B,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IA8B3D,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAoBrD,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkBxC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAgCzC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAgB9C"}
{"version":3,"file":"node-type-normalizer.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"AA2CA,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CACzD;AAED,qBAAa,kBAAkB;IAyB7B,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAuChD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,2BAA2B;IAkBtE,OAAO,CAAC,MAAM,CAAC,aAAa;IAuB5B,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IA8B3D,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAoBrD,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkBxC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAU1C"}

View File

@@ -70,18 +70,6 @@ class NodeTypeNormalizer {
return (type.startsWith('nodes-base.') ||
type.startsWith('nodes-langchain.'));
}
static toWorkflowFormat(type) {
if (!type || typeof type !== 'string') {
return type;
}
if (type.startsWith('nodes-base.')) {
return type.replace(/^nodes-base\./, 'n8n-nodes-base.');
}
if (type.startsWith('nodes-langchain.')) {
return type.replace(/^nodes-langchain\./, '@n8n/n8n-nodes-langchain.');
}
return type;
}
}
exports.NodeTypeNormalizer = NodeTypeNormalizer;
//# sourceMappingURL=node-type-normalizer.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"node-type-normalizer.js","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"node-type-normalizer.js","sourceRoot":"","sources":["../../src/utils/node-type-normalizer.ts"],"names":[],"mappings":"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"}

View File

@@ -1 +1 @@
{"version":3,"file":"node-type-utils.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"AAcA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AASD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAQ3F;AASD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AASD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS1D;AAKD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAKD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAa3D;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB5D;AAkBD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAsBvD;AAqBD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG9D;AAQD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiClE"}
{"version":3,"file":"node-type-utils.d.ts","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"AAcA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AASD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAQ3F;AASD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AASD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS1D;AAKD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAKD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAa3D;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB5D;AAkBD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAsBvD;AAoBD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAW9D;AAQD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiClE"}

View File

@@ -95,6 +95,11 @@ function isTriggerNode(nodeType) {
return specificTriggers.includes(normalized);
}
function isActivatableTrigger(nodeType) {
const normalized = normalizeNodeType(nodeType);
const lowerType = normalized.toLowerCase();
if (lowerType.includes('executeworkflow')) {
return false;
}
return isTriggerNode(nodeType);
}
function getTriggerTypeDescription(nodeType) {

View File

@@ -1 +1 @@
{"version":3,"file":"node-type-utils.js","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"node-type-utils.js","sourceRoot":"","sources":["../../src/utils/node-type-utils.ts"],"names":[],"mappings":"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"}

6024
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "n8n-mcp",
"version": "2.31.2",
"version": "2.28.7",
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -141,16 +141,16 @@
},
"dependencies": {
"@modelcontextprotocol/sdk": "1.20.1",
"@n8n/n8n-nodes-langchain": "^2.1.3",
"@n8n/n8n-nodes-langchain": "^1.121.1",
"@supabase/supabase-js": "^2.57.4",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"express-rate-limit": "^7.1.5",
"form-data": "^4.0.5",
"lru-cache": "^11.2.1",
"n8n": "^2.1.4",
"n8n-core": "^2.1.3",
"n8n-workflow": "^2.1.1",
"n8n": "^1.122.4",
"n8n-core": "^1.121.1",
"n8n-workflow": "^1.119.1",
"openai": "^4.77.0",
"sql.js": "^1.13.0",
"tslib": "^2.6.2",

View File

@@ -1,6 +1,6 @@
{
"name": "n8n-mcp-runtime",
"version": "2.29.5",
"version": "2.28.7",
"description": "n8n MCP Server Runtime Dependencies Only",
"private": true,
"dependencies": {

View File

@@ -23,13 +23,12 @@ export class NodeRepository {
INSERT OR REPLACE INTO nodes (
node_type, package_name, display_name, description,
category, development_style, is_ai_tool, is_trigger,
is_webhook, is_versioned, is_tool_variant, tool_variant_of,
has_tool_variant, version, documentation,
is_webhook, is_versioned, version, documentation,
properties_schema, operations, credentials_required,
outputs, output_names
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(
node.nodeType,
node.packageName,
@@ -41,9 +40,6 @@ export class NodeRepository {
node.isTrigger ? 1 : 0,
node.isWebhook ? 1 : 0,
node.isVersioned ? 1 : 0,
node.isToolVariant ? 1 : 0,
node.toolVariantOf || null,
node.hasToolVariant ? 1 : 0,
node.version,
node.documentation || null,
JSON.stringify(node.properties, null, 2),
@@ -198,58 +194,6 @@ export class NodeRepository {
return this.getAITools();
}
/**
* Get the Tool variant for a base node
*/
getToolVariant(baseNodeType: string): any | null {
// Validate node type format (must be package.nodeName pattern)
if (!baseNodeType || typeof baseNodeType !== 'string' || !baseNodeType.includes('.')) {
return null;
}
const toolNodeType = `${baseNodeType}Tool`;
return this.getNode(toolNodeType);
}
/**
* Get the base node for a Tool variant
*/
getBaseNodeForToolVariant(toolNodeType: string): any | null {
const row = this.db.prepare(`
SELECT tool_variant_of FROM nodes WHERE node_type = ?
`).get(toolNodeType) as any;
if (!row?.tool_variant_of) return null;
return this.getNode(row.tool_variant_of);
}
/**
* Get all Tool variants
*/
getToolVariants(): any[] {
const rows = this.db.prepare(`
SELECT node_type, display_name, description, package_name, tool_variant_of
FROM nodes
WHERE is_tool_variant = 1
ORDER BY display_name
`).all() as any[];
return rows.map(row => ({
nodeType: row.node_type,
displayName: row.display_name,
description: row.description,
package: row.package_name,
toolVariantOf: row.tool_variant_of
}));
}
/**
* Get count of Tool variants
*/
getToolVariantCount(): number {
const result = this.db.prepare('SELECT COUNT(*) as count FROM nodes WHERE is_tool_variant = 1').get() as any;
return result.count;
}
getNodesByPackage(packageName: string): any[] {
const rows = this.db.prepare(`
SELECT * FROM nodes WHERE package_name = ?
@@ -306,9 +250,6 @@ export class NodeRepository {
isTrigger: Number(row.is_trigger) === 1,
isWebhook: Number(row.is_webhook) === 1,
isVersioned: Number(row.is_versioned) === 1,
isToolVariant: Number(row.is_tool_variant) === 1,
toolVariantOf: row.tool_variant_of || null,
hasToolVariant: Number(row.has_tool_variant) === 1,
version: row.version,
properties: this.safeJsonParse(row.properties_schema, []),
operations: this.safeJsonParse(row.operations, []),

View File

@@ -10,9 +10,6 @@ CREATE TABLE IF NOT EXISTS nodes (
is_trigger INTEGER DEFAULT 0,
is_webhook INTEGER DEFAULT 0,
is_versioned INTEGER DEFAULT 0,
is_tool_variant INTEGER DEFAULT 0, -- 1 if this is a *Tool variant for AI Agents
tool_variant_of TEXT, -- For Tool variants: base node type (e.g., nodes-base.supabase)
has_tool_variant INTEGER DEFAULT 0, -- For base nodes: 1 if Tool variant exists
version TEXT,
documentation TEXT,
properties_schema TEXT,
@@ -27,8 +24,6 @@ CREATE TABLE IF NOT EXISTS nodes (
CREATE INDEX IF NOT EXISTS idx_package ON nodes(package_name);
CREATE INDEX IF NOT EXISTS idx_ai_tool ON nodes(is_ai_tool);
CREATE INDEX IF NOT EXISTS idx_category ON nodes(category);
CREATE INDEX IF NOT EXISTS idx_tool_variant ON nodes(is_tool_variant);
CREATE INDEX IF NOT EXISTS idx_tool_variant_of ON nodes(tool_variant_of);
-- FTS5 full-text search index for nodes
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(

View File

@@ -518,13 +518,8 @@ export async function handleCreateWorkflow(args: unknown, context?: InstanceCont
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
nodeCount: workflow.nodes?.length || 0
},
message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}. Use n8n_get_workflow with mode 'structure' to verify current state.`
data: workflow,
message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}`
};
} catch (error) {
if (error instanceof z.ZodError) {
@@ -818,13 +813,8 @@ export async function handleUpdateWorkflow(
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
nodeCount: workflow.nodes?.length || 0
},
message: `Workflow "${workflow.name}" updated successfully. Use n8n_get_workflow with mode 'structure' to verify current state.`
data: workflow,
message: `Workflow "${workflow.name}" updated successfully`
};
} catch (error) {
// Track failed mutation
@@ -890,12 +880,8 @@ export async function handleDeleteWorkflow(args: unknown, context?: InstanceCont
return {
success: true,
data: {
id: deleted?.id || id,
name: deleted?.name,
deleted: true
},
message: `Workflow "${deleted?.name || id}" deleted successfully.`
data: deleted,
message: `Workflow ${id} deleted successfully`
};
} catch (error) {
if (error instanceof z.ZodError) {
@@ -998,7 +984,7 @@ export async function handleValidateWorkflow(
const input = validateWorkflowSchema.parse(args);
// First, fetch the workflow from n8n
const workflowResponse = await handleGetWorkflow({ id: input.id }, context);
const workflowResponse = await handleGetWorkflow({ id: input.id });
if (!workflowResponse.success) {
return workflowResponse; // Return the error from fetching
@@ -1421,33 +1407,17 @@ export async function handleGetExecution(args: unknown, context?: InstanceContex
// Parse and validate input with new parameters
const schema = z.object({
id: z.string(),
// Filtering parameters
mode: z.enum(['preview', 'summary', 'filtered', 'full', 'error']).optional(),
// New filtering parameters
mode: z.enum(['preview', 'summary', 'filtered', 'full']).optional(),
nodeNames: z.array(z.string()).optional(),
itemsLimit: z.number().optional(),
includeInputData: z.boolean().optional(),
// Legacy parameter (backward compatibility)
includeData: z.boolean().optional(),
// Error mode specific parameters
errorItemsLimit: z.number().min(0).max(100).optional(),
includeStackTrace: z.boolean().optional(),
includeExecutionPath: z.boolean().optional(),
fetchWorkflow: z.boolean().optional()
includeData: z.boolean().optional()
});
const params = schema.parse(args);
const {
id,
mode,
nodeNames,
itemsLimit,
includeInputData,
includeData,
errorItemsLimit,
includeStackTrace,
includeExecutionPath,
fetchWorkflow
} = params;
const { id, mode, nodeNames, itemsLimit, includeInputData, includeData } = params;
/**
* Map legacy includeData parameter to mode for backward compatibility
@@ -1486,33 +1456,15 @@ export async function handleGetExecution(args: unknown, context?: InstanceContex
};
}
// For error mode, optionally fetch workflow for accurate upstream detection
let workflow: Workflow | undefined;
if (effectiveMode === 'error' && fetchWorkflow !== false && execution.workflowId) {
try {
workflow = await client.getWorkflow(execution.workflowId);
} catch (e) {
// Workflow fetch failed - continue without it (use heuristics)
logger.debug('Could not fetch workflow for error analysis', {
workflowId: execution.workflowId,
error: e instanceof Error ? e.message : 'Unknown error'
});
}
}
// Apply filtering using ExecutionProcessor
const filterOptions: ExecutionFilterOptions = {
mode: effectiveMode,
nodeNames,
itemsLimit,
includeInputData,
// Error mode specific options
errorItemsLimit,
includeStackTrace,
includeExecutionPath
includeInputData
};
const processedExecution = processExecution(execution, filterOptions, workflow);
const processedExecution = processExecution(execution, filterOptions);
return {
success: true,

View File

@@ -363,15 +363,13 @@ export async function handleUpdatePartialWorkflow(
return {
success: true,
data: {
id: finalWorkflow.id,
name: finalWorkflow.name,
active: finalWorkflow.active,
nodeCount: finalWorkflow.nodes?.length || 0,
operationsApplied: diffResult.operationsApplied
},
message: `Workflow "${finalWorkflow.name}" updated successfully. Applied ${diffResult.operationsApplied} operations.${activationMessage} Use n8n_get_workflow with mode 'structure' to verify current state.`,
data: finalWorkflow,
message: `Workflow "${finalWorkflow.name}" updated successfully. Applied ${diffResult.operationsApplied} operations.${activationMessage}`,
details: {
operationsApplied: diffResult.operationsApplied,
workflowId: finalWorkflow.id,
workflowName: finalWorkflow.name,
active: finalWorkflow.active,
applied: diffResult.applied,
failed: diffResult.failed,
errors: diffResult.errors,

View File

@@ -52,9 +52,6 @@ interface NodeRow {
is_trigger: number;
is_webhook: number;
is_versioned: number;
is_tool_variant: number;
tool_variant_of?: string;
has_tool_variant: number;
version?: string;
documentation?: string;
properties_schema?: string;
@@ -68,14 +65,6 @@ interface VersionSummary {
hasVersionHistory: boolean;
}
interface ToolVariantGuidance {
isToolVariant: boolean;
toolVariantOf?: string;
hasToolVariant: boolean;
toolVariantNodeType?: string;
guidance?: string;
}
interface NodeMinimalInfo {
nodeType: string;
workflowNodeType: string;
@@ -86,7 +75,6 @@ interface NodeMinimalInfo {
isAITool: boolean;
isTrigger: boolean;
isWebhook: boolean;
toolVariantInfo?: ToolVariantGuidance;
}
interface NodeStandardInfo {
@@ -100,7 +88,6 @@ interface NodeStandardInfo {
credentials?: any;
examples?: any[];
versionInfo: VersionSummary;
toolVariantInfo?: ToolVariantGuidance;
}
interface NodeFullInfo {
@@ -113,7 +100,6 @@ interface NodeFullInfo {
credentials?: any;
documentation?: string;
versionInfo: VersionSummary;
toolVariantInfo?: ToolVariantGuidance;
}
interface VersionHistoryInfo {
@@ -1390,20 +1376,12 @@ export class N8NDocumentationMCPServer {
});
}
const result: any = {
return {
...node,
workflowNodeType: getWorkflowNodeType(node.package ?? 'n8n-nodes-base', node.nodeType),
aiToolCapabilities,
outputs
};
// Add tool variant guidance if applicable
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
return result;
}
/**
@@ -2267,7 +2245,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
// Get the latest version - this is important for AI to use correct typeVersion
const latestVersion = node.version ?? '1';
const result: any = {
const result = {
nodeType: node.nodeType,
workflowNodeType: getWorkflowNodeType(node.package ?? 'n8n-nodes-base', node.nodeType),
displayName: node.displayName,
@@ -2297,12 +2275,6 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
}
};
// Add tool variant guidance if applicable
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
// Add examples from templates if requested
if (includeExamples) {
try {
@@ -2454,7 +2426,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
throw new Error(`Node ${nodeType} not found`);
}
const result: NodeMinimalInfo = {
return {
nodeType: node.nodeType,
workflowNodeType: getWorkflowNodeType(node.package ?? 'n8n-nodes-base', node.nodeType),
displayName: node.displayName,
@@ -2465,14 +2437,6 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
isTrigger: node.isTrigger,
isWebhook: node.isWebhook
};
// Add tool variant guidance if applicable
const toolVariantInfo = this.buildToolVariantGuidance(node);
if (toolVariantInfo) {
result.toolVariantInfo = toolVariantInfo;
}
return result;
}
case 'standard': {
@@ -2905,18 +2869,12 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
// Get properties
const properties = node.properties || [];
// Add @version to config for displayOptions evaluation (supports _cnd operators)
const configWithVersion = {
'@version': node.version || 1,
...config
};
// Use enhanced validator with operation mode by default
const validationResult = EnhancedConfigValidator.validateWithMode(
node.nodeType,
configWithVersion,
properties,
node.nodeType,
config,
properties,
mode,
profile
);
@@ -3160,45 +3118,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
'Extend AI agent capabilities'
];
}
/**
* Build tool variant guidance for node responses.
* Provides cross-reference information between base nodes and their Tool variants.
*/
private buildToolVariantGuidance(node: any): ToolVariantGuidance | undefined {
const isToolVariant = !!node.isToolVariant;
const hasToolVariant = !!node.hasToolVariant;
const toolVariantOf = node.toolVariantOf;
// If this is neither a Tool variant nor has one, no guidance needed
if (!isToolVariant && !hasToolVariant) {
return undefined;
}
if (isToolVariant) {
// This IS a Tool variant (e.g., nodes-base.supabaseTool)
return {
isToolVariant: true,
toolVariantOf,
hasToolVariant: false,
guidance: `This is the Tool variant for AI Agent integration. Use this node type when connecting to AI Agents. The base node is: ${toolVariantOf}`
};
}
if (hasToolVariant && node.nodeType) {
// This base node HAS a Tool variant (e.g., nodes-base.supabase)
const toolVariantNodeType = `${node.nodeType}Tool`;
return {
isToolVariant: false,
hasToolVariant: true,
toolVariantNodeType,
guidance: `To use this node with AI Agents, use the Tool variant: ${toolVariantNodeType}. The Tool variant has an additional 'toolDescription' property and outputs 'ai_tool' instead of 'main'.`
};
}
return undefined;
}
private getAIToolExamples(nodeType: string): any {
const exampleMap: Record<string, any> = {
'nodes-base.slack': {
@@ -3282,27 +3202,57 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
throw new Error(`Node ${nodeType} not found`);
}
// Get properties
// Get properties
const properties = node.properties || [];
// Add @version to config for displayOptions evaluation (supports _cnd operators)
const configWithVersion = {
'@version': node.version || 1,
...(config || {})
// Extract operation context (safely handle undefined config properties)
const operationContext = {
resource: config?.resource,
operation: config?.operation,
action: config?.action,
mode: config?.mode
};
// Find missing required fields
const missingFields: string[] = [];
for (const prop of properties) {
// Skip if not required
if (!prop.required) continue;
// Skip if not visible based on current config (uses ConfigValidator for _cnd support)
if (prop.displayOptions && !ConfigValidator.isPropertyVisible(prop, configWithVersion)) {
continue;
// Skip if not visible based on current config
if (prop.displayOptions) {
let isVisible = true;
// Check show conditions
if (prop.displayOptions.show) {
for (const [key, values] of Object.entries(prop.displayOptions.show)) {
const configValue = config?.[key];
const expectedValues = Array.isArray(values) ? values : [values];
if (!expectedValues.includes(configValue)) {
isVisible = false;
break;
}
}
}
// Check hide conditions
if (isVisible && prop.displayOptions.hide) {
for (const [key, values] of Object.entries(prop.displayOptions.hide)) {
const configValue = config?.[key];
const expectedValues = Array.isArray(values) ? values : [values];
if (expectedValues.includes(configValue)) {
isVisible = false;
break;
}
}
}
if (!isVisible) continue;
}
// Check if field is missing (safely handle null/undefined config)
if (!config || !(prop.name in config)) {
missingFields.push(prop.displayName || prop.name);

View File

@@ -23,7 +23,7 @@ export const n8nCreateWorkflowDoc: ToolDocumentation = {
connections: { type: 'object', required: true, description: 'Node connections. Keys are source node IDs' },
settings: { type: 'object', description: 'Optional workflow settings (timezone, error handling, etc.)' }
},
returns: 'Minimal summary (id, name, active, nodeCount) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed.',
returns: 'Created workflow object with id, name, nodes, connections, active status',
examples: [
`// Basic webhook to Slack workflow
n8n_create_workflow({

View File

@@ -19,7 +19,7 @@ export const n8nDeleteWorkflowDoc: ToolDocumentation = {
parameters: {
id: { type: 'string', required: true, description: 'Workflow ID to delete permanently' }
},
returns: 'Minimal confirmation (id, name, deleted: true) for token efficiency.',
returns: 'Success confirmation or error if workflow not found/cannot be deleted',
examples: [
'n8n_delete_workflow({id: "abc123"}) - Delete specific workflow',
'if (confirm) { n8n_delete_workflow({id: wf.id}); } // With confirmation'

View File

@@ -5,14 +5,13 @@ export const n8nExecutionsDoc: ToolDocumentation = {
category: 'workflow_management',
essentials: {
description: 'Manage workflow executions: get details, list, or delete. Unified tool for all execution operations.',
keyParameters: ['action', 'id', 'workflowId', 'status', 'mode'],
example: 'n8n_executions({action: "get", id: "exec_456", mode: "error"})',
keyParameters: ['action', 'id', 'workflowId', 'status'],
example: 'n8n_executions({action: "list", workflowId: "abc123", status: "error"})',
performance: 'Fast (50-200ms)',
tips: [
'action="get": Get execution details by ID',
'action="list": List executions with filters',
'action="delete": Delete execution record',
'Use mode="error" for efficient failure debugging (80-90% token savings)',
'Use mode parameter for action=get to control detail level'
]
},
@@ -26,26 +25,14 @@ export const n8nExecutionsDoc: ToolDocumentation = {
- preview: Structure only, no data
- summary: 2 items per node (default)
- filtered: Custom items limit, optionally filter by node names
- full: All execution data (can be very large)
- error: Optimized for debugging failures - extracts error info, upstream context, and AI suggestions
**Error Mode Features:**
- Extracts error message, type, and node configuration
- Samples input data from upstream node (configurable limit)
- Shows execution path leading to error
- Provides AI-friendly fix suggestions based on error patterns
- Token-efficient (80-90% smaller than full mode)`,
- full: All execution data (can be very large)`,
parameters: {
action: { type: 'string', required: true, description: 'Operation: "get", "list", or "delete"' },
id: { type: 'string', required: false, description: 'Execution ID (required for action=get or action=delete)' },
mode: { type: 'string', required: false, description: 'For action=get: "preview", "summary" (default), "filtered", "full", "error"' },
mode: { type: 'string', required: false, description: 'For action=get: "preview", "summary" (default), "filtered", "full"' },
nodeNames: { type: 'array', required: false, description: 'For action=get with mode=filtered: Filter to specific nodes by name' },
itemsLimit: { type: 'number', required: false, description: 'For action=get with mode=filtered: Items per node (0=structure, 2=default, -1=unlimited)' },
includeInputData: { type: 'boolean', required: false, description: 'For action=get: Include input data in addition to output (default: false)' },
errorItemsLimit: { type: 'number', required: false, description: 'For action=get with mode=error: Sample items from upstream (default: 2, max: 100)' },
includeStackTrace: { type: 'boolean', required: false, description: 'For action=get with mode=error: Include full stack trace (default: false, shows truncated)' },
includeExecutionPath: { type: 'boolean', required: false, description: 'For action=get with mode=error: Include execution path (default: true)' },
fetchWorkflow: { type: 'boolean', required: false, description: 'For action=get with mode=error: Fetch workflow for accurate upstream detection (default: true)' },
workflowId: { type: 'string', required: false, description: 'For action=list: Filter by workflow ID' },
status: { type: 'string', required: false, description: 'For action=list: Filter by status ("success", "error", "waiting")' },
limit: { type: 'number', required: false, description: 'For action=list: Number of results (1-100, default: 100)' },
@@ -54,15 +41,10 @@ export const n8nExecutionsDoc: ToolDocumentation = {
includeData: { type: 'boolean', required: false, description: 'For action=list: Include execution data (default: false)' }
},
returns: `Depends on action:
- get (error mode): { errorInfo: { primaryError, upstreamContext, executionPath, suggestions }, summary }
- get (other modes): Execution object with data based on mode
- get: Execution object with data based on mode
- list: { data: [...executions], nextCursor?: string }
- delete: { success: boolean, message: string }`,
examples: [
'// Debug a failed execution (recommended for errors)\nn8n_executions({action: "get", id: "exec_456", mode: "error"})',
'// Debug with more sample data from upstream\nn8n_executions({action: "get", id: "exec_456", mode: "error", errorItemsLimit: 5})',
'// Debug with full stack trace\nn8n_executions({action: "get", id: "exec_456", mode: "error", includeStackTrace: true})',
'// Debug without workflow fetch (faster but less accurate)\nn8n_executions({action: "get", id: "exec_456", mode: "error", fetchWorkflow: false})',
'// List recent executions for a workflow\nn8n_executions({action: "list", workflowId: "abc123", limit: 10})',
'// List failed executions\nn8n_executions({action: "list", status: "error"})',
'// Get execution summary\nn8n_executions({action: "get", id: "exec_456"})',
@@ -71,10 +53,7 @@ export const n8nExecutionsDoc: ToolDocumentation = {
'// Delete an execution\nn8n_executions({action: "delete", id: "exec_456"})'
],
useCases: [
'Debug workflow failures efficiently (mode=error) - 80-90% token savings',
'Get AI suggestions for fixing common errors',
'Analyze input data that caused failure',
'Debug workflow failures with full data (mode=full)',
'Debug workflow failures (get with mode=full)',
'Monitor workflow health (list with status filter)',
'Audit execution history',
'Clean up old execution records',
@@ -83,22 +62,18 @@ export const n8nExecutionsDoc: ToolDocumentation = {
performance: `Response times:
- list: 50-150ms depending on filters
- get (preview/summary): 30-100ms
- get (error): 50-200ms (includes optional workflow fetch)
- get (full): 100-500ms+ depending on data size
- delete: 30-80ms`,
bestPractices: [
'Use mode="error" for debugging failed executions - 80-90% token savings vs full',
'Use mode="summary" (default) for quick inspection',
'Use mode="summary" (default) for debugging - shows enough data',
'Use mode="filtered" with nodeNames for large workflows',
'Filter by workflowId when listing to reduce results',
'Use cursor for pagination through large result sets',
'Set fetchWorkflow=false if you already know the workflow structure',
'Delete old executions to save storage'
],
pitfalls: [
'Requires N8N_API_URL and N8N_API_KEY configured',
'mode="full" can return very large responses for complex workflows',
'mode="error" fetches workflow by default (adds ~50-100ms), disable with fetchWorkflow=false',
'Execution must exist or returns 404',
'Delete is permanent - cannot undo'
],

View File

@@ -25,7 +25,7 @@ export const n8nUpdateFullWorkflowDoc: ToolDocumentation = {
settings: { type: 'object', description: 'Workflow settings to update (timezone, error handling, etc.)' },
intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Migrate workflow to new node versions".' }
},
returns: 'Minimal summary (id, name, active, nodeCount) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed.',
returns: 'Updated workflow object with all fields including the changes applied',
examples: [
'n8n_update_full_workflow({id: "abc", intent: "Rename workflow for clarity", name: "New Name"}) - Rename with intent',
'n8n_update_full_workflow({id: "abc", name: "New Name"}) - Rename only',

View File

@@ -312,7 +312,7 @@ n8n_update_partial_workflow({
continueOnError: { type: 'boolean', description: 'If true, apply valid operations even if some fail (best-effort mode). Returns applied and failed operation indices. Default: false (atomic)' },
intent: { type: 'string', description: 'Intent of the change - helps to return better response. Include in every tool call. Example: "Add error handling for API failures".' }
},
returns: 'Minimal summary (id, name, active, nodeCount, operationsApplied) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed. Returns validation results if validateOnly=true.',
returns: 'Updated workflow object or validation results if validateOnly=true',
examples: [
'// Include intent parameter for better responses\nn8n_update_partial_workflow({id: "abc", intent: "Add error handling for API failures", operations: [{type: "addConnection", source: "HTTP Request", target: "Error Handler"}]})',
'// Add a basic node (minimal configuration)\nn8n_update_partial_workflow({id: "abc", operations: [{type: "addNode", node: {name: "Process Data", type: "n8n-nodes-base.set", position: [400, 300], parameters: {}}}]})',

View File

@@ -349,8 +349,8 @@ export const n8nManagementTools: ToolDefinition[] = [
// For action='get' - detail level
mode: {
type: 'string',
enum: ['preview', 'summary', 'filtered', 'full', 'error'],
description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data, error=optimized error debugging'
enum: ['preview', 'summary', 'filtered', 'full'],
description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data'
},
nodeNames: {
type: 'array',
@@ -365,23 +365,6 @@ export const n8nManagementTools: ToolDefinition[] = [
type: 'boolean',
description: 'For action=get: include input data in addition to output (default: false)'
},
// Error mode specific parameters
errorItemsLimit: {
type: 'number',
description: 'For action=get with mode=error: sample items from upstream node (default: 2, max: 100)'
},
includeStackTrace: {
type: 'boolean',
description: 'For action=get with mode=error: include full stack trace (default: false, shows truncated)'
},
includeExecutionPath: {
type: 'boolean',
description: 'For action=get with mode=error: include execution path leading to error (default: true)'
},
fetchWorkflow: {
type: 'boolean',
description: 'For action=get with mode=error: fetch workflow for accurate upstream detection (default: true)'
},
// For action='list'
limit: {
type: 'number',

View File

@@ -28,10 +28,6 @@ export interface ParsedNode {
documentation?: string;
outputs?: any[];
outputNames?: string[];
// Tool variant fields (for nodes with usableAsTool: true)
isToolVariant?: boolean; // True for *Tool variants (e.g., supabaseTool)
toolVariantOf?: string; // For Tool variants: base node type (e.g., nodes-base.supabase)
hasToolVariant?: boolean; // For base nodes: true if Tool variant exists
}
export class NodeParser {

View File

@@ -8,7 +8,6 @@ import { N8nNodeLoader } from '../loaders/node-loader';
import { NodeParser, ParsedNode } from '../parsers/node-parser';
import { DocsMapper } from '../mappers/docs-mapper';
import { NodeRepository } from '../database/node-repository';
import { ToolVariantGenerator } from '../services/tool-variant-generator';
import { TemplateSanitizer } from '../utils/template-sanitizer';
import * as fs from 'fs';
import * as path from 'path';
@@ -22,7 +21,6 @@ async function rebuild() {
const parser = new NodeParser();
const mapper = new DocsMapper();
const repository = new NodeRepository(db);
const toolVariantGenerator = new ToolVariantGenerator();
// Initialize database
const schema = fs.readFileSync(path.join(__dirname, '../../src/database/schema.sql'), 'utf8');
@@ -45,8 +43,7 @@ async function rebuild() {
webhooks: 0,
withProperties: 0,
withOperations: 0,
withDocs: 0,
toolVariants: 0
withDocs: 0
};
// Process each node (documentation fetching must be outside transaction due to async)
@@ -57,38 +54,21 @@ async function rebuild() {
try {
// Parse node
const parsed = parser.parse(NodeClass, packageName);
// Validate parsed data
if (!parsed.nodeType || !parsed.displayName) {
throw new Error(`Missing required fields - nodeType: ${parsed.nodeType}, displayName: ${parsed.displayName}, packageName: ${parsed.packageName}`);
}
// Additional validation for required fields
if (!parsed.packageName) {
throw new Error(`Missing packageName for node ${nodeName}`);
}
// Get documentation
const docs = await mapper.fetchDocumentation(parsed.nodeType);
parsed.documentation = docs || undefined;
// Generate Tool variant for nodes with usableAsTool: true
if (parsed.isAITool && !parsed.isTrigger) {
const toolVariant = toolVariantGenerator.generateToolVariant(parsed);
if (toolVariant) {
// Mark base node as having a Tool variant
parsed.hasToolVariant = true;
// Add Tool variant to processed nodes
processedNodes.push({
parsed: toolVariant,
docs: undefined, // Tool variants don't have separate docs
nodeName: `${nodeName}Tool`
});
stats.toolVariants++;
}
}
processedNodes.push({ parsed, docs: docs || undefined, nodeName });
} catch (error) {
stats.failed++;
@@ -147,7 +127,6 @@ async function rebuild() {
console.log(` Successful: ${stats.successful}`);
console.log(` Failed: ${stats.failed}`);
console.log(` AI Tools: ${stats.aiTools}`);
console.log(` Tool Variants: ${stats.toolVariants}`);
console.log(` Triggers: ${stats.triggers}`);
console.log(` Webhooks: ${stats.webhooks}`);
console.log(` With Properties: ${stats.withProperties}`);
@@ -186,9 +165,6 @@ async function rebuild() {
db.close();
}
// Expected minimum based on n8n v1.123.4 AI-capable nodes
const MIN_EXPECTED_TOOL_VARIANTS = 200;
function validateDatabase(repository: NodeRepository): { passed: boolean; issues: string[] } {
const issues = [];
@@ -229,14 +205,6 @@ function validateDatabase(repository: NodeRepository): { passed: boolean; issues
issues.push('No AI tools found - check detection logic');
}
// Check Tool variants
const toolVariantCount = repository.getToolVariantCount();
if (toolVariantCount === 0) {
issues.push('No Tool variants found - check ToolVariantGenerator');
} else if (toolVariantCount < MIN_EXPECTED_TOOL_VARIANTS) {
issues.push(`Only ${toolVariantCount} Tool variants found - expected at least ${MIN_EXPECTED_TOOL_VARIANTS}`);
}
// Check FTS5 table existence and population
const ftsTableCheck = db.prepare(`
SELECT name FROM sqlite_master

View File

@@ -176,107 +176,35 @@ export class ConfigValidator {
}
/**
* Evaluate a single _cnd conditional operator from n8n displayOptions.
* Supports: eq, not, gte, lte, gt, lt, between, startsWith, endsWith, includes, regex, exists
* Check if a property is visible given current config
*/
private static evaluateCondition(
condition: { _cnd: Record<string, any> },
configValue: any
): boolean {
const cnd = condition._cnd;
if ('eq' in cnd) return configValue === cnd.eq;
if ('not' in cnd) return configValue !== cnd.not;
if ('gte' in cnd) return configValue >= cnd.gte;
if ('lte' in cnd) return configValue <= cnd.lte;
if ('gt' in cnd) return configValue > cnd.gt;
if ('lt' in cnd) return configValue < cnd.lt;
if ('between' in cnd) {
const between = cnd.between;
if (!between || typeof between.from === 'undefined' || typeof between.to === 'undefined') {
return false; // Invalid between structure
}
return configValue >= between.from && configValue <= between.to;
}
if ('startsWith' in cnd) {
return typeof configValue === 'string' && configValue.startsWith(cnd.startsWith);
}
if ('endsWith' in cnd) {
return typeof configValue === 'string' && configValue.endsWith(cnd.endsWith);
}
if ('includes' in cnd) {
return typeof configValue === 'string' && configValue.includes(cnd.includes);
}
if ('regex' in cnd) {
if (typeof configValue !== 'string') return false;
try {
return new RegExp(cnd.regex).test(configValue);
} catch {
return false; // Invalid regex pattern
}
}
if ('exists' in cnd) {
return configValue !== undefined && configValue !== null;
}
// Unknown operator - default to not matching (conservative)
return false;
}
/**
* Check if a config value matches an expected value.
* Handles both plain values and _cnd conditional operators.
*/
private static valueMatches(expectedValue: any, configValue: any): boolean {
// Check if this is a _cnd conditional
if (expectedValue && typeof expectedValue === 'object' && '_cnd' in expectedValue) {
return this.evaluateCondition(expectedValue, configValue);
}
// Plain value comparison
return configValue === expectedValue;
}
/**
* Check if a property is visible given current config.
* Supports n8n's _cnd conditional operators in displayOptions.
*/
public static isPropertyVisible(prop: any, config: Record<string, any>): boolean {
protected static isPropertyVisible(prop: any, config: Record<string, any>): boolean {
if (!prop.displayOptions) return true;
// Check show conditions - property visible only if ALL conditions match
// Check show conditions
if (prop.displayOptions.show) {
for (const [key, values] of Object.entries(prop.displayOptions.show)) {
const configValue = config[key];
const expectedValues = Array.isArray(values) ? values : [values];
// Check if ANY expected value matches (OR logic within a key)
const anyMatch = expectedValues.some(expected =>
this.valueMatches(expected, configValue)
);
if (!anyMatch) {
if (!expectedValues.includes(configValue)) {
return false;
}
}
}
// Check hide conditions - property hidden if ANY condition matches
// Check hide conditions
if (prop.displayOptions.hide) {
for (const [key, values] of Object.entries(prop.displayOptions.hide)) {
const configValue = config[key];
const expectedValues = Array.isArray(values) ? values : [values];
// Check if ANY expected value matches (property should be hidden)
const anyMatch = expectedValues.some(expected =>
this.valueMatches(expected, configValue)
);
if (anyMatch) {
if (expectedValues.includes(configValue)) {
return false;
}
}
}
return true;
}

View File

@@ -1,606 +0,0 @@
/**
* Error Execution Processor Service
*
* Specialized processor for extracting error context from failed n8n executions.
* Designed for AI agent debugging workflows with token efficiency.
*
* Features:
* - Auto-identify error nodes
* - Extract upstream context (input data to error node)
* - Build execution path from trigger to error
* - Generate AI-friendly fix suggestions
*/
import {
Execution,
Workflow,
ErrorAnalysis,
ErrorSuggestion,
} from '../types/n8n-api';
import { logger } from '../utils/logger';
/**
* Options for error processing
*/
export interface ErrorProcessorOptions {
itemsLimit?: number; // Default: 2
includeStackTrace?: boolean; // Default: false
includeExecutionPath?: boolean; // Default: true
workflow?: Workflow; // Optional: for accurate upstream detection
}
// Constants
const MAX_STACK_LINES = 3;
/**
* Keys that could enable prototype pollution attacks
* These are blocked entirely from processing
*/
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
/**
* Patterns for sensitive data that should be masked in output
* Expanded from code review recommendations
*/
const SENSITIVE_PATTERNS = [
'password',
'secret',
'token',
'apikey',
'api_key',
'credential',
'auth',
'private_key',
'privatekey',
'bearer',
'jwt',
'oauth',
'certificate',
'passphrase',
'access_token',
'refresh_token',
'session',
'cookie',
'authorization'
];
/**
* Process execution for error debugging
*/
export function processErrorExecution(
execution: Execution,
options: ErrorProcessorOptions = {}
): ErrorAnalysis {
const {
itemsLimit = 2,
includeStackTrace = false,
includeExecutionPath = true,
workflow
} = options;
const resultData = execution.data?.resultData;
const error = resultData?.error as Record<string, unknown> | undefined;
const runData = resultData?.runData as Record<string, any> || {};
const lastNode = resultData?.lastNodeExecuted;
// 1. Extract primary error info
const primaryError = extractPrimaryError(error, lastNode, runData, includeStackTrace);
// 2. Find and extract upstream context
const upstreamContext = extractUpstreamContext(
primaryError.nodeName,
runData,
workflow,
itemsLimit
);
// 3. Build execution path if requested
const executionPath = includeExecutionPath
? buildExecutionPath(primaryError.nodeName, runData, workflow)
: undefined;
// 4. Find additional errors (for batch failures)
const additionalErrors = findAdditionalErrors(
primaryError.nodeName,
runData
);
// 5. Generate AI suggestions
const suggestions = generateSuggestions(primaryError, upstreamContext);
return {
primaryError,
upstreamContext,
executionPath,
additionalErrors: additionalErrors.length > 0 ? additionalErrors : undefined,
suggestions: suggestions.length > 0 ? suggestions : undefined
};
}
/**
* Extract primary error information
*/
function extractPrimaryError(
error: Record<string, unknown> | undefined,
lastNode: string | undefined,
runData: Record<string, any>,
includeFullStackTrace: boolean
): ErrorAnalysis['primaryError'] {
// Error info from resultData.error
const errorNode = error?.node as Record<string, unknown> | undefined;
const nodeName = (errorNode?.name as string) || lastNode || 'Unknown';
// Also check runData for node-level errors
const nodeRunData = runData[nodeName];
const nodeError = nodeRunData?.[0]?.error;
const stackTrace = (error?.stack || nodeError?.stack) as string | undefined;
return {
message: (error?.message || nodeError?.message || 'Unknown error') as string,
errorType: (error?.name || nodeError?.name || 'Error') as string,
nodeName,
nodeType: (errorNode?.type || '') as string,
nodeId: errorNode?.id as string | undefined,
nodeParameters: extractRelevantParameters(errorNode?.parameters),
stackTrace: includeFullStackTrace ? stackTrace : truncateStackTrace(stackTrace)
};
}
/**
* Extract upstream context (input data to error node)
*/
function extractUpstreamContext(
errorNodeName: string,
runData: Record<string, any>,
workflow?: Workflow,
itemsLimit: number = 2
): ErrorAnalysis['upstreamContext'] | undefined {
// Strategy 1: Use workflow connections if available
if (workflow) {
const upstreamNode = findUpstreamNode(errorNodeName, workflow);
if (upstreamNode) {
const context = extractNodeOutput(upstreamNode, runData, itemsLimit);
if (context) {
// Enrich with node type from workflow
const nodeInfo = workflow.nodes.find(n => n.name === upstreamNode);
if (nodeInfo) {
context.nodeType = nodeInfo.type;
}
return context;
}
}
}
// Strategy 2: Heuristic - find node that produced data most recently before error
const successfulNodes = Object.entries(runData)
.filter(([name, data]) => {
if (name === errorNodeName) return false;
const runs = data as any[];
return runs?.[0]?.data?.main?.[0]?.length > 0 && !runs?.[0]?.error;
})
.map(([name, data]) => ({
name,
executionTime: (data as any[])?.[0]?.executionTime || 0,
startTime: (data as any[])?.[0]?.startTime || 0
}))
.sort((a, b) => b.startTime - a.startTime);
if (successfulNodes.length > 0) {
const upstreamName = successfulNodes[0].name;
return extractNodeOutput(upstreamName, runData, itemsLimit);
}
return undefined;
}
/**
* Find upstream node using workflow connections
* Connections format: { sourceNode: { main: [[{node: targetNode, type, index}]] } }
*/
function findUpstreamNode(
targetNode: string,
workflow: Workflow
): string | undefined {
for (const [sourceName, outputs] of Object.entries(workflow.connections)) {
const connections = outputs as Record<string, any>;
const mainOutputs = connections?.main || [];
for (const outputBranch of mainOutputs) {
if (!Array.isArray(outputBranch)) continue;
for (const connection of outputBranch) {
if (connection?.node === targetNode) {
return sourceName;
}
}
}
}
return undefined;
}
/**
* Find all upstream nodes (for building complete path)
*/
function findAllUpstreamNodes(
targetNode: string,
workflow: Workflow,
visited: Set<string> = new Set()
): string[] {
const path: string[] = [];
let currentNode = targetNode;
while (currentNode && !visited.has(currentNode)) {
visited.add(currentNode);
const upstream = findUpstreamNode(currentNode, workflow);
if (upstream) {
path.unshift(upstream);
currentNode = upstream;
} else {
break;
}
}
return path;
}
/**
* Extract node output with sampling and sanitization
*/
function extractNodeOutput(
nodeName: string,
runData: Record<string, any>,
itemsLimit: number
): ErrorAnalysis['upstreamContext'] | undefined {
const nodeData = runData[nodeName];
if (!nodeData?.[0]?.data?.main?.[0]) return undefined;
const items = nodeData[0].data.main[0];
// Sanitize sample items to remove sensitive data
const rawSamples = items.slice(0, itemsLimit);
const sanitizedSamples = rawSamples.map((item: unknown) => sanitizeData(item));
return {
nodeName,
nodeType: '', // Will be enriched if workflow available
itemCount: items.length,
sampleItems: sanitizedSamples,
dataStructure: extractStructure(items[0])
};
}
/**
* Build execution path leading to error
*/
function buildExecutionPath(
errorNodeName: string,
runData: Record<string, any>,
workflow?: Workflow
): ErrorAnalysis['executionPath'] {
const path: ErrorAnalysis['executionPath'] = [];
// If we have workflow, trace connections backward for ordered path
if (workflow) {
const upstreamNodes = findAllUpstreamNodes(errorNodeName, workflow);
// Add upstream nodes
for (const nodeName of upstreamNodes) {
const nodeData = runData[nodeName];
const runs = nodeData as any[] | undefined;
const hasError = runs?.[0]?.error;
const itemCount = runs?.[0]?.data?.main?.[0]?.length || 0;
path.push({
nodeName,
status: hasError ? 'error' : (runs ? 'success' : 'skipped'),
itemCount,
executionTime: runs?.[0]?.executionTime
});
}
// Add error node
const errorNodeData = runData[errorNodeName];
path.push({
nodeName: errorNodeName,
status: 'error',
itemCount: 0,
executionTime: errorNodeData?.[0]?.executionTime
});
} else {
// Without workflow, list all executed nodes by execution order (best effort)
const nodesByTime = Object.entries(runData)
.map(([name, data]) => ({
name,
data: data as any[],
startTime: (data as any[])?.[0]?.startTime || 0
}))
.sort((a, b) => a.startTime - b.startTime);
for (const { name, data } of nodesByTime) {
path.push({
nodeName: name,
status: data?.[0]?.error ? 'error' : 'success',
itemCount: data?.[0]?.data?.main?.[0]?.length || 0,
executionTime: data?.[0]?.executionTime
});
}
}
return path;
}
/**
* Find additional error nodes (for batch/parallel failures)
*/
function findAdditionalErrors(
primaryErrorNode: string,
runData: Record<string, any>
): Array<{ nodeName: string; message: string }> {
const additional: Array<{ nodeName: string; message: string }> = [];
for (const [nodeName, data] of Object.entries(runData)) {
if (nodeName === primaryErrorNode) continue;
const runs = data as any[];
const error = runs?.[0]?.error;
if (error) {
additional.push({
nodeName,
message: error.message || 'Unknown error'
});
}
}
return additional;
}
/**
* Generate AI-friendly error suggestions based on patterns
*/
function generateSuggestions(
error: ErrorAnalysis['primaryError'],
upstream?: ErrorAnalysis['upstreamContext']
): ErrorSuggestion[] {
const suggestions: ErrorSuggestion[] = [];
const message = error.message.toLowerCase();
// Pattern: Missing required field
if (message.includes('required') || message.includes('must be provided') || message.includes('is required')) {
suggestions.push({
type: 'fix',
title: 'Missing Required Field',
description: `Check "${error.nodeName}" parameters for required fields. Error indicates a mandatory value is missing.`,
confidence: 'high'
});
}
// Pattern: Empty input
if (upstream?.itemCount === 0) {
suggestions.push({
type: 'investigate',
title: 'No Input Data',
description: `"${error.nodeName}" received 0 items from "${upstream.nodeName}". Check upstream node's filtering or data source.`,
confidence: 'high'
});
}
// Pattern: Authentication error
if (message.includes('auth') || message.includes('credentials') ||
message.includes('401') || message.includes('unauthorized') ||
message.includes('forbidden') || message.includes('403')) {
suggestions.push({
type: 'fix',
title: 'Authentication Issue',
description: 'Verify credentials are configured correctly. Check API key permissions and expiration.',
confidence: 'high'
});
}
// Pattern: Rate limiting
if (message.includes('rate limit') || message.includes('429') ||
message.includes('too many requests') || message.includes('throttle')) {
suggestions.push({
type: 'workaround',
title: 'Rate Limited',
description: 'Add delay between requests or reduce batch size. Consider using retry with exponential backoff.',
confidence: 'high'
});
}
// Pattern: Connection error
if (message.includes('econnrefused') || message.includes('enotfound') ||
message.includes('etimedout') || message.includes('network') ||
message.includes('connect')) {
suggestions.push({
type: 'investigate',
title: 'Network/Connection Error',
description: 'Check if the external service is reachable. Verify URL, firewall rules, and DNS resolution.',
confidence: 'high'
});
}
// Pattern: Invalid JSON
if (message.includes('json') || message.includes('parse error') ||
message.includes('unexpected token') || message.includes('syntax error')) {
suggestions.push({
type: 'fix',
title: 'Invalid JSON Format',
description: 'Check the data format. Ensure JSON is properly structured with correct syntax.',
confidence: 'high'
});
}
// Pattern: Field not found / invalid path
if (message.includes('not found') || message.includes('undefined') ||
message.includes('cannot read property') || message.includes('does not exist')) {
suggestions.push({
type: 'investigate',
title: 'Missing Data Field',
description: 'A referenced field does not exist in the input data. Check data structure and field names.',
confidence: 'medium'
});
}
// Pattern: Type error
if (message.includes('type') && (message.includes('expected') || message.includes('invalid'))) {
suggestions.push({
type: 'fix',
title: 'Data Type Mismatch',
description: 'Input data type does not match expected type. Check if strings/numbers/arrays are used correctly.',
confidence: 'medium'
});
}
// Pattern: Timeout
if (message.includes('timeout') || message.includes('timed out')) {
suggestions.push({
type: 'workaround',
title: 'Operation Timeout',
description: 'The operation took too long. Consider increasing timeout, reducing data size, or optimizing the query.',
confidence: 'high'
});
}
// Pattern: Permission denied
if (message.includes('permission') || message.includes('access denied') || message.includes('not allowed')) {
suggestions.push({
type: 'fix',
title: 'Permission Denied',
description: 'The operation lacks required permissions. Check user roles, API scopes, or resource access settings.',
confidence: 'high'
});
}
// Generic NodeOperationError guidance
if (error.errorType === 'NodeOperationError' && suggestions.length === 0) {
suggestions.push({
type: 'investigate',
title: 'Node Configuration Issue',
description: `Review "${error.nodeName}" parameters and operation settings. Validate against the node's requirements.`,
confidence: 'medium'
});
}
return suggestions;
}
// Helper functions
/**
* Check if a key contains sensitive patterns
*/
function isSensitiveKey(key: string): boolean {
const lowerKey = key.toLowerCase();
return SENSITIVE_PATTERNS.some(pattern => lowerKey.includes(pattern));
}
/**
* Recursively sanitize data by removing dangerous keys and masking sensitive values
*
* @param data - The data to sanitize
* @param depth - Current recursion depth
* @param maxDepth - Maximum recursion depth (default: 10)
* @returns Sanitized data with sensitive values masked
*/
function sanitizeData(data: unknown, depth = 0, maxDepth = 10): unknown {
// Prevent infinite recursion
if (depth >= maxDepth) {
return '[max depth reached]';
}
// Handle null/undefined
if (data === null || data === undefined) {
return data;
}
// Handle primitives
if (typeof data !== 'object') {
// Truncate long strings
if (typeof data === 'string' && data.length > 500) {
return '[truncated]';
}
return data;
}
// Handle arrays
if (Array.isArray(data)) {
return data.map(item => sanitizeData(item, depth + 1, maxDepth));
}
// Handle objects
const sanitized: Record<string, unknown> = {};
const obj = data as Record<string, unknown>;
for (const [key, value] of Object.entries(obj)) {
// Block prototype pollution attempts
if (DANGEROUS_KEYS.has(key)) {
logger.warn(`Blocked potentially dangerous key: ${key}`);
continue;
}
// Mask sensitive fields
if (isSensitiveKey(key)) {
sanitized[key] = '[REDACTED]';
continue;
}
// Recursively sanitize nested values
sanitized[key] = sanitizeData(value, depth + 1, maxDepth);
}
return sanitized;
}
/**
* Extract relevant parameters (filtering sensitive data)
*/
function extractRelevantParameters(params: unknown): Record<string, unknown> | undefined {
if (!params || typeof params !== 'object') return undefined;
const sanitized = sanitizeData(params);
if (!sanitized || typeof sanitized !== 'object' || Array.isArray(sanitized)) {
return undefined;
}
return Object.keys(sanitized).length > 0 ? sanitized as Record<string, unknown> : undefined;
}
/**
* Truncate stack trace to first few lines
*/
function truncateStackTrace(stack?: string): string | undefined {
if (!stack) return undefined;
const lines = stack.split('\n');
if (lines.length <= MAX_STACK_LINES) return stack;
return lines.slice(0, MAX_STACK_LINES).join('\n') + `\n... (${lines.length - MAX_STACK_LINES} more lines)`;
}
/**
* Extract data structure from an item
*/
function extractStructure(item: unknown, depth = 0, maxDepth = 3): Record<string, unknown> {
if (depth >= maxDepth) return { _type: typeof item };
if (item === null || item === undefined) {
return { _type: 'null' };
}
if (Array.isArray(item)) {
if (item.length === 0) return { _type: 'array', _length: 0 };
return {
_type: 'array',
_length: item.length,
_itemStructure: extractStructure(item[0], depth + 1, maxDepth)
};
}
if (typeof item === 'object') {
const structure: Record<string, unknown> = {};
for (const [key, value] of Object.entries(item)) {
structure[key] = extractStructure(value, depth + 1, maxDepth);
}
return structure;
}
return { _type: typeof item };
}

View File

@@ -21,10 +21,8 @@ import {
FilteredExecutionResponse,
FilteredNodeData,
ExecutionStatus,
Workflow,
} from '../types/n8n-api';
import { logger } from '../utils/logger';
import { processErrorExecution } from './error-execution-processor';
/**
* Size estimation and threshold constants
@@ -346,8 +344,7 @@ function truncateItems(
*/
export function filterExecutionData(
execution: Execution,
options: ExecutionFilterOptions,
workflow?: Workflow
options: ExecutionFilterOptions
): FilteredExecutionResponse {
const mode = options.mode || 'summary';
@@ -391,33 +388,6 @@ export function filterExecutionData(
return response;
}
// Handle error mode
if (mode === 'error') {
const errorAnalysis = processErrorExecution(execution, {
itemsLimit: options.errorItemsLimit ?? 2,
includeStackTrace: options.includeStackTrace ?? false,
includeExecutionPath: options.includeExecutionPath !== false,
workflow
});
const runData = execution.data?.resultData?.runData || {};
const executedNodes = Object.keys(runData).length;
response.errorInfo = errorAnalysis;
response.summary = {
totalNodes: executedNodes,
executedNodes,
totalItems: 0,
hasMoreData: false
};
if (execution.data?.resultData?.error) {
response.error = execution.data.resultData.error as Record<string, unknown>;
}
return response;
}
// Handle no data case
if (!execution.data?.resultData?.runData) {
response.summary = {
@@ -538,13 +508,12 @@ export function filterExecutionData(
*/
export function processExecution(
execution: Execution,
options: ExecutionFilterOptions = {},
workflow?: Workflow
options: ExecutionFilterOptions = {}
): FilteredExecutionResponse | Execution {
// Legacy behavior: if no mode specified and no filtering options, return original
if (!options.mode && !options.nodeNames && options.itemsLimit === undefined) {
return execution;
}
return filterExecutionData(execution, options, workflow);
return filterExecutionData(execution, options);
}

View File

@@ -248,32 +248,23 @@ export function validateWorkflowStructure(workflow: Partial<Workflow>): string[]
const connectedNodes = new Set<string>();
// Collect all nodes that appear in connections (as source or target)
// Check ALL connection types, not just 'main' - AI workflows use ai_tool, ai_languageModel, etc.
const ALL_CONNECTION_TYPES = ['main', 'error', 'ai_tool', 'ai_languageModel', 'ai_memory', 'ai_embedding', 'ai_vectorStore'] as const;
Object.entries(workflow.connections).forEach(([sourceName, connection]) => {
connectedNodes.add(sourceName); // Node has outgoing connection
// Check all connection types for target nodes
ALL_CONNECTION_TYPES.forEach(connType => {
const connData = (connection as Record<string, unknown>)[connType];
if (connData && Array.isArray(connData)) {
connData.forEach((outputs) => {
if (Array.isArray(outputs)) {
outputs.forEach((target: { node: string }) => {
if (target?.node) {
connectedNodes.add(target.node); // Node has incoming connection
}
});
}
});
}
});
if (connection.main && Array.isArray(connection.main)) {
connection.main.forEach((outputs) => {
if (Array.isArray(outputs)) {
outputs.forEach((target) => {
connectedNodes.add(target.node); // Node has incoming connection
});
}
});
}
});
// Find disconnected nodes (excluding non-executable nodes and triggers)
// Non-executable nodes (sticky notes) are UI-only and don't need connections
// Trigger nodes need either outgoing connections OR inbound AI connections (for mcpTrigger)
// Trigger nodes only need outgoing connections
const disconnectedNodes = workflow.nodes.filter(node => {
// Skip non-executable nodes (sticky notes, etc.) - they're UI-only annotations
if (isNonExecutableNode(node.type)) {
@@ -283,12 +274,9 @@ export function validateWorkflowStructure(workflow: Partial<Workflow>): string[]
const isConnected = connectedNodes.has(node.name);
const isNodeTrigger = isTriggerNode(node.type);
// Trigger nodes need outgoing connections OR inbound connections (for mcpTrigger)
// mcpTrigger is special: it has "trigger" in its name but only receives inbound ai_tool connections
// Trigger nodes only need outgoing connections
if (isNodeTrigger) {
const hasOutgoingConnections = !!workflow.connections?.[node.name];
const hasInboundConnections = isConnected;
return !hasOutgoingConnections && !hasInboundConnections; // Disconnected if NEITHER
return !workflow.connections?.[node.name]; // Disconnected if no outgoing connections
}
// Regular nodes need at least one connection (incoming or outgoing)
@@ -343,16 +331,24 @@ export function validateWorkflowStructure(workflow: Partial<Workflow>): string[]
}
// Validate active workflows have activatable triggers
// NOTE: Since n8n 2.0, executeWorkflowTrigger is now activatable and MUST be activated to work
// Issue #351: executeWorkflowTrigger cannot activate a workflow
// It can only be invoked by other workflows
if ((workflow as any).active === true && workflow.nodes && workflow.nodes.length > 0) {
const activatableTriggers = workflow.nodes.filter(node =>
!node.disabled && isActivatableTrigger(node.type)
);
if (activatableTriggers.length === 0) {
const executeWorkflowTriggers = workflow.nodes.filter(node =>
!node.disabled && node.type.toLowerCase().includes('executeworkflow')
);
if (activatableTriggers.length === 0 && executeWorkflowTriggers.length > 0) {
// Workflow is active but only has executeWorkflowTrigger nodes
const triggerNames = executeWorkflowTriggers.map(n => n.name).join(', ');
errors.push(
'Cannot activate workflow: No activatable trigger nodes found. ' +
'Workflows must have at least one enabled trigger node (webhook, schedule, executeWorkflowTrigger, etc.).'
`Cannot activate workflow with only Execute Workflow Trigger nodes (${triggerNames}). ` +
'Execute Workflow Trigger can only be invoked by other workflows, not activated. ' +
'Either deactivate the workflow or add a webhook/schedule/polling trigger.'
);
}
}

View File

@@ -1,158 +0,0 @@
/**
* Tool Variant Generator
*
* Generates Tool variant nodes for nodes with usableAsTool: true.
*
* n8n dynamically creates Tool variants (e.g., supabaseTool from supabase)
* that can be connected to AI Agents. These variants have:
* - A 'Tool' suffix on the node type
* - An additional 'toolDescription' property
* - Output type 'ai_tool' instead of 'main'
*/
import type { ParsedNode } from '../parsers/node-parser';
export class ToolVariantGenerator {
/**
* Generate a Tool variant from a base node with usableAsTool: true
*
* @param baseNode - The base ParsedNode that has isAITool: true
* @returns A new ParsedNode representing the Tool variant, or null if not applicable
*/
generateToolVariant(baseNode: ParsedNode): ParsedNode | null {
// Only generate for nodes with usableAsTool: true (isAITool)
if (!baseNode.isAITool) {
return null;
}
// Don't generate Tool variant for nodes that are already Tool variants
if (baseNode.isToolVariant) {
return null;
}
// Don't generate for trigger nodes (they can't be used as tools)
if (baseNode.isTrigger) {
return null;
}
// Validate nodeType exists
if (!baseNode.nodeType) {
return null;
}
// Generate the Tool variant node type
// e.g., nodes-base.supabase -> nodes-base.supabaseTool
const toolNodeType = `${baseNode.nodeType}Tool`;
// Ensure properties is an array to prevent spread operator errors
const baseProperties = Array.isArray(baseNode.properties) ? baseNode.properties : [];
return {
...baseNode,
nodeType: toolNodeType,
displayName: `${baseNode.displayName} Tool`,
description: baseNode.description
? `${baseNode.description} (AI Tool variant for use with AI Agents)`
: 'AI Tool variant for use with AI Agents',
// Mark as Tool variant
isToolVariant: true,
toolVariantOf: baseNode.nodeType,
hasToolVariant: false, // Tool variants don't have further variants
// Override outputs for Tool variant
outputs: [{ type: 'ai_tool', displayName: 'Tool' }],
outputNames: ['Tool'],
// Add toolDescription property at the beginning
properties: this.addToolDescriptionProperty(baseProperties, baseNode.displayName),
};
}
/**
* Add the toolDescription property to the beginning of the properties array
*/
private addToolDescriptionProperty(properties: any[], displayName: string): any[] {
const toolDescriptionProperty = {
displayName: 'Tool Description',
name: 'toolDescription',
type: 'string',
default: '',
required: false,
description: 'Description for the AI to understand what this tool does and when to use it',
typeOptions: {
rows: 3
},
placeholder: `e.g., Use this tool to ${this.generateDescriptionPlaceholder(displayName)}`
};
return [toolDescriptionProperty, ...properties];
}
/**
* Generate a placeholder description based on the node display name
*/
private generateDescriptionPlaceholder(displayName: string): string {
const lowerName = displayName.toLowerCase();
// Common patterns
if (lowerName.includes('database') || lowerName.includes('sql')) {
return 'query and manage data in the database';
}
if (lowerName.includes('email') || lowerName.includes('mail')) {
return 'send and manage emails';
}
if (lowerName.includes('sheet') || lowerName.includes('spreadsheet')) {
return 'read and write spreadsheet data';
}
if (lowerName.includes('file') || lowerName.includes('drive') || lowerName.includes('storage')) {
return 'manage files and storage';
}
if (lowerName.includes('message') || lowerName.includes('chat') || lowerName.includes('slack')) {
return 'send messages and communicate';
}
if (lowerName.includes('http') || lowerName.includes('api') || lowerName.includes('request')) {
return 'make API requests and fetch data';
}
if (lowerName.includes('calendar') || lowerName.includes('event')) {
return 'manage calendar events and schedules';
}
// Default placeholder
return `interact with ${displayName}`;
}
/**
* Check if a node type looks like a Tool variant.
* Valid Tool variants must:
* - End with 'Tool' but not 'ToolTool'
* - Have a valid package.nodeName pattern (contain a dot)
* - Have content after the dot before 'Tool' suffix
*/
static isToolVariantNodeType(nodeType: string): boolean {
if (!nodeType || !nodeType.endsWith('Tool') || nodeType.endsWith('ToolTool')) {
return false;
}
// The base part (without 'Tool' suffix) should be a valid node pattern
const basePart = nodeType.slice(0, -4);
// Valid pattern: package.nodeName (must contain a dot and have content after it)
return basePart.includes('.') && basePart.split('.').pop()!.length > 0;
}
/**
* Get the base node type from a Tool variant node type
*/
static getBaseNodeType(toolNodeType: string): string | null {
if (!ToolVariantGenerator.isToolVariantNodeType(toolNodeType)) {
return null;
}
return toolNodeType.slice(0, -4); // Remove 'Tool' suffix
}
/**
* Get the Tool variant node type from a base node type
*/
static getToolVariantNodeType(baseNodeType: string): string {
return `${baseNodeType}Tool`;
}
}

View File

@@ -30,9 +30,8 @@ export type FixType =
| 'error-output-config'
| 'node-type-correction'
| 'webhook-missing-path'
| 'typeversion-upgrade' // Proactive version upgrades
| 'version-migration' // Smart version migrations with breaking changes
| 'tool-variant-correction'; // Fix base nodes used as AI tools when Tool variant exists
| 'typeversion-upgrade' // NEW: Proactive version upgrades
| 'version-migration'; // NEW: Smart version migrations with breaking changes
export interface AutoFixConfig {
applyFixes: boolean;
@@ -160,12 +159,7 @@ export class WorkflowAutoFixer {
this.processWebhookPathFixes(validationResult, nodeMap, operations, fixes);
}
// Process tool variant corrections (HIGH confidence)
if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('tool-variant-correction')) {
this.processToolVariantFixes(validationResult, nodeMap, workflow, operations, fixes);
}
// Process version upgrades (HIGH/MEDIUM confidence)
// NEW: Process version upgrades (HIGH/MEDIUM confidence)
if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('typeversion-upgrade')) {
await this.processVersionUpgradeFixes(workflow, nodeMap, operations, fixes, postUpdateGuidance);
}
@@ -465,69 +459,6 @@ export class WorkflowAutoFixer {
}
}
/**
* Process tool variant corrections for base nodes incorrectly used as AI tools.
*
* When a base node (e.g., n8n-nodes-base.supabase) is connected via ai_tool output
* but has a Tool variant available (e.g., n8n-nodes-base.supabaseTool), this fix
* replaces the node type with the correct Tool variant.
*
* @param validationResult - Validation result containing errors to process
* @param nodeMap - Map of node names/IDs to node objects
* @param _workflow - Workflow object (unused, kept for API consistency with other fix methods)
* @param operations - Array to push generated diff operations to
* @param fixes - Array to push generated fix records to
*/
private processToolVariantFixes(
validationResult: WorkflowValidationResult,
nodeMap: Map<string, WorkflowNode>,
_workflow: Workflow,
operations: WorkflowDiffOperation[],
fixes: FixOperation[]
): void {
for (const error of validationResult.errors) {
// Check for errors with the WRONG_NODE_TYPE_FOR_AI_TOOL code
// ValidationIssue interface includes optional code and fix properties
if (error.code !== 'WRONG_NODE_TYPE_FOR_AI_TOOL' || !error.fix) {
continue;
}
const fix = error.fix;
if (fix.type !== 'tool-variant-correction') {
continue;
}
const nodeName = error.nodeName || error.nodeId;
if (!nodeName) continue;
const node = nodeMap.get(nodeName);
if (!node) continue;
// Create the fix record
fixes.push({
node: nodeName,
field: 'type',
type: 'tool-variant-correction',
before: fix.currentType,
after: fix.suggestedType,
confidence: 'high', // This is a direct match - we know exactly which type to use
description: fix.description || `Replace "${fix.currentType}" with Tool variant "${fix.suggestedType}"`
});
// Create the update operation
const operation: UpdateNodeOperation = {
type: 'updateNode',
nodeId: nodeName,
updates: {
type: fix.suggestedType
}
};
operations.push(operation);
logger.info(`Generated tool variant correction for ${nodeName}: ${fix.currentType}${fix.suggestedType}`);
}
}
/**
* Set a nested value in an object using a path array
* Includes validation to prevent silent failures
@@ -676,8 +607,7 @@ export class WorkflowAutoFixer {
'node-type-correction': 0,
'webhook-missing-path': 0,
'typeversion-upgrade': 0,
'version-migration': 0,
'tool-variant-correction': 0
'version-migration': 0
},
byConfidence: {
'high': 0,
@@ -726,9 +656,6 @@ export class WorkflowAutoFixer {
if (stats.byType['version-migration'] > 0) {
parts.push(`${stats.byType['version-migration']} version ${stats.byType['version-migration'] === 1 ? 'migration' : 'migrations'}`);
}
if (stats.byType['tool-variant-correction'] > 0) {
parts.push(`${stats.byType['tool-variant-correction']} tool variant ${stats.byType['tool-variant-correction'] === 1 ? 'correction' : 'corrections'}`);
}
if (parts.length === 0) {
return `Fixed ${stats.total} ${stats.total === 1 ? 'issue' : 'issues'}`;

View File

@@ -897,13 +897,13 @@ export class WorkflowDiffEngine {
// Workflow activation operation validators
private validateActivateWorkflow(workflow: Workflow, operation: ActivateWorkflowOperation): string | null {
// Check if workflow has at least one activatable trigger
// NOTE: Since n8n 2.0, executeWorkflowTrigger is activatable and MUST be activated to work
// Issue #351: executeWorkflowTrigger cannot activate workflows
const activatableTriggers = workflow.nodes.filter(
node => !node.disabled && isActivatableTrigger(node.type)
);
if (activatableTriggers.length === 0) {
return 'Cannot activate workflow: No activatable trigger nodes found. Workflows must have at least one enabled trigger node (webhook, schedule, executeWorkflowTrigger, etc.).';
return 'Cannot activate workflow: No activatable trigger nodes found. Workflows must have at least one enabled trigger node (webhook, schedule, email, etc.). Note: executeWorkflowTrigger cannot activate workflows as they can only be invoked by other workflows.';
}
return null;

View File

@@ -12,10 +12,8 @@ import { NodeSimilarityService, NodeSuggestion } from './node-similarity-service
import { NodeTypeNormalizer } from '../utils/node-type-normalizer';
import { Logger } from '../utils/logger';
import { validateAISpecificNodes, hasAINodes } from './ai-node-validator';
import { isAIToolSubNode } from './ai-tool-validators';
import { isTriggerNode } from '../utils/node-type-utils';
import { isNonExecutableNode } from '../utils/node-classification';
import { ToolVariantGenerator } from './tool-variant-generator';
const logger = new Logger({ prefix: '[WorkflowValidator]' });
interface WorkflowNode {
@@ -56,19 +54,12 @@ interface WorkflowJson {
meta?: any;
}
export interface ValidationIssue {
interface ValidationIssue {
type: 'error' | 'warning';
nodeId?: string;
nodeName?: string;
message: string;
details?: any;
code?: string;
fix?: {
type: string;
currentType?: string;
suggestedType?: string;
description?: string;
};
}
export interface WorkflowValidationResult {
@@ -495,14 +486,9 @@ export class WorkflowValidator {
}
// Validate node configuration
// Add @version to parameters for displayOptions evaluation (supports _cnd operators)
const paramsWithVersion = {
'@version': node.typeVersion || 1,
...node.parameters
};
const nodeValidation = this.nodeValidator.validateWithMode(
node.type,
paramsWithVersion,
node.parameters,
nodeInfo.properties || [],
'operation',
profile as any
@@ -599,9 +585,6 @@ export class WorkflowValidator {
// Check AI tool outputs
if (outputs.ai_tool) {
// Validate that the source node can actually output ai_tool
this.validateAIToolSource(sourceNode, result);
this.validateConnectionOutputs(
sourceName,
outputs.ai_tool,
@@ -875,83 +858,6 @@ export class WorkflowValidator {
}
}
/**
* Validate that a node can actually output ai_tool connections.
*
* Valid ai_tool sources are:
* 1. Langchain tool nodes (in AI_TOOL_VALIDATORS)
* 2. Tool variant nodes (e.g., nodes-base.supabaseTool)
*
* If a base node (e.g., nodes-base.supabase) is used with ai_tool connection
* but it has a Tool variant available, this is an error.
*/
private validateAIToolSource(
sourceNode: WorkflowNode,
result: WorkflowValidationResult
): void {
const normalizedType = NodeTypeNormalizer.normalizeToFullForm(sourceNode.type);
// Check if it's a known langchain tool node
if (isAIToolSubNode(normalizedType)) {
return; // Valid - it's a langchain tool
}
// Get node info from repository (single lookup, reused below)
const nodeInfo = this.nodeRepository.getNode(normalizedType);
// Check if it's a Tool variant (ends with Tool and is in database as isToolVariant)
if (ToolVariantGenerator.isToolVariantNodeType(normalizedType)) {
// It looks like a Tool variant, verify it exists in database
if (nodeInfo?.isToolVariant) {
return; // Valid - it's a Tool variant
}
}
if (!nodeInfo) {
// Node not found in database - might be a community node or unknown
// Don't error here, let other validation handle unknown nodes
return;
}
// Check if this is a base node that has a Tool variant available
if (nodeInfo.hasToolVariant) {
const toolVariantType = ToolVariantGenerator.getToolVariantNodeType(normalizedType);
const workflowToolVariantType = NodeTypeNormalizer.toWorkflowFormat(toolVariantType);
result.errors.push({
type: 'error',
nodeId: sourceNode.id,
nodeName: sourceNode.name,
message: `Node "${sourceNode.name}" uses "${sourceNode.type}" which cannot output ai_tool connections. ` +
`Use the Tool variant "${workflowToolVariantType}" instead for AI Agent integration.`,
code: 'WRONG_NODE_TYPE_FOR_AI_TOOL',
fix: {
type: 'tool-variant-correction',
currentType: sourceNode.type,
suggestedType: workflowToolVariantType,
description: `Change node type from "${sourceNode.type}" to "${workflowToolVariantType}"`
}
});
return;
}
// Check if it's an AI-capable node (isAITool flag) but not a Tool variant
if (nodeInfo.isAITool) {
// This node is AI-capable, which is fine for ai_tool connections
return;
}
// Node is not valid for ai_tool connections
result.errors.push({
type: 'error',
nodeId: sourceNode.id,
nodeName: sourceNode.name,
message: `Node "${sourceNode.name}" of type "${sourceNode.type}" cannot output ai_tool connections. ` +
`Only AI tool nodes (e.g., Calculator, HTTP Request Tool) or Tool variants (e.g., *Tool suffix nodes) can be connected to AI Agents as tools.`,
code: 'INVALID_AI_TOOL_SOURCE'
});
}
/**
* Check if workflow has cycles
* Allow legitimate loops for SplitInBatches and similar loop nodes

View File

@@ -321,7 +321,7 @@ export interface McpToolResponse {
}
// Execution Filtering Types
export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full' | 'error';
export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full';
export interface ExecutionPreview {
totalNodes: number;
@@ -354,10 +354,6 @@ export interface ExecutionFilterOptions {
itemsLimit?: number;
includeInputData?: boolean;
fieldsToInclude?: string[];
// Error mode specific options
errorItemsLimit?: number; // Sample items from upstream node (default: 2)
includeStackTrace?: boolean; // Include full stack trace (default: false)
includeExecutionPath?: boolean; // Include execution path to error (default: true)
}
export interface FilteredExecutionResponse {
@@ -385,9 +381,6 @@ export interface FilteredExecutionResponse {
// Error information
error?: Record<string, unknown>;
// Error mode specific (mode='error')
errorInfo?: ErrorAnalysis;
}
export interface FilteredNodeData {
@@ -405,51 +398,4 @@ export interface FilteredNodeData {
truncated: boolean;
};
};
}
// Error Mode Types
export interface ErrorAnalysis {
// Primary error information
primaryError: {
message: string;
errorType: string; // NodeOperationError, NodeApiError, etc.
nodeName: string;
nodeType: string;
nodeId?: string;
nodeParameters?: Record<string, unknown>; // Relevant params only (no secrets)
stackTrace?: string; // Truncated by default
};
// Upstream context (input to error node)
upstreamContext?: {
nodeName: string;
nodeType: string;
itemCount: number;
sampleItems: unknown[]; // Configurable limit, default 2
dataStructure: Record<string, unknown>;
};
// Execution path leading to error (from trigger to error)
executionPath?: Array<{
nodeName: string;
status: 'success' | 'error' | 'skipped';
itemCount: number;
executionTime?: number;
}>;
// Additional errors (if workflow had multiple failures)
additionalErrors?: Array<{
nodeName: string;
message: string;
}>;
// AI-friendly suggestions
suggestions?: ErrorSuggestion[];
}
export interface ErrorSuggestion {
type: 'fix' | 'investigate' | 'workaround';
title: string;
description: string;
confidence: 'high' | 'medium' | 'low';
}

View File

@@ -231,42 +231,4 @@ export class NodeTypeNormalizer {
type.startsWith('nodes-langchain.')
);
}
/**
* Convert short database format to full n8n workflow format.
*
* This method converts node types from the SHORT form used in the database
* to the FULL form required by the n8n API.
*
* @param type - Node type in short database format (e.g., 'nodes-base.webhook')
* @returns Node type in full workflow format (e.g., 'n8n-nodes-base.webhook')
*
* @example
* toWorkflowFormat('nodes-base.webhook')
* // → 'n8n-nodes-base.webhook'
*
* @example
* toWorkflowFormat('nodes-langchain.agent')
* // → '@n8n/n8n-nodes-langchain.agent'
*
* @example
* toWorkflowFormat('n8n-nodes-base.webhook')
* // → 'n8n-nodes-base.webhook' (already in full format)
*/
static toWorkflowFormat(type: string): string {
if (!type || typeof type !== 'string') {
return type;
}
// Convert short form to full form (API/workflow format)
if (type.startsWith('nodes-base.')) {
return type.replace(/^nodes-base\./, 'n8n-nodes-base.');
}
if (type.startsWith('nodes-langchain.')) {
return type.replace(/^nodes-langchain\./, '@n8n/n8n-nodes-langchain.');
}
// Already in full form or community node - return unchanged
return type;
}
}

View File

@@ -183,7 +183,7 @@ export function isTriggerNode(nodeType: string): boolean {
}
/**
* Check if a node is an ACTIVATABLE trigger
* Check if a node is an ACTIVATABLE trigger (excludes executeWorkflowTrigger)
*
* This function determines if a node can be used to activate a workflow.
* Returns true for:
@@ -191,18 +191,25 @@ export function isTriggerNode(nodeType: string): boolean {
* - Time-based triggers (schedule, cron)
* - Poll-based triggers (emailTrigger, slackTrigger, etc.)
* - Manual triggers (manualTrigger, start, formTrigger)
* - Sub-workflow triggers (executeWorkflowTrigger) - requires activation in n8n 2.0+
*
* Returns FALSE for:
* - executeWorkflowTrigger (can only be invoked by other workflows)
*
* Used for: Activation validation (active workflows need activatable triggers)
*
* NOTE: Since n8n 2.0, executeWorkflowTrigger workflows MUST be activated to work.
* This is a breaking change from pre-2.0 behavior.
*
* @param nodeType - The node type to check
* @returns true if node can activate a workflow
*/
export function isActivatableTrigger(nodeType: string): boolean {
// All trigger nodes can activate workflows (including executeWorkflowTrigger in n8n 2.0+)
const normalized = normalizeNodeType(nodeType);
const lowerType = normalized.toLowerCase();
// executeWorkflowTrigger cannot activate a workflow (invoked by other workflows)
if (lowerType.includes('executeworkflow')) {
return false;
}
// All other triggers can activate workflows
return isTriggerNode(nodeType);
}

View File

@@ -175,18 +175,14 @@ describe.skipIf(!dbExists)('Database Content Validation', () => {
).toBeGreaterThan(100); // Should have ~108 triggers
});
it('MUST have templates table populated', () => {
it('MUST have templates table (optional but recommended)', () => {
const templatesCount = db.prepare('SELECT COUNT(*) as count FROM templates').get();
expect(templatesCount.count,
'CRITICAL: Templates table is EMPTY! Templates are required for search_templates MCP tool and real-world examples. ' +
'Run: npm run fetch:templates OR restore from git history.'
).toBeGreaterThan(0);
expect(templatesCount.count,
`WARNING: Expected at least 2500 templates, got ${templatesCount.count}. ` +
'Templates may have been partially lost. Run: npm run fetch:templates'
).toBeGreaterThanOrEqual(2500);
if (templatesCount.count === 0) {
console.warn('WARNING: No workflow templates found. Run: npm run fetch:templates');
}
// This is not critical, so we don't fail the test
expect(templatesCount.count).toBeGreaterThanOrEqual(0);
});
});

View File

@@ -348,8 +348,8 @@ describe('MCP Performance Tests', () => {
console.log(`Memory increase after large operations: ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`);
// Should not retain excessive memory (30MB threshold accounts for CI variability)
expect(memoryIncrease).toBeLessThan(30 * 1024 * 1024);
// Should not retain excessive memory
expect(memoryIncrease).toBeLessThan(20 * 1024 * 1024);
});
});

Some files were not shown because too many files have changed in this diff Show More