feat: Tool Consolidation - Reduce MCP Tools by 38% (v2.26.0) (#439)

* feat: Remove 9 low-value tools and consolidate n8n_health_check (v2.25.0)

Telemetry-driven tool cleanup to improve API clarity:

**Removed Tools (9):**
- list_nodes - Use search_nodes instead
- list_ai_tools - Use search_nodes with isAITool filter
- list_tasks - Low usage (0.02%)
- get_database_statistics - Use n8n_health_check
- list_templates - Use search_templates or get_templates_for_task
- get_node_as_tool_info - Documented in get_node
- validate_workflow_connections - Use validate_workflow
- validate_workflow_expressions - Use validate_workflow
- n8n_list_available_tools - Use n8n_health_check
- n8n_diagnostic - Merged into n8n_health_check

**Consolidated Tool:**
- n8n_health_check now supports mode='diagnostic' for detailed troubleshooting

**Tool Count:**
- Before: 38 tools
- After: 31 tools (18% reduction)

Concieved by Romuald Członkowski - www.aiadvisors.pl/en

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

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: cleanup stale references and update tests after tool removal

- Remove handleListAvailableTools dead code from handlers-n8n-manager.ts
- Update error messages to reference n8n_health_check(mode="diagnostic") instead of n8n_diagnostic
- Update tool counts in diagnostic messages (14 doc tools, 31 total)
- Fix error-handling.test.ts to use valid tools (search_nodes, tools_documentation)
- Remove obsolete list-tools.test.ts integration tests
- Remove unused ListToolsResponse type from response-types.ts
- Update tools.ts QUICK REFERENCE to remove list_nodes references
- Update tools-documentation.ts to remove references to removed tools
- Update tool-docs files to remove stale relatedTools references
- Fix tools.test.ts to not test removed tools (list_nodes, list_ai_tools, etc.)
- Fix parameter-validation.test.ts to not test removed tools
- Update handlers-n8n-manager.test.ts error message expectations

All 399 MCP unit tests now pass.

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

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

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: update integration tests to use valid tools after v2.25.0 removal

Replaced all references to removed tools in integration tests:
- list_nodes -> search_nodes
- get_database_statistics -> tools_documentation
- list_ai_tools -> search_nodes/tools_documentation
- list_tasks -> tools_documentation
- get_node_as_tool_info -> removed test section

Updated test files:
- tests/integration/mcp-protocol/basic-connection.test.ts
- tests/integration/mcp-protocol/performance.test.ts
- tests/integration/mcp-protocol/session-management.test.ts
- tests/integration/mcp-protocol/test-helpers.ts
- tests/integration/mcp-protocol/tool-invocation.test.ts
- tests/integration/telemetry/mcp-telemetry.test.ts
- tests/unit/mcp/disabled-tools.test.ts
- tests/unit/mcp/tools-documentation.test.ts

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

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

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Tool consolidation v2.26.0 - reduce tools by 38% (31 → 19)

Major consolidation of MCP tools using mode-based parameters for better
AI agent ergonomics:

Node Tools:
- get_node_documentation → get_node with mode='documentation'
- search_node_properties → get_node with mode='search_properties'
- get_property_dependencies → removed

Validation Tools:
- validate_node_operation + validate_node_minimal → validate_node with mode param

Template Tools:
- list_node_templates → search_templates with searchMode='nodes'
- search_templates_by_metadata → search_templates with searchMode='metadata'
- get_templates_for_task → search_templates with searchMode='task'

Workflow Getters:
- n8n_get_workflow_details/structure/minimal → n8n_get_workflow with mode param

Execution Tools:
- n8n_list/get/delete_execution → n8n_executions with action param

Test updates for all consolidated tools.

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

Co-Authored-By: Claude <noreply@anthropic.com>

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

* docs: comprehensive README update for v2.26.0 tool consolidation

- Quick Start: Added hosted service (dashboard.n8n-mcp.com) as primary option
- Self-hosting: Renamed options to A (npx), B (Docker), C (Local), D (Railway)
- Removed: "Memory Leak Fix (v2.20.2)" section (outdated)
- Removed: "Known Issues" section (outdated container management)
- Claude Project Setup: Updated all tool references to v2.26.0 consolidated tools
  - validate_node({mode: 'minimal'|'full'}) instead of separate tools
  - search_templates({searchMode: ...}) unified template search
  - get_node({mode: 'docs'|'search_properties'}) for documentation
  - n8n_executions({action: ...}) unified execution management
- Available MCP Tools: Updated to show 19 consolidated tools (7 core + 12 mgmt)
- Recent Updates: Simplified to just link to CHANGELOG.md

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

Co-Authored-By: Claude <noreply@anthropic.com>

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

* fix: update tool count from 31 to 19 in diagnostic message

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

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(tests): update tool count expectations for v2.26.0

Update handlers-n8n-manager.test.ts to expect new consolidated
tool counts (7/12/19) after v2.26.0 tool consolidation.

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

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

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2025-11-25 18:39:00 +01:00
committed by GitHub
parent 9ee4b9492f
commit ff69e4ccca
28 changed files with 925 additions and 1766 deletions

View File

@@ -1553,7 +1553,7 @@ export async function handleHealthCheck(context?: InstanceContext): Promise<McpT
'1. Verify n8n instance is running',
'2. Check N8N_API_URL is correct',
'3. Verify N8N_API_KEY has proper permissions',
'4. Run n8n_diagnostic for detailed analysis'
'4. Run n8n_health_check with mode="diagnostic" for detailed analysis'
]
}
};
@@ -1566,63 +1566,6 @@ export async function handleHealthCheck(context?: InstanceContext): Promise<McpT
}
}
export async function handleListAvailableTools(context?: InstanceContext): Promise<McpToolResponse> {
const tools = [
{
category: 'Workflow Management',
tools: [
{ name: 'n8n_create_workflow', description: 'Create new workflows' },
{ name: 'n8n_get_workflow', description: 'Get workflow by ID' },
{ name: 'n8n_get_workflow_details', description: 'Get detailed workflow info with stats' },
{ name: 'n8n_get_workflow_structure', description: 'Get simplified workflow structure' },
{ name: 'n8n_get_workflow_minimal', description: 'Get minimal workflow info' },
{ name: 'n8n_update_workflow', description: 'Update existing workflows' },
{ name: 'n8n_delete_workflow', description: 'Delete workflows' },
{ name: 'n8n_list_workflows', description: 'List workflows with filters' },
{ name: 'n8n_validate_workflow', description: 'Validate workflow from n8n instance' },
{ name: 'n8n_autofix_workflow', description: 'Automatically fix common workflow errors' }
]
},
{
category: 'Execution Management',
tools: [
{ name: 'n8n_trigger_webhook_workflow', description: 'Trigger workflows via webhook' },
{ name: 'n8n_get_execution', description: 'Get execution details' },
{ name: 'n8n_list_executions', description: 'List executions with filters' },
{ name: 'n8n_delete_execution', description: 'Delete execution records' }
]
},
{
category: 'System',
tools: [
{ name: 'n8n_health_check', description: 'Check API connectivity' },
{ name: 'n8n_list_available_tools', description: 'List all available tools' }
]
}
];
const config = getN8nApiConfig();
const apiConfigured = config !== null;
return {
success: true,
data: {
tools,
apiConfigured,
configuration: config ? {
apiUrl: config.baseUrl,
timeout: config.timeout,
maxRetries: config.maxRetries
} : null,
limitations: [
'Cannot execute workflows directly (must use webhooks)',
'Cannot stop running executions',
'Tags and credentials have limited API support'
]
}
};
}
// Environment-aware debugging helpers
/**
@@ -1844,8 +1787,8 @@ export async function handleDiagnostic(request: any, context?: InstanceContext):
}
// Check which tools are available
const documentationTools = 22; // Base documentation tools
const managementTools = apiConfigured ? 16 : 0;
const documentationTools = 7; // Base documentation tools (after v2.26.0 consolidation)
const managementTools = apiConfigured ? 12 : 0; // Management tools requiring API (after v2.26.0 consolidation)
const totalTools = documentationTools + managementTools;
// Check npm version
@@ -1981,7 +1924,7 @@ export async function handleDiagnostic(request: any, context?: InstanceContext):
example: 'validate_workflow({workflow: {...}})'
}
],
note: '22 documentation tools available without API configuration'
note: '14 documentation tools available without API configuration'
},
whatYouCannotDo: [
'✗ Create/update workflows in n8n instance',
@@ -1996,8 +1939,8 @@ export async function handleDiagnostic(request: any, context?: InstanceContext):
' N8N_API_URL=https://your-n8n-instance.com',
' N8N_API_KEY=your_api_key_here',
'3. Restart the MCP server',
'4. Run n8n_diagnostic again to verify',
'5. All 38 tools will be available!'
'4. Run n8n_health_check with mode="diagnostic" to verify',
'5. All 19 tools will be available!'
],
documentation: 'https://github.com/czlonkowski/n8n-mcp?tab=readme-ov-file#n8n-management-tools-optional---requires-api-configuration'
}

View File

@@ -830,38 +830,32 @@ export class N8NDocumentationMCPServer {
let validationResult;
switch (toolName) {
case 'validate_node_operation':
case 'validate_node':
// Consolidated tool handles both modes - validate as operation for now
validationResult = ToolValidation.validateNodeOperation(args);
break;
case 'validate_node_minimal':
validationResult = ToolValidation.validateNodeMinimal(args);
break;
case 'validate_workflow':
case 'validate_workflow_connections':
case 'validate_workflow_expressions':
validationResult = ToolValidation.validateWorkflow(args);
break;
case 'search_nodes':
validationResult = ToolValidation.validateSearchNodes(args);
break;
case 'list_node_templates':
validationResult = ToolValidation.validateListNodeTemplates(args);
break;
case 'n8n_create_workflow':
validationResult = ToolValidation.validateCreateWorkflow(args);
break;
case 'n8n_get_workflow':
case 'n8n_get_workflow_details':
case 'n8n_get_workflow_structure':
case 'n8n_get_workflow_minimal':
case 'n8n_update_full_workflow':
case 'n8n_delete_workflow':
case 'n8n_validate_workflow':
case 'n8n_autofix_workflow':
case 'n8n_get_execution':
case 'n8n_delete_execution':
validationResult = ToolValidation.validateWorkflowId(args);
break;
case 'n8n_executions':
// Requires action parameter, id validation done in handler based on action
validationResult = args.action
? { valid: true, errors: [] }
: { valid: false, errors: [{ field: 'action', message: 'action is required' }] };
break;
default:
// For tools not yet migrated to schema validation, use basic validation
return this.validateToolParamsBasic(toolName, args, legacyRequiredParams || []);
@@ -1015,25 +1009,24 @@ export class N8NDocumentationMCPServer {
case 'tools_documentation':
// No required parameters
return this.getToolsDocumentation(args.topic, args.depth);
case 'list_nodes':
// No required parameters
return this.listNodes(args);
case 'search_nodes':
this.validateToolParams(name, args, ['query']);
// Convert limit to number if provided, otherwise use default
const limit = args.limit !== undefined ? Number(args.limit) || 20 : 20;
return this.searchNodes(args.query, limit, { mode: args.mode, includeExamples: args.includeExamples });
case 'list_ai_tools':
// No required parameters
return this.listAITools();
case 'get_node_documentation':
this.validateToolParams(name, args, ['nodeType']);
return this.getNodeDocumentation(args.nodeType);
case 'get_database_statistics':
// No required parameters
return this.getDatabaseStatistics();
case 'get_node':
this.validateToolParams(name, args, ['nodeType']);
// Handle consolidated modes: docs, search_properties
if (args.mode === 'docs') {
return this.getNodeDocumentation(args.nodeType);
}
if (args.mode === 'search_properties') {
if (!args.propertyQuery) {
throw new Error('propertyQuery is required for mode=search_properties');
}
const maxResults = args.maxPropertyResults !== undefined ? Number(args.maxPropertyResults) || 20 : 20;
return this.searchNodeProperties(args.nodeType, args.propertyQuery, maxResults);
}
return this.getNode(
args.nodeType,
args.detail,
@@ -1043,18 +1036,23 @@ export class N8NDocumentationMCPServer {
args.fromVersion,
args.toVersion
);
case 'search_node_properties':
this.validateToolParams(name, args, ['nodeType', 'query']);
const maxResults = args.maxResults !== undefined ? Number(args.maxResults) || 20 : 20;
return this.searchNodeProperties(args.nodeType, args.query, maxResults);
case 'list_tasks':
// No required parameters
return this.listTasks(args.category);
case 'validate_node_operation':
case 'validate_node':
this.validateToolParams(name, args, ['nodeType', 'config']);
// Ensure config is an object
if (typeof args.config !== 'object' || args.config === null) {
logger.warn(`validate_node_operation called with invalid config type: ${typeof args.config}`);
logger.warn(`validate_node called with invalid config type: ${typeof args.config}`);
const validationMode = args.mode || 'full';
if (validationMode === 'minimal') {
return {
nodeType: args.nodeType || 'unknown',
displayName: 'Unknown Node',
valid: false,
missingRequiredFields: [
'Invalid config format - expected object',
'🔧 RECOVERY: Use format { "resource": "...", "operation": "..." } or {} for empty config'
]
};
}
return {
nodeType: args.nodeType || 'unknown',
workflowNodeType: args.nodeType || 'unknown',
@@ -1070,7 +1068,7 @@ export class N8NDocumentationMCPServer {
suggestions: [
'🔧 RECOVERY: Invalid config detected. Fix with:',
' • Ensure config is an object: { "resource": "...", "operation": "..." }',
' • Use get_node_essentials to see required fields for this node type',
' • Use get_node to see required fields for this node type',
' • Check if the node type is correct before configuring it'
],
summary: {
@@ -1081,95 +1079,75 @@ export class N8NDocumentationMCPServer {
}
};
}
return this.validateNodeConfig(args.nodeType, args.config, 'operation', args.profile);
case 'validate_node_minimal':
this.validateToolParams(name, args, ['nodeType', 'config']);
// Ensure config is an object
if (typeof args.config !== 'object' || args.config === null) {
logger.warn(`validate_node_minimal called with invalid config type: ${typeof args.config}`);
return {
nodeType: args.nodeType || 'unknown',
displayName: 'Unknown Node',
valid: false,
missingRequiredFields: [
'Invalid config format - expected object',
'🔧 RECOVERY: Use format { "resource": "...", "operation": "..." } or {} for empty config'
]
};
// Handle mode parameter
const validationMode = args.mode || 'full';
if (validationMode === 'minimal') {
return this.validateNodeMinimal(args.nodeType, args.config);
}
return this.validateNodeMinimal(args.nodeType, args.config);
case 'get_property_dependencies':
this.validateToolParams(name, args, ['nodeType']);
return this.getPropertyDependencies(args.nodeType, args.config);
case 'get_node_as_tool_info':
this.validateToolParams(name, args, ['nodeType']);
return this.getNodeAsToolInfo(args.nodeType);
case 'list_templates':
// No required params
const listLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
const listOffset = Math.max(Number(args.offset) || 0, 0);
const sortBy = args.sortBy || 'views';
const includeMetadata = Boolean(args.includeMetadata);
return this.listTemplates(listLimit, listOffset, sortBy, includeMetadata);
case 'list_node_templates':
this.validateToolParams(name, args, ['nodeTypes']);
const templateLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
const templateOffset = Math.max(Number(args.offset) || 0, 0);
return this.listNodeTemplates(args.nodeTypes, templateLimit, templateOffset);
return this.validateNodeConfig(args.nodeType, args.config, 'operation', args.profile);
case 'get_template':
this.validateToolParams(name, args, ['templateId']);
const templateId = Number(args.templateId);
const mode = args.mode || 'full';
return this.getTemplate(templateId, mode);
case 'search_templates':
this.validateToolParams(name, args, ['query']);
const templateMode = args.mode || 'full';
return this.getTemplate(templateId, templateMode);
case 'search_templates': {
// Consolidated tool with searchMode parameter
const searchMode = args.searchMode || 'keyword';
const searchLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
const searchOffset = Math.max(Number(args.offset) || 0, 0);
const searchFields = args.fields as string[] | undefined;
return this.searchTemplates(args.query, searchLimit, searchOffset, searchFields);
case 'get_templates_for_task':
this.validateToolParams(name, args, ['task']);
const taskLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
const taskOffset = Math.max(Number(args.offset) || 0, 0);
return this.getTemplatesForTask(args.task, taskLimit, taskOffset);
case 'search_templates_by_metadata':
// No required params - all filters are optional
const metadataLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
const metadataOffset = Math.max(Number(args.offset) || 0, 0);
return this.searchTemplatesByMetadata({
category: args.category,
complexity: args.complexity,
maxSetupMinutes: args.maxSetupMinutes ? Number(args.maxSetupMinutes) : undefined,
minSetupMinutes: args.minSetupMinutes ? Number(args.minSetupMinutes) : undefined,
requiredService: args.requiredService,
targetAudience: args.targetAudience
}, metadataLimit, metadataOffset);
switch (searchMode) {
case 'by_nodes':
if (!args.nodeTypes || !Array.isArray(args.nodeTypes) || args.nodeTypes.length === 0) {
throw new Error('nodeTypes array is required for searchMode=by_nodes');
}
return this.listNodeTemplates(args.nodeTypes, searchLimit, searchOffset);
case 'by_task':
if (!args.task) {
throw new Error('task is required for searchMode=by_task');
}
return this.getTemplatesForTask(args.task, searchLimit, searchOffset);
case 'by_metadata':
return this.searchTemplatesByMetadata({
category: args.category,
complexity: args.complexity,
maxSetupMinutes: args.maxSetupMinutes ? Number(args.maxSetupMinutes) : undefined,
minSetupMinutes: args.minSetupMinutes ? Number(args.minSetupMinutes) : undefined,
requiredService: args.requiredService,
targetAudience: args.targetAudience
}, searchLimit, searchOffset);
case 'keyword':
default:
if (!args.query) {
throw new Error('query is required for searchMode=keyword');
}
const searchFields = args.fields as string[] | undefined;
return this.searchTemplates(args.query, searchLimit, searchOffset, searchFields);
}
}
case 'validate_workflow':
this.validateToolParams(name, args, ['workflow']);
return this.validateWorkflow(args.workflow, args.options);
case 'validate_workflow_connections':
this.validateToolParams(name, args, ['workflow']);
return this.validateWorkflowConnections(args.workflow);
case 'validate_workflow_expressions':
this.validateToolParams(name, args, ['workflow']);
return this.validateWorkflowExpressions(args.workflow);
// n8n Management Tools (if API is configured)
case 'n8n_create_workflow':
this.validateToolParams(name, args, ['name', 'nodes', 'connections']);
return n8nHandlers.handleCreateWorkflow(args, this.instanceContext);
case 'n8n_get_workflow':
case 'n8n_get_workflow': {
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleGetWorkflow(args, this.instanceContext);
case 'n8n_get_workflow_details':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleGetWorkflowDetails(args, this.instanceContext);
case 'n8n_get_workflow_structure':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleGetWorkflowStructure(args, this.instanceContext);
case 'n8n_get_workflow_minimal':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleGetWorkflowMinimal(args, this.instanceContext);
const workflowMode = args.mode || 'full';
switch (workflowMode) {
case 'details':
return n8nHandlers.handleGetWorkflowDetails(args, this.instanceContext);
case 'structure':
return n8nHandlers.handleGetWorkflowStructure(args, this.instanceContext);
case 'minimal':
return n8nHandlers.handleGetWorkflowMinimal(args, this.instanceContext);
case 'full':
default:
return n8nHandlers.handleGetWorkflow(args, this.instanceContext);
}
}
case 'n8n_update_full_workflow':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleUpdateWorkflow(args, this.repository!, this.instanceContext);
@@ -1195,24 +1173,32 @@ export class N8NDocumentationMCPServer {
case 'n8n_trigger_webhook_workflow':
this.validateToolParams(name, args, ['webhookUrl']);
return n8nHandlers.handleTriggerWebhookWorkflow(args, this.instanceContext);
case 'n8n_get_execution':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleGetExecution(args, this.instanceContext);
case 'n8n_list_executions':
// No required parameters
return n8nHandlers.handleListExecutions(args, this.instanceContext);
case 'n8n_delete_execution':
this.validateToolParams(name, args, ['id']);
return n8nHandlers.handleDeleteExecution(args, this.instanceContext);
case 'n8n_executions': {
this.validateToolParams(name, args, ['action']);
const execAction = args.action;
switch (execAction) {
case 'get':
if (!args.id) {
throw new Error('id is required for action=get');
}
return n8nHandlers.handleGetExecution(args, this.instanceContext);
case 'list':
return n8nHandlers.handleListExecutions(args, this.instanceContext);
case 'delete':
if (!args.id) {
throw new Error('id is required for action=delete');
}
return n8nHandlers.handleDeleteExecution(args, this.instanceContext);
default:
throw new Error(`Unknown action: ${execAction}. Valid actions: get, list, delete`);
}
}
case 'n8n_health_check':
// No required parameters
// No required parameters - supports mode='status' (default) or mode='diagnostic'
if (args.mode === 'diagnostic') {
return n8nHandlers.handleDiagnostic({ params: { arguments: args } }, this.instanceContext);
}
return n8nHandlers.handleHealthCheck(this.instanceContext);
case 'n8n_list_available_tools':
// No required parameters
return n8nHandlers.handleListAvailableTools(this.instanceContext);
case 'n8n_diagnostic':
// No required parameters
return n8nHandlers.handleDiagnostic({ params: { arguments: args } }, this.instanceContext);
case 'n8n_workflow_versions':
this.validateToolParams(name, args, ['mode']);
return n8nHandlers.handleWorkflowVersions(args, this.repository!, this.instanceContext);

View File

@@ -58,6 +58,6 @@ export const toolsDocumentationDoc: ToolDocumentation = {
'Not all internal functions are documented',
'Special topics (code guides) require exact names'
],
relatedTools: ['n8n_list_available_tools for dynamic tool discovery', 'list_tasks for common configurations', 'get_database_statistics to verify MCP connection']
relatedTools: ['n8n_health_check for verifying API connection', 'get_node_for_task for common configurations', 'search_nodes for finding nodes']
}
};

View File

@@ -10,7 +10,7 @@ export const getTemplatesForTaskDoc: ToolDocumentation = {
performance: 'Fast (<100ms) - pre-categorized results',
tips: [
'Returns hand-picked templates for specific automation tasks',
'Use list_tasks to see all available task categories',
'Available tasks: ai_automation, data_sync, webhook_processing, email_automation, slack_integration, etc.',
'Templates are curated for quality and relevance'
]
},

View File

@@ -66,6 +66,6 @@ Requires N8N_API_URL and N8N_API_KEY environment variables to be configured.`,
'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', 'n8n_autofix_workflow']
relatedTools: ['validate_workflow', 'n8n_get_workflow', 'n8n_health_check', 'n8n_autofix_workflow']
}
};

View File

@@ -88,8 +88,8 @@ When working with Code nodes, always start by calling the relevant guide:
1. **Find** the node you need:
- search_nodes({query: "slack"}) - Search by keyword
- list_nodes({category: "communication"}) - List by category
- list_ai_tools() - List AI-capable nodes
- search_nodes({query: "communication"}) - Search by category name
- search_nodes({query: "AI langchain"}) - Search for AI-capable nodes
2. **Configure** the node (ALWAYS START WITH STANDARD DETAIL):
- ✅ get_node("nodes-base.slack", {detail: 'standard'}) - Get essential properties FIRST (~1-2KB, shows required fields)
@@ -105,9 +105,7 @@ When working with Code nodes, always start by calling the relevant guide:
## Tool Categories
**Discovery Tools**
- search_nodes - Full-text search across all nodes
- list_nodes - List nodes with filtering by category, package, or type
- list_ai_tools - List all AI-capable nodes with usage guidance
- search_nodes - Full-text search across all nodes (supports OR, AND, FUZZY modes)
**Configuration Tools**
- get_node - ✅ Unified node information tool with progressive detail levels:
@@ -125,10 +123,11 @@ When working with Code nodes, always start by calling the relevant guide:
- validate_workflow - Complete workflow validation including connections
**Template Tools**
- list_tasks - List common task templates
- get_node_for_task - Get pre-configured node for specific tasks
- search_templates - Search workflow templates by keyword
- get_template - Get complete workflow JSON by ID
- list_node_templates - Find templates using specific nodes
- get_templates_for_task - Get curated templates by task type
**n8n API Tools** (requires N8N_API_URL configuration)
- n8n_create_workflow - Create new workflows
@@ -137,7 +136,7 @@ When working with Code nodes, always start by calling the relevant guide:
- n8n_trigger_webhook_workflow - Trigger workflow execution
## Performance Characteristics
- Instant (<10ms): search_nodes, list_nodes, get_node (minimal/standard)
- Instant (<10ms): search_nodes, get_node (minimal/standard)
- Fast (<100ms): validate_node_minimal, get_node_for_task
- Moderate (100-500ms): validate_workflow, get_node (full detail)
- Network-dependent: All n8n_* tools

View File

@@ -70,55 +70,19 @@ export const n8nManagementTools: ToolDefinition[] = [
},
{
name: 'n8n_get_workflow',
description: `Get a workflow by ID. Returns the complete workflow including nodes, connections, and settings.`,
description: `Get workflow by ID with different detail levels. Use mode='full' for complete workflow, 'details' for metadata+stats, 'structure' for nodes/connections only, 'minimal' for id/name/active/tags.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_details',
description: `Get workflow details with metadata, version, execution stats. More info than get_workflow.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_structure',
description: `Get workflow structure: nodes and connections only. No parameter details.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_minimal',
description: `Get minimal info: ID, name, active status, tags. Fast for listings.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
id: {
type: 'string',
description: 'Workflow ID'
},
mode: {
type: 'string',
enum: ['full', 'details', 'structure', 'minimal'],
default: 'full',
description: 'Detail level: full=complete workflow, details=full+execution stats, structure=nodes/connections topology, minimal=metadata only'
}
},
required: ['id']
@@ -343,122 +307,87 @@ export const n8nManagementTools: ToolDefinition[] = [
}
},
{
name: 'n8n_get_execution',
description: `Get execution details with smart filtering. RECOMMENDED: Use mode='preview' first to assess data size.
Examples:
- {id, mode:'preview'} - Structure & counts (fast, no data)
- {id, mode:'summary'} - 2 samples per node (default)
- {id, mode:'filtered', itemsLimit:5} - 5 items per node
- {id, nodeNames:['HTTP Request']} - Specific node only
- {id, mode:'full'} - Complete data (use with caution)`,
name: 'n8n_executions',
description: `Manage workflow executions: get details, list, or delete. Use action='get' with id for execution details, action='list' for listing executions, action='delete' to remove execution record.`,
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['get', 'list', 'delete'],
description: 'Operation: get=get execution details, list=list executions, delete=delete execution'
},
// For action='get' and action='delete'
id: {
type: 'string',
description: 'Execution ID'
description: 'Execution ID (required for action=get or action=delete)'
},
// For action='get' - detail level
mode: {
type: 'string',
enum: ['preview', 'summary', 'filtered', 'full'],
description: 'Data retrieval mode: preview=structure only, summary=2 items, filtered=custom, full=all data'
description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data'
},
nodeNames: {
type: 'array',
items: { type: 'string' },
description: 'Filter to specific nodes by name (for filtered mode)'
description: 'For action=get with mode=filtered: filter to specific nodes by name'
},
itemsLimit: {
type: 'number',
description: 'Items per node: 0=structure only, 2=default, -1=unlimited (for filtered mode)'
description: 'For action=get with mode=filtered: items per node (0=structure, 2=default, -1=unlimited)'
},
includeInputData: {
type: 'boolean',
description: 'Include input data in addition to output (default: false)'
description: 'For action=get: include input data in addition to output (default: false)'
},
// For action='list'
limit: {
type: 'number',
description: 'For action=list: number of executions to return (1-100, default: 100)'
},
cursor: {
type: 'string',
description: 'For action=list: pagination cursor from previous response'
},
workflowId: {
type: 'string',
description: 'For action=list: filter by workflow ID'
},
projectId: {
type: 'string',
description: 'For action=list: filter by project ID (enterprise feature)'
},
status: {
type: 'string',
enum: ['success', 'error', 'waiting'],
description: 'For action=list: filter by execution status'
},
includeData: {
type: 'boolean',
description: 'Legacy: Include execution data. Maps to mode=summary if true (deprecated, use mode instead)'
description: 'For action=list: include execution data (default: false)'
}
},
required: ['id']
}
},
{
name: 'n8n_list_executions',
description: `List workflow executions (returns up to limit). Check hasMore/nextCursor for pagination.`,
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'Number of executions to return (1-100, default: 100)'
},
cursor: {
type: 'string',
description: 'Pagination cursor from previous response'
},
workflowId: {
type: 'string',
description: 'Filter by workflow ID'
},
projectId: {
type: 'string',
description: 'Filter by project ID (enterprise feature)'
},
status: {
type: 'string',
enum: ['success', 'error', 'waiting'],
description: 'Filter by execution status'
},
includeData: {
type: 'boolean',
description: 'Include execution data (default: false)'
}
}
}
},
{
name: 'n8n_delete_execution',
description: `Delete an execution record. This only removes the execution history, not any data processed.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Execution ID to delete'
}
},
required: ['id']
required: ['action']
}
},
// System Tools
{
name: 'n8n_health_check',
description: `Check n8n instance health and API connectivity. Returns status and available features.`,
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'n8n_list_available_tools',
description: `List available n8n tools and capabilities.`,
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'n8n_diagnostic',
description: `Diagnose n8n API config. Shows tool status, API connectivity, env vars. Helps troubleshoot missing tools.`,
description: `Check n8n instance health and API connectivity. Use mode='diagnostic' for detailed troubleshooting with env vars and tool status.`,
inputSchema: {
type: 'object',
properties: {
mode: {
type: 'string',
enum: ['status', 'diagnostic'],
description: 'Mode: "status" (default) for quick health check, "diagnostic" for detailed debug info including env vars and tool status',
default: 'status'
},
verbose: {
type: 'boolean',
description: 'Include detailed debug information (default: false)'
description: 'Include extra details in diagnostic mode (default: false)'
}
}
}

View File

@@ -26,37 +26,6 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
},
},
},
{
name: 'list_nodes',
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.`,
inputSchema: {
type: 'object',
properties: {
package: {
type: 'string',
description: '"n8n-nodes-base" (core) or "@n8n/n8n-nodes-langchain" (AI)',
},
category: {
type: 'string',
description: 'trigger|transform|output|input|AI',
},
developmentStyle: {
type: 'string',
enum: ['declarative', 'programmatic'],
description: 'Usually "programmatic"',
},
isAITool: {
type: 'boolean',
description: 'Filter AI-capable nodes',
},
limit: {
type: 'number',
description: 'Max results (default 50, use 200+ for all)',
default: 50,
},
},
},
},
{
name: 'search_nodes',
description: `Search n8n nodes by keyword with optional real-world examples. Pass query as string. Example: query="webhook" or query="database". Returns max 20 results. Use includeExamples=true to get top 2 template configs per node.`,
@@ -87,39 +56,9 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
required: ['query'],
},
},
{
name: 'list_ai_tools',
description: `List 263 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.`,
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'get_node_documentation',
description: `Get readable docs with examples/auth/patterns. Better than raw schema! 87% coverage. Format: "nodes-base.slack"`,
inputSchema: {
type: 'object',
properties: {
nodeType: {
type: 'string',
description: 'Full type with prefix: "nodes-base.slack"',
},
},
required: ['nodeType'],
},
},
{
name: 'get_database_statistics',
description: `Node stats: 525 total, 263 AI tools, 104 triggers, 87% docs coverage. Verifies MCP working.`,
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'get_node',
description: `Get node info with progressive detail levels. Detail: minimal (~200 tokens), standard (~1-2K, default), full (~3-8K). Version modes: versions (history), compare (diff), breaking (changes), migrations (auto-migrate). Supports includeTypeInfo and includeExamples. Use standard for most tasks.`,
description: `Get node info with progressive detail levels and multiple modes. Detail: minimal (~200 tokens), standard (~1-2K, default), full (~3-8K). Modes: info (default), docs (markdown documentation), search_properties (find properties), versions/compare/breaking/migrations (version info). Use format='docs' for readable documentation, mode='search_properties' with propertyQuery for finding specific fields.`,
inputSchema: {
type: 'object',
properties: {
@@ -135,9 +74,9 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
},
mode: {
type: 'string',
enum: ['info', 'versions', 'compare', 'breaking', 'migrations'],
enum: ['info', 'docs', 'search_properties', 'versions', 'compare', 'breaking', 'migrations'],
default: 'info',
description: 'Operation mode. info=node information, versions=version history, compare/breaking/migrations=version comparison',
description: 'Operation mode. info=node schema, docs=readable markdown documentation, search_properties=find specific properties, versions/compare/breaking/migrations=version info',
},
includeTypeInfo: {
type: 'boolean',
@@ -157,49 +96,22 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
type: 'string',
description: 'Target version for compare mode (e.g., "2.0"). Defaults to latest if omitted.',
},
propertyQuery: {
type: 'string',
description: 'For mode=search_properties: search term to find properties (e.g., "auth", "header", "body")',
},
maxPropertyResults: {
type: 'number',
description: 'For mode=search_properties: max results (default 20)',
default: 20,
},
},
required: ['nodeType'],
},
},
{
name: 'search_node_properties',
description: `Find specific properties in a node (auth, headers, body, etc). Returns paths and descriptions.`,
inputSchema: {
type: 'object',
properties: {
nodeType: {
type: 'string',
description: 'Full type with prefix',
},
query: {
type: 'string',
description: 'Property to find: "auth", "header", "body", "json"',
},
maxResults: {
type: 'number',
description: 'Max results (default 20)',
default: 20,
},
},
required: ['nodeType', 'query'],
},
},
{
name: 'list_tasks',
description: `List task templates by category: HTTP/API, Webhooks, Database, AI, Data Processing, Communication.`,
inputSchema: {
type: 'object',
properties: {
category: {
type: 'string',
description: 'Filter by category (optional)',
},
},
},
},
{
name: 'validate_node_operation',
description: `Validate n8n node configuration. Pass nodeType as string and config as object. Example: nodeType="nodes-base.slack", config={resource:"channel",operation:"create"}`,
name: 'validate_node',
description: `Validate n8n node configuration. Use mode='full' for comprehensive validation with errors/warnings/suggestions, mode='minimal' for quick required fields check. Example: nodeType="nodes-base.slack", config={resource:"channel",operation:"create"}`,
inputSchema: {
type: 'object',
properties: {
@@ -211,10 +123,16 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
type: 'object',
description: 'Configuration as object. For simple nodes use {}. For complex nodes include fields like {resource:"channel",operation:"create"}',
},
mode: {
type: 'string',
enum: ['full', 'minimal'],
description: 'Validation mode. full=comprehensive validation with errors/warnings/suggestions, minimal=quick required fields check only. Default is "full"',
default: 'full',
},
profile: {
type: 'string',
enum: ['strict', 'runtime', 'ai-friendly', 'minimal'],
description: 'Profile string: "minimal", "runtime", "ai-friendly", or "strict". Default is "ai-friendly"',
description: 'Profile for mode=full: "minimal", "runtime", "ai-friendly", or "strict". Default is "ai-friendly"',
default: 'ai-friendly',
},
},
@@ -253,6 +171,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
}
},
suggestions: { type: 'array', items: { type: 'string' } },
missingRequiredFields: {
type: 'array',
items: { type: 'string' },
description: 'Only present in mode=minimal'
},
summary: {
type: 'object',
properties: {
@@ -263,132 +186,7 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
}
}
},
required: ['nodeType', 'displayName', 'valid', 'errors', 'warnings', 'suggestions', 'summary']
},
},
{
name: 'validate_node_minimal',
description: `Check n8n node required fields. Pass nodeType as string and config as empty object {}. Example: nodeType="nodes-base.webhook", config={}`,
inputSchema: {
type: 'object',
properties: {
nodeType: {
type: 'string',
description: 'Node type as string. Example: "nodes-base.slack"',
},
config: {
type: 'object',
description: 'Configuration object. Always pass {} for empty config',
},
},
required: ['nodeType', 'config'],
additionalProperties: false,
},
outputSchema: {
type: 'object',
properties: {
nodeType: { type: 'string' },
displayName: { type: 'string' },
valid: { type: 'boolean' },
missingRequiredFields: {
type: 'array',
items: { type: 'string' }
}
},
required: ['nodeType', 'displayName', 'valid', 'missingRequiredFields']
},
},
{
name: 'get_property_dependencies',
description: `Shows property dependencies and visibility rules. Example: sendBody=true reveals body fields. Test visibility with optional config.`,
inputSchema: {
type: 'object',
properties: {
nodeType: {
type: 'string',
description: 'The node type to analyze (e.g., "nodes-base.httpRequest")',
},
config: {
type: 'object',
description: 'Optional partial configuration to check visibility impact',
},
},
required: ['nodeType'],
},
},
{
name: 'get_node_as_tool_info',
description: `How to use ANY node as AI tool. Shows requirements, use cases, examples. Works for all nodes, not just AI-marked ones.`,
inputSchema: {
type: 'object',
properties: {
nodeType: {
type: 'string',
description: 'Full node type WITH prefix: "nodes-base.slack", "nodes-base.googleSheets", etc.',
},
},
required: ['nodeType'],
},
},
{
name: 'list_templates',
description: `List all templates with minimal data (id, name, description, views, node count). Optionally include AI-generated metadata for smart filtering.`,
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'Number of results (1-100). Default 10.',
default: 10,
minimum: 1,
maximum: 100,
},
offset: {
type: 'number',
description: 'Pagination offset. Default 0.',
default: 0,
minimum: 0,
},
sortBy: {
type: 'string',
enum: ['views', 'created_at', 'name'],
description: 'Sort field. Default: views (popularity).',
default: 'views',
},
includeMetadata: {
type: 'boolean',
description: 'Include AI-generated metadata (categories, complexity, setup time, etc.). Default false.',
default: false,
},
},
},
},
{
name: 'list_node_templates',
description: `Find templates using specific nodes. Returns paginated results. Use FULL types: "n8n-nodes-base.httpRequest".`,
inputSchema: {
type: 'object',
properties: {
nodeTypes: {
type: 'array',
items: { type: 'string' },
description: 'Array of node types to search for (e.g., ["n8n-nodes-base.httpRequest", "n8n-nodes-base.openAi"])',
},
limit: {
type: 'number',
description: 'Maximum number of templates to return. Default 10.',
default: 10,
minimum: 1,
maximum: 100,
},
offset: {
type: 'number',
description: 'Pagination offset. Default 0.',
default: 0,
minimum: 0,
},
},
required: ['nodeTypes'],
required: ['nodeType', 'displayName', 'valid']
},
},
{
@@ -413,13 +211,20 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
},
{
name: 'search_templates',
description: `Search templates by name/description keywords. Returns paginated results. NOT for node types! For nodes use list_node_templates.`,
description: `Search templates with multiple modes. Use searchMode='keyword' for text search, 'by_nodes' to find templates using specific nodes, 'by_task' for curated task-based templates, 'by_metadata' for filtering by complexity/setup time/services.`,
inputSchema: {
type: 'object',
properties: {
searchMode: {
type: 'string',
enum: ['keyword', 'by_nodes', 'by_task', 'by_metadata'],
description: 'Search mode. keyword=text search (default), by_nodes=find by node types, by_task=curated task templates, by_metadata=filter by complexity/services',
default: 'keyword',
},
// For searchMode='keyword'
query: {
type: 'string',
description: 'Search keyword as string. Example: "chatbot"',
description: 'For searchMode=keyword: search keyword (e.g., "chatbot")',
},
fields: {
type: 'array',
@@ -427,36 +232,20 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
type: 'string',
enum: ['id', 'name', 'description', 'author', 'nodes', 'views', 'created', 'url', 'metadata'],
},
description: 'Fields to include in response. Default: all fields. Example: ["id", "name"] for minimal response.',
description: 'For searchMode=keyword: fields to include in response. Default: all fields.',
},
limit: {
type: 'number',
description: 'Maximum number of results. Default 20.',
default: 20,
minimum: 1,
maximum: 100,
// For searchMode='by_nodes'
nodeTypes: {
type: 'array',
items: { type: 'string' },
description: 'For searchMode=by_nodes: array of node types (e.g., ["n8n-nodes-base.httpRequest", "n8n-nodes-base.slack"])',
},
offset: {
type: 'number',
description: 'Pagination offset. Default 0.',
default: 0,
minimum: 0,
},
},
required: ['query'],
},
},
{
name: 'get_templates_for_task',
description: `Curated templates by task. Returns paginated results sorted by popularity.`,
inputSchema: {
type: 'object',
properties: {
// For searchMode='by_task'
task: {
type: 'string',
enum: [
'ai_automation',
'data_sync',
'data_sync',
'webhook_processing',
'email_automation',
'slack_integration',
@@ -466,60 +255,39 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
'api_integration',
'database_operations'
],
description: 'The type of task to get templates for',
description: 'For searchMode=by_task: the type of task',
},
limit: {
type: 'number',
description: 'Maximum number of results. Default 10.',
default: 10,
minimum: 1,
maximum: 100,
},
offset: {
type: 'number',
description: 'Pagination offset. Default 0.',
default: 0,
minimum: 0,
},
},
required: ['task'],
},
},
{
name: 'search_templates_by_metadata',
description: `Search templates by AI-generated metadata. Filter by category, complexity, setup time, services, or audience. Returns rich metadata for smart template discovery.`,
inputSchema: {
type: 'object',
properties: {
// For searchMode='by_metadata'
category: {
type: 'string',
description: 'Filter by category (e.g., "automation", "integration", "data processing")',
description: 'For searchMode=by_metadata: filter by category (e.g., "automation", "integration")',
},
complexity: {
type: 'string',
enum: ['simple', 'medium', 'complex'],
description: 'Filter by complexity level',
description: 'For searchMode=by_metadata: filter by complexity level',
},
maxSetupMinutes: {
type: 'number',
description: 'Maximum setup time in minutes',
description: 'For searchMode=by_metadata: maximum setup time in minutes',
minimum: 5,
maximum: 480,
},
minSetupMinutes: {
type: 'number',
description: 'Minimum setup time in minutes',
description: 'For searchMode=by_metadata: minimum setup time in minutes',
minimum: 5,
maximum: 480,
},
requiredService: {
type: 'string',
description: 'Filter by required service (e.g., "openai", "slack", "google")',
description: 'For searchMode=by_metadata: filter by required service (e.g., "openai", "slack")',
},
targetAudience: {
type: 'string',
description: 'Filter by target audience (e.g., "developers", "marketers", "analysts")',
description: 'For searchMode=by_metadata: filter by target audience (e.g., "developers", "marketers")',
},
// Common pagination
limit: {
type: 'number',
description: 'Maximum number of results. Default 20.',
@@ -534,7 +302,6 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
minimum: 0,
},
},
additionalProperties: false,
},
},
{
@@ -622,143 +389,43 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [
required: ['valid', 'summary']
},
},
{
name: 'validate_workflow_connections',
description: `Check workflow connections only: valid nodes, no cycles, proper triggers, AI tool links. Fast structure validation.`,
inputSchema: {
type: 'object',
properties: {
workflow: {
type: 'object',
description: 'The workflow JSON with nodes array and connections object.',
},
},
required: ['workflow'],
additionalProperties: false,
},
outputSchema: {
type: 'object',
properties: {
valid: { type: 'boolean' },
statistics: {
type: 'object',
properties: {
totalNodes: { type: 'number' },
triggerNodes: { type: 'number' },
validConnections: { type: 'number' },
invalidConnections: { type: 'number' }
}
},
errors: {
type: 'array',
items: {
type: 'object',
properties: {
node: { type: 'string' },
message: { type: 'string' }
}
}
},
warnings: {
type: 'array',
items: {
type: 'object',
properties: {
node: { type: 'string' },
message: { type: 'string' }
}
}
}
},
required: ['valid', 'statistics']
},
},
{
name: 'validate_workflow_expressions',
description: `Validate n8n expressions: syntax {{}}, variables ($json/$node), references. Returns errors with locations.`,
inputSchema: {
type: 'object',
properties: {
workflow: {
type: 'object',
description: 'The workflow JSON to check for expression errors.',
},
},
required: ['workflow'],
additionalProperties: false,
},
outputSchema: {
type: 'object',
properties: {
valid: { type: 'boolean' },
statistics: {
type: 'object',
properties: {
totalNodes: { type: 'number' },
expressionsValidated: { type: 'number' }
}
},
errors: {
type: 'array',
items: {
type: 'object',
properties: {
node: { type: 'string' },
message: { type: 'string' }
}
}
},
warnings: {
type: 'array',
items: {
type: 'object',
properties: {
node: { type: 'string' },
message: { type: 'string' }
}
}
},
tips: { type: 'array', items: { type: 'string' } }
},
required: ['valid', 'statistics']
},
},
];
/**
* QUICK REFERENCE for AI Agents:
*
*
* 1. RECOMMENDED WORKFLOW:
* - Start: search_nodes → get_node_essentials → get_node_for_task → validate_node_operation
* - Discovery: list_nodes({category:"trigger"}) for browsing categories
* - Quick Config: get_node_essentials("nodes-base.httpRequest") - only essential properties
* - Full Details: get_node_info only when essentials aren't enough
* - Validation: Use validate_node_operation for complex nodes (Slack, Google Sheets, etc.)
*
* - Start: search_nodes → get_node → validate_node
* - Discovery: search_nodes({query:"trigger"}) for finding nodes
* - Quick Config: get_node("nodes-base.httpRequest", {detail:"standard"}) - only essential properties
* - Documentation: get_node("nodes-base.httpRequest", {mode:"docs"}) - readable markdown docs
* - Find Properties: get_node("nodes-base.httpRequest", {mode:"search_properties", propertyQuery:"auth"})
* - Full Details: get_node with detail="full" only when standard isn't enough
* - Validation: Use validate_node for complex nodes (Slack, Google Sheets, etc.)
*
* 2. COMMON NODE TYPES:
* Triggers: webhook, schedule, emailReadImap, slackTrigger
* Core: httpRequest, code, set, if, merge, splitInBatches
* Integrations: slack, gmail, googleSheets, postgres, mongodb
* AI: agent, openAi, chainLlm, documentLoader
*
*
* 3. SEARCH TIPS:
* - search_nodes returns ANY word match (OR logic)
* - Single words more precise, multiple words broader
* - If no results: use list_nodes with category filter
*
* - If no results: try different keywords or partial names
*
* 4. TEMPLATE SEARCHING:
* - search_templates("slack") searches template names/descriptions, NOT node types!
* - To find templates using Slack node: list_node_templates(["n8n-nodes-base.slack"])
* - For task-based templates: get_templates_for_task("slack_integration")
* - 399 templates available from the last year
*
* - To find templates using Slack node: search_templates({searchMode:"by_nodes", nodeTypes:["n8n-nodes-base.slack"]})
* - For task-based templates: search_templates({searchMode:"by_task", task:"slack_integration"})
*
* 5. KNOWN ISSUES:
* - Some nodes have duplicate properties with different conditions
* - Package names: use 'n8n-nodes-base' not '@n8n/n8n-nodes-base'
* - Check showWhen/hideWhen to identify the right property variant
*
*
* 6. PERFORMANCE:
* - get_node_essentials: Fast (<5KB)
* - get_node_info: Slow (100KB+) - use sparingly
* - search_nodes/list_nodes: Fast, cached
* - get_node (detail=standard): Fast (<5KB)
* - get_node (detail=full): Slow (100KB+) - use sparingly
* - search_nodes: Fast, cached
*/