diff --git a/data/nodes.db b/data/nodes.db index 4bcc122..ea61912 100644 Binary files a/data/nodes.db and b/data/nodes.db differ diff --git a/scripts/migrate-tool-docs.ts b/scripts/migrate-tool-docs.ts new file mode 100644 index 0000000..d2bce85 --- /dev/null +++ b/scripts/migrate-tool-docs.ts @@ -0,0 +1,146 @@ +#!/usr/bin/env tsx +import * as fs from 'fs'; +import * as path from 'path'; + +// This is a helper script to migrate tool documentation to the new structure +// It creates a template file for each tool that needs to be migrated + +const toolsByCategory = { + discovery: [ + 'search_nodes', + 'list_nodes', + 'list_ai_tools', + 'get_database_statistics' + ], + configuration: [ + 'get_node_info', + 'get_node_essentials', + 'get_node_documentation', + 'search_node_properties', + 'get_node_as_tool_info', + 'get_property_dependencies' + ], + validation: [ + 'validate_node_minimal', + 'validate_node_operation', + 'validate_workflow', + 'validate_workflow_connections', + 'validate_workflow_expressions' + ], + templates: [ + 'get_node_for_task', + 'list_tasks', + 'list_node_templates', + 'get_template', + 'search_templates', + 'get_templates_for_task' + ], + workflow_management: [ + 'n8n_create_workflow', + 'n8n_get_workflow', + 'n8n_get_workflow_details', + 'n8n_get_workflow_structure', + 'n8n_get_workflow_minimal', + 'n8n_update_full_workflow', + 'n8n_update_partial_workflow', + 'n8n_delete_workflow', + 'n8n_list_workflows', + 'n8n_validate_workflow', + 'n8n_trigger_webhook_workflow', + 'n8n_get_execution', + 'n8n_list_executions', + 'n8n_delete_execution' + ], + system: [ + 'tools_documentation', + 'n8n_diagnostic', + 'n8n_health_check', + 'n8n_list_available_tools' + ], + special: [ + 'code_node_guide' + ] +}; + +const template = (toolName: string, category: string) => `import { ToolDocumentation } from '../types'; + +export const ${toCamelCase(toolName)}Doc: ToolDocumentation = { + name: '${toolName}', + category: '${category}', + essentials: { + description: 'TODO: Add description from old file', + keyParameters: ['TODO'], + example: '${toolName}({TODO})', + performance: 'TODO', + tips: [ + 'TODO: Add tips' + ] + }, + full: { + description: 'TODO: Add full description', + parameters: { + // TODO: Add parameters + }, + returns: 'TODO: Add return description', + examples: [ + '${toolName}({TODO}) - TODO' + ], + useCases: [ + 'TODO: Add use cases' + ], + performance: 'TODO: Add performance description', + bestPractices: [ + 'TODO: Add best practices' + ], + pitfalls: [ + 'TODO: Add pitfalls' + ], + relatedTools: ['TODO'] + } +};`; + +function toCamelCase(str: string): string { + return str.split('_').map((part, index) => + index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1) + ).join(''); +} + +function toKebabCase(str: string): string { + return str.replace(/_/g, '-'); +} + +// Create template files for tools that don't exist yet +Object.entries(toolsByCategory).forEach(([category, tools]) => { + tools.forEach(toolName => { + const fileName = toKebabCase(toolName) + '.ts'; + const filePath = path.join('src/mcp/tool-docs', category, fileName); + + // Skip if file already exists + if (fs.existsSync(filePath)) { + console.log(`✓ ${filePath} already exists`); + return; + } + + // Create the file with template + fs.writeFileSync(filePath, template(toolName, category)); + console.log(`✨ Created ${filePath}`); + }); + + // Create index file for the category + const indexPath = path.join('src/mcp/tool-docs', category, 'index.ts'); + if (!fs.existsSync(indexPath)) { + const indexContent = tools.map(toolName => + `export { ${toCamelCase(toolName)}Doc } from './${toKebabCase(toolName)}';` + ).join('\n'); + + fs.writeFileSync(indexPath, indexContent); + console.log(`✨ Created ${indexPath}`); + } +}); + +console.log('\n📝 Migration templates created!'); +console.log('Next steps:'); +console.log('1. Copy documentation from the old tools-documentation.ts file'); +console.log('2. Update each template file with the actual documentation'); +console.log('3. Update src/mcp/tool-docs/index.ts to import all tools'); +console.log('4. Replace the old tools-documentation.ts with the new one'); \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/get-node-as-tool-info.ts b/src/mcp/tool-docs/configuration/get-node-as-tool-info.ts new file mode 100644 index 0000000..12a5e1f --- /dev/null +++ b/src/mcp/tool-docs/configuration/get-node-as-tool-info.ts @@ -0,0 +1,71 @@ +import { ToolDocumentation } from '../types'; + +export const getNodeAsToolInfoDoc: ToolDocumentation = { + name: 'get_node_as_tool_info', + category: 'configuration', + essentials: { + description: 'Explains how to use ANY node as an AI tool with requirements and examples.', + keyParameters: ['nodeType'], + example: 'get_node_as_tool_info({nodeType: "nodes-base.slack"})', + performance: 'Fast - returns guidance and examples', + tips: [ + 'ANY node can be used as AI tool, not just AI-marked ones', + 'Community nodes need N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true', + 'Provides specific use cases and connection requirements' + ] + }, + full: { + description: `Shows how to use any n8n node as an AI tool in AI Agent workflows. In n8n, ANY node can be connected to an AI Agent's tool port, allowing the AI to use that node's functionality. This tool provides specific guidance, requirements, and examples for using a node as an AI tool.`, + parameters: { + nodeType: { + type: 'string', + required: true, + description: 'Full node type WITH prefix: "nodes-base.slack", "nodes-base.googleSheets", etc.', + examples: [ + 'nodes-base.slack', + 'nodes-base.httpRequest', + 'nodes-base.googleSheets', + 'nodes-langchain.documentLoader' + ] + } + }, + returns: `Object containing: +- nodeType: The node's full type identifier +- displayName: Human-readable name +- isMarkedAsAITool: Whether node has usableAsTool property +- aiToolCapabilities: Detailed AI tool usage information including: + - canBeUsedAsTool: Always true in n8n + - requiresEnvironmentVariable: For community nodes + - commonUseCases: Specific AI tool use cases + - requirements: Connection and environment setup + - examples: Code examples for common scenarios + - tips: Best practices for AI tool usage`, + examples: [ + 'get_node_as_tool_info({nodeType: "nodes-base.slack"}) - Get AI tool guidance for Slack', + 'get_node_as_tool_info({nodeType: "nodes-base.httpRequest"}) - Learn to use HTTP Request as AI tool', + 'get_node_as_tool_info({nodeType: "nodes-base.postgres"}) - Database queries as AI tools' + ], + useCases: [ + 'Understanding how to connect any node to AI Agent', + 'Learning environment requirements for community nodes', + 'Getting specific use case examples for AI tool usage', + 'Checking if a node is optimized for AI usage', + 'Understanding credential requirements for AI tools' + ], + performance: 'Very fast - returns pre-computed guidance and examples', + bestPractices: [ + 'Use this before configuring nodes as AI tools', + 'Check environment requirements for community nodes', + 'Review common use cases to understand best applications', + 'Test nodes independently before connecting to AI Agent', + 'Give tools descriptive names in AI Agent configuration' + ], + pitfalls: [ + 'Community nodes require environment variable to be used as tools', + 'Not all nodes make sense as AI tools (e.g., triggers)', + 'Some nodes require specific credentials configuration', + 'Tool descriptions in AI Agent must be clear and detailed' + ], + relatedTools: ['list_ai_tools', 'get_node_essentials', 'validate_node_operation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/get-node-documentation.ts b/src/mcp/tool-docs/configuration/get-node-documentation.ts new file mode 100644 index 0000000..9b01d8c --- /dev/null +++ b/src/mcp/tool-docs/configuration/get-node-documentation.ts @@ -0,0 +1,45 @@ +import { ToolDocumentation } from '../types'; + +export const getNodeDocumentationDoc: ToolDocumentation = { + name: 'get_node_documentation', + category: 'configuration', + essentials: { + description: 'Get readable docs with examples/auth/patterns. Better than raw schema! 87% coverage. Format: "nodes-base.slack"', + keyParameters: ['nodeType'], + example: 'get_node_documentation({nodeType: "nodes-base.slack"})', + performance: 'Fast - pre-parsed', + tips: [ + '87% coverage', + 'Includes auth examples', + 'Human-readable format' + ] + }, + full: { + description: 'Returns human-readable documentation parsed from n8n-docs including examples, authentication setup, and common patterns. More useful than raw schema for understanding node usage.', + parameters: { + nodeType: { type: 'string', required: true, description: 'Full node type with prefix (e.g., "nodes-base.slack")' } + }, + returns: 'Parsed markdown documentation with examples, authentication guides, common patterns', + examples: [ + 'get_node_documentation({nodeType: "nodes-base.slack"}) - Slack usage guide', + 'get_node_documentation({nodeType: "nodes-base.googleSheets"}) - Sheets examples' + ], + useCases: [ + 'Understanding authentication setup', + 'Finding usage examples', + 'Learning common patterns' + ], + performance: 'Fast - Pre-parsed documentation stored in database', + bestPractices: [ + 'Use for learning node usage', + 'Check coverage with get_database_statistics', + 'Combine with get_node_essentials' + ], + pitfalls: [ + 'Not all nodes have docs (87% coverage)', + 'May be outdated for new features', + 'Requires full node type prefix' + ], + relatedTools: ['get_node_info', 'get_node_essentials', 'search_nodes'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/get-node-essentials.ts b/src/mcp/tool-docs/configuration/get-node-essentials.ts new file mode 100644 index 0000000..0b5e08b --- /dev/null +++ b/src/mcp/tool-docs/configuration/get-node-essentials.ts @@ -0,0 +1,40 @@ +import { ToolDocumentation } from '../types'; + +export const getNodeEssentialsDoc: ToolDocumentation = { + name: 'get_node_essentials', + category: 'configuration', + essentials: { + description: 'Get 10-20 key properties with examples (<5KB)', + keyParameters: ['nodeType'], + example: 'get_node_essentials("nodes-base.slack")', + performance: 'Fast (<5KB response)', + tips: [ + 'Use this first - has examples' + ] + }, + full: { + description: 'Curated essential properties only. 95% smaller than full schema, includes examples.', + parameters: { + nodeType: { type: 'string', description: 'e.g., "nodes-base.slack"', required: true } + }, + returns: 'Essential properties, examples, common patterns', + examples: [ + 'get_node_essentials("nodes-base.httpRequest")' + ], + useCases: [ + 'Quick node configuration', + 'Getting examples', + 'Learning basics' + ], + performance: 'Fast - minimal data', + bestPractices: [ + 'Always use before get_node_info', + 'Copy examples as starting point' + ], + pitfalls: [ + 'Advanced properties not included', + 'Use search_node_properties for specific needs' + ], + relatedTools: ['get_node_info', 'search_node_properties'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/get-node-info.ts b/src/mcp/tool-docs/configuration/get-node-info.ts new file mode 100644 index 0000000..d04efd4 --- /dev/null +++ b/src/mcp/tool-docs/configuration/get-node-info.ts @@ -0,0 +1,45 @@ +import { ToolDocumentation } from '../types'; + +export const getNodeInfoDoc: ToolDocumentation = { + name: 'get_node_info', + category: 'configuration', + essentials: { + description: 'Get FULL node schema (100KB+). TIP: Use get_node_essentials first! Returns all properties/operations/credentials. Prefix required: "nodes-base.httpRequest" not "httpRequest".', + keyParameters: ['nodeType'], + example: 'get_node_info({nodeType: "nodes-base.slack"})', + performance: 'Moderate - large responses', + tips: [ + 'Use get_node_essentials first', + 'Required: Full prefix "nodes-base."', + 'Returns entire schema' + ] + }, + full: { + description: 'Returns complete node JSON schema including all properties, operations, credentials, and metadata. Response size often exceeds 100KB. Always prefer get_node_essentials unless you need the complete schema.', + parameters: { + nodeType: { type: 'string', required: true, description: 'Full node type with prefix (e.g., "nodes-base.slack", "nodes-langchain.openAi")' } + }, + returns: 'Complete node JSON with type, displayName, description, properties, credentials, version info', + examples: [ + 'get_node_info({nodeType: "nodes-base.httpRequest"}) - Get HTTP Request node', + 'get_node_info({nodeType: "nodes-langchain.openAi"}) - Get OpenAI node' + ], + useCases: [ + 'Complete schema analysis', + 'Credential requirement discovery', + 'Advanced property exploration' + ], + performance: 'Moderate - Response size 50-500KB depending on node complexity', + bestPractices: [ + 'Always use get_node_essentials first', + 'Only use when complete schema needed', + 'Cache results for repeated access' + ], + pitfalls: [ + 'Response often exceeds 100KB', + 'Overwhelming for simple configurations', + 'Must include full prefix' + ], + relatedTools: ['get_node_essentials', 'search_node_properties', 'validate_node_operation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/get-property-dependencies.ts b/src/mcp/tool-docs/configuration/get-property-dependencies.ts new file mode 100644 index 0000000..6156254 --- /dev/null +++ b/src/mcp/tool-docs/configuration/get-property-dependencies.ts @@ -0,0 +1,79 @@ +import { ToolDocumentation } from '../types'; + +export const getPropertyDependenciesDoc: ToolDocumentation = { + name: 'get_property_dependencies', + category: 'configuration', + essentials: { + description: 'Shows property dependencies and visibility rules - which fields appear when.', + keyParameters: ['nodeType', 'config?'], + example: 'get_property_dependencies({nodeType: "nodes-base.httpRequest"})', + performance: 'Fast - analyzes property conditions', + tips: [ + 'Shows which properties depend on other property values', + 'Test visibility impact with optional config parameter', + 'Helps understand complex conditional property displays' + ] + }, + full: { + description: `Analyzes property dependencies and visibility conditions for a node. Shows which properties control the visibility of other properties (e.g., sendBody=true reveals body-related fields). Optionally test how a specific configuration affects property visibility.`, + parameters: { + nodeType: { + type: 'string', + required: true, + description: 'The node type to analyze (e.g., "nodes-base.httpRequest")', + examples: [ + 'nodes-base.httpRequest', + 'nodes-base.slack', + 'nodes-base.if', + 'nodes-base.switch' + ] + }, + config: { + type: 'object', + required: false, + description: 'Optional partial configuration to check visibility impact', + examples: [ + '{ method: "POST", sendBody: true }', + '{ operation: "create", resource: "contact" }', + '{ mode: "rules" }' + ] + } + }, + returns: `Object containing: +- nodeType: The analyzed node type +- displayName: Human-readable node name +- controllingProperties: Properties that control visibility of others +- dependentProperties: Properties whose visibility depends on others +- complexDependencies: Multi-condition dependencies +- currentConfig: If config provided, shows: + - providedValues: The configuration you passed + - visibilityImpact: Which properties are visible/hidden`, + examples: [ + 'get_property_dependencies({nodeType: "nodes-base.httpRequest"}) - Analyze HTTP Request dependencies', + 'get_property_dependencies({nodeType: "nodes-base.httpRequest", config: {sendBody: true}}) - Test visibility with sendBody enabled', + 'get_property_dependencies({nodeType: "nodes-base.if", config: {mode: "rules"}}) - Check If node in rules mode' + ], + useCases: [ + 'Understanding which properties control others', + 'Debugging why certain fields are not visible', + 'Building dynamic UIs that match n8n behavior', + 'Testing configurations before applying them', + 'Understanding complex node property relationships' + ], + performance: 'Fast - analyzes property metadata without database queries', + bestPractices: [ + 'Use before configuring complex nodes with many conditional fields', + 'Test different config values to understand visibility rules', + 'Check dependencies when properties seem to be missing', + 'Use for nodes with multiple operation modes (Slack, Google Sheets)', + 'Combine with search_node_properties to find specific fields' + ], + pitfalls: [ + 'Some properties have complex multi-condition dependencies', + 'Visibility rules can be nested (property A controls B which controls C)', + 'Not all hidden properties are due to dependencies (some are deprecated)', + 'Config parameter only tests visibility, does not validate values' + ], + relatedTools: ['search_node_properties', 'get_node_essentials', 'validate_node_operation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/index.ts b/src/mcp/tool-docs/configuration/index.ts new file mode 100644 index 0000000..09d00ff --- /dev/null +++ b/src/mcp/tool-docs/configuration/index.ts @@ -0,0 +1,6 @@ +export { getNodeInfoDoc } from './get-node-info'; +export { getNodeEssentialsDoc } from './get-node-essentials'; +export { getNodeDocumentationDoc } from './get-node-documentation'; +export { searchNodePropertiesDoc } from './search-node-properties'; +export { getNodeAsToolInfoDoc } from './get-node-as-tool-info'; +export { getPropertyDependenciesDoc } from './get-property-dependencies'; \ No newline at end of file diff --git a/src/mcp/tool-docs/configuration/search-node-properties.ts b/src/mcp/tool-docs/configuration/search-node-properties.ts new file mode 100644 index 0000000..0c0383a --- /dev/null +++ b/src/mcp/tool-docs/configuration/search-node-properties.ts @@ -0,0 +1,97 @@ +import { ToolDocumentation } from '../types'; + +export const searchNodePropertiesDoc: ToolDocumentation = { + name: 'search_node_properties', + category: 'configuration', + essentials: { + description: 'Find specific properties in a node without downloading all 200+ properties.', + keyParameters: ['nodeType', 'query'], + example: 'search_node_properties({nodeType: "nodes-base.httpRequest", query: "auth"})', + performance: 'Fast - searches indexed properties', + tips: [ + 'Search for "auth", "header", "body", "json", "credential"', + 'Returns property paths and descriptions', + 'Much faster than get_node_info for finding specific fields' + ] + }, + full: { + description: `Searches for specific properties within a node's configuration schema. Essential for finding authentication fields, headers, body parameters, or any specific property without downloading the entire node schema (which can be 100KB+). Returns matching properties with their paths, types, and descriptions.`, + parameters: { + nodeType: { + type: 'string', + required: true, + description: 'Full type with prefix', + examples: [ + 'nodes-base.httpRequest', + 'nodes-base.slack', + 'nodes-base.postgres', + 'nodes-base.googleSheets' + ] + }, + query: { + type: 'string', + required: true, + description: 'Property to find: "auth", "header", "body", "json"', + examples: [ + 'auth', + 'header', + 'body', + 'json', + 'credential', + 'timeout', + 'retry', + 'pagination' + ] + }, + maxResults: { + type: 'number', + required: false, + description: 'Max results (default 20)', + default: 20 + } + }, + returns: `Object containing: +- nodeType: The searched node type +- query: Your search term +- matches: Array of matching properties with: + - name: Property identifier + - displayName: Human-readable name + - type: Property type (string, number, options, etc.) + - description: Property description + - path: Full path to property (for nested properties) + - required: Whether property is required + - default: Default value if any + - options: Available options for selection properties + - showWhen: Visibility conditions +- totalMatches: Number of matches found +- searchedIn: Total properties searched`, + examples: [ + 'search_node_properties({nodeType: "nodes-base.httpRequest", query: "auth"}) - Find authentication fields', + 'search_node_properties({nodeType: "nodes-base.slack", query: "channel"}) - Find channel-related properties', + 'search_node_properties({nodeType: "nodes-base.postgres", query: "query"}) - Find query fields', + 'search_node_properties({nodeType: "nodes-base.webhook", query: "response"}) - Find response options' + ], + useCases: [ + 'Finding authentication/credential fields quickly', + 'Locating specific parameters without full node info', + 'Discovering header or body configuration options', + 'Finding nested properties in complex nodes', + 'Checking if a node supports specific features (retry, pagination, etc.)' + ], + performance: 'Very fast - searches pre-indexed property metadata', + bestPractices: [ + 'Use before get_node_info to find specific properties', + 'Search for common terms: auth, header, body, credential', + 'Check showWhen conditions to understand visibility', + 'Use with get_property_dependencies for complete understanding', + 'Limit results if you only need to check existence' + ], + pitfalls: [ + 'Some properties may be hidden due to visibility conditions', + 'Property names may differ from display names', + 'Nested properties show full path (e.g., "options.retry.limit")', + 'Search is case-sensitive for property names' + ], + relatedTools: ['get_node_essentials', 'get_property_dependencies', 'get_node_info'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/discovery/get-database-statistics.ts b/src/mcp/tool-docs/discovery/get-database-statistics.ts new file mode 100644 index 0000000..6342b04 --- /dev/null +++ b/src/mcp/tool-docs/discovery/get-database-statistics.ts @@ -0,0 +1,42 @@ +import { ToolDocumentation } from '../types'; + +export const getDatabaseStatisticsDoc: ToolDocumentation = { + name: 'get_database_statistics', + category: 'discovery', + essentials: { + description: 'Node stats: 525 total, 263 AI tools, 104 triggers, 87% docs coverage. Verifies MCP working.', + keyParameters: [], + example: 'get_database_statistics()', + performance: 'Instant', + tips: [ + 'Use to verify MCP connection', + 'Check doc coverage', + 'See AI tool counts' + ] + }, + full: { + description: 'Returns comprehensive database statistics including node counts, AI tool availability, trigger nodes, documentation coverage, and package distribution. Useful for verifying MCP connectivity.', + parameters: {}, + returns: 'Statistics object with total_nodes, ai_tools, triggers, docs_coverage, packages breakdown', + examples: [ + 'get_database_statistics() - Get all statistics' + ], + useCases: [ + 'Verify MCP is working', + 'Check documentation coverage', + 'Audit available nodes', + 'Monitor AI tool availability' + ], + performance: 'Instant - Pre-calculated statistics', + bestPractices: [ + 'Use to verify connection', + 'Check before bulk operations', + 'Monitor after database updates' + ], + pitfalls: [ + 'Stats cached until rebuild', + 'May not reflect runtime changes' + ], + relatedTools: ['list_nodes', 'list_ai_tools', 'search_nodes'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/discovery/index.ts b/src/mcp/tool-docs/discovery/index.ts new file mode 100644 index 0000000..b2d4a50 --- /dev/null +++ b/src/mcp/tool-docs/discovery/index.ts @@ -0,0 +1,4 @@ +export { searchNodesDoc } from './search-nodes'; +export { listNodesDoc } from './list-nodes'; +export { listAiToolsDoc } from './list-ai-tools'; +export { getDatabaseStatisticsDoc } from './get-database-statistics'; \ No newline at end of file diff --git a/src/mcp/tool-docs/discovery/list-ai-tools.ts b/src/mcp/tool-docs/discovery/list-ai-tools.ts new file mode 100644 index 0000000..5487bcc --- /dev/null +++ b/src/mcp/tool-docs/discovery/list-ai-tools.ts @@ -0,0 +1,24 @@ +import { ToolDocumentation } from '../types'; + +export const listAiToolsDoc: ToolDocumentation = { + name: 'list_ai_tools', + category: 'discovery', + essentials: { + description: 'List AI-optimized nodes. Note: ANY node can be AI tool! Connect any node to AI Agent\'s tool port. Community nodes need N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true.', + keyParameters: [], + example: 'list_ai_tools()', + performance: 'Fast query', + tips: ['ANY node works as AI tool'] + }, + full: { + description: 'List nodes marked as AI tools. IMPORTANT: Any n8n node can be used as AI tool by connecting to AI Agent\'s tool port.', + parameters: {}, + returns: 'Array of AI-optimized nodes with usage hints', + examples: ['list_ai_tools() - Get AI-optimized nodes'], + useCases: ['Find AI model integrations', 'Build agent toolchains'], + performance: 'Fast query, cached results', + bestPractices: ['Any node works as tool', 'Community nodes need env var'], + pitfalls: ['List not exhaustive - all nodes work'], + relatedTools: ['get_node_as_tool_info', 'search_nodes'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/discovery/list-nodes.ts b/src/mcp/tool-docs/discovery/list-nodes.ts new file mode 100644 index 0000000..255a1c9 --- /dev/null +++ b/src/mcp/tool-docs/discovery/list-nodes.ts @@ -0,0 +1,35 @@ +import { ToolDocumentation } from '../types'; + +export const listNodesDoc: ToolDocumentation = { + name: 'list_nodes', + category: 'discovery', + essentials: { + description: 'List n8n nodes. Common: list_nodes({limit:200}) for all, list_nodes({category:"trigger"}) for triggers. Package: "n8n-nodes-base" or "@n8n/n8n-nodes-langchain". Categories: trigger/transform/output/input.', + keyParameters: ['category', 'package', 'limit', 'isAITool'], + example: 'list_nodes({limit:200})', + performance: 'Fast query', + tips: ['limit:200+ for all'] + }, + full: { + description: 'List n8n nodes with filtering. Returns array of nodes with metadata.', + parameters: { + category: { type: 'string', description: 'trigger|transform|output|input|AI', required: false }, + package: { type: 'string', description: '"n8n-nodes-base" (core) or "@n8n/n8n-nodes-langchain" (AI)', required: false }, + limit: { type: 'number', description: 'Max results (default 50, use 200+ for all)', required: false }, + isAITool: { type: 'boolean', description: 'Filter AI-capable nodes', required: false }, + developmentStyle: { type: 'string', description: 'Usually "programmatic"', required: false } + }, + returns: 'Array with nodeType, displayName, description, category', + examples: [ + 'list_nodes({limit:200}) - All nodes', + 'list_nodes({category:"trigger"}) - Webhook, Schedule, etc.', + 'list_nodes({package:"@n8n/n8n-nodes-langchain"}) - AI/LangChain nodes', + 'list_nodes({isAITool:true}) - Nodes usable as AI tools' + ], + useCases: ['Browse by category', 'Find triggers', 'Get AI nodes'], + performance: 'Fast query, returns metadata only', + bestPractices: ['Use limit:200+ for full list', 'Category for focused search'], + pitfalls: ['No text search - use search_nodes'], + relatedTools: ['search_nodes', 'list_ai_tools'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/discovery/search-nodes.ts b/src/mcp/tool-docs/discovery/search-nodes.ts new file mode 100644 index 0000000..1b52bcd --- /dev/null +++ b/src/mcp/tool-docs/discovery/search-nodes.ts @@ -0,0 +1,45 @@ +import { ToolDocumentation } from '../types'; + +export const searchNodesDoc: ToolDocumentation = { + name: 'search_nodes', + category: 'discovery', + essentials: { + description: 'Search nodes by keyword. Common nodes ranked first.', + keyParameters: ['query', 'mode'], + example: 'search_nodes({query: "webhook"})', + performance: 'Fast (<20ms)', + tips: [ + 'OR=any word, AND=all words, FUZZY=typos', + 'Quotes for exact phrase' + ] + }, + full: { + description: 'Full-text search with relevance ranking. Common nodes (webhook, http) prioritized.', + parameters: { + query: { type: 'string', description: 'Use quotes for exact phrase', required: true }, + limit: { type: 'number', description: 'Default: 20', required: false }, + mode: { type: 'string', description: 'OR|AND|FUZZY', required: false } + }, + returns: 'Nodes array sorted by relevance', + examples: [ + 'search_nodes({query: "webhook"}) - Finds Webhook node', + 'search_nodes({query: "slak", mode: "FUZZY"}) - Finds Slack' + ], + useCases: [ + 'Finding nodes by keyword', + 'Typo-tolerant search', + 'Multi-word searches' + ], + performance: 'Fast - FTS5 search', + bestPractices: [ + 'Single words for best results', + 'FUZZY for uncertain spelling', + 'AND requires all terms anywhere' + ], + pitfalls: [ + 'AND searches all fields not just names', + 'Short queries + FUZZY = unexpected results' + ], + relatedTools: ['list_nodes', 'get_node_essentials'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/index.ts b/src/mcp/tool-docs/index.ts new file mode 100644 index 0000000..bc551ea --- /dev/null +++ b/src/mcp/tool-docs/index.ts @@ -0,0 +1,110 @@ +import { ToolDocumentation } from './types'; + +// Import all tool documentations +import { searchNodesDoc, listNodesDoc, listAiToolsDoc, getDatabaseStatisticsDoc } from './discovery'; +import { + getNodeEssentialsDoc, + getNodeInfoDoc, + getNodeDocumentationDoc, + searchNodePropertiesDoc, + getNodeAsToolInfoDoc, + getPropertyDependenciesDoc +} from './configuration'; +import { + validateNodeMinimalDoc, + validateNodeOperationDoc, + validateWorkflowDoc, + validateWorkflowConnectionsDoc, + validateWorkflowExpressionsDoc +} from './validation'; +import { + listTasksDoc, + getNodeForTaskDoc, + listNodeTemplatesDoc, + getTemplateDoc, + searchTemplatesDoc, + getTemplatesForTaskDoc +} from './templates'; +import { + toolsDocumentationDoc, + n8nDiagnosticDoc, + n8nHealthCheckDoc, + n8nListAvailableToolsDoc +} from './system'; +import { codeNodeGuideDoc } from './special'; +import { + n8nCreateWorkflowDoc, + n8nGetWorkflowDoc, + n8nGetWorkflowDetailsDoc, + n8nGetWorkflowStructureDoc, + n8nGetWorkflowMinimalDoc, + n8nUpdateFullWorkflowDoc, + n8nUpdatePartialWorkflowDoc, + n8nDeleteWorkflowDoc, + n8nListWorkflowsDoc, + n8nValidateWorkflowDoc, + n8nTriggerWebhookWorkflowDoc, + n8nGetExecutionDoc, + n8nListExecutionsDoc, + n8nDeleteExecutionDoc +} from './workflow_management'; + +// Combine all tool documentations into a single object +export const toolsDocumentation: Record = { + // System tools + tools_documentation: toolsDocumentationDoc, + n8n_diagnostic: n8nDiagnosticDoc, + n8n_health_check: n8nHealthCheckDoc, + n8n_list_available_tools: n8nListAvailableToolsDoc, + + // Special tools + code_node_guide: codeNodeGuideDoc, + + // Discovery tools + search_nodes: searchNodesDoc, + list_nodes: listNodesDoc, + list_ai_tools: listAiToolsDoc, + get_database_statistics: getDatabaseStatisticsDoc, + + // Configuration tools + get_node_essentials: getNodeEssentialsDoc, + get_node_info: getNodeInfoDoc, + get_node_documentation: getNodeDocumentationDoc, + search_node_properties: searchNodePropertiesDoc, + get_node_as_tool_info: getNodeAsToolInfoDoc, + get_property_dependencies: getPropertyDependenciesDoc, + + // Validation tools + validate_node_minimal: validateNodeMinimalDoc, + validate_node_operation: validateNodeOperationDoc, + validate_workflow: validateWorkflowDoc, + validate_workflow_connections: validateWorkflowConnectionsDoc, + validate_workflow_expressions: validateWorkflowExpressionsDoc, + + // Template tools + list_tasks: listTasksDoc, + get_node_for_task: getNodeForTaskDoc, + list_node_templates: listNodeTemplatesDoc, + get_template: getTemplateDoc, + search_templates: searchTemplatesDoc, + get_templates_for_task: getTemplatesForTaskDoc, + + // Workflow Management tools (n8n API) + n8n_create_workflow: n8nCreateWorkflowDoc, + n8n_get_workflow: n8nGetWorkflowDoc, + n8n_get_workflow_details: n8nGetWorkflowDetailsDoc, + n8n_get_workflow_structure: n8nGetWorkflowStructureDoc, + n8n_get_workflow_minimal: n8nGetWorkflowMinimalDoc, + n8n_update_full_workflow: n8nUpdateFullWorkflowDoc, + n8n_update_partial_workflow: n8nUpdatePartialWorkflowDoc, + n8n_delete_workflow: n8nDeleteWorkflowDoc, + n8n_list_workflows: n8nListWorkflowsDoc, + n8n_validate_workflow: n8nValidateWorkflowDoc, + n8n_trigger_webhook_workflow: n8nTriggerWebhookWorkflowDoc, + n8n_get_execution: n8nGetExecutionDoc, + n8n_list_executions: n8nListExecutionsDoc, + n8n_delete_execution: n8nDeleteExecutionDoc +}; + +// Re-export types +export type { ToolDocumentation } from './types'; \ No newline at end of file diff --git a/src/mcp/tool-docs/special/code-node-guide.ts b/src/mcp/tool-docs/special/code-node-guide.ts new file mode 100644 index 0000000..1cd465b --- /dev/null +++ b/src/mcp/tool-docs/special/code-node-guide.ts @@ -0,0 +1,59 @@ +import { ToolDocumentation } from '../types'; + +export const codeNodeGuideDoc: ToolDocumentation = { + name: 'code_node_guide', + category: 'special', + essentials: { + description: 'Get comprehensive guide for using Code nodes in n8n - JavaScript/Python execution, data access patterns, and common pitfalls', + keyParameters: [], + example: 'code_node_guide()', + performance: 'Instant (<10ms) - returns static guide', + tips: [ + 'Use $input.all() to access all items from previous nodes, not items[0]', + 'Return data in [{json: {...}}] format, not just plain objects', + 'External libraries (requests, pandas) not available - use built-in functions or JavaScript $helpers' + ] + }, + full: { + description: `Provides a comprehensive guide for using Code nodes in n8n workflows. This special tool returns detailed documentation about: + +- JavaScript and Python code execution in n8n +- Correct data access patterns ($input, $json, $node syntax) +- Available helper functions ($helpers.httpRequest, $jmespath, etc.) +- Common mistakes and how to avoid them +- Working with webhook data (critical: data is under .body property) +- Returning data in the correct format +- Limitations and security restrictions + +This guide is essential for AI agents configuring Code nodes, as it covers the most common issues and correct patterns.`, + parameters: {}, + returns: 'String containing a comprehensive Code node usage guide with examples and best practices', + examples: [ + 'code_node_guide() - Get the complete Code node guide', + '// Use this before configuring any Code node to understand correct patterns' + ], + useCases: [ + 'Learning how to access data from previous nodes correctly', + 'Understanding webhook data structure (body property nesting)', + 'Configuring JavaScript vs Python Code nodes', + 'Troubleshooting common Code node errors', + 'Understanding available helper functions and limitations' + ], + performance: 'Returns instantly - guide is pre-generated and cached', + bestPractices: [ + 'Always read this guide before configuring Code nodes', + 'Pay special attention to data access patterns - most errors come from incorrect syntax', + 'Remember webhook data is nested under .body, not at the root level', + 'Use JavaScript for HTTP requests ($helpers.httpRequest) as Python lacks external libraries', + 'Test with sample data to ensure correct output format' + ], + pitfalls: [ + 'Accessing webhook data incorrectly (forgetting .body nesting)', + 'Using items[0] instead of $input.all() for data access', + 'Returning plain objects instead of [{json: {...}}] format', + 'Trying to use external Python libraries (requests, pandas)', + 'Using expression syntax {{...}} inside Code nodes' + ], + relatedTools: ['get_node_essentials', 'validate_node_operation', 'get_node_for_task'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/special/index.ts b/src/mcp/tool-docs/special/index.ts new file mode 100644 index 0000000..75a3b1a --- /dev/null +++ b/src/mcp/tool-docs/special/index.ts @@ -0,0 +1 @@ +export { codeNodeGuideDoc } from './code-node-guide'; \ No newline at end of file diff --git a/src/mcp/tool-docs/system/index.ts b/src/mcp/tool-docs/system/index.ts new file mode 100644 index 0000000..561fb80 --- /dev/null +++ b/src/mcp/tool-docs/system/index.ts @@ -0,0 +1,4 @@ +export { toolsDocumentationDoc } from './tools-documentation'; +export { n8nDiagnosticDoc } from './n8n-diagnostic'; +export { n8nHealthCheckDoc } from './n8n-health-check'; +export { n8nListAvailableToolsDoc } from './n8n-list-available-tools'; \ No newline at end of file diff --git a/src/mcp/tool-docs/system/n8n-diagnostic.ts b/src/mcp/tool-docs/system/n8n-diagnostic.ts new file mode 100644 index 0000000..d10cd70 --- /dev/null +++ b/src/mcp/tool-docs/system/n8n-diagnostic.ts @@ -0,0 +1,79 @@ +import { ToolDocumentation } from '../types'; + +export const n8nDiagnosticDoc: ToolDocumentation = { + name: 'n8n_diagnostic', + category: 'system', + essentials: { + description: 'Diagnose n8n API configuration and troubleshoot why n8n management tools might not be working', + keyParameters: ['verbose'], + example: 'n8n_diagnostic({verbose: true})', + performance: 'Instant - checks environment and configuration only', + tips: [ + 'Run first when n8n tools are missing or failing - shows exact configuration issues', + 'Use verbose=true for detailed debugging info including environment variables', + 'If tools are missing, check that N8N_API_URL and N8N_API_KEY are configured' + ] + }, + full: { + description: `Comprehensive diagnostic tool for troubleshooting n8n API configuration and management tool availability. + +This tool performs a detailed check of: +- Environment variable configuration (N8N_API_URL, N8N_API_KEY) +- API connectivity and authentication +- Tool availability status +- Common configuration issues + +The diagnostic is essential when: +- n8n management tools aren't showing up in the available tools list +- API calls are failing with authentication or connection errors +- You need to verify your n8n instance configuration`, + parameters: { + verbose: { + type: 'boolean', + description: 'Include detailed debug information including full environment variables and API response details', + required: false, + default: false + } + }, + returns: `Diagnostic report object containing: +- status: Overall health status ('ok', 'error', 'not_configured') +- apiUrl: Detected API URL (or null if not configured) +- apiKeyStatus: Status of API key ('configured', 'missing', 'invalid') +- toolsAvailable: Number of n8n management tools available +- connectivity: API connectivity test results +- errors: Array of specific error messages +- suggestions: Array of actionable fix suggestions +- verbose: Additional debug information (if verbose=true)`, + examples: [ + 'n8n_diagnostic({}) - Quick diagnostic check', + 'n8n_diagnostic({verbose: true}) - Detailed diagnostic with environment info', + 'n8n_diagnostic({verbose: false}) - Standard diagnostic without sensitive data' + ], + useCases: [ + 'Initial setup verification after configuring N8N_API_URL and N8N_API_KEY', + 'Troubleshooting when n8n management tools are not available', + 'Debugging API connection failures or authentication errors', + 'Verifying n8n instance compatibility and feature availability', + 'Pre-deployment checks before using workflow management tools' + ], + performance: `Instant response time: +- No database queries +- Only checks environment and makes one test API call +- Verbose mode adds minimal overhead +- Safe to run frequently for monitoring`, + bestPractices: [ + 'Always run diagnostic first when encountering n8n tool issues', + 'Use verbose mode only in secure environments (may expose API URLs)', + 'Check diagnostic before attempting workflow operations', + 'Include diagnostic output when reporting issues', + 'Run after any configuration changes to verify setup' + ], + pitfalls: [ + 'Verbose mode may expose sensitive configuration details - use carefully', + 'Requires proper environment variables to detect n8n configuration', + 'API connectivity test requires network access to n8n instance', + 'Does not test specific workflow operations, only basic connectivity' + ], + relatedTools: ['n8n_health_check', 'n8n_list_available_tools', 'tools_documentation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/system/n8n-health-check.ts b/src/mcp/tool-docs/system/n8n-health-check.ts new file mode 100644 index 0000000..f5ffa40 --- /dev/null +++ b/src/mcp/tool-docs/system/n8n-health-check.ts @@ -0,0 +1,75 @@ +import { ToolDocumentation } from '../types'; + +export const n8nHealthCheckDoc: ToolDocumentation = { + name: 'n8n_health_check', + category: 'system', + essentials: { + description: 'Check n8n instance health, API connectivity, and available features', + keyParameters: [], + example: 'n8n_health_check({})', + performance: 'Fast - single API call to health endpoint', + tips: [ + 'Use before starting workflow operations to ensure n8n is responsive', + 'Check regularly in production environments for monitoring', + 'Returns version info and feature availability for compatibility checks' + ] + }, + full: { + description: `Performs a comprehensive health check of the configured n8n instance through its API. + +This tool verifies: +- API endpoint accessibility and response time +- n8n instance version and build information +- Authentication status and permissions +- Available features and enterprise capabilities +- Database connectivity (as reported by n8n) +- Queue system status (if configured) + +Health checks are crucial for: +- Monitoring n8n instance availability +- Detecting performance degradation +- Verifying API compatibility before operations +- Ensuring authentication is working correctly`, + parameters: {}, + returns: `Health status object containing: +- status: Overall health status ('healthy', 'degraded', 'error') +- version: n8n instance version information +- instanceId: Unique identifier for the n8n instance +- features: Object listing available features and their status +- apiVersion: API version for compatibility checking +- responseTime: API response time in milliseconds +- timestamp: Check timestamp +- details: Additional health metrics from n8n`, + examples: [ + 'n8n_health_check({}) - Standard health check', + '// Use in monitoring scripts\nconst health = await n8n_health_check({});\nif (health.status !== "healthy") alert("n8n is down!");', + '// Check before critical operations\nconst health = await n8n_health_check({});\nif (health.responseTime > 1000) console.warn("n8n is slow");' + ], + useCases: [ + 'Pre-flight checks before workflow deployments', + 'Continuous monitoring of n8n instance health', + 'Troubleshooting connectivity or performance issues', + 'Verifying n8n version compatibility with workflows', + 'Detecting feature availability (enterprise features, queue mode, etc.)' + ], + performance: `Fast response expected: +- Single HTTP request to /health endpoint +- Typically responds in <100ms for healthy instances +- Timeout after 10 seconds indicates severe issues +- Minimal server load - safe for frequent polling`, + bestPractices: [ + 'Run health checks before batch operations or deployments', + 'Set up automated monitoring with regular health checks', + 'Log response times to detect performance trends', + 'Check version compatibility when deploying workflows', + 'Use health status to implement circuit breaker patterns' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY to be configured', + 'Network issues may cause false negatives', + 'Does not check individual workflow health', + 'Health endpoint might be cached - not real-time for all metrics' + ], + relatedTools: ['n8n_diagnostic', 'n8n_list_available_tools', 'n8n_list_workflows'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/system/n8n-list-available-tools.ts b/src/mcp/tool-docs/system/n8n-list-available-tools.ts new file mode 100644 index 0000000..b8f3fcd --- /dev/null +++ b/src/mcp/tool-docs/system/n8n-list-available-tools.ts @@ -0,0 +1,73 @@ +import { ToolDocumentation } from '../types'; + +export const n8nListAvailableToolsDoc: ToolDocumentation = { + name: 'n8n_list_available_tools', + category: 'system', + essentials: { + description: 'List all available n8n management tools and their capabilities', + keyParameters: [], + example: 'n8n_list_available_tools({})', + performance: 'Instant - returns static tool list', + tips: [ + 'Shows only tools available with current API configuration', + 'If no n8n tools appear, run n8n_diagnostic to troubleshoot', + 'Tool availability depends on N8N_API_URL and N8N_API_KEY being set' + ] + }, + full: { + description: `Lists all available n8n management tools based on current configuration. + +This tool provides: +- Complete list of n8n management tools (when API is configured) +- Tool descriptions and capabilities +- Categorized tool listing (workflow, execution, system) +- Dynamic availability based on API configuration + +The tool list is dynamic: +- Shows 14+ management tools when N8N_API_URL and N8N_API_KEY are configured +- Shows only documentation tools when API is not configured +- Helps discover available functionality +- Provides quick reference for tool names and purposes`, + parameters: {}, + returns: `Object containing: +- tools: Array of available tool objects, each with: + - name: Tool identifier (e.g., 'n8n_create_workflow') + - description: Brief description of tool functionality + - category: Tool category ('workflow', 'execution', 'system') + - requiresApi: Whether tool needs API configuration +- categories: Summary count by category +- totalTools: Total number of available tools +- apiConfigured: Whether n8n API is configured`, + examples: [ + 'n8n_list_available_tools({}) - List all available tools', + '// Check for specific tool availability\nconst tools = await n8n_list_available_tools({});\nconst hasWorkflowTools = tools.tools.some(t => t.category === "workflow");', + '// Discover management capabilities\nconst result = await n8n_list_available_tools({});\nconsole.log(`${result.totalTools} tools available`);' + ], + useCases: [ + 'Discovering available n8n management capabilities', + 'Checking if API configuration is working correctly', + 'Finding the right tool for a specific task', + 'Generating help documentation or command lists', + 'Verifying tool availability before automation scripts' + ], + performance: `Instant response: +- No API calls required +- Returns pre-defined tool list +- Filtered based on configuration +- Zero network overhead`, + bestPractices: [ + 'Check tool availability before building automation workflows', + 'Use with n8n_diagnostic if expected tools are missing', + 'Reference tool names exactly as returned by this tool', + 'Group operations by category for better organization', + 'Cache results as tool list only changes with configuration' + ], + pitfalls: [ + 'Tool list is empty if N8N_API_URL and N8N_API_KEY are not set', + 'Does not validate if tools will actually work - just shows availability', + 'Tool names must be used exactly as returned', + 'Does not show tool parameters - use tools_documentation for details' + ], + relatedTools: ['n8n_diagnostic', 'n8n_health_check', 'tools_documentation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/system/tools-documentation.ts b/src/mcp/tool-docs/system/tools-documentation.ts new file mode 100644 index 0000000..5b35c73 --- /dev/null +++ b/src/mcp/tool-docs/system/tools-documentation.ts @@ -0,0 +1,44 @@ +import { ToolDocumentation } from '../types'; + +export const toolsDocumentationDoc: ToolDocumentation = { + name: 'tools_documentation', + category: 'system', + essentials: { + description: 'Get MCP tool docs. No params = overview.', + keyParameters: ['topic', 'depth'], + example: 'tools_documentation({topic: "search_nodes"})', + performance: 'Instant', + tips: [ + 'No params = quick start', + 'depth:"full" for details' + ] + }, + full: { + description: 'Get documentation for any MCP tool. Without params returns quick start guide. With topic returns tool-specific docs.', + parameters: { + topic: { type: 'string', description: 'Tool name or "overview"', required: false }, + depth: { type: 'string', description: '"essentials" or "full"', required: false } + }, + returns: 'Markdown documentation', + examples: [ + 'tools_documentation() - Quick start', + 'tools_documentation({topic: "search_nodes", depth: "full"}) - Full docs' + ], + useCases: [ + 'Learning tool usage', + 'Finding parameters', + 'Getting examples' + ], + performance: 'Instant', + bestPractices: [ + 'Start with no params', + 'Use essentials for quick lookup', + 'Full depth for debugging' + ], + pitfalls: [ + 'Tool names must match exactly', + 'Some features undocumented' + ], + relatedTools: ['n8n_list_available_tools', 'list_tasks'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/get-node-for-task.ts b/src/mcp/tool-docs/templates/get-node-for-task.ts new file mode 100644 index 0000000..0ac0d38 --- /dev/null +++ b/src/mcp/tool-docs/templates/get-node-for-task.ts @@ -0,0 +1,48 @@ +import { ToolDocumentation } from '../types'; + +export const getNodeForTaskDoc: ToolDocumentation = { + name: 'get_node_for_task', + category: 'templates', + essentials: { + description: 'Get pre-configured node for tasks: post_json_request, receive_webhook, query_database, send_slack_message, etc. Use list_tasks for all.', + keyParameters: ['task'], + example: 'get_node_for_task({task: "post_json_request"})', + performance: 'Instant', + tips: [ + 'Returns ready-to-use configuration', + 'See list_tasks for available tasks', + 'Includes credentials structure' + ] + }, + full: { + description: 'Returns pre-configured node settings for common automation tasks. Each configuration includes the correct node type, essential parameters, and credential requirements. Perfect for quickly setting up standard automations.', + parameters: { + task: { type: 'string', required: true, description: 'Task name from list_tasks (e.g., "post_json_request", "send_email")' } + }, + returns: 'Complete node configuration with type, displayName, parameters, credentials structure', + examples: [ + 'get_node_for_task({task: "post_json_request"}) - HTTP POST setup', + 'get_node_for_task({task: "receive_webhook"}) - Webhook receiver', + 'get_node_for_task({task: "send_slack_message"}) - Slack config' + ], + useCases: [ + 'Quick node configuration', + 'Learning proper node setup', + 'Standard automation patterns', + 'Credential structure reference' + ], + performance: 'Instant - Pre-configured templates', + bestPractices: [ + 'Use list_tasks to discover options', + 'Customize returned config as needed', + 'Check credential requirements', + 'Validate with validate_node_operation' + ], + pitfalls: [ + 'Templates may need customization', + 'Credentials must be configured separately', + 'Not all tasks available for all nodes' + ], + relatedTools: ['list_tasks', 'validate_node_operation', 'get_node_essentials'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/get-template.ts b/src/mcp/tool-docs/templates/get-template.ts new file mode 100644 index 0000000..5e5602b --- /dev/null +++ b/src/mcp/tool-docs/templates/get-template.ts @@ -0,0 +1,71 @@ +import { ToolDocumentation } from '../types'; + +export const getTemplateDoc: ToolDocumentation = { + name: 'get_template', + category: 'templates', + essentials: { + description: 'Get complete workflow JSON by ID. Ready to import. IDs from list_node_templates or search_templates.', + keyParameters: ['templateId'], + example: 'get_template({templateId: 1234})', + performance: 'Fast (<100ms) - single database lookup', + tips: [ + 'Get template IDs from list_node_templates or search_templates first', + 'Returns complete workflow JSON ready for import into n8n', + 'Includes all nodes, connections, and settings' + ] + }, + full: { + description: `Retrieves the complete workflow JSON for a specific template by its ID. The returned workflow can be directly imported into n8n through the UI or API. This tool fetches pre-built workflows from the community template library containing 399+ curated workflows.`, + parameters: { + templateId: { + type: 'number', + required: true, + description: 'The numeric ID of the template to retrieve. Get IDs from list_node_templates or search_templates' + } + }, + returns: `Returns an object containing: +- template: Complete template information including workflow JSON + - id: Template ID + - name: Template name + - description: What the workflow does + - author: Creator information (name, username, verified status) + - nodes: Array of node types used + - views: Number of times viewed + - created: Creation date + - url: Link to template on n8n.io + - workflow: Complete workflow JSON ready for import +- usage: Instructions for using the workflow`, + examples: [ + 'get_template({templateId: 1234}) - Get Slack notification workflow', + 'get_template({templateId: 5678}) - Get data sync workflow', + 'get_template({templateId: 9012}) - Get AI chatbot workflow' + ], + useCases: [ + 'Download workflows for direct import into n8n', + 'Study workflow patterns and best practices', + 'Get complete workflow JSON for customization', + 'Clone popular workflows for your use case', + 'Learn how complex automations are built' + ], + performance: `Fast performance with single database lookup: +- Query time: <10ms for template retrieval +- Workflow JSON parsing: <50ms +- Total response time: <100ms +- No network calls (uses local cache)`, + bestPractices: [ + 'Always check if template exists before attempting modifications', + 'Review workflow nodes before importing to ensure compatibility', + 'Save template JSON locally if planning multiple customizations', + 'Check template creation date for most recent patterns', + 'Verify all required credentials are configured before import' + ], + pitfalls: [ + 'Template IDs change when database is refreshed', + 'Some templates may use deprecated node versions', + 'Credentials in templates are placeholders - configure your own', + 'Not all templates work with all n8n versions', + 'Template may reference external services you don\'t have access to' + ], + relatedTools: ['list_node_templates', 'search_templates', 'get_templates_for_task', 'n8n_create_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/get-templates-for-task.ts b/src/mcp/tool-docs/templates/get-templates-for-task.ts new file mode 100644 index 0000000..1fb8b2f --- /dev/null +++ b/src/mcp/tool-docs/templates/get-templates-for-task.ts @@ -0,0 +1,74 @@ +import { ToolDocumentation } from '../types'; + +export const getTemplatesForTaskDoc: ToolDocumentation = { + name: 'get_templates_for_task', + category: 'templates', + essentials: { + description: 'Curated templates by task: ai_automation, data_sync, webhooks, email, slack, data_transform, files, scheduling, api, database.', + keyParameters: ['task'], + example: 'get_templates_for_task({task: "slack_integration"})', + performance: 'Fast (<100ms) - pre-categorized results', + tips: [ + 'Returns hand-picked templates for specific automation tasks', + 'Use list_tasks to see all available task categories', + 'Templates are curated for quality and relevance' + ] + }, + full: { + description: `Retrieves curated workflow templates for specific automation tasks. This tool provides hand-picked templates organized by common use cases, making it easy to find the right workflow for your needs. Each task category contains the most popular and effective templates for that particular automation scenario.`, + parameters: { + task: { + type: 'string', + required: true, + description: 'The type of task to get templates for. Options: ai_automation, data_sync, webhook_processing, email_automation, slack_integration, data_transformation, file_processing, scheduling, api_integration, database_operations' + } + }, + returns: `Returns an object containing: +- task: The requested task type +- templates: Array of curated templates + - id: Template ID + - name: Template name + - description: What the workflow does + - author: Creator information + - nodes: Array of node types used + - views: Popularity metric + - created: Creation date + - url: Link to template +- totalFound: Number of templates in this category +- availableTasks: List of all task categories (if no templates found)`, + examples: [ + 'get_templates_for_task({task: "slack_integration"}) - Get Slack automation workflows', + 'get_templates_for_task({task: "ai_automation"}) - Get AI-powered workflows', + 'get_templates_for_task({task: "data_sync"}) - Get data synchronization workflows', + 'get_templates_for_task({task: "webhook_processing"}) - Get webhook handler workflows', + 'get_templates_for_task({task: "email_automation"}) - Get email automation workflows' + ], + useCases: [ + 'Find workflows for specific business needs', + 'Discover best practices for common automations', + 'Get started quickly with pre-built solutions', + 'Learn patterns for specific integration types', + 'Browse curated collections of quality workflows' + ], + performance: `Excellent performance with pre-categorized templates: +- Query time: <10ms (indexed by task) +- No filtering needed (pre-curated) +- Returns 5-20 templates per category +- Total response time: <100ms`, + bestPractices: [ + 'Start with task-based search for faster results', + 'Review multiple templates to find best patterns', + 'Check template age for most current approaches', + 'Combine templates from same category for complex workflows', + 'Use returned node lists to understand requirements' + ], + pitfalls: [ + 'Not all tasks have many templates available', + 'Task categories are predefined - no custom categories', + 'Some templates may overlap between categories', + 'Curation is subjective - browse all results', + 'Templates may need updates for latest n8n features' + ], + relatedTools: ['search_templates', 'list_node_templates', 'get_template', 'list_tasks'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/index.ts b/src/mcp/tool-docs/templates/index.ts new file mode 100644 index 0000000..51ebc64 --- /dev/null +++ b/src/mcp/tool-docs/templates/index.ts @@ -0,0 +1,6 @@ +export { getNodeForTaskDoc } from './get-node-for-task'; +export { listTasksDoc } from './list-tasks'; +export { listNodeTemplatesDoc } from './list-node-templates'; +export { getTemplateDoc } from './get-template'; +export { searchTemplatesDoc } from './search-templates'; +export { getTemplatesForTaskDoc } from './get-templates-for-task'; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/list-node-templates.ts b/src/mcp/tool-docs/templates/list-node-templates.ts new file mode 100644 index 0000000..a88f72d --- /dev/null +++ b/src/mcp/tool-docs/templates/list-node-templates.ts @@ -0,0 +1,78 @@ +import { ToolDocumentation } from '../types'; + +export const listNodeTemplatesDoc: ToolDocumentation = { + name: 'list_node_templates', + category: 'templates', + essentials: { + description: 'Find templates using specific nodes. 399 community workflows. Use FULL types: "n8n-nodes-base.httpRequest".', + keyParameters: ['nodeTypes', 'limit'], + example: 'list_node_templates({nodeTypes: ["n8n-nodes-base.slack"]})', + performance: 'Fast (<100ms) - indexed node search', + tips: [ + 'Must use FULL node type with package prefix: "n8n-nodes-base.slack"', + 'Can search for multiple nodes to find workflows using all of them', + 'Returns templates sorted by popularity (view count)' + ] + }, + full: { + description: `Finds workflow templates that use specific n8n nodes. This is the best way to discover how particular nodes are used in real workflows. Search the community library of 399+ templates by specifying which nodes you want to see in action. Templates are sorted by popularity to show the most useful examples first.`, + parameters: { + nodeTypes: { + type: 'array', + required: true, + description: 'Array of node types to search for. Must use full type names with package prefix (e.g., ["n8n-nodes-base.httpRequest", "n8n-nodes-base.openAi"])' + }, + limit: { + type: 'number', + required: false, + description: 'Maximum number of templates to return. Default 10, max 100' + } + }, + returns: `Returns an object containing: +- templates: Array of matching templates + - id: Template ID for retrieval + - name: Template name + - description: What the workflow does + - author: Creator details (name, username, verified) + - nodes: Complete list of nodes used + - views: View count (popularity metric) + - created: Creation date + - url: Link to template on n8n.io +- totalFound: Total number of matching templates +- tip: Usage hints if no results`, + examples: [ + 'list_node_templates({nodeTypes: ["n8n-nodes-base.slack"]}) - Find all Slack workflows', + 'list_node_templates({nodeTypes: ["n8n-nodes-base.httpRequest", "n8n-nodes-base.postgres"]}) - Find workflows using both HTTP and Postgres', + 'list_node_templates({nodeTypes: ["@n8n/n8n-nodes-langchain.openAi"], limit: 20}) - Find AI workflows with OpenAI', + 'list_node_templates({nodeTypes: ["n8n-nodes-base.webhook", "n8n-nodes-base.respondToWebhook"]}) - Find webhook examples' + ], + useCases: [ + 'Learn how to use specific nodes through examples', + 'Find workflows combining particular integrations', + 'Discover patterns for node combinations', + 'See real-world usage of complex nodes', + 'Find templates for your exact tech stack' + ], + performance: `Optimized for node-based searches: +- Indexed by node type for fast lookups +- Query time: <50ms for single node +- Multiple nodes: <100ms (uses AND logic) +- Returns pre-sorted by popularity +- No full-text search needed`, + bestPractices: [ + 'Always use full node type with package prefix', + 'Search for core nodes that define the workflow purpose', + 'Start with single node searches, then refine', + 'Check node types with list_nodes if unsure of names', + 'Review multiple templates to learn different approaches' + ], + pitfalls: [ + 'Node types must match exactly - no partial matches', + 'Package prefix required: "slack" won\'t work, use "n8n-nodes-base.slack"', + 'Some nodes have version numbers: "n8n-nodes-base.httpRequestV3"', + 'Templates may use old node versions not in current n8n', + 'AND logic means all specified nodes must be present' + ], + relatedTools: ['get_template', 'search_templates', 'get_templates_for_task', 'list_nodes'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/list-tasks.ts b/src/mcp/tool-docs/templates/list-tasks.ts new file mode 100644 index 0000000..1a03d69 --- /dev/null +++ b/src/mcp/tool-docs/templates/list-tasks.ts @@ -0,0 +1,46 @@ +import { ToolDocumentation } from '../types'; + +export const listTasksDoc: ToolDocumentation = { + name: 'list_tasks', + category: 'templates', + essentials: { + description: 'List task templates by category: HTTP/API, Webhooks, Database, AI, Data Processing, Communication.', + keyParameters: ['category'], + example: 'list_tasks({category: "HTTP/API"})', + performance: 'Instant', + tips: [ + 'Categories: HTTP/API, Webhooks, Database, AI', + 'Shows pre-configured node settings', + 'Use get_node_for_task for details' + ] + }, + full: { + description: 'Lists available task templates organized by category. Each task represents a common automation pattern with pre-configured node settings. Categories include HTTP/API, Webhooks, Database, AI, Data Processing, and Communication.', + parameters: { + category: { type: 'string', description: 'Filter by category (optional)' } + }, + returns: 'Array of tasks with name, category, description, nodeType', + examples: [ + 'list_tasks() - Get all task templates', + 'list_tasks({category: "Database"}) - Database-related tasks', + 'list_tasks({category: "AI"}) - AI automation tasks' + ], + useCases: [ + 'Discover common automation patterns', + 'Find pre-configured solutions', + 'Learn node usage patterns', + 'Quick workflow setup' + ], + performance: 'Instant - Static task list', + bestPractices: [ + 'Browse all categories first', + 'Use get_node_for_task for config', + 'Combine multiple tasks in workflows' + ], + pitfalls: [ + 'Tasks are templates, customize as needed', + 'Not all nodes have task templates' + ], + relatedTools: ['get_node_for_task', 'search_templates', 'get_templates_for_task'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/templates/search-templates.ts b/src/mcp/tool-docs/templates/search-templates.ts new file mode 100644 index 0000000..b5007c4 --- /dev/null +++ b/src/mcp/tool-docs/templates/search-templates.ts @@ -0,0 +1,81 @@ +import { ToolDocumentation } from '../types'; + +export const searchTemplatesDoc: ToolDocumentation = { + name: 'search_templates', + category: 'templates', + essentials: { + description: 'Search templates by name/description keywords. NOT for node types! For nodes use list_node_templates. Example: "chatbot".', + keyParameters: ['query', 'limit'], + example: 'search_templates({query: "chatbot"})', + performance: 'Fast (<100ms) - FTS5 full-text search', + tips: [ + 'Searches template names and descriptions, NOT node types', + 'Use keywords like "automation", "sync", "notification"', + 'For node-specific search, use list_node_templates instead' + ] + }, + full: { + description: `Performs full-text search across workflow template names and descriptions. This tool is ideal for finding workflows based on their purpose or functionality rather than specific nodes used. It searches through the community library of 399+ templates using SQLite FTS5 for fast, fuzzy matching.`, + parameters: { + query: { + type: 'string', + required: true, + description: 'Search query for template names/descriptions. NOT for node types! Examples: "chatbot", "automation", "social media", "webhook". For node-based search use list_node_templates instead.' + }, + limit: { + type: 'number', + required: false, + description: 'Maximum number of results. Default 20, max 100' + } + }, + returns: `Returns an object containing: +- templates: Array of matching templates sorted by relevance + - id: Template ID for retrieval + - name: Template name (with match highlights) + - description: What the workflow does + - author: Creator information + - nodes: Array of all nodes used + - views: Popularity metric + - created: Creation date + - url: Link to template + - relevanceScore: Search match score +- totalFound: Total matching templates +- searchQuery: The processed search query +- tip: Helpful hints if no results`, + examples: [ + 'search_templates({query: "chatbot"}) - Find chatbot and conversational AI workflows', + 'search_templates({query: "email notification"}) - Find email alert workflows', + 'search_templates({query: "data sync"}) - Find data synchronization workflows', + 'search_templates({query: "webhook automation", limit: 30}) - Find webhook-based automations', + 'search_templates({query: "social media scheduler"}) - Find social posting workflows' + ], + useCases: [ + 'Find workflows by business purpose', + 'Discover automations for specific use cases', + 'Search by workflow functionality', + 'Find templates by problem they solve', + 'Explore workflows by industry or domain' + ], + performance: `Excellent performance with FTS5 indexing: +- Full-text search: <50ms for most queries +- Fuzzy matching enabled for typos +- Relevance-based sorting included +- Searches both title and description +- Returns highlighted matches`, + bestPractices: [ + 'Use descriptive keywords about the workflow purpose', + 'Try multiple related terms if first search has few results', + 'Combine terms for more specific results', + 'Check both name and description in results', + 'Use quotes for exact phrase matching' + ], + pitfalls: [ + 'Does NOT search by node types - use list_node_templates', + 'Search is case-insensitive but not semantic', + 'Very specific terms may return no results', + 'Descriptions may be brief - check full template', + 'Relevance scoring may not match your expectations' + ], + relatedTools: ['list_node_templates', 'get_templates_for_task', 'get_template', 'search_nodes'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/types.ts b/src/mcp/tool-docs/types.ts new file mode 100644 index 0000000..f8e919e --- /dev/null +++ b/src/mcp/tool-docs/types.ts @@ -0,0 +1,29 @@ +export interface ToolDocumentation { + name: string; + category: string; + essentials: { + description: string; + keyParameters: string[]; + example: string; + performance: string; + tips: string[]; + }; + full: { + description: string; + parameters: Record; + returns: string; + examples: string[]; + useCases: string[]; + performance: string; + bestPractices: string[]; + pitfalls: string[]; + relatedTools: string[]; + }; +} \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/index.ts b/src/mcp/tool-docs/validation/index.ts new file mode 100644 index 0000000..1a247da --- /dev/null +++ b/src/mcp/tool-docs/validation/index.ts @@ -0,0 +1,5 @@ +export { validateNodeMinimalDoc } from './validate-node-minimal'; +export { validateNodeOperationDoc } from './validate-node-operation'; +export { validateWorkflowDoc } from './validate-workflow'; +export { validateWorkflowConnectionsDoc } from './validate-workflow-connections'; +export { validateWorkflowExpressionsDoc } from './validate-workflow-expressions'; \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/validate-node-minimal.ts b/src/mcp/tool-docs/validation/validate-node-minimal.ts new file mode 100644 index 0000000..6eba21d --- /dev/null +++ b/src/mcp/tool-docs/validation/validate-node-minimal.ts @@ -0,0 +1,47 @@ +import { ToolDocumentation } from '../types'; + +export const validateNodeMinimalDoc: ToolDocumentation = { + name: 'validate_node_minimal', + category: 'validation', + essentials: { + description: 'Fast check for missing required fields only. No warnings/suggestions. Returns: list of missing fields.', + keyParameters: ['nodeType', 'config'], + example: 'validate_node_minimal("nodes-base.slack", {resource: "message"})', + performance: 'Instant', + tips: [ + 'Returns only missing required fields', + 'No warnings or suggestions', + 'Perfect for real-time validation' + ] + }, + full: { + description: 'Minimal validation that only checks for missing required fields. Returns array of missing field names without any warnings or suggestions. Ideal for quick validation during node configuration.', + parameters: { + nodeType: { type: 'string', required: true, description: 'Node type with prefix (e.g., "nodes-base.slack")' }, + config: { type: 'object', required: true, description: 'Node configuration to validate' } + }, + returns: 'Array of missing required field names (empty if valid)', + examples: [ + 'validate_node_minimal("nodes-base.slack", {resource: "message", operation: "post"}) - Check Slack config', + 'validate_node_minimal("nodes-base.httpRequest", {method: "GET"}) - Check HTTP config' + ], + useCases: [ + 'Real-time form validation', + 'Quick configuration checks', + 'Pre-deployment validation', + 'Interactive configuration builders' + ], + performance: 'Instant - Simple field checking without complex validation', + bestPractices: [ + 'Use for quick feedback loops', + 'Follow with validate_node_operation for thorough check', + 'Check return array length for validity' + ], + pitfalls: [ + 'Only checks required fields', + 'No type validation', + 'No operation-specific validation' + ], + relatedTools: ['validate_node_operation', 'get_node_essentials', 'get_property_dependencies'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/validate-node-operation.ts b/src/mcp/tool-docs/validation/validate-node-operation.ts new file mode 100644 index 0000000..9f88c03 --- /dev/null +++ b/src/mcp/tool-docs/validation/validate-node-operation.ts @@ -0,0 +1,49 @@ +import { ToolDocumentation } from '../types'; + +export const validateNodeOperationDoc: ToolDocumentation = { + name: 'validate_node_operation', + category: 'validation', + essentials: { + description: 'Validate node config. Checks required fields, types, operation rules. Returns errors with fixes. Essential for Slack/Sheets/DB nodes.', + keyParameters: ['nodeType', 'config', 'profile'], + example: 'validate_node_operation("nodes-base.slack", {resource: "message", operation: "post", text: "Hi"})', + performance: 'Fast', + tips: [ + 'Returns errors, warnings, fixes', + 'Operation-aware validation', + 'Use profiles: minimal/runtime/ai-friendly/strict' + ] + }, + full: { + description: 'Comprehensive node configuration validation with operation awareness. Validates required fields, types, operation-specific rules, and provides fix suggestions. Supports validation profiles for different use cases.', + parameters: { + nodeType: { type: 'string', required: true, description: 'Node type with prefix (e.g., "nodes-base.slack")' }, + config: { type: 'object', required: true, description: 'Configuration including operation fields (resource/operation/action)' }, + profile: { type: 'string', description: 'Validation profile: minimal/runtime/ai-friendly(default)/strict' } + }, + returns: 'Validation result with isValid, errors[], warnings[], suggestions[], fixes{}', + examples: [ + 'validate_node_operation("nodes-base.slack", {resource: "message", operation: "post", text: "Hello"}) - Validate Slack message', + 'validate_node_operation("nodes-base.httpRequest", {method: "POST", url: "{{$json.url}}"}, "strict") - Strict HTTP validation' + ], + useCases: [ + 'Pre-deployment validation', + 'Configuration debugging', + 'Operation-specific checks', + 'Fix suggestion generation' + ], + performance: 'Fast - Schema analysis with operation context', + bestPractices: [ + 'Include operation fields in config', + 'Use ai-friendly profile by default', + 'Apply suggested fixes', + 'Validate before workflow deployment' + ], + pitfalls: [ + 'Config must include operation fields', + 'Some fixes are suggestions only', + 'Profile affects strictness level' + ], + relatedTools: ['validate_node_minimal', 'get_node_essentials', 'validate_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/validate-workflow-connections.ts b/src/mcp/tool-docs/validation/validate-workflow-connections.ts new file mode 100644 index 0000000..07c36c3 --- /dev/null +++ b/src/mcp/tool-docs/validation/validate-workflow-connections.ts @@ -0,0 +1,56 @@ +import { ToolDocumentation } from '../types'; + +export const validateWorkflowConnectionsDoc: ToolDocumentation = { + name: 'validate_workflow_connections', + category: 'validation', + essentials: { + description: 'Check workflow connections only: valid nodes, no cycles, proper triggers, AI tool links. Fast structure validation.', + keyParameters: ['workflow'], + example: 'validate_workflow_connections({workflow: {nodes: [...], connections: {...}}})', + performance: 'Fast (<100ms)', + tips: [ + 'Use for quick structure checks when editing connections', + 'Detects orphaned nodes and circular dependencies', + 'Validates AI Agent tool connections to ensure proper node references' + ] + }, + full: { + description: 'Validates only the connection structure of a workflow without checking node configurations or expressions. This focused validation checks that all referenced nodes exist, detects circular dependencies, ensures proper trigger node placement, validates AI tool connections, and identifies orphaned or unreachable nodes.', + parameters: { + workflow: { + type: 'object', + required: true, + description: 'The workflow JSON with nodes array and connections object.' + } + }, + returns: 'Object with valid (boolean), errors (array), warnings (array), and statistics about connections', + examples: [ + 'validate_workflow_connections({workflow: myWorkflow}) - Check all connections', + 'validate_workflow_connections({workflow: {nodes: [...], connections: {...}}}) - Validate structure only' + ], + useCases: [ + 'Quick validation when modifying workflow connections', + 'Ensure all node references in connections are valid', + 'Detect circular dependencies that would cause infinite loops', + 'Validate AI Agent nodes have proper tool connections', + 'Check workflow has at least one trigger node', + 'Find orphaned nodes not connected to any flow' + ], + performance: 'Fast (<100ms). Only validates structure, not node content. Scales linearly with connection count.', + bestPractices: [ + 'Run after adding or removing connections', + 'Use before validate_workflow for quick structural checks', + 'Check for warnings about orphaned nodes', + 'Ensure trigger nodes are properly positioned', + 'Validate after using n8n_update_partial_workflow with connection operations' + ], + pitfalls: [ + 'Does not validate node configurations - use validate_workflow for full validation', + 'Cannot detect logical errors in connection flow', + 'Some valid workflows may have intentionally disconnected nodes', + 'Circular dependency detection only catches direct loops', + 'Does not validate connection types match node capabilities' + ], + relatedTools: ['validate_workflow', 'validate_workflow_expressions', 'n8n_update_partial_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/validate-workflow-expressions.ts b/src/mcp/tool-docs/validation/validate-workflow-expressions.ts new file mode 100644 index 0000000..5d8a3e7 --- /dev/null +++ b/src/mcp/tool-docs/validation/validate-workflow-expressions.ts @@ -0,0 +1,56 @@ +import { ToolDocumentation } from '../types'; + +export const validateWorkflowExpressionsDoc: ToolDocumentation = { + name: 'validate_workflow_expressions', + category: 'validation', + essentials: { + description: 'Validate n8n expressions: syntax {{}}, variables ($json/$node), references. Returns errors with locations.', + keyParameters: ['workflow'], + example: 'validate_workflow_expressions({workflow: {nodes: [...], connections: {...}}})', + performance: 'Fast (<100ms)', + tips: [ + 'Catches syntax errors in {{}} expressions before runtime', + 'Validates $json, $node, and other n8n variables', + 'Shows exact location of expression errors in node parameters' + ] + }, + full: { + description: 'Validates all n8n expressions within a workflow for syntax correctness and reference validity. This tool scans all node parameters for n8n expressions (enclosed in {{}}), checks expression syntax, validates variable references like $json and $node("NodeName"), ensures referenced nodes exist in the workflow, and provides detailed error locations for debugging.', + parameters: { + workflow: { + type: 'object', + required: true, + description: 'The workflow JSON to check for expression errors.' + } + }, + returns: 'Object with valid (boolean), errors (array with node ID, parameter path, and error details), and expression count', + examples: [ + 'validate_workflow_expressions({workflow: myWorkflow}) - Check all expressions', + 'validate_workflow_expressions({workflow: {nodes: [...], connections: {...}}}) - Validate expression syntax' + ], + useCases: [ + 'Catch expression syntax errors before workflow execution', + 'Validate node references in $node() expressions exist', + 'Find typos in variable names like $json or $input', + 'Ensure complex expressions are properly formatted', + 'Debug expression errors with exact parameter locations', + 'Validate expressions after workflow modifications' + ], + performance: 'Fast (<100ms). Scans all string parameters in all nodes. Performance scales with workflow size and expression count.', + bestPractices: [ + 'Run after modifying any expressions in node parameters', + 'Check all $node() references when renaming nodes', + 'Validate expressions before workflow deployment', + 'Pay attention to nested object paths in expressions', + 'Use with validate_workflow for comprehensive validation' + ], + pitfalls: [ + 'Cannot validate expression logic, only syntax', + 'Runtime data availability not checked (e.g., if $json.field exists)', + 'Complex JavaScript in expressions may need runtime testing', + 'Does not validate expression return types', + 'Some valid expressions may use advanced features not fully parsed' + ], + relatedTools: ['validate_workflow', 'validate_workflow_connections', 'validate_node_operation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/validation/validate-workflow.ts b/src/mcp/tool-docs/validation/validate-workflow.ts new file mode 100644 index 0000000..5c7a735 --- /dev/null +++ b/src/mcp/tool-docs/validation/validate-workflow.ts @@ -0,0 +1,81 @@ +import { ToolDocumentation } from '../types'; + +export const validateWorkflowDoc: ToolDocumentation = { + name: 'validate_workflow', + category: 'validation', + essentials: { + description: 'Full workflow validation: structure, connections, expressions, AI tools. Returns errors/warnings/fixes. Essential before deploy.', + keyParameters: ['workflow', 'options'], + example: 'validate_workflow({workflow: {nodes: [...], connections: {...}}})', + performance: 'Moderate (100-500ms)', + tips: [ + 'Always validate before n8n_create_workflow to catch errors early', + 'Use options.profile="minimal" for quick checks during development', + 'AI tool connections are automatically validated for proper node references' + ] + }, + full: { + description: 'Performs comprehensive validation of n8n workflows including structure, node configurations, connections, and expressions. This is a three-layer validation system that catches errors before deployment, validates complex multi-node workflows, checks all n8n expressions for syntax errors, and ensures proper node connections and data flow.', + parameters: { + workflow: { + type: 'object', + required: true, + description: 'The complete workflow JSON to validate. Must include nodes array and connections object.' + }, + options: { + type: 'object', + required: false, + description: 'Validation options object' + }, + 'options.validateNodes': { + type: 'boolean', + required: false, + description: 'Validate individual node configurations. Default: true' + }, + 'options.validateConnections': { + type: 'boolean', + required: false, + description: 'Validate node connections and flow. Default: true' + }, + 'options.validateExpressions': { + type: 'boolean', + required: false, + description: 'Validate n8n expressions syntax and references. Default: true' + }, + 'options.profile': { + type: 'string', + required: false, + description: 'Validation profile for node validation: minimal, runtime (default), ai-friendly, strict' + } + }, + returns: 'Object with valid (boolean), errors (array), warnings (array), statistics (object), and suggestions (array)', + examples: [ + 'validate_workflow({workflow: myWorkflow}) - Full validation with default settings', + 'validate_workflow({workflow: myWorkflow, options: {profile: "minimal"}}) - Quick validation for editing', + 'validate_workflow({workflow: myWorkflow, options: {validateExpressions: false}}) - Skip expression validation' + ], + useCases: [ + 'Pre-deployment validation to catch all workflow issues', + 'Quick validation during workflow development', + 'Validate workflows with AI Agent nodes and tool connections', + 'Check expression syntax before workflow execution', + 'Ensure workflow structure integrity after modifications' + ], + performance: 'Moderate (100-500ms). Depends on workflow size and validation options. Expression validation adds ~50-100ms.', + bestPractices: [ + 'Always validate workflows before creating or updating in n8n', + 'Use minimal profile during development, strict profile before production', + 'Pay attention to warnings - they often indicate potential runtime issues', + 'Validate after any workflow modifications, especially connection changes', + 'Check statistics to understand workflow complexity' + ], + pitfalls: [ + 'Large workflows (100+ nodes) may take longer to validate', + 'Expression validation requires proper node references to exist', + 'Some warnings may be acceptable depending on use case', + 'Validation cannot catch all runtime errors (e.g., API failures)', + 'Profile setting only affects node validation, not connection/expression checks' + ], + relatedTools: ['validate_workflow_connections', 'validate_workflow_expressions', 'validate_node_operation', 'n8n_create_workflow', 'n8n_update_partial_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/index.ts b/src/mcp/tool-docs/workflow_management/index.ts new file mode 100644 index 0000000..9b0fd64 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/index.ts @@ -0,0 +1,14 @@ +export { n8nCreateWorkflowDoc } from './n8n-create-workflow'; +export { n8nGetWorkflowDoc } from './n8n-get-workflow'; +export { n8nGetWorkflowDetailsDoc } from './n8n-get-workflow-details'; +export { n8nGetWorkflowStructureDoc } from './n8n-get-workflow-structure'; +export { n8nGetWorkflowMinimalDoc } from './n8n-get-workflow-minimal'; +export { n8nUpdateFullWorkflowDoc } from './n8n-update-full-workflow'; +export { n8nUpdatePartialWorkflowDoc } from './n8n-update-partial-workflow'; +export { n8nDeleteWorkflowDoc } from './n8n-delete-workflow'; +export { n8nListWorkflowsDoc } from './n8n-list-workflows'; +export { n8nValidateWorkflowDoc } from './n8n-validate-workflow'; +export { n8nTriggerWebhookWorkflowDoc } from './n8n-trigger-webhook-workflow'; +export { n8nGetExecutionDoc } from './n8n-get-execution'; +export { n8nListExecutionsDoc } from './n8n-list-executions'; +export { n8nDeleteExecutionDoc } from './n8n-delete-execution'; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts new file mode 100644 index 0000000..8590933 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-create-workflow.ts @@ -0,0 +1,51 @@ +import { ToolDocumentation } from '../types'; + +export const n8nCreateWorkflowDoc: ToolDocumentation = { + name: 'n8n_create_workflow', + category: 'workflow_management', + essentials: { + description: 'Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.', + keyParameters: ['name', 'nodes', 'connections'], + example: 'n8n_create_workflow({name: "My Flow", nodes: [...], connections: {...}})', + performance: 'Network-dependent', + tips: [ + 'Workflow created inactive', + 'Returns ID for future updates', + 'Validate first with validate_workflow' + ] + }, + full: { + description: 'Creates a new workflow in n8n with specified nodes and connections. Workflow is created in inactive state. Each node requires: id, name, type, typeVersion, position, and parameters.', + parameters: { + name: { type: 'string', required: true, description: 'Workflow name' }, + nodes: { type: 'array', required: true, description: 'Array of nodes with id, name, type, typeVersion, position, parameters' }, + 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: 'Created workflow object with id, name, nodes, connections, active status', + examples: [ + 'n8n_create_workflow({name: "Webhook to Slack", nodes: [...], connections: {...}}) - Basic workflow', + 'n8n_create_workflow({name: "Data ETL", nodes: [...], connections: {...], settings: {timezone: "UTC"}}) - With settings' + ], + useCases: [ + 'Deploy validated workflows', + 'Automate workflow creation', + 'Clone workflow structures', + 'Template deployment' + ], + performance: 'Network-dependent - Typically 100-500ms depending on workflow size', + bestPractices: [ + 'Validate with validate_workflow first', + 'Use unique node IDs', + 'Position nodes for readability', + 'Test with n8n_trigger_webhook_workflow' + ], + pitfalls: [ + 'Requires API configuration', + 'Created workflows are inactive', + 'Node IDs must be unique', + 'Credentials configured separately' + ], + relatedTools: ['validate_workflow', 'n8n_update_partial_workflow', 'n8n_trigger_webhook_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-delete-execution.ts b/src/mcp/tool-docs/workflow_management/n8n-delete-execution.ts new file mode 100644 index 0000000..29d35da --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-delete-execution.ts @@ -0,0 +1,57 @@ +import { ToolDocumentation } from '../types'; + +export const n8nDeleteExecutionDoc: ToolDocumentation = { + name: 'n8n_delete_execution', + category: 'workflow_management', + essentials: { + description: 'Delete an execution record. This only removes the execution history, not any data processed.', + keyParameters: ['id'], + example: 'n8n_delete_execution({id: "12345"})', + performance: 'Immediate deletion, no undo available', + tips: [ + 'Deletion is permanent - execution cannot be recovered', + 'Only removes execution history, not external data changes', + 'Use for cleanup of test executions or sensitive data' + ] + }, + full: { + description: `Permanently deletes a workflow execution record from n8n's history. This removes the execution metadata, logs, and any stored input/output data. However, it does NOT undo any actions the workflow performed (API calls, database changes, file operations, etc.). Use this for cleaning up test executions, removing sensitive data, or managing storage.`, + parameters: { + id: { + type: 'string', + required: true, + description: 'The execution ID to delete. This action cannot be undone' + } + }, + returns: `Confirmation of deletion or error if execution not found. No data is returned about the deleted execution.`, + examples: [ + 'n8n_delete_execution({id: "12345"}) - Delete a specific execution', + 'n8n_delete_execution({id: "test-run-567"}) - Clean up test execution', + 'n8n_delete_execution({id: "sensitive-data-890"}) - Remove execution with sensitive data', + 'n8n_delete_execution({id: "failed-execution-123"}) - Delete failed execution after debugging' + ], + useCases: [ + 'Clean up test or development execution history', + 'Remove executions containing sensitive or personal data', + 'Manage storage by deleting old execution records', + 'Clean up after debugging failed workflows', + 'Comply with data retention policies' + ], + performance: `Deletion is immediate and permanent. The operation is fast (< 100ms) as it only removes database records. No external systems or data are affected.`, + bestPractices: [ + 'Verify execution ID before deletion - action cannot be undone', + 'Consider exporting execution data before deletion if needed', + 'Use list_executions to find executions to delete', + 'Document why executions were deleted for audit trails', + 'Remember deletion only affects n8n records, not external changes' + ], + pitfalls: [ + 'Deletion is PERMANENT - no undo or recovery possible', + 'Does NOT reverse workflow actions (API calls, DB changes, etc.)', + 'Deleting executions breaks audit trails and debugging history', + 'Cannot delete currently running executions (waiting status)', + 'Bulk deletion not supported - must delete one at a time' + ], + relatedTools: ['n8n_list_executions', 'n8n_get_execution', 'n8n_trigger_webhook_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts new file mode 100644 index 0000000..c8f76e8 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-delete-workflow.ts @@ -0,0 +1,50 @@ +import { ToolDocumentation } from '../types'; + +export const n8nDeleteWorkflowDoc: ToolDocumentation = { + name: 'n8n_delete_workflow', + category: 'workflow_management', + essentials: { + description: 'Permanently delete a workflow. This action cannot be undone.', + keyParameters: ['id'], + example: 'n8n_delete_workflow({id: "workflow_123"})', + performance: 'Fast (50-150ms)', + tips: [ + 'Action is irreversible', + 'Deletes all execution history', + 'Check workflow first with get_minimal' + ] + }, + full: { + description: 'Permanently deletes a workflow from n8n including all associated data, execution history, and settings. This is an irreversible operation that should be used with caution. The workflow must exist and the user must have appropriate permissions.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to delete permanently' } + }, + 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' + ], + useCases: [ + 'Remove obsolete workflows', + 'Clean up test workflows', + 'Delete failed experiments', + 'Manage workflow limits', + 'Remove duplicates' + ], + performance: 'Fast operation - typically 50-150ms. May take longer if workflow has extensive execution history.', + bestPractices: [ + 'Always confirm before deletion', + 'Check workflow with get_minimal first', + 'Consider deactivating instead of deleting', + 'Export workflow before deletion for backup' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Cannot be undone - permanent deletion', + 'Deletes all execution history', + 'Active workflows can be deleted', + 'No built-in confirmation' + ], + relatedTools: ['n8n_get_workflow_minimal', 'n8n_list_workflows', 'n8n_update_partial_workflow', 'n8n_delete_execution'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-get-execution.ts b/src/mcp/tool-docs/workflow_management/n8n-get-execution.ts new file mode 100644 index 0000000..647e990 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-get-execution.ts @@ -0,0 +1,62 @@ +import { ToolDocumentation } from '../types'; + +export const n8nGetExecutionDoc: ToolDocumentation = { + name: 'n8n_get_execution', + category: 'workflow_management', + essentials: { + description: 'Get details of a specific execution by ID, including status, timing, and error information.', + keyParameters: ['id', 'includeData'], + example: 'n8n_get_execution({id: "12345"})', + performance: 'Fast lookup, data inclusion may increase response size significantly', + tips: [ + 'Use includeData:true to see full execution data and node outputs', + 'Execution IDs come from list_executions or webhook responses', + 'Check status field for success/error/waiting states' + ] + }, + full: { + description: `Retrieves detailed information about a specific workflow execution. This tool is essential for monitoring workflow runs, debugging failures, and accessing execution results. Returns execution metadata by default, with optional full data inclusion for complete visibility into node inputs/outputs.`, + parameters: { + id: { + type: 'string', + required: true, + description: 'The execution ID to retrieve. Obtained from list_executions or webhook trigger responses' + }, + includeData: { + type: 'boolean', + required: false, + description: 'Include full execution data with node inputs/outputs (default: false). Significantly increases response size' + } + }, + returns: `Execution object containing status, timing, error details, and optionally full execution data with all node inputs/outputs.`, + examples: [ + 'n8n_get_execution({id: "12345"}) - Get execution summary only', + 'n8n_get_execution({id: "12345", includeData: true}) - Get full execution with all data', + 'n8n_get_execution({id: "67890"}) - Check status of a running execution', + 'n8n_get_execution({id: "failed-123", includeData: true}) - Debug failed execution with error details' + ], + useCases: [ + 'Monitor status of triggered workflow executions', + 'Debug failed workflows by examining error messages', + 'Access execution results and node output data', + 'Track execution duration and performance metrics', + 'Verify successful completion of critical workflows' + ], + performance: `Metadata retrieval is fast (< 100ms). Including full data (includeData: true) can significantly increase response time and size, especially for workflows processing large datasets. Use data inclusion judiciously.`, + bestPractices: [ + 'Start with includeData:false to check status first', + 'Only include data when you need to see node outputs', + 'Store execution IDs from trigger responses for tracking', + 'Check status field to determine if execution completed', + 'Use error field to diagnose execution failures' + ], + pitfalls: [ + 'Large executions with includeData:true can timeout or exceed limits', + 'Execution data is retained based on n8n settings - old executions may be purged', + 'Waiting status indicates execution is still running', + 'Error executions may have partial data from successful nodes', + 'Execution IDs are unique per n8n instance' + ], + relatedTools: ['n8n_list_executions', 'n8n_trigger_webhook_workflow', 'n8n_delete_execution', 'n8n_get_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-get-workflow-details.ts b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-details.ts new file mode 100644 index 0000000..cf34d6e --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-details.ts @@ -0,0 +1,49 @@ +import { ToolDocumentation } from '../types'; + +export const n8nGetWorkflowDetailsDoc: ToolDocumentation = { + name: 'n8n_get_workflow_details', + category: 'workflow_management', + essentials: { + description: 'Get workflow details with metadata, version, execution stats. More info than get_workflow.', + keyParameters: ['id'], + example: 'n8n_get_workflow_details({id: "workflow_123"})', + performance: 'Fast (100-300ms)', + tips: [ + 'Includes execution statistics', + 'Shows version history info', + 'Contains metadata like tags' + ] + }, + full: { + description: 'Retrieves comprehensive workflow details including metadata, execution statistics, version information, and usage analytics. Provides more information than get_workflow, including data not typically needed for editing but useful for monitoring and analysis.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to retrieve details for' } + }, + returns: 'Extended workflow object with: id, name, nodes, connections, settings, plus metadata (tags, owner, shared users), execution stats (success/error counts, average runtime), version info, created/updated timestamps', + examples: [ + 'n8n_get_workflow_details({id: "abc123"}) - Get workflow with stats', + 'const details = n8n_get_workflow_details({id: "xyz789"}); // Analyze performance' + ], + useCases: [ + 'Monitor workflow performance', + 'Analyze execution patterns', + 'View workflow metadata', + 'Check version information', + 'Audit workflow usage' + ], + performance: 'Slightly slower than get_workflow due to additional metadata - typically 100-300ms. Stats may be cached.', + bestPractices: [ + 'Use for monitoring and analysis', + 'Check execution stats before optimization', + 'Review error counts for debugging', + 'Monitor average execution times' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'More data than needed for simple edits', + 'Stats may have slight delay', + 'Not all n8n versions support all fields' + ], + relatedTools: ['n8n_get_workflow', 'n8n_list_executions', 'n8n_get_execution', 'n8n_list_workflows'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.ts b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.ts new file mode 100644 index 0000000..0e6a517 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-minimal.ts @@ -0,0 +1,49 @@ +import { ToolDocumentation } from '../types'; + +export const n8nGetWorkflowMinimalDoc: ToolDocumentation = { + name: 'n8n_get_workflow_minimal', + category: 'workflow_management', + essentials: { + description: 'Get minimal info: ID, name, active status, tags. Fast for listings.', + keyParameters: ['id'], + example: 'n8n_get_workflow_minimal({id: "workflow_123"})', + performance: 'Very fast (<50ms)', + tips: [ + 'Fastest way to check workflow exists', + 'Perfect for status checks', + 'Use in list displays' + ] + }, + full: { + description: 'Retrieves only essential workflow information without nodes or connections. Returns minimal data needed for listings, status checks, and quick lookups. Optimized for performance when full workflow data is not needed.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to retrieve minimal info for' } + }, + returns: 'Minimal workflow object with: id, name, active status, tags array, createdAt, updatedAt. No nodes, connections, or settings included.', + examples: [ + 'n8n_get_workflow_minimal({id: "abc123"}) - Quick existence check', + 'const info = n8n_get_workflow_minimal({id: "xyz789"}); // Check if active' + ], + useCases: [ + 'Quick workflow existence checks', + 'Display workflow lists', + 'Check active/inactive status', + 'Get workflow tags', + 'Performance-critical operations' + ], + performance: 'Extremely fast - typically under 50ms. Returns only database metadata without loading workflow definition.', + bestPractices: [ + 'Use for list displays and dashboards', + 'Ideal for existence checks before operations', + 'Cache results for UI responsiveness', + 'Combine with list_workflows for bulk checks' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'No workflow content - cannot edit or validate', + 'Tags may be empty array', + 'Must use get_workflow for actual workflow data' + ], + relatedTools: ['n8n_list_workflows', 'n8n_get_workflow', 'n8n_get_workflow_structure', 'n8n_update_partial_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.ts b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.ts new file mode 100644 index 0000000..a2d3d70 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-get-workflow-structure.ts @@ -0,0 +1,49 @@ +import { ToolDocumentation } from '../types'; + +export const n8nGetWorkflowStructureDoc: ToolDocumentation = { + name: 'n8n_get_workflow_structure', + category: 'workflow_management', + essentials: { + description: 'Get workflow structure: nodes and connections only. No parameter details.', + keyParameters: ['id'], + example: 'n8n_get_workflow_structure({id: "workflow_123"})', + performance: 'Fast (75-150ms)', + tips: [ + 'Shows workflow topology', + 'Node types without parameters', + 'Perfect for visualization' + ] + }, + full: { + description: 'Retrieves workflow structural information including node types, positions, and connections, but without detailed node parameters. Ideal for understanding workflow topology, creating visualizations, or analyzing workflow complexity without the overhead of full parameter data.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to retrieve structure for' } + }, + returns: 'Workflow structure with: id, name, nodes array (id, name, type, position only), connections object. No node parameters, credentials, or settings included.', + examples: [ + 'n8n_get_workflow_structure({id: "abc123"}) - Visualize workflow', + 'const structure = n8n_get_workflow_structure({id: "xyz789"}); // Analyze complexity' + ], + useCases: [ + 'Generate workflow visualizations', + 'Analyze workflow complexity', + 'Understand node relationships', + 'Create workflow diagrams', + 'Quick topology validation' + ], + performance: 'Fast retrieval - typically 75-150ms. Faster than get_workflow as parameters are stripped.', + bestPractices: [ + 'Use for visualization tools', + 'Ideal for workflow analysis', + 'Good for connection validation', + 'Cache for UI diagram rendering' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'No parameter data for configuration', + 'Cannot validate node settings', + 'Must use get_workflow for editing' + ], + relatedTools: ['n8n_get_workflow', 'n8n_validate_workflow_connections', 'n8n_get_workflow_minimal', 'validate_workflow_connections'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-get-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-get-workflow.ts new file mode 100644 index 0000000..6c01ab3 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-get-workflow.ts @@ -0,0 +1,49 @@ +import { ToolDocumentation } from '../types'; + +export const n8nGetWorkflowDoc: ToolDocumentation = { + name: 'n8n_get_workflow', + category: 'workflow_management', + essentials: { + description: 'Get a workflow by ID. Returns the complete workflow including nodes, connections, and settings.', + keyParameters: ['id'], + example: 'n8n_get_workflow({id: "workflow_123"})', + performance: 'Fast (50-200ms)', + tips: [ + 'Returns complete workflow JSON', + 'Includes all node parameters', + 'Use get_workflow_minimal for faster listings' + ] + }, + full: { + description: 'Retrieves a complete workflow from n8n by its ID. Returns full workflow definition including all nodes with their parameters, connections between nodes, and workflow settings. This is the primary tool for fetching workflows for viewing, editing, or cloning.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to retrieve' } + }, + returns: 'Complete workflow object containing: id, name, active status, nodes array (with full parameters), connections object, settings, createdAt, updatedAt', + examples: [ + 'n8n_get_workflow({id: "abc123"}) - Get workflow for editing', + 'const wf = n8n_get_workflow({id: "xyz789"}); // Clone workflow structure' + ], + useCases: [ + 'View workflow configuration', + 'Export workflow for backup', + 'Clone workflow structure', + 'Debug workflow issues', + 'Prepare for updates' + ], + performance: 'Fast retrieval - typically 50-200ms depending on workflow size. Cached by n8n for performance.', + bestPractices: [ + 'Check workflow exists before updating', + 'Use for complete workflow data needs', + 'Cache results when making multiple operations', + 'Validate after retrieving if modifying' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Returns all data - use minimal/structure for performance', + 'Workflow must exist or returns 404', + 'Credentials are referenced but not included' + ], + relatedTools: ['n8n_get_workflow_minimal', 'n8n_get_workflow_structure', 'n8n_update_full_workflow', 'n8n_validate_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-list-executions.ts b/src/mcp/tool-docs/workflow_management/n8n-list-executions.ts new file mode 100644 index 0000000..94e8223 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-list-executions.ts @@ -0,0 +1,84 @@ +import { ToolDocumentation } from '../types'; + +export const n8nListExecutionsDoc: ToolDocumentation = { + name: 'n8n_list_executions', + category: 'workflow_management', + essentials: { + description: 'List workflow executions with optional filters. Supports pagination for large result sets.', + keyParameters: ['workflowId', 'status', 'limit'], + example: 'n8n_list_executions({workflowId: "abc123", status: "error"})', + performance: 'Fast metadata retrieval, use pagination for large datasets', + tips: [ + 'Filter by status (success/error/waiting) to find specific execution types', + 'Use workflowId to see all executions for a specific workflow', + 'Pagination via cursor allows retrieving large execution histories' + ] + }, + full: { + description: `Lists workflow executions with powerful filtering options. This tool is essential for monitoring workflow performance, finding failed executions, and tracking workflow activity. Supports pagination for retrieving large execution histories and filtering by workflow, status, and project.`, + parameters: { + limit: { + type: 'number', + required: false, + description: 'Number of executions to return (1-100, default: 100). Use with cursor for pagination' + }, + cursor: { + type: 'string', + required: false, + description: 'Pagination cursor from previous response. Used to retrieve next page of results' + }, + workflowId: { + type: 'string', + required: false, + description: 'Filter executions by specific workflow ID. Shows all executions for that workflow' + }, + projectId: { + type: 'string', + required: false, + description: 'Filter by project ID (enterprise feature). Groups executions by project' + }, + status: { + type: 'string', + required: false, + enum: ['success', 'error', 'waiting'], + description: 'Filter by execution status. Success = completed, Error = failed, Waiting = running' + }, + includeData: { + type: 'boolean', + required: false, + description: 'Include execution data in results (default: false). Significantly increases response size' + } + }, + returns: `Array of execution objects with metadata, pagination cursor for next page, and optionally execution data. Each execution includes ID, status, start/end times, and workflow reference.`, + examples: [ + 'n8n_list_executions({limit: 10}) - Get 10 most recent executions', + 'n8n_list_executions({workflowId: "abc123"}) - All executions for specific workflow', + 'n8n_list_executions({status: "error", limit: 50}) - Find failed executions', + 'n8n_list_executions({status: "waiting"}) - Monitor currently running workflows', + 'n8n_list_executions({cursor: "next-page-token"}) - Get next page of results' + ], + useCases: [ + 'Monitor workflow execution history and patterns', + 'Find and debug failed workflow executions', + 'Track currently running workflows (waiting status)', + 'Analyze workflow performance and execution frequency', + 'Generate execution reports for specific workflows' + ], + performance: `Listing executions is fast for metadata only. Including data (includeData: true) significantly impacts performance. Use pagination (limit + cursor) for large result sets. Default limit of 100 balances performance with usability.`, + bestPractices: [ + 'Use status filters to focus on specific execution types', + 'Implement pagination for large execution histories', + 'Avoid includeData unless you need execution details', + 'Filter by workflowId when monitoring specific workflows', + 'Check for cursor in response to detect more pages' + ], + pitfalls: [ + 'Large limits with includeData can cause timeouts', + 'Execution retention depends on n8n configuration', + 'Cursor tokens expire - use them promptly', + 'Status "waiting" includes both running and queued executions', + 'Deleted workflows still show in execution history' + ], + relatedTools: ['n8n_get_execution', 'n8n_trigger_webhook_workflow', 'n8n_delete_execution', 'n8n_list_workflows'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-list-workflows.ts b/src/mcp/tool-docs/workflow_management/n8n-list-workflows.ts new file mode 100644 index 0000000..2549ecd --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-list-workflows.ts @@ -0,0 +1,55 @@ +import { ToolDocumentation } from '../types'; + +export const n8nListWorkflowsDoc: ToolDocumentation = { + name: 'n8n_list_workflows', + category: 'workflow_management', + essentials: { + description: 'List workflows with optional filters. Supports pagination via cursor.', + keyParameters: ['limit', 'active', 'tags'], + example: 'n8n_list_workflows({limit: 20, active: true})', + performance: 'Fast (100-300ms)', + tips: [ + 'Use cursor for pagination', + 'Filter by active status', + 'Tag filtering for organization' + ] + }, + full: { + description: 'Lists workflows from n8n with powerful filtering options including active status, tags, and project assignment. Supports cursor-based pagination for large workflow collections. Returns minimal workflow information by default for performance.', + parameters: { + limit: { type: 'number', description: 'Number of workflows to return (1-100, default: 100)' }, + cursor: { type: 'string', description: 'Pagination cursor from previous response for next page' }, + active: { type: 'boolean', description: 'Filter by active/inactive status' }, + tags: { type: 'array', description: 'Filter by exact tag matches (AND logic)' }, + projectId: { type: 'string', description: 'Filter by project ID (enterprise feature)' }, + excludePinnedData: { type: 'boolean', description: 'Exclude pinned data from response (default: true)' } + }, + returns: 'Object with: data array (workflows with id, name, active, tags, dates), nextCursor (for pagination), and metadata (total count if available)', + examples: [ + 'n8n_list_workflows({limit: 20}) - First 20 workflows', + 'n8n_list_workflows({active: true, tags: ["production"]}) - Active production workflows', + 'n8n_list_workflows({cursor: "abc123", limit: 50}) - Next page of results' + ], + useCases: [ + 'Build workflow dashboards', + 'Find workflows by status', + 'Organize by tags', + 'Bulk workflow operations', + 'Generate workflow reports' + ], + performance: 'Fast listing - typically 100-300ms for standard page sizes. Excludes workflow content for speed.', + bestPractices: [ + 'Use pagination for large instances', + 'Cache results for UI responsiveness', + 'Filter to reduce result set', + 'Combine with get_workflow_minimal for details' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Maximum 100 workflows per request', + 'Tags must match exactly (case-sensitive)', + 'No workflow content in results' + ], + relatedTools: ['n8n_get_workflow_minimal', 'n8n_get_workflow', 'n8n_update_partial_workflow', 'n8n_list_executions'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.ts new file mode 100644 index 0000000..772b255 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-trigger-webhook-workflow.ts @@ -0,0 +1,78 @@ +import { ToolDocumentation } from '../types'; + +export const n8nTriggerWebhookWorkflowDoc: ToolDocumentation = { + name: 'n8n_trigger_webhook_workflow', + category: 'workflow_management', + essentials: { + description: 'Trigger workflow via webhook. Must be ACTIVE with Webhook node. Method must match config.', + keyParameters: ['webhookUrl', 'httpMethod', 'data'], + example: 'n8n_trigger_webhook_workflow({webhookUrl: "https://n8n.example.com/webhook/abc-def-ghi"})', + performance: 'Immediate trigger, response time depends on workflow complexity', + tips: [ + 'Workflow MUST be active and contain a Webhook node for triggering', + 'HTTP method must match webhook node configuration (often GET)', + 'Use waitForResponse:false for async execution without waiting' + ] + }, + full: { + description: `Triggers a workflow execution via its webhook URL. This is the primary method for external systems to start n8n workflows. The target workflow must be active and contain a properly configured Webhook node as the trigger. The HTTP method used must match the webhook configuration.`, + parameters: { + webhookUrl: { + type: 'string', + required: true, + description: 'Full webhook URL from n8n workflow (e.g., https://n8n.example.com/webhook/abc-def-ghi)' + }, + httpMethod: { + type: 'string', + required: false, + enum: ['GET', 'POST', 'PUT', 'DELETE'], + description: 'HTTP method (must match webhook configuration, often GET). Defaults to GET if not specified' + }, + data: { + type: 'object', + required: false, + description: 'Data to send with the webhook request. For GET requests, becomes query parameters' + }, + headers: { + type: 'object', + required: false, + description: 'Additional HTTP headers to include in the request' + }, + waitForResponse: { + type: 'boolean', + required: false, + description: 'Wait for workflow completion and return results (default: true). Set to false for fire-and-forget' + } + }, + returns: `Webhook response data if waitForResponse is true, or immediate acknowledgment if false. Response format depends on webhook node configuration.`, + examples: [ + 'n8n_trigger_webhook_workflow({webhookUrl: "https://n8n.example.com/webhook/order-process"}) - Trigger with GET', + 'n8n_trigger_webhook_workflow({webhookUrl: "https://n8n.example.com/webhook/data-import", httpMethod: "POST", data: {name: "John", email: "john@example.com"}}) - POST with data', + 'n8n_trigger_webhook_workflow({webhookUrl: "https://n8n.example.com/webhook/async-job", waitForResponse: false}) - Fire and forget', + 'n8n_trigger_webhook_workflow({webhookUrl: "https://n8n.example.com/webhook/api", headers: {"API-Key": "secret"}}) - With auth headers' + ], + useCases: [ + 'Trigger data processing workflows from external applications', + 'Start scheduled jobs manually via webhook', + 'Integrate n8n workflows with third-party services', + 'Create REST API endpoints using n8n workflows', + 'Implement event-driven architectures with n8n' + ], + performance: `Performance varies based on workflow complexity and waitForResponse setting. Synchronous calls (waitForResponse: true) block until workflow completes. For long-running workflows, use async mode (waitForResponse: false) and monitor execution separately.`, + bestPractices: [ + 'Always verify workflow is active before attempting webhook triggers', + 'Match HTTP method exactly with webhook node configuration', + 'Use async mode (waitForResponse: false) for long-running workflows', + 'Include authentication headers when webhook requires them', + 'Test webhook URL manually first to ensure it works' + ], + pitfalls: [ + 'Workflow must be ACTIVE - inactive workflows cannot be triggered', + 'HTTP method mismatch returns 404 even if URL is correct', + 'Webhook node must be the trigger node in the workflow', + 'Timeout errors occur with long workflows in sync mode', + 'Data format must match webhook node expectations' + ], + relatedTools: ['n8n_get_execution', 'n8n_list_executions', 'n8n_get_workflow', 'n8n_create_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts new file mode 100644 index 0000000..0ab6f0c --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-update-full-workflow.ts @@ -0,0 +1,55 @@ +import { ToolDocumentation } from '../types'; + +export const n8nUpdateFullWorkflowDoc: ToolDocumentation = { + name: 'n8n_update_full_workflow', + category: 'workflow_management', + essentials: { + description: 'Full workflow update. Requires complete nodes[] and connections{}. For incremental use n8n_update_partial_workflow.', + keyParameters: ['id', 'nodes', 'connections'], + example: 'n8n_update_full_workflow({id: "wf_123", nodes: [...], connections: {...}})', + performance: 'Network-dependent', + tips: [ + 'Must provide complete workflow', + 'Use update_partial for small changes', + 'Validate before updating' + ] + }, + full: { + description: 'Performs a complete workflow update by replacing the entire workflow definition. Requires providing the complete nodes array and connections object, even for small changes. This is a full replacement operation - any nodes or connections not included will be removed.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to update' }, + name: { type: 'string', description: 'New workflow name (optional)' }, + nodes: { type: 'array', description: 'Complete array of workflow nodes (required if modifying structure)' }, + connections: { type: 'object', description: 'Complete connections object (required if modifying structure)' }, + settings: { type: 'object', description: 'Workflow settings to update (timezone, error handling, etc.)' } + }, + returns: 'Updated workflow object with all fields including the changes applied', + examples: [ + 'n8n_update_full_workflow({id: "abc", name: "New Name"}) - Rename only', + 'n8n_update_full_workflow({id: "xyz", nodes: [...], connections: {...}}) - Full structure update', + 'const wf = n8n_get_workflow({id}); wf.nodes.push(newNode); n8n_update_full_workflow(wf); // Add node' + ], + useCases: [ + 'Major workflow restructuring', + 'Bulk node updates', + 'Workflow imports/cloning', + 'Complete workflow replacement', + 'Settings changes' + ], + performance: 'Network-dependent - typically 200-500ms. Larger workflows take longer. Consider update_partial for better performance.', + bestPractices: [ + 'Get workflow first, modify, then update', + 'Validate with validate_workflow before updating', + 'Use update_partial for small changes', + 'Test updates in non-production first' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Must include ALL nodes/connections', + 'Missing nodes will be deleted', + 'Can break active workflows', + 'No partial updates - use update_partial instead' + ], + relatedTools: ['n8n_get_workflow', 'n8n_update_partial_workflow', 'validate_workflow', 'n8n_create_workflow'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts new file mode 100644 index 0000000..0f5b425 --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts @@ -0,0 +1,57 @@ +import { ToolDocumentation } from '../types'; + +export const n8nUpdatePartialWorkflowDoc: ToolDocumentation = { + name: 'n8n_update_partial_workflow', + category: 'workflow_management', + essentials: { + description: 'Update workflow incrementally with diff operations. Max 5 ops. Types: addNode, removeNode, updateNode, moveNode, enable/disableNode, addConnection, removeConnection, updateSettings, updateName, add/removeTag.', + keyParameters: ['id', 'operations'], + example: 'n8n_update_partial_workflow({id: "wf_123", operations: [{type: "updateNode", ...}]})', + performance: 'Fast (50-200ms)', + tips: [ + 'Use for targeted changes', + 'Supports up to 5 operations', + 'Validate with validateOnly first' + ] + }, + full: { + description: 'Updates workflows using surgical diff operations instead of full replacement. Supports 13 operation types for precise modifications. Operations are validated and applied atomically - all succeed or none are applied. Maximum 5 operations per call for safety.', + parameters: { + id: { type: 'string', required: true, description: 'Workflow ID to update' }, + operations: { + type: 'array', + required: true, + description: 'Array of diff operations. Each must have "type" field and operation-specific properties. Max 5 operations.' + }, + validateOnly: { type: 'boolean', description: 'If true, only validate operations without applying them' } + }, + returns: 'Updated workflow object or validation results if validateOnly=true', + examples: [ + 'n8n_update_partial_workflow({id: "abc", operations: [{type: "updateNode", nodeId: "n1", updates: {name: "New Name"}}]})', + 'n8n_update_partial_workflow({id: "xyz", operations: [{type: "addConnection", source: "n1", target: "n2"}]})', + 'n8n_update_partial_workflow({id: "123", operations: [{type: "removeNode", nodeId: "oldNode"}], validateOnly: true})' + ], + useCases: [ + 'Update single node parameters', + 'Add/remove connections', + 'Enable/disable nodes', + 'Rename workflows or nodes', + 'Manage tags efficiently' + ], + performance: 'Very fast - typically 50-200ms. Much faster than full updates as only changes are processed.', + bestPractices: [ + 'Use validateOnly to test operations', + 'Group related changes in one call', + 'Keep operations under 5 for clarity', + 'Check operation order for dependencies' + ], + pitfalls: [ + 'Requires N8N_API_URL and N8N_API_KEY configured', + 'Maximum 5 operations per call', + 'Operations must be valid together', + 'Some operations have dependencies', + 'See full docs for operation schemas' + ], + relatedTools: ['n8n_update_full_workflow', 'n8n_get_workflow', 'validate_workflow', 'tools_documentation'] + } +}; \ No newline at end of file diff --git a/src/mcp/tool-docs/workflow_management/n8n-validate-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-validate-workflow.ts new file mode 100644 index 0000000..e4db73c --- /dev/null +++ b/src/mcp/tool-docs/workflow_management/n8n-validate-workflow.ts @@ -0,0 +1,71 @@ +import { ToolDocumentation } from '../types'; + +export const n8nValidateWorkflowDoc: ToolDocumentation = { + name: 'n8n_validate_workflow', + category: 'workflow_management', + essentials: { + description: 'Validate workflow from n8n instance by ID - checks nodes, connections, expressions, and returns errors/warnings', + keyParameters: ['id'], + example: 'n8n_validate_workflow({id: "wf_abc123"})', + performance: 'Network-dependent (100-500ms) - fetches and validates workflow', + tips: [ + 'Use options.profile to control validation strictness (minimal/runtime/ai-friendly/strict)', + 'Validation includes node configs, connections, and n8n expression syntax', + 'Returns categorized errors, warnings, and actionable fix suggestions' + ] + }, + full: { + description: `Validates a workflow stored in your n8n instance by fetching it via API and running comprehensive validation checks. This tool: + +- Fetches the workflow from n8n using the workflow ID +- Validates all node configurations based on their schemas +- Checks workflow connections and data flow +- Validates n8n expression syntax in all fields +- Returns categorized issues with fix suggestions + +The validation uses the same engine as validate_workflow but works with workflows already in n8n, making it perfect for validating existing workflows before execution. + +Requires N8N_API_URL and N8N_API_KEY environment variables to be configured.`, + parameters: { + id: { + type: 'string', + required: true, + description: 'The workflow ID to validate from your n8n instance' + }, + options: { + type: 'object', + required: false, + description: 'Validation options: {validateNodes: bool (default true), validateConnections: bool (default true), validateExpressions: bool (default true), profile: "minimal"|"runtime"|"ai-friendly"|"strict" (default "runtime")}' + } + }, + returns: 'ValidationResult object containing isValid boolean, arrays of errors/warnings, and suggestions for fixes', + examples: [ + 'n8n_validate_workflow({id: "wf_abc123"}) - Validate with default settings', + 'n8n_validate_workflow({id: "wf_abc123", options: {profile: "strict"}}) - Strict validation', + 'n8n_validate_workflow({id: "wf_abc123", options: {validateExpressions: false}}) - Skip expression validation' + ], + useCases: [ + 'Validating workflows before running them in production', + 'Checking imported workflows for compatibility', + 'Debugging workflow execution failures', + 'Ensuring workflows follow best practices', + 'Pre-deployment validation in CI/CD pipelines' + ], + performance: 'Depends on workflow size and API latency. Typically 100-500ms for medium workflows.', + bestPractices: [ + 'Run validation before activating workflows in production', + 'Use "runtime" profile for pre-execution checks', + 'Use "strict" profile for code review and best practices', + 'Fix errors before warnings - errors will likely cause execution failures', + 'Pay attention to expression validation - syntax errors are common' + ], + pitfalls: [ + 'Requires valid API credentials - check n8n_health_check first', + 'Large workflows may take longer to validate', + 'Some warnings may be intentional (e.g., optional parameters)', + 'Profile affects validation time - strict is slower but more thorough', + 'Expression validation may flag working but non-standard syntax' + ], + relatedTools: ['validate_workflow', 'n8n_get_workflow', 'validate_workflow_expressions', 'n8n_health_check'] + } +}; \ No newline at end of file diff --git a/src/mcp/tools-documentation.ts b/src/mcp/tools-documentation.ts index 82ccf11..7c04f99 100644 --- a/src/mcp/tools-documentation.ts +++ b/src/mcp/tools-documentation.ts @@ -1,1152 +1,4 @@ -interface ToolDocumentation { - name: string; - category: string; - essentials: { - description: string; - keyParameters: string[]; - example: string; - performance: string; - tips: string[]; - }; - full: { - description: string; - parameters: Record; - returns: string; - examples: string[]; - useCases: string[]; - performance: string; - bestPractices: string[]; - pitfalls: string[]; - relatedTools: string[]; - }; -} - -export const toolsDocumentation: Record = { - search_nodes: { - name: 'search_nodes', - category: 'discovery', - essentials: { - description: 'Search nodes. Primary nodes ranked first.', - keyParameters: ['query', 'limit', 'mode'], - example: 'search_nodes({query: "webhook"})', - performance: 'Fast - FTS5 when available', - tips: [ - 'Primary nodes first: webhook→Webhook, http→HTTP Request', - 'Modes: OR (any word), AND (all words), FUZZY (typos OK)' - ] - }, - full: { - description: 'Search n8n nodes using FTS5 full-text search (when available) with relevance ranking. Supports OR (default), AND, and FUZZY search modes. Results are sorted by relevance, ensuring primary nodes like Webhook and HTTP Request appear first.', - parameters: { - query: { type: 'string', description: 'Search terms. Wrap in quotes for exact phrase matching', required: true }, - limit: { type: 'number', description: 'Maximum results to return (default: 20)', required: false }, - mode: { type: 'string', description: 'Search mode: OR (any word), AND (all words in ANY field), FUZZY (typo-tolerant using edit distance)', required: false } - }, - returns: 'Array of nodes sorted by relevance with nodeType, displayName, description, category. AND mode includes searchInfo explaining the search scope.', - examples: [ - 'search_nodes({query: "webhook"}) - Webhook node appears first', - 'search_nodes({query: "http call"}) - HTTP Request node appears first', - 'search_nodes({query: "send message", mode: "AND"}) - Nodes with both words anywhere in their data', - 'search_nodes({query: "slak", mode: "FUZZY"}) - Finds Slack using typo tolerance' - ], - useCases: [ - 'Finding primary nodes quickly (webhook, http, email)', - 'Discovering nodes with typo tolerance', - 'Precise searches with AND mode', - 'Exploratory searches with OR mode' - ], - performance: 'FTS5: <20ms for most queries. Falls back to optimized LIKE queries if FTS5 unavailable.', - bestPractices: [ - 'Default OR mode is best for exploration', - 'Use AND mode when you need all terms present', - 'Use FUZZY mode if unsure of spelling', - 'Quotes force exact phrase matching', - 'Primary nodes are boosted in relevance' - ], - pitfalls: [ - 'AND mode searches ALL fields (description, documentation, operations) not just names', - 'FUZZY mode uses edit distance - may return unexpected matches for very short queries', - 'Special characters are ignored in search', - 'FTS5 syntax errors fallback to basic LIKE search' - ], - relatedTools: ['list_nodes', 'get_node_essentials', 'get_node_info'] - } - }, - - get_node_essentials: { - name: 'get_node_essentials', - category: 'configuration', - essentials: { - description: 'Get 10-20 key properties with examples', - keyParameters: ['nodeType'], - example: 'get_node_essentials("nodes-base.slack")', - performance: '<5KB vs 100KB+', - tips: [ - 'Use this first! Has examples.' - ] - }, - full: { - description: 'Returns a curated set of essential properties for a node, typically 10-20 most commonly used properties. Includes working examples and is 95% smaller than get_node_info. Designed for efficient node configuration.', - parameters: { - nodeType: { type: 'string', description: 'Full node type (e.g., "n8n-nodes-base.slack")', required: true } - }, - returns: 'Object with node info, essential properties, examples, and common patterns', - examples: [ - 'get_node_essentials("n8n-nodes-base.httpRequest") - Get HTTP request essentials', - 'get_node_essentials("n8n-nodes-base.webhook") - Get webhook configuration', - 'get_node_essentials("n8n-nodes-base.slack") - Get Slack essentials' - ], - useCases: [ - 'Quickly configuring nodes without information overload', - 'Getting working examples for immediate use', - 'Understanding the most important node options', - 'Building workflows efficiently' - ], - performance: 'Extremely fast - returns pre-filtered data. Response size <5KB vs 100KB+ for full node info.', - bestPractices: [ - 'Always try this before get_node_info', - 'Use included examples as starting points', - 'Check commonPatterns for typical configurations', - 'Combine with validate_node_minimal for quick validation' - ], - pitfalls: [ - 'May not include rarely-used properties', - 'Some advanced options might be missing', - 'Use search_node_properties if specific property not found' - ], - relatedTools: ['get_node_info', 'search_node_properties', 'validate_node_minimal'] - } - }, - - list_nodes: { - name: 'list_nodes', - category: 'discovery', - essentials: { - description: 'List all available n8n nodes with optional filtering', - keyParameters: ['category', 'limit', 'onlyTriggers'], - example: 'list_nodes({category: "communication", limit: 20})', - performance: 'Fast - direct database query', - tips: [ - 'Great for browsing nodes by category', - 'Use onlyTriggers:true to find workflow starters' - ] - }, - full: { - description: 'Lists all available n8n nodes with comprehensive filtering options. Can filter by category, package, trigger status, and more. Returns complete node metadata.', - parameters: { - category: { type: 'string', description: 'Filter by category (e.g., "communication", "data")', required: false }, - limit: { type: 'number', description: 'Maximum results (default: 50)', required: false }, - offset: { type: 'number', description: 'Pagination offset', required: false }, - onlyTriggers: { type: 'boolean', description: 'Only show trigger nodes', required: false }, - onlyAITools: { type: 'boolean', description: 'Only show AI-capable nodes', required: false }, - package: { type: 'string', description: 'Filter by package name', required: false } - }, - returns: 'Array of nodes with complete metadata including type, name, description, category', - examples: [ - 'list_nodes() - Get first 50 nodes', - 'list_nodes({category: "trigger"}) - All trigger nodes', - 'list_nodes({onlyAITools: true}) - Nodes marked as AI tools', - 'list_nodes({package: "n8n-nodes-base", limit: 100}) - Core nodes' - ], - useCases: [ - 'Browsing available nodes by category', - 'Finding all triggers or webhooks', - 'Discovering AI-capable nodes', - 'Getting overview of available integrations' - ], - performance: 'Fast - uses indexed queries. Returns in <100ms even for large result sets.', - bestPractices: [ - 'Use categories for focused browsing', - 'Combine with search_nodes for keyword search', - 'Use pagination for large result sets', - 'Check onlyTriggers for workflow starting points' - ], - pitfalls: [ - 'No text search - use search_nodes for that', - 'Categories are predefined, not all nodes have them', - 'Large result sets without limit can be overwhelming' - ], - relatedTools: ['search_nodes', 'list_ai_tools', 'get_node_essentials'] - } - }, - - validate_node_minimal: { - name: 'validate_node_minimal', - category: 'validation', - essentials: { - description: 'Quick validation checking only required fields', - keyParameters: ['nodeType', 'config'], - example: 'validate_node_minimal("n8n-nodes-base.slack", {resource: "message", operation: "post"})', - performance: 'Very fast - minimal checks only', - tips: [ - 'Use for quick validation during configuration', - 'Follow up with validate_node_operation for full validation' - ] - }, - full: { - description: 'Performs minimal validation checking only required fields. Fastest validation option, perfect for iterative configuration. Checks if all required fields are present without complex dependency validation.', - parameters: { - nodeType: { type: 'string', description: 'Full node type', required: true }, - config: { type: 'object', description: 'Node configuration to validate', required: true } - }, - returns: 'Object with isValid boolean, missing required fields, and basic feedback', - examples: [ - 'validate_node_minimal("n8n-nodes-base.httpRequest", {url: "https://api.example.com"})', - 'validate_node_minimal("n8n-nodes-base.slack", {resource: "message", operation: "post", channel: "general"})' - ], - useCases: [ - 'Quick validation during iterative configuration', - 'Checking if minimum requirements are met', - 'Fast feedback loop while building', - 'Pre-validation before full check' - ], - performance: 'Extremely fast - only checks required fields. Typically <10ms.', - bestPractices: [ - 'Use during configuration for quick feedback', - 'Follow with validate_node_operation for complete validation', - 'Great for iterative development', - 'Combine with get_node_essentials for requirements' - ], - pitfalls: [ - 'Doesn\'t check field dependencies', - 'Won\'t catch configuration conflicts', - 'Missing optional but recommended fields' - ], - relatedTools: ['validate_node_operation', 'get_node_essentials', 'validate_workflow'] - } - }, - - validate_node_operation: { - name: 'validate_node_operation', - category: 'validation', - essentials: { - description: 'Full validation with operation-aware checking and helpful suggestions', - keyParameters: ['nodeType', 'config', 'profile'], - example: 'validate_node_operation("n8n-nodes-base.slack", {resource: "message", operation: "post", channel: "general"})', - performance: 'Moderate - comprehensive validation', - tips: [ - 'Provides specific error messages and fixes', - 'Use "strict" profile for production workflows' - ] - }, - full: { - description: 'Comprehensive validation that understands operation-specific requirements. Checks dependencies, validates field values, and provides helpful suggestions for fixing issues.', - parameters: { - nodeType: { type: 'string', description: 'Full node type', required: true }, - config: { type: 'object', description: 'Complete node configuration', required: true }, - profile: { type: 'string', description: 'Validation profile: "development" or "strict"', required: false } - }, - returns: 'Detailed validation results with errors, warnings, suggestions, and fixes', - examples: [ - 'validate_node_operation("n8n-nodes-base.httpRequest", {method: "POST", url: "{{$json.url}}", bodyParametersUi: {...}})', - 'validate_node_operation("n8n-nodes-base.postgres", {operation: "executeQuery", query: "SELECT * FROM users"}, "strict")' - ], - useCases: [ - 'Final validation before deployment', - 'Understanding complex field dependencies', - 'Getting suggestions for configuration improvements', - 'Validating operation-specific requirements' - ], - performance: 'Moderate speed - performs comprehensive checks. 50-200ms depending on complexity.', - bestPractices: [ - 'Use after validate_node_minimal passes', - 'Apply suggested fixes from response', - 'Use strict profile for production', - 'Check warnings even if validation passes' - ], - pitfalls: [ - 'Slower than minimal validation', - 'May be overkill for simple configurations', - 'Strict profile might be too restrictive for development' - ], - relatedTools: ['validate_node_minimal', 'validate_workflow', 'get_property_dependencies'] - } - }, - - get_node_for_task: { - name: 'get_node_for_task', - category: 'templates', - essentials: { - description: 'Get pre-configured node settings for common tasks', - keyParameters: ['task'], - example: 'get_node_for_task("send_slack_message")', - performance: 'Instant - returns pre-built configurations', - tips: [ - 'Use list_tasks() to see all available tasks', - 'Look for userMustProvide fields to complete' - ] - }, - full: { - description: 'Returns pre-configured node settings for common automation tasks. Each template includes the correct node type, operation settings, and clear markers for what needs user input.', - parameters: { - task: { type: 'string', description: 'Task identifier (use list_tasks to see all)', required: true } - }, - returns: 'Complete node configuration with parameters, position, and user guidance', - examples: [ - 'get_node_for_task("send_slack_message") - Slack message template', - 'get_node_for_task("receive_webhook") - Webhook trigger setup', - 'get_node_for_task("query_database") - Database query template' - ], - useCases: [ - 'Quickly setting up common automation patterns', - 'Learning correct node configurations', - 'Avoiding configuration mistakes', - 'Rapid workflow prototyping' - ], - performance: 'Instant - returns static templates. No computation required.', - bestPractices: [ - 'Check userMustProvide fields for required inputs', - 'Use list_tasks() to discover available templates', - 'Validate with validate_node_minimal after filling in', - 'Use as starting point, then customize' - ], - pitfalls: [ - 'Templates are generic - customize for specific needs', - 'Not all tasks have templates', - 'Some fields marked userMustProvide are critical' - ], - relatedTools: ['list_tasks', 'get_node_essentials', 'validate_node_minimal'] - } - }, - - n8n_create_workflow: { - name: 'n8n_create_workflow', - category: 'workflow_management', - essentials: { - description: 'Create a new workflow in n8n via API', - keyParameters: ['name', 'nodes', 'connections'], - example: 'n8n_create_workflow({name: "My Workflow", nodes: [...], connections: {...}})', - performance: 'API call - depends on n8n instance', - tips: [ - 'ALWAYS use node names in connections, never IDs', - 'Error handling properties go at NODE level, not inside parameters!', - 'Requires N8N_API_URL and N8N_API_KEY configuration' - ] - }, - full: { - description: 'Creates a new workflow in your n8n instance via API. Requires proper API configuration. Returns the created workflow with assigned ID.\n\n⚠️ CRITICAL: Error handling properties (onError, retryOnFail, etc.) are NODE-LEVEL properties, not inside parameters!', - parameters: { - name: { type: 'string', description: 'Workflow name', required: true }, - nodes: { type: 'array', description: 'Array of node configurations', required: true }, - connections: { type: 'object', description: 'Node connections (use names!)', required: true }, - settings: { type: 'object', description: 'Workflow settings', required: false }, - tags: { type: 'array', description: 'Tag IDs (not names)', required: false } - }, - returns: 'Created workflow object with id, name, nodes, connections, and metadata', - examples: [ - `// Basic workflow with proper error handling -n8n_create_workflow({ - name: "Slack Notification with Error Handling", - nodes: [ - { - id: "1", - name: "Webhook", - type: "n8n-nodes-base.webhook", - typeVersion: 2, - position: [250, 300], - parameters: { - path: "/webhook", - method: "POST" - }, - // ✅ CORRECT - Error handling at node level - onError: "continueRegularOutput" - }, - { - id: "2", - name: "Database Query", - type: "n8n-nodes-base.postgres", - typeVersion: 2.4, - position: [450, 300], - parameters: { - operation: "executeQuery", - query: "SELECT * FROM users" - }, - // ✅ CORRECT - Error handling at node level - onError: "continueErrorOutput", - retryOnFail: true, - maxTries: 3, - waitBetweenTries: 2000 - }, - { - id: "3", - name: "Error Handler", - type: "n8n-nodes-base.slack", - typeVersion: 2.2, - position: [650, 450], - parameters: { - resource: "message", - operation: "post", - channel: "#errors", - text: "Database query failed!" - } - } - ], - connections: { - "Webhook": { - main: [[{node: "Database Query", type: "main", index: 0}]] - }, - "Database Query": { - main: [[{node: "Success Handler", type: "main", index: 0}]], - error: [[{node: "Error Handler", type: "main", index: 0}]] // Error output - } - } -})` - ], - useCases: [ - 'Deploying workflows programmatically', - 'Automating workflow creation', - 'Migrating workflows between instances', - 'Creating workflows from templates', - 'Building error-resilient workflows' - ], - performance: 'Depends on n8n instance and network. Typically 100-500ms.', - bestPractices: [ - 'CRITICAL: Use node NAMES in connections, not IDs', - 'CRITICAL: Place error handling at NODE level, not in parameters', - 'Validate workflow before creating', - 'Use meaningful workflow names', - 'Add error handling to external service nodes', - 'Check n8n_health_check before creating' - ], - pitfalls: [ - 'Placing error handling properties inside parameters object', - 'Using node IDs in connections breaks UI display', - 'Workflow not automatically activated', - 'Tags must exist (use tag IDs not names)', - 'API must be configured correctly' - ], - relatedTools: ['validate_workflow', 'n8n_update_partial_workflow', 'n8n_list_workflows'] - } - }, - - n8n_update_partial_workflow: { - name: 'n8n_update_partial_workflow', - category: 'workflow_management', - essentials: { - description: 'Update workflows using diff operations - only send changes, not entire workflow', - keyParameters: ['id', 'operations'], - example: 'n8n_update_partial_workflow({id: "123", operations: [{type: "updateNode", nodeName: "Slack", changes: {onError: "continueRegularOutput"}}]})', - performance: '80-90% more efficient than full updates', - tips: [ - 'Maximum 5 operations per request', - 'Can reference nodes by name or ID', - 'Error handling properties go at NODE level, not inside parameters!' - ] - }, - full: { - description: 'Update existing workflows using diff operations. Much more efficient than full updates as it only sends the changes. Supports 13 different operation types.\n\n⚠️ CRITICAL: Error handling properties (onError, retryOnFail, maxTries, etc.) are NODE-LEVEL properties, not parameters!', - parameters: { - id: { type: 'string', description: 'Workflow ID to update', required: true }, - operations: { type: 'array', description: 'Array of diff operations (max 5)', required: true }, - validateOnly: { type: 'boolean', description: 'Only validate without applying', required: false } - }, - returns: 'Updated workflow with applied changes and operation results', - examples: [ - `// Update node parameters (properties inside parameters object) -n8n_update_partial_workflow({ - id: "123", - operations: [{ - type: "updateNode", - nodeName: "Slack", - changes: { - "parameters.channel": "#general", // Nested property - "parameters.text": "Hello world" // Nested property - } - }] -})`, - `// Update error handling (NODE-LEVEL properties, NOT inside parameters!) -n8n_update_partial_workflow({ - id: "123", - operations: [{ - type: "updateNode", - nodeName: "HTTP Request", - changes: { - onError: "continueErrorOutput", // ✅ Correct - node level - retryOnFail: true, // ✅ Correct - node level - maxTries: 3, // ✅ Correct - node level - waitBetweenTries: 2000 // ✅ Correct - node level - } - }] -})`, - `// WRONG - Don't put error handling inside parameters! -// ❌ BAD: changes: {"parameters.onError": "continueErrorOutput"} -// ✅ GOOD: changes: {onError: "continueErrorOutput"}`, - `// Add error connection between nodes -n8n_update_partial_workflow({ - id: "123", - operations: [{ - type: "addConnection", - source: "Database Query", - target: "Error Handler", - sourceOutput: "error", // Error output - targetInput: "main" - }] -})` - ], - useCases: [ - 'Updating node configurations', - 'Adding error handling to nodes', - 'Adding/removing connections', - 'Enabling/disabling nodes', - 'Moving nodes in canvas', - 'Updating workflow metadata' - ], - performance: 'Very efficient - only sends changes. 80-90% less data than full updates.', - bestPractices: [ - 'Error handling properties (onError, retryOnFail, etc.) go at NODE level, not in parameters', - 'Use dot notation for nested properties: "parameters.url"', - 'Batch related operations together', - 'Use validateOnly:true to test first', - 'Reference nodes by name for clarity' - ], - pitfalls: [ - 'Placing error handling properties inside parameters (common mistake!)', - 'Maximum 5 operations per request', - 'Some operations have dependencies', - 'Node must exist for update operations', - 'Connection nodes must both exist' - ], - relatedTools: ['n8n_get_workflow', 'n8n_update_full_workflow', 'validate_workflow'] - } - }, - - // Code Node specific documentation - code_node_guide: { - name: 'code_node_guide', - category: 'code_node', - essentials: { - description: 'Comprehensive guide for writing Code node JavaScript and Python', - keyParameters: ['topic'], - example: 'tools_documentation({topic: "code_node_guide"})', - performance: 'Instant - returns documentation', - tips: [ - 'Essential reading before writing Code node scripts', - 'Covers all built-in variables and helpers', - 'Includes common patterns and error handling' - ] - }, - full: { - description: `Complete reference for the n8n Code node, covering JavaScript and Python execution environments, built-in variables, helper functions, and best practices. - -## Code Node Basics - -The Code node allows custom JavaScript or Python code execution within workflows. It runs in a sandboxed environment with access to n8n-specific variables and helpers. - -### JavaScript Environment -- **ES2022 support** with async/await -- **Built-in libraries**: - - **luxon** (DateTime) - Date/time manipulation - - **jmespath** - JSON queries via $jmespath() - - **crypto** - Available via require('crypto') despite editor warnings! -- **Node.js globals**: Buffer, process.env (limited) -- **require() IS available** for built-in modules only (crypto, util, etc.) -- **No npm packages** - only Node.js built-ins and n8n-provided libraries - -### Python Environment -- **Python 3.10+** with standard library (Pyodide runtime) -- **No pip install** - standard library only -- **Variables use underscore prefix**: \`_input\`, \`_json\`, \`_jmespath\` (not \`$\`) -- **item.json is JsProxy**: Use \`.to_py()\` to convert to Python dict -- **Shared state** between Code nodes in same execution - -## Essential Variables - -### $input -Access to all incoming data: -\`\`\`javascript -// Get all items from all inputs -const allItems = $input.all(); // Returns: Item[][] - -// Get items from specific input (0-indexed) -const firstInput = $input.all(0); // Returns: Item[] - -// Get first item from first input -const firstItem = $input.first(); // Returns: Item - -// Get last item from first input -const lastItem = $input.last(); // Returns: Item - -// Get specific item by index -const item = $input.item(2); // Returns: Item at index 2 -\`\`\` - -### items -Direct access to incoming items (legacy, prefer $input): -\`\`\`javascript -// items is equivalent to $input.all()[0] -for (const item of items) { - console.log(item.json); // Access JSON data - console.log(item.binary); // Access binary data -} -\`\`\` - -### $json -Shortcut to current item's JSON data (only in "Run Once for Each Item" mode): -\`\`\`javascript -// These are equivalent in single-item mode: -const value1 = $json.fieldName; -const value2 = items[0].json.fieldName; -\`\`\` - -### Accessing Other Nodes -Access data from other nodes using $('Node Name') syntax: -\`\`\`javascript -// Access another node's output - use $('Node Name') NOT $node -const prevData = $('Previous Node').all(); -const firstItem = $('Previous Node').first(); -const specificItem = $('Previous Node').item(0); - -// Get node parameter -const webhookUrl = $('Webhook').params.path; - -// Python uses underscore prefix -const pythonData = _('Previous Node').all(); -\`\`\` - -⚠️ **Expression vs Code Node Syntax**: -- **Expressions**: \`{{$node['Previous Node'].json.field}}\` -- **Code Node**: \`$('Previous Node').first().json.field\` -- These are NOT interchangeable! - -### $workflow -Workflow metadata: -\`\`\`javascript -const workflowId = $workflow.id; -const workflowName = $workflow.name; -const isActive = $workflow.active; -\`\`\` - -### $execution -Execution context: -\`\`\`javascript -const executionId = $execution.id; -const executionMode = $execution.mode; // 'manual', 'trigger', etc. -const resumeUrl = $execution.resumeUrl; // For wait nodes -\`\`\` - -### $prevNode -Access to the immediate previous node: -\`\`\`javascript -const prevOutput = $prevNode.outputIndex; // Which output triggered this -const prevData = $prevNode.data; // Previous node's data -const prevName = $prevNode.name; // Previous node's name -\`\`\` - -## Helper Functions - -### Date/Time (Luxon) -\`\`\`javascript -// Current time -const now = DateTime.now(); -const iso = now.toISO(); - -// Parse dates -const date = DateTime.fromISO('2024-01-01'); -const formatted = date.toFormat('yyyy-MM-dd'); - -// Time math -const tomorrow = now.plus({ days: 1 }); -const hourAgo = now.minus({ hours: 1 }); -\`\`\` - -### JSON Queries (JMESPath) -\`\`\`javascript -// n8n uses $jmespath() - NOTE: parameter order is reversed from standard JMESPath! -const data = { users: [{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }] }; -const names = $jmespath(data, 'users[*].name'); // ['John', 'Jane'] - -// ⚠️ IMPORTANT: Numeric literals in filters need BACKTICKS in n8n! -const adults = $jmespath(data, 'users[?age >= \`18\`]'); // ✅ CORRECT - backticks around 18 -const seniors = $jmespath(data, 'users[?age >= \`65\`]'); // ✅ CORRECT - -// ❌ WRONG - This will cause a syntax error! -// const adults = $jmespath(data, 'users[?age >= 18]'); // Missing backticks - -// More filter examples with proper backticks: -const expensive = $jmespath(items, '[?price > \`100\`]'); -const inStock = $jmespath(products, '[?quantity >= \`1\`]'); -const highPriority = $jmespath(tasks, '[?priority == \`1\`]'); - -// String comparisons don't need backticks -const activeUsers = $jmespath(data, 'users[?status == "active"]'); - -// Python uses underscore prefix -const pythonAdults = _jmespath(data, 'users[?age >= \`18\`]'); -\`\`\` - -⚠️ **CRITICAL DIFFERENCES** from standard JMESPath: -1. **Parameter order is REVERSED**: - - **Expression**: \`{{$jmespath("query", data)}}\` - - **Code Node**: \`$jmespath(data, "query")\` -2. **Numeric literals in filters MUST use backticks**: \`[?age >= \`18\`]\` - - This is n8n-specific and differs from standard JMESPath documentation! - -### Available Functions and Libraries - -#### Built-in Node.js Modules (via require) -\`\`\`javascript -// ✅ These modules ARE available via require(): -const crypto = require('crypto'); // Cryptographic functions -const util = require('util'); // Utility functions -const querystring = require('querystring'); // URL query string utilities - -// Example: Generate secure random token -const crypto = require('crypto'); -const token = crypto.randomBytes(32).toString('hex'); -const uuid = crypto.randomUUID(); -\`\`\` - -**Note**: The editor may show errors for require() but it WORKS at runtime! - -#### Standalone Functions (Global Scope) -\`\`\`javascript -// ✅ Workflow static data - persists between executions -// IMPORTANT: These are standalone functions, NOT methods on $helpers! -const staticData = $getWorkflowStaticData('global'); // Global static data -const nodeData = $getWorkflowStaticData('node'); // Node-specific data - -// Example: Counter that persists -const staticData = $getWorkflowStaticData('global'); -staticData.counter = (staticData.counter || 0) + 1; - -// ❌ WRONG - This will cause "$helpers is not defined" error: -// const data = $helpers.getWorkflowStaticData('global'); - -// JMESPath queries - note the parameter order! -const result = $jmespath(data, 'users[*].name'); -\`\`\` - -#### $helpers Object (When Available) -\`\`\`javascript -// Some n8n versions provide $helpers with these methods: -// (Always test availability in your n8n instance) - -// HTTP requests -const response = await $helpers.httpRequest({ - method: 'GET', - url: 'https://api.example.com/data', - headers: { 'Authorization': 'Bearer token' } -}); - -// Binary data preparation -const binaryData = await $helpers.prepareBinaryData( - Buffer.from('content'), - 'file.txt', - 'text/plain' -); - -// Check if $helpers exists before using: -if (typeof $helpers !== 'undefined' && $helpers.httpRequest) { - // Use $helpers.httpRequest -} else { - throw new Error('HTTP requests not available in this n8n version'); -} -\`\`\` - -#### Important Notes: -- **$getWorkflowStaticData()** is ALWAYS a standalone function -- **require()** works for built-in Node.js modules despite editor warnings -- **$helpers** availability varies by n8n version - always check first -- Python uses underscore prefix: \`_getWorkflowStaticData()\`, \`_jmespath()\` -- Editor red underlines are often false positives - test at runtime! - -## Return Format - -Code nodes MUST return an array of objects with 'json' property: - -\`\`\`javascript -// ✅ CORRECT - Array of objects with json property -return [ - { json: { id: 1, name: 'Item 1' } }, - { json: { id: 2, name: 'Item 2' } } -]; - -// ✅ CORRECT - Single item (still wrapped in array) -return [{ json: { result: 'success' } }]; - -// ✅ CORRECT - With binary data -return [{ - json: { filename: 'report.pdf' }, - binary: { - data: { - data: base64String, - mimeType: 'application/pdf', - fileName: 'report.pdf' - } - } -}]; - -// ❌ WRONG - Not an array -return { json: { result: 'success' } }; - -// ❌ WRONG - No json property -return [{ result: 'success' }]; - -// ❌ WRONG - Not wrapped in object -return ['item1', 'item2']; -\`\`\` - -## Common Patterns - -### Data Transformation -\`\`\`javascript -// Transform all items -const transformedItems = []; -for (const item of items) { - transformedItems.push({ - json: { - ...item.json, - processed: true, - timestamp: DateTime.now().toISO(), - uppercaseName: item.json.name?.toUpperCase() - } - }); -} -return transformedItems; -\`\`\` - -### Filtering Items -\`\`\`javascript -// Filter items based on condition -return items - .filter(item => item.json.status === 'active') - .map(item => ({ json: item.json })); -\`\`\` - -### Aggregation -\`\`\`javascript -// Aggregate data from all items -const total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0); -const average = total / items.length; - -return [{ - json: { - total, - average, - count: items.length, - items: items.map(i => i.json) - } -}]; -\`\`\` - -### Error Handling -\`\`\`javascript -// Safe data access with defaults -const results = []; -for (const item of items) { - try { - const value = item.json?.nested?.field || 'default'; - results.push({ - json: { - processed: value, - status: 'success' - } - }); - } catch (error) { - results.push({ - json: { - error: error.message, - status: 'failed', - originalItem: item.json - } - }); - } -} -return results; -\`\`\` - -### Working with APIs -\`\`\`javascript -// Make HTTP request and process response -try { - const response = await $helpers.httpRequest({ - method: 'POST', - url: 'https://api.example.com/process', - body: { - data: items.map(item => item.json) - }, - headers: { - 'Content-Type': 'application/json' - } - }); - - return [{ json: response }]; -} catch (error) { - throw new Error(\`API request failed: \${error.message}\`); -} -\`\`\` - -### Async Operations -\`\`\`javascript -// Process items with async operations -const results = []; -for (const item of items) { - // Simulate async operation - await new Promise(resolve => setTimeout(resolve, 100)); - - results.push({ - json: { - ...item.json, - processedAt: new Date().toISOString() - } - }); -} -return results; -\`\`\` - -### Webhook Data Access (CRITICAL!) -\`\`\`javascript -// ⚠️ WEBHOOK DATA IS NESTED UNDER 'body' PROPERTY! -// This is a common source of errors in webhook-triggered workflows - -// ❌ WRONG - This will be undefined for webhook data: -const command = items[0].json.testCommand; - -// ✅ CORRECT - Webhook data is wrapped in 'body': -const command = items[0].json.body.testCommand; - -// Complete webhook data processing example: -const webhookData = items[0].json.body; // Get the actual webhook payload -const headers = items[0].json.headers; // HTTP headers are separate -const query = items[0].json.query; // Query parameters are separate - -// Process webhook payload -return [{ - json: { - command: webhookData.testCommand, - user: webhookData.user, - timestamp: DateTime.now().toISO(), - requestId: headers['x-request-id'], - source: query.source || 'unknown' - } -}]; - -// For other trigger nodes (non-webhook), data is directly under json: -// - Schedule Trigger: items[0].json contains timestamp -// - Database Trigger: items[0].json contains row data -// - File Trigger: items[0].json contains file info -\`\`\` - -## Python Code Examples - -### Basic Python Structure -\`\`\`python -import json -from datetime import datetime - -# Access items - Python uses underscore prefix for built-in variables -results = [] -for item in _input.all(): - # IMPORTANT: item.json is NOT a standard Python dict! - # Use to_py() to convert to a proper Python dict - processed_item = item.json.to_py() # Converts JsProxy to Python dict - processed_item['timestamp'] = datetime.now().isoformat() - results.append({'json': processed_item}) - -return results -\`\`\` - -### Python Data Processing -\`\`\`python -# Aggregate data - use _input.all() to get items -items = _input.all() -total = sum(item.json.get('amount', 0) for item in items) -average = total / len(items) if items else 0 - -# For safe dict operations, convert JsProxy to Python dict -safe_items = [] -for item in items: - # Convert JsProxy to dict to avoid KeyError with null values - safe_dict = item.json.to_py() - safe_items.append(safe_dict) - -# Return aggregated result -return [{ - 'json': { - 'total': total, - 'average': average, - 'count': len(items), - 'processed_at': datetime.now().isoformat(), - 'items': safe_items # Now these are proper Python dicts - } -}] -\`\`\` - -## Code Node as AI Tool - -Code nodes can be used as custom tools for AI agents: - -\`\`\`javascript -// Code node configured as AI tool -// Name: "Calculate Discount" -// Description: "Calculates discount based on quantity" - -const quantity = $json.quantity || 1; -const basePrice = $json.price || 0; - -let discount = 0; -if (quantity >= 100) discount = 0.20; -else if (quantity >= 50) discount = 0.15; -else if (quantity >= 20) discount = 0.10; -else if (quantity >= 10) discount = 0.05; - -const discountAmount = basePrice * quantity * discount; -const finalPrice = (basePrice * quantity) - discountAmount; - -return [{ - json: { - quantity, - basePrice, - discountPercentage: discount * 100, - discountAmount, - finalPrice, - savings: discountAmount - } -}]; -\`\`\` - -## Security Considerations - -### Available Security Features -\`\`\`javascript -// ✅ Crypto IS available despite editor warnings! -const crypto = require('crypto'); - -// Generate secure random values -const randomBytes = crypto.randomBytes(32); -const randomUUID = crypto.randomUUID(); - -// Create hashes -const hash = crypto.createHash('sha256') - .update('data to hash') - .digest('hex'); - -// HMAC for signatures -const hmac = crypto.createHmac('sha256', 'secret-key') - .update('data to sign') - .digest('hex'); -\`\`\` - -### Banned Operations -- No file system access (fs module) - except read-only for some paths -- No network requests except via $helpers.httpRequest -- No child process execution -- No external npm packages (only built-in Node.js modules) -- No eval() or Function() constructor - -### Safe Practices -\`\`\`javascript -// ✅ SAFE - Use crypto for secure operations -const crypto = require('crypto'); -const token = crypto.randomBytes(32).toString('hex'); - -// ✅ SAFE - Use built-in JSON parsing -const parsed = JSON.parse(jsonString); - -// ❌ UNSAFE - Never use eval -const parsed = eval('(' + jsonString + ')'); - -// ✅ SAFE - Validate input -if (typeof item.json.userId !== 'string') { - throw new Error('userId must be a string'); -} - -// ✅ SAFE - Sanitize for logs -const safeLog = String(userInput).substring(0, 100); - -// ✅ SAFE - Time-safe comparison for secrets -const expectedToken = 'abc123'; -const providedToken = item.json.token; -const tokensMatch = crypto.timingSafeEqual( - Buffer.from(expectedToken), - Buffer.from(providedToken || '') -); -\`\`\` - -## Debugging Tips - -### Console Output -\`\`\`javascript -// Console.log appears in n8n execution logs -console.log('Processing item:', item.json.id); -console.error('Error details:', error); - -// Return debug info in development -return [{ - json: { - result: processedData, - debug: { - itemCount: items.length, - executionId: $execution.id, - timestamp: new Date().toISOString() - } - } -}]; -\`\`\` - -### Error Messages -\`\`\`javascript -// Provide helpful error context -if (!item.json.requiredField) { - throw new Error(\`Missing required field 'requiredField' in item \${items.indexOf(item)}\`); -} - -// Include original data in errors -try { - // processing... -} catch (error) { - throw new Error(\`Failed to process item \${item.json.id}: \${error.message}\`); -} -\`\`\` - -## Performance Best Practices - -1. **Avoid nested loops** when possible -2. **Use array methods** (map, filter, reduce) for clarity -3. **Limit HTTP requests** - batch when possible -4. **Return early** for error conditions -5. **Keep state minimal** - Code nodes are stateless between executions - -## Common Mistakes to Avoid - -1. **Forgetting to return an array** -2. **Not wrapping in json property** -3. **Modifying items array directly** -4. **Using undefined variables** -5. **Infinite loops with while statements** -6. **Not handling missing data gracefully** -7. **Forgetting await for async operations**`, - parameters: { - topic: { type: 'string', description: 'Specific Code node topic (optional)', required: false } - }, - returns: 'Comprehensive Code node documentation and examples', - examples: [ - 'tools_documentation({topic: "code_node_guide"}) - Full guide', - 'tools_documentation({topic: "code_node_guide", depth: "full"}) - Complete reference' - ], - useCases: [ - 'Learning Code node capabilities', - 'Understanding built-in variables', - 'Finding the right helper function', - 'Debugging Code node issues', - 'Building custom AI tools' - ], - performance: 'Instant - returns static documentation', - bestPractices: [ - 'Read before writing Code nodes', - 'Reference for variable names', - 'Copy examples as starting points', - 'Check security considerations' - ], - pitfalls: [ - 'Not all Node.js features available', - 'Python has limited libraries', - 'State not preserved between executions' - ], - relatedTools: ['get_node_essentials', 'validate_node_operation', 'get_node_for_task'] - } - } -}; +import { toolsDocumentation, ToolDocumentation } from './tool-docs'; export function getToolDocumentation(toolName: string, depth: 'essentials' | 'full' = 'essentials'): string { const tool = toolsDocumentation[toolName]; @@ -1209,201 +61,92 @@ export function getToolsOverview(depth: 'essentials' | 'full' = 'essentials'): s if (depth === 'essentials') { return `# n8n MCP Tools Quick Reference -Welcome! Here's how to efficiently work with n8n nodes: +Welcome to n8n-mcp! This tool provides comprehensive access to n8n node documentation. -## Essential Workflow -1. **Find**: search_nodes({query: "slack"}) -2. **Configure**: get_node_essentials("n8n-nodes-base.slack") -3. **Validate**: validate_node_minimal() → validate_node_operation() -4. **Deploy**: n8n_create_workflow() (if API configured) +## Most Used Tools -## Key Tips -- Always use get_node_essentials instead of get_node_info (95% smaller!) -- Use node NAMES in connections, never IDs -- Try get_node_for_task() for common patterns -- Call validate_node_minimal() for quick checks +### 🔍 Discovery +- **search_nodes**: Search nodes by keyword +- **list_nodes**: List all nodes with filters +- **list_ai_tools**: See all AI-capable nodes -## Get Help -- tools_documentation({topic: "search_nodes"}) - Get help for specific tool -- tools_documentation({topic: "code_node_guide"}) - Essential Code node reference -- tools_documentation({topic: "overview", depth: "full"}) - See complete guide -- list_tasks() - See available task templates - -Available tools: ${Object.keys(toolsDocumentation).join(', ')}`; - } - - // Full overview - return `# n8n MCP Tools Complete Guide - -## Overview -The n8n MCP provides 39 tools to help you discover, configure, validate, and deploy n8n workflows. Tools are organized into categories for easy discovery. - -## Tool Categories - -### Discovery Tools -- **search_nodes**: Find nodes by keyword (uses OR logic) -- **list_nodes**: Browse nodes by category, package, or type -- **list_ai_tools**: See all AI-capable nodes (263 available) - -### Configuration Tools +### ⚙️ Configuration - **get_node_essentials**: Get key properties only (<5KB vs 100KB+) -- **get_node_info**: Get complete node details (use sparingly) -- **search_node_properties**: Find specific properties in large nodes -- **get_property_dependencies**: Understand field relationships +- **get_node_info**: Get complete node schema +- **search_node_properties**: Find specific properties -### Validation Tools +### ✅ Validation - **validate_node_minimal**: Quick required field check -- **validate_node_operation**: Full operation-aware validation +- **validate_node_operation**: Full validation with fixes - **validate_workflow**: Complete workflow validation -- **validate_workflow_connections**: Check node connections -- **validate_workflow_expressions**: Validate n8n expressions -### Task & Template Tools -- **list_tasks**: See available task templates +### 📋 Templates +- **list_tasks**: See common task templates - **get_node_for_task**: Get pre-configured nodes -- **list_node_templates**: Find workflow templates -- **search_templates**: Search template library +- **search_templates**: Find workflow templates -### Workflow Management (requires API config) -- **n8n_create_workflow**: Create new workflows -- **n8n_update_partial_workflow**: Efficient diff-based updates -- **n8n_update_full_workflow**: Replace entire workflow -- **n8n_list_workflows**: List workflows with filtering +### 🔧 n8n Management (requires API config) +- **n8n_create_workflow**: Create workflows +- **n8n_update_partial_workflow**: Update with diffs +- **n8n_health_check**: Test API connectivity -## Recommended Patterns +## Quick Start Examples -### Building a Simple Workflow \`\`\`javascript -// 1. Find what you need -search_nodes({query: "webhook"}) +// Find a node search_nodes({query: "slack"}) -// 2. Get configurations -get_node_essentials("n8n-nodes-base.webhook") -get_node_essentials("n8n-nodes-base.slack") +// Get essential config +get_node_essentials("nodes-base.slack") -// 3. Build and validate -const workflow = { - name: "My Webhook to Slack", - nodes: [...], - connections: {"Webhook": {main: [[{node: "Slack", type: "main", index: 0}]]}} -}; -validate_workflow(workflow) - -// 4. Deploy (if API configured) -n8n_create_workflow(workflow) -\`\`\` - -### Working with Code Nodes -The Code node is essential for custom logic. Always reference the guide: -\`\`\`javascript -// Get comprehensive Code node documentation -tools_documentation({topic: "code_node_guide"}) - -// Common Code node pattern -get_node_essentials("n8n-nodes-base.code") -// Returns minimal config with JavaScript/Python examples - -// Validate Code node configuration -validate_node_operation("n8n-nodes-base.code", { - language: "javaScript", - jsCode: "return items.map(item => ({json: {...item.json, processed: true}}))" -}) -\`\`\` - -### Node-Level Properties Reference -⚠️ **CRITICAL**: These properties go at the NODE level, not inside parameters! - -\`\`\`javascript -{ - // Required properties - "id": "unique_id", - "name": "Node Name", - "type": "n8n-nodes-base.postgres", - "typeVersion": 2.6, - "position": [450, 300], - "parameters": { /* operation-specific params */ }, - - // Optional properties (all at node level!) - "credentials": { - "postgres": { - "id": "cred-id", - "name": "My Postgres" - } - }, - "disabled": false, // Disable node execution - "notes": "Internal note", // Node documentation - "notesInFlow": true, // Show notes on canvas - "executeOnce": true, // Execute only once per run - - // Error handling (at node level!) - "onError": "continueErrorOutput", // or "continueRegularOutput", "stopWorkflow" - "retryOnFail": true, - "maxTries": 3, - "waitBetweenTries": 2000, - "alwaysOutputData": true, - - // Deprecated (use onError instead) - "continueOnFail": false -} -\`\`\` - -**Common properties explained:** -- **credentials**: Links to credential sets (use credential ID and name) -- **disabled**: Node won't execute when true -- **notes**: Internal documentation for the node -- **notesInFlow**: Display notes on workflow canvas -- **executeOnce**: Execute node only once even with multiple input items -- **onError**: Modern error handling - what to do on failure -- **retryOnFail**: Automatically retry failed executions -- **maxTries**: Number of retry attempts (with retryOnFail) -- **waitBetweenTries**: Milliseconds between retries -- **alwaysOutputData**: Output data even on error (for debugging) - -### Using AI Tools -Any node can be an AI tool! Connect it to an AI Agent's ai_tool port: -\`\`\`javascript -get_node_as_tool_info("n8n-nodes-base.slack") -// Returns how to configure Slack as an AI tool -\`\`\` - -### Efficient Updates -Use partial updates to save 80-90% bandwidth: -\`\`\`javascript -n8n_update_partial_workflow({ - id: "workflow-id", - operations: [ - {type: "updateNode", nodeId: "Slack", updates: {parameters: {channel: "general"}}} - ] -}) +// Validate configuration +validate_node_minimal("nodes-base.slack", {resource: "message", operation: "post"}) \`\`\` ## Performance Guide -- **Fastest**: get_node_essentials, validate_node_minimal, list_tasks -- **Fast**: search_nodes, list_nodes, get_node_for_task -- **Moderate**: validate_node_operation, n8n_update_partial_workflow -- **Slow**: get_node_info (100KB+), validate_workflow (full analysis) +- **Instant**: <10ms (static/cached) +- **Fast**: <100ms (queries/generation) +- **Moderate**: 100-500ms (validation/analysis) +- **Network-dependent**: Varies with API -## Common Pitfalls to Avoid -1. Using get_node_info when get_node_essentials would work -2. Using node IDs instead of names in connections -3. Not validating before creating workflows -4. Searching with long phrases instead of keywords -5. Forgetting to configure N8N_API_URL for management tools +For detailed tool documentation, use: +\`tools_documentation({topic: "tool_name", depth: "full"})\``; + } -## Getting More Help -- Use tools_documentation({topic: "toolname"}) for any tool -- Check CLAUDE.md for latest updates and examples -- Run n8n_health_check() to verify API connectivity`; + // Full overview + const categories = getAllCategories(); + return `# n8n MCP Tools Complete Reference + +## Available Tools by Category + +${categories.map(cat => { + const tools = getToolsByCategory(cat); + return `### ${cat.charAt(0).toUpperCase() + cat.slice(1)} +${tools.map(toolName => { + const tool = toolsDocumentation[toolName]; + return `- **${toolName}**: ${tool.essentials.description}`; +}).join('\n')}`; +}).join('\n\n')} + +## Tool Categories Explained + +- **discovery**: Find and explore n8n nodes +- **configuration**: Configure and understand nodes +- **validation**: Validate node and workflow configurations +- **templates**: Pre-built configurations and examples +- **workflow_management**: Create and manage n8n workflows (requires API) +- **system**: MCP system tools and diagnostics + +For specific tool documentation, use: +\`tools_documentation({topic: "tool_name", depth: "full"})\``; } -export function searchToolDocumentation(query: string): string[] { +export function searchToolDocumentation(keyword: string): string[] { const results: string[] = []; - const searchTerms = query.toLowerCase().split(' '); for (const [toolName, tool] of Object.entries(toolsDocumentation)) { - const searchText = `${toolName} ${tool.essentials.description} ${tool.category}`.toLowerCase(); - if (searchTerms.some(term => searchText.includes(term))) { + const searchText = `${toolName} ${tool.essentials.description} ${tool.full.description}`.toLowerCase(); + if (searchText.includes(keyword.toLowerCase())) { results.push(toolName); } } diff --git a/scripts/test-tools-documentation.ts b/src/scripts/test-tools-documentation.ts similarity index 92% rename from scripts/test-tools-documentation.ts rename to src/scripts/test-tools-documentation.ts index c938a41..be7d430 100644 --- a/scripts/test-tools-documentation.ts +++ b/src/scripts/test-tools-documentation.ts @@ -1,9 +1,7 @@ -import { N8NDocumentationMCPServer } from '../src/mcp/server'; -import path from 'path'; +import { N8NDocumentationMCPServer } from '../mcp/server'; async function testToolsDocumentation() { - const dbPath = path.join(__dirname, '..', 'nodes.db'); - const server = new N8NDocumentationMCPServer(dbPath); + const server = new N8NDocumentationMCPServer(); console.log('=== Testing tools_documentation tool ===\n');