feat: integrate n8n management tools from n8n-manager-for-ai-agents (v2.6.0)

- Added 14 n8n management tools for workflow CRUD and execution management
- Integrated n8n API client with full error handling and validation
- Added conditional tool registration (only when N8N_API_URL configured)
- Complete workflow lifecycle: discover → build → validate → deploy → execute
- Updated documentation and added integration tests
- Maintains backward compatibility - existing functionality unchanged

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-06-26 11:09:09 +02:00
parent 150de3d1c2
commit 74f05e937f
13 changed files with 2409 additions and 6 deletions

View File

@@ -0,0 +1,732 @@
import { N8nApiClient } from '../services/n8n-api-client';
import { n8nApiConfig } from '../config/n8n-api';
import {
Workflow,
WorkflowNode,
WorkflowConnection,
ExecutionStatus,
WebhookRequest,
McpToolResponse
} from '../types/n8n-api';
import {
validateWorkflowStructure,
hasWebhookTrigger,
getWebhookUrl
} from '../services/n8n-validation';
import {
N8nApiError,
N8nNotFoundError,
getUserFriendlyErrorMessage
} from '../utils/n8n-errors';
import { logger } from '../utils/logger';
import { z } from 'zod';
// Singleton n8n API client instance
let apiClient: N8nApiClient | null = null;
// Get or create API client
export function getN8nApiClient(): N8nApiClient | null {
if (!n8nApiConfig) {
return null;
}
if (!apiClient) {
apiClient = new N8nApiClient(n8nApiConfig);
}
return apiClient;
}
// Helper to ensure API is configured
function ensureApiConfigured(): N8nApiClient {
const client = getN8nApiClient();
if (!client) {
throw new Error('n8n API not configured. Please set N8N_API_URL and N8N_API_KEY environment variables.');
}
return client;
}
// Zod schemas for input validation
const createWorkflowSchema = z.object({
name: z.string(),
nodes: z.array(z.any()),
connections: z.record(z.any()),
settings: z.object({
executionOrder: z.enum(['v0', 'v1']).optional(),
timezone: z.string().optional(),
saveDataErrorExecution: z.enum(['all', 'none']).optional(),
saveDataSuccessExecution: z.enum(['all', 'none']).optional(),
saveManualExecutions: z.boolean().optional(),
saveExecutionProgress: z.boolean().optional(),
executionTimeout: z.number().optional(),
errorWorkflow: z.string().optional(),
}).optional(),
});
const updateWorkflowSchema = z.object({
id: z.string(),
name: z.string().optional(),
nodes: z.array(z.any()).optional(),
connections: z.record(z.any()).optional(),
settings: z.any().optional(),
});
const listWorkflowsSchema = z.object({
limit: z.number().min(1).max(100).optional(),
cursor: z.string().optional(),
active: z.boolean().optional(),
tags: z.array(z.string()).optional(),
projectId: z.string().optional(),
excludePinnedData: z.boolean().optional(),
});
const triggerWebhookSchema = z.object({
webhookUrl: z.string().url(),
httpMethod: z.enum(['GET', 'POST', 'PUT', 'DELETE']).optional(),
data: z.record(z.unknown()).optional(),
headers: z.record(z.string()).optional(),
waitForResponse: z.boolean().optional(),
});
const listExecutionsSchema = z.object({
limit: z.number().min(1).max(100).optional(),
cursor: z.string().optional(),
workflowId: z.string().optional(),
projectId: z.string().optional(),
status: z.enum(['success', 'error', 'waiting']).optional(),
includeData: z.boolean().optional(),
});
// Workflow Management Handlers
export async function handleCreateWorkflow(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const input = createWorkflowSchema.parse(args);
// Validate workflow structure
const errors = validateWorkflowStructure(input);
if (errors.length > 0) {
return {
success: false,
error: 'Workflow validation failed',
details: { errors }
};
}
// Create workflow
const workflow = await client.createWorkflow(input);
return {
success: true,
data: workflow,
message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}`
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code,
details: error.details as Record<string, unknown> | undefined
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleGetWorkflow(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
const workflow = await client.getWorkflow(id);
return {
success: true,
data: workflow
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleGetWorkflowDetails(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
const workflow = await client.getWorkflow(id);
// Get recent executions for this workflow
const executions = await client.listExecutions({
workflowId: id,
limit: 10
});
// Calculate execution statistics
const stats = {
totalExecutions: executions.data.length,
successCount: executions.data.filter(e => e.status === ExecutionStatus.SUCCESS).length,
errorCount: executions.data.filter(e => e.status === ExecutionStatus.ERROR).length,
lastExecutionTime: executions.data[0]?.startedAt || null
};
return {
success: true,
data: {
workflow,
executionStats: stats,
hasWebhookTrigger: hasWebhookTrigger(workflow),
webhookPath: getWebhookUrl(workflow)
}
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleGetWorkflowStructure(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
const workflow = await client.getWorkflow(id);
// Simplify nodes to just essential structure
const simplifiedNodes = workflow.nodes.map(node => ({
id: node.id,
name: node.name,
type: node.type,
position: node.position,
disabled: node.disabled || false
}));
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
nodes: simplifiedNodes,
connections: workflow.connections,
nodeCount: workflow.nodes.length,
connectionCount: Object.keys(workflow.connections).length
}
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleGetWorkflowMinimal(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
const workflow = await client.getWorkflow(id);
return {
success: true,
data: {
id: workflow.id,
name: workflow.name,
active: workflow.active,
tags: workflow.tags || [],
createdAt: workflow.createdAt,
updatedAt: workflow.updatedAt
}
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleUpdateWorkflow(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const input = updateWorkflowSchema.parse(args);
const { id, ...updateData } = input;
// If nodes/connections are being updated, validate the structure
if (updateData.nodes || updateData.connections) {
// Fetch current workflow if only partial update
let fullWorkflow = updateData as Partial<Workflow>;
if (!updateData.nodes || !updateData.connections) {
const current = await client.getWorkflow(id);
fullWorkflow = {
...current,
...updateData
};
}
const errors = validateWorkflowStructure(fullWorkflow);
if (errors.length > 0) {
return {
success: false,
error: 'Workflow validation failed',
details: { errors }
};
}
}
// Update workflow
const workflow = await client.updateWorkflow(id, updateData);
return {
success: true,
data: workflow,
message: `Workflow "${workflow.name}" updated successfully`
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code,
details: error.details as Record<string, unknown> | undefined
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleDeleteWorkflow(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
await client.deleteWorkflow(id);
return {
success: true,
message: `Workflow ${id} deleted successfully`
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleListWorkflows(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const input = listWorkflowsSchema.parse(args || {});
const response = await client.listWorkflows({
limit: input.limit || 100,
cursor: input.cursor,
active: input.active,
tags: input.tags,
projectId: input.projectId,
excludePinnedData: input.excludePinnedData ?? true
});
return {
success: true,
data: {
workflows: response.data,
nextCursor: response.nextCursor,
total: response.data.length
}
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
// Execution Management Handlers
export async function handleTriggerWebhookWorkflow(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const input = triggerWebhookSchema.parse(args);
const webhookRequest: WebhookRequest = {
webhookUrl: input.webhookUrl,
httpMethod: input.httpMethod || 'POST',
data: input.data,
headers: input.headers,
waitForResponse: input.waitForResponse ?? true
};
const response = await client.triggerWebhook(webhookRequest);
return {
success: true,
data: response,
message: 'Webhook triggered successfully'
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code,
details: error.details as Record<string, unknown> | undefined
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleGetExecution(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id, includeData } = z.object({
id: z.string(),
includeData: z.boolean().optional()
}).parse(args);
const execution = await client.getExecution(id, includeData || false);
return {
success: true,
data: execution
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleListExecutions(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const input = listExecutionsSchema.parse(args || {});
const response = await client.listExecutions({
limit: input.limit || 100,
cursor: input.cursor,
workflowId: input.workflowId,
projectId: input.projectId,
status: input.status as ExecutionStatus | undefined,
includeData: input.includeData || false
});
return {
success: true,
data: {
executions: response.data,
nextCursor: response.nextCursor,
total: response.data.length
}
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleDeleteExecution(args: unknown): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const { id } = z.object({ id: z.string() }).parse(args);
await client.deleteExecution(id);
return {
success: true,
message: `Execution ${id} deleted successfully`
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
success: false,
error: 'Invalid input',
details: { errors: error.errors }
};
}
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
// System Tools Handlers
export async function handleHealthCheck(): Promise<McpToolResponse> {
try {
const client = ensureApiConfigured();
const health = await client.healthCheck();
return {
success: true,
data: {
status: health.status,
instanceId: health.instanceId,
n8nVersion: health.n8nVersion,
features: health.features,
apiUrl: n8nApiConfig?.baseUrl
}
};
} catch (error) {
if (error instanceof N8nApiError) {
return {
success: false,
error: getUserFriendlyErrorMessage(error),
code: error.code,
details: {
apiUrl: n8nApiConfig?.baseUrl,
hint: 'Check if n8n is running and API is enabled'
}
};
}
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
export async function handleListAvailableTools(): 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' }
]
},
{
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 apiConfigured = n8nApiConfig !== null;
return {
success: true,
data: {
tools,
apiConfigured,
configuration: apiConfigured ? {
apiUrl: n8nApiConfig!.baseUrl,
timeout: n8nApiConfig!.timeout,
maxRetries: n8nApiConfig!.maxRetries
} : null,
limitations: [
'Cannot activate/deactivate workflows via API',
'Cannot execute workflows directly (must use webhooks)',
'Cannot stop running executions',
'Tags and credentials have limited API support'
]
}
};
}

View File

@@ -8,6 +8,7 @@ import {
import { existsSync } from 'fs';
import path from 'path';
import { n8nDocumentationToolsFinal } from './tools-update';
import { n8nManagementTools } from './tools-n8n-manager';
import { logger } from '../utils/logger';
import { NodeRepository } from '../database/node-repository';
import { DatabaseAdapter, createDatabaseAdapter } from '../database/database-adapter';
@@ -20,6 +21,8 @@ import { PropertyDependencies } from '../services/property-dependencies';
import { SimpleCache } from '../utils/simple-cache';
import { TemplateService } from '../templates/template-service';
import { WorkflowValidator } from '../services/workflow-validator';
import { isN8nApiConfigured } from '../config/n8n-api';
import * as n8nHandlers from './handlers-n8n-manager';
interface NodeRow {
node_type: string;
@@ -130,9 +133,19 @@ export class N8NDocumentationMCPServer {
});
// Handle tool listing
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: n8nDocumentationToolsFinal,
}));
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
// Combine documentation tools with management tools if API is configured
const tools = [...n8nDocumentationToolsFinal];
if (isN8nApiConfigured()) {
tools.push(...n8nManagementTools);
logger.info('n8n management tools enabled');
} else {
logger.info('n8n management tools disabled (API not configured)');
}
return { tools };
});
// Handle tool execution
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -211,6 +224,37 @@ export class N8NDocumentationMCPServer {
return this.validateWorkflowConnections(args.workflow);
case 'validate_workflow_expressions':
return this.validateWorkflowExpressions(args.workflow);
// n8n Management Tools (if API is configured)
case 'n8n_create_workflow':
return n8nHandlers.handleCreateWorkflow(args);
case 'n8n_get_workflow':
return n8nHandlers.handleGetWorkflow(args);
case 'n8n_get_workflow_details':
return n8nHandlers.handleGetWorkflowDetails(args);
case 'n8n_get_workflow_structure':
return n8nHandlers.handleGetWorkflowStructure(args);
case 'n8n_get_workflow_minimal':
return n8nHandlers.handleGetWorkflowMinimal(args);
case 'n8n_update_workflow':
return n8nHandlers.handleUpdateWorkflow(args);
case 'n8n_delete_workflow':
return n8nHandlers.handleDeleteWorkflow(args);
case 'n8n_list_workflows':
return n8nHandlers.handleListWorkflows(args);
case 'n8n_trigger_webhook_workflow':
return n8nHandlers.handleTriggerWebhookWorkflow(args);
case 'n8n_get_execution':
return n8nHandlers.handleGetExecution(args);
case 'n8n_list_executions':
return n8nHandlers.handleListExecutions(args);
case 'n8n_delete_execution':
return n8nHandlers.handleDeleteExecution(args);
case 'n8n_health_check':
return n8nHandlers.handleHealthCheck();
case 'n8n_list_available_tools':
return n8nHandlers.handleListAvailableTools();
default:
throw new Error(`Unknown tool: ${name}`);
}

View File

@@ -0,0 +1,322 @@
import { ToolDefinition } from '../types';
/**
* n8n Management Tools
*
* These tools enable AI agents to manage n8n workflows through the n8n API.
* They require N8N_API_URL and N8N_API_KEY to be configured.
*/
export const n8nManagementTools: ToolDefinition[] = [
// Workflow Management Tools
{
name: 'n8n_create_workflow',
description: `Create a new workflow in n8n. Requires workflow name, nodes array, and connections object. The workflow will be created in inactive state and must be manually activated in the UI. Returns the created workflow with its ID.`,
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Workflow name (required)'
},
nodes: {
type: 'array',
description: 'Array of workflow nodes. Each node must have: id, name, type, typeVersion, position, and parameters',
items: {
type: 'object',
required: ['id', 'name', 'type', 'typeVersion', 'position', 'parameters'],
properties: {
id: { type: 'string' },
name: { type: 'string' },
type: { type: 'string' },
typeVersion: { type: 'number' },
position: {
type: 'array',
items: { type: 'number' },
minItems: 2,
maxItems: 2
},
parameters: { type: 'object' },
credentials: { type: 'object' },
disabled: { type: 'boolean' },
notes: { type: 'string' },
continueOnFail: { type: 'boolean' },
retryOnFail: { type: 'boolean' },
maxTries: { type: 'number' },
waitBetweenTries: { type: 'number' }
}
}
},
connections: {
type: 'object',
description: 'Workflow connections object. Keys are source node IDs, values define output connections'
},
settings: {
type: 'object',
description: 'Optional workflow settings (execution order, timezone, error handling)',
properties: {
executionOrder: { type: 'string', enum: ['v0', 'v1'] },
timezone: { type: 'string' },
saveDataErrorExecution: { type: 'string', enum: ['all', 'none'] },
saveDataSuccessExecution: { type: 'string', enum: ['all', 'none'] },
saveManualExecutions: { type: 'boolean' },
saveExecutionProgress: { type: 'boolean' },
executionTimeout: { type: 'number' },
errorWorkflow: { type: 'string' }
}
}
},
required: ['name', 'nodes', 'connections']
}
},
{
name: 'n8n_get_workflow',
description: `Get a workflow by ID. Returns the complete workflow including nodes, connections, and settings.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_details',
description: `Get detailed workflow information including metadata, version, and execution statistics. More comprehensive than get_workflow.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_structure',
description: `Get simplified workflow structure showing only nodes and their connections. Useful for understanding workflow flow without parameter details.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_get_workflow_minimal',
description: `Get minimal workflow information (ID, name, active status, tags). Fast and lightweight for listing purposes.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID'
}
},
required: ['id']
}
},
{
name: 'n8n_update_workflow',
description: `Update an existing workflow. Requires the full nodes array when modifying nodes/connections. Cannot activate workflows via API - use UI instead.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID to update'
},
name: {
type: 'string',
description: 'New workflow name'
},
nodes: {
type: 'array',
description: 'Complete array of workflow nodes (required if modifying workflow structure)'
},
connections: {
type: 'object',
description: 'Complete connections object (required if modifying workflow structure)'
},
settings: {
type: 'object',
description: 'Workflow settings to update'
}
},
required: ['id']
}
},
{
name: 'n8n_delete_workflow',
description: `Permanently delete a workflow. This action cannot be undone.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Workflow ID to delete'
}
},
required: ['id']
}
},
{
name: 'n8n_list_workflows',
description: `List workflows with optional filters. Supports pagination via cursor.`,
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'Number of workflows to return (1-100, default: 100)'
},
cursor: {
type: 'string',
description: 'Pagination cursor from previous response'
},
active: {
type: 'boolean',
description: 'Filter by active status'
},
tags: {
type: 'array',
items: { type: 'string' },
description: 'Filter by tags (exact match)'
},
projectId: {
type: 'string',
description: 'Filter by project ID (enterprise feature)'
},
excludePinnedData: {
type: 'boolean',
description: 'Exclude pinned data from response (default: true)'
}
}
}
},
// Execution Management Tools
{
name: 'n8n_trigger_webhook_workflow',
description: `Trigger a workflow via webhook. Workflow must be ACTIVE and have a Webhook trigger node. HTTP method must match webhook configuration.`,
inputSchema: {
type: 'object',
properties: {
webhookUrl: {
type: 'string',
description: 'Full webhook URL from n8n workflow (e.g., https://n8n.example.com/webhook/abc-def-ghi)'
},
httpMethod: {
type: 'string',
enum: ['GET', 'POST', 'PUT', 'DELETE'],
description: 'HTTP method (must match webhook configuration, often GET)'
},
data: {
type: 'object',
description: 'Data to send with the webhook request'
},
headers: {
type: 'object',
description: 'Additional HTTP headers'
},
waitForResponse: {
type: 'boolean',
description: 'Wait for workflow completion (default: true)'
}
},
required: ['webhookUrl']
}
},
{
name: 'n8n_get_execution',
description: `Get details of a specific execution by ID.`,
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Execution ID'
},
includeData: {
type: 'boolean',
description: 'Include full execution data (default: false)'
}
},
required: ['id']
}
},
{
name: 'n8n_list_executions',
description: `List workflow executions with optional filters. Supports 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']
}
},
// 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 all available n8n management tools and their capabilities. Useful for understanding what operations are possible.`,
inputSchema: {
type: 'object',
properties: {}
}
}
];