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
This commit is contained in:
czlonkowski
2025-11-25 16:38:13 +01:00
parent 7f03f51e87
commit 96dfbc3a16
12 changed files with 534 additions and 590 deletions

View File

@@ -135,11 +135,13 @@ describe('MCP Error Handling', () => {
});
describe('Validation Errors', () => {
// v2.26.0: validate_node_operation consolidated into validate_node
it('should handle invalid validation profile', async () => {
try {
await client.callTool({ name: 'validate_node_operation', arguments: {
await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: { method: 'GET', url: 'https://api.example.com' },
mode: 'full',
profile: 'invalid_profile' as any
} });
expect.fail('Should have thrown an error');
@@ -292,12 +294,14 @@ describe('MCP Error Handling', () => {
});
describe('Invalid JSON Handling', () => {
// v2.26.0: validate_node_operation consolidated into validate_node
it('should handle invalid JSON in tool parameters', async () => {
try {
// Config should be an object, not a string
await client.callTool({ name: 'validate_node_operation', arguments: {
await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: 'invalid json string' as any
config: 'invalid json string' as any,
mode: 'full'
} });
expect.fail('Should have thrown an error');
} catch (error: any) {
@@ -509,13 +513,15 @@ describe('MCP Error Handling', () => {
}
});
// v2.26.0: validate_node_operation consolidated into validate_node
it('should provide context for validation errors', async () => {
const response = await client.callTool({ name: 'validate_node_operation', arguments: {
const response = await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: {
// Missing required fields
method: 'INVALID_METHOD'
}
},
mode: 'full'
} });
const validation = JSON.parse((response as any).content[0].text);

View File

@@ -217,13 +217,14 @@ describe('MCP Protocol Compliance', () => {
describe('Protocol Extensions', () => {
it('should handle tool-specific extensions', async () => {
// Test tool with complex params
const response = await client.callTool({ name: 'validate_node_operation', arguments: {
// Test tool with complex params (using consolidated validate_node from v2.26.0)
const response = await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: {
method: 'GET',
url: 'https://api.example.com'
},
mode: 'full',
profile: 'runtime'
} });

View File

@@ -151,14 +151,16 @@ describe('MCP Tool Invocation', () => {
});
describe('Validation Tools', () => {
describe('validate_node_operation', () => {
// v2.26.0: validate_node_operation consolidated into validate_node with mode parameter
describe('validate_node', () => {
it('should validate valid node configuration', async () => {
const response = await client.callTool({ name: 'validate_node_operation', arguments: {
const response = await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: {
method: 'GET',
url: 'https://api.example.com/data'
}
},
mode: 'full'
}});
const validation = JSON.parse(((response as any).content[0]).text);
@@ -168,12 +170,13 @@ describe('MCP Tool Invocation', () => {
});
it('should detect missing required fields', async () => {
const response = await client.callTool({ name: 'validate_node_operation', arguments: {
const response = await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: {
method: 'GET'
// Missing required 'url' field
}
},
mode: 'full'
}});
const validation = JSON.parse(((response as any).content[0]).text);
@@ -184,11 +187,12 @@ describe('MCP Tool Invocation', () => {
it('should support different validation profiles', async () => {
const profiles = ['minimal', 'runtime', 'ai-friendly', 'strict'];
for (const profile of profiles) {
const response = await client.callTool({ name: 'validate_node_operation', arguments: {
const response = await client.callTool({ name: 'validate_node', arguments: {
nodeType: 'nodes-base.httpRequest',
config: { method: 'GET', url: 'https://api.example.com' },
mode: 'full',
profile
}});