mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-04-01 07:03:08 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b800ff0cd9 |
18
CHANGELOG.md
18
CHANGELOG.md
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.44.0] - 2026-04-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Multi-step workflow generation flow**: `n8n_generate_workflow` now supports a three-step flow where AI agents act as quality gates — get proposals, review, then deploy. New parameters: `deploy_id` (deploy a specific proposal), `confirm_deploy` (deploy a previously generated preview).
|
||||||
|
|
||||||
|
- **`GenerateWorkflowProposal` type**: New exported type for workflow proposals with `id`, `name`, `description`, `flow_summary`, and `credentials_needed` fields.
|
||||||
|
|
||||||
|
- **`status` field on `GenerateWorkflowResult`**: Indicates the current phase — `proposals`, `preview`, `deployed`, or `error`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Tool description updated**: `n8n_generate_workflow` description now explains the multi-step flow instead of auto-deploy behavior.
|
||||||
|
|
||||||
|
- **Tool documentation updated**: Essentials and full docs reflect the three-step flow with examples for each step.
|
||||||
|
|
||||||
|
Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en
|
||||||
|
|
||||||
## [2.43.0] - 2026-03-31
|
## [2.43.0] - 2026-03-31
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
2
dist/index.d.ts
vendored
2
dist/index.d.ts
vendored
@@ -5,7 +5,7 @@ export { N8NDocumentationMCPServer } from './mcp/server';
|
|||||||
export type { InstanceContext } from './types/instance-context';
|
export type { InstanceContext } from './types/instance-context';
|
||||||
export { validateInstanceContext, isInstanceContext } from './types/instance-context';
|
export { validateInstanceContext, isInstanceContext } from './types/instance-context';
|
||||||
export type { SessionState } from './types/session-state';
|
export type { SessionState } from './types/session-state';
|
||||||
export type { GenerateWorkflowArgs, GenerateWorkflowResult, GenerateWorkflowHandler, GenerateWorkflowHelpers } from './types/generate-workflow';
|
export type { GenerateWorkflowArgs, GenerateWorkflowResult, GenerateWorkflowProposal, GenerateWorkflowHandler, GenerateWorkflowHelpers } from './types/generate-workflow';
|
||||||
export type { UIAppConfig, UIMetadata } from './mcp/ui/types';
|
export type { UIAppConfig, UIMetadata } from './mcp/ui/types';
|
||||||
export { UI_APP_CONFIGS } from './mcp/ui/app-configs';
|
export { UI_APP_CONFIGS } from './mcp/ui/app-configs';
|
||||||
export type { Tool, CallToolResult, ListToolsResult } from '@modelcontextprotocol/sdk/types.js';
|
export type { Tool, CallToolResult, ListToolsResult } from '@modelcontextprotocol/sdk/types.js';
|
||||||
|
|||||||
2
dist/index.d.ts.map
vendored
2
dist/index.d.ts.map
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGzD,YAAY,EACV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,YAAY,EACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,YAAY,EACV,IAAI,EACJ,cAAc,EACd,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,YAAY,MAAM,cAAc,CAAC;AACxC,eAAe,YAAY,CAAC"}
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGzD,YAAY,EACV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,YAAY,EACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,YAAY,EACV,IAAI,EACJ,cAAc,EACd,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,YAAY,MAAM,cAAc,CAAC;AACxC,eAAe,YAAY,CAAC"}
|
||||||
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAOA,2CAAyE;AAAhE,0GAAA,YAAY,OAAA;AACrB,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA;AAChC,2DAAyD;AAAhD,iHAAA,cAAc,OAAA;AACvB,uCAAyD;AAAhD,mHAAA,yBAAyB,OAAA;AAMlC,6DAGkC;AAFhC,2HAAA,uBAAuB,OAAA;AACvB,qHAAA,iBAAiB,OAAA;AAcnB,oDAAsD;AAA7C,6GAAA,cAAc,OAAA;AAUvB,8DAAwC;AACxC,kBAAe,oBAAY,CAAC"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAOA,2CAAyE;AAAhE,0GAAA,YAAY,OAAA;AACrB,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA;AAChC,2DAAyD;AAAhD,iHAAA,cAAc,OAAA;AACvB,uCAAyD;AAAhD,mHAAA,yBAAyB,OAAA;AAMlC,6DAGkC;AAFhC,2HAAA,uBAAuB,OAAA;AACvB,qHAAA,iBAAiB,OAAA;AAenB,oDAAsD;AAA7C,6GAAA,cAAc,OAAA;AAUvB,8DAAwC;AACxC,kBAAe,oBAAY,CAAC"}
|
||||||
2
dist/mcp/server.d.ts.map
vendored
2
dist/mcp/server.d.ts.map
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
||||||
2
dist/mcp/server.js
vendored
2
dist/mcp/server.js
vendored
@@ -1156,7 +1156,7 @@ class N8NDocumentationMCPServer {
|
|||||||
getWorkflow: (id) => n8nHandlers.handleGetWorkflow({ id }, ctx),
|
getWorkflow: (id) => n8nHandlers.handleGetWorkflow({ id }, ctx),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const result = await this.generateWorkflowHandler({ description: args.description, skip_cache: args.skip_cache }, ctx, helpers);
|
const result = await this.generateWorkflowHandler(args, ctx, helpers);
|
||||||
return result ?? { success: false, error: 'Handler returned no result' };
|
return result ?? { success: false, error: 'Handler returned no result' };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
|||||||
2
dist/mcp/server.js.map
vendored
2
dist/mcp/server.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/mcp/tools-n8n-manager.d.ts.map
vendored
2
dist/mcp/tools-n8n-manager.d.ts.map
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"tools-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAsqB9C,CAAC"}
|
{"version":3,"file":"tools-n8n-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/tools-n8n-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1C,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAgrB9C,CAAC"}
|
||||||
20
dist/mcp/tools-n8n-manager.js
vendored
20
dist/mcp/tools-n8n-manager.js
vendored
@@ -638,9 +638,10 @@ exports.n8nManagementTools = [
|
|||||||
{
|
{
|
||||||
name: 'n8n_generate_workflow',
|
name: 'n8n_generate_workflow',
|
||||||
description: 'Generate an n8n workflow from a natural language description using AI. ' +
|
description: 'Generate an n8n workflow from a natural language description using AI. ' +
|
||||||
'Describe what the workflow should do (trigger type, services, logic) and this tool ' +
|
'Call with just a description to get workflow proposals. ' +
|
||||||
'will create and deploy a ready-to-use workflow to your n8n instance. ' +
|
'Then call again with deploy_id to deploy a chosen proposal, ' +
|
||||||
'Set skip_cache=true to force fresh generation instead of using pre-built templates.',
|
'or set skip_cache=true to generate a fresh workflow. ' +
|
||||||
|
'Use confirm_deploy=true to deploy a previously generated workflow.',
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@@ -651,8 +652,17 @@ exports.n8nManagementTools = [
|
|||||||
},
|
},
|
||||||
skip_cache: {
|
skip_cache: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Set to true to bypass the workflow cache and force fresh AI generation. ' +
|
description: 'Set to true to skip proposals and generate a fresh workflow from scratch. ' +
|
||||||
'Default: false (uses cached workflows when a good match exists).'
|
'Returns a preview — call again with confirm_deploy=true to deploy it.'
|
||||||
|
},
|
||||||
|
deploy_id: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'ID of a proposal to deploy. Get proposal IDs from a previous call ' +
|
||||||
|
'that returned status "proposals".'
|
||||||
|
},
|
||||||
|
confirm_deploy: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Set to true to deploy the workflow from the last generation preview.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['description'],
|
required: ['description'],
|
||||||
|
|||||||
2
dist/mcp/tools-n8n-manager.js.map
vendored
2
dist/mcp/tools-n8n-manager.js.map
vendored
File diff suppressed because one or more lines are too long
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "n8n-mcp",
|
"name": "n8n-mcp",
|
||||||
"version": "2.43.0",
|
"version": "2.44.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "n8n-mcp",
|
"name": "n8n-mcp",
|
||||||
"version": "2.43.0",
|
"version": "2.44.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "1.28.0",
|
"@modelcontextprotocol/sdk": "1.28.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "n8n-mcp",
|
"name": "n8n-mcp",
|
||||||
"version": "2.43.0",
|
"version": "2.44.0",
|
||||||
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
|
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export type {
|
|||||||
export type {
|
export type {
|
||||||
GenerateWorkflowArgs,
|
GenerateWorkflowArgs,
|
||||||
GenerateWorkflowResult,
|
GenerateWorkflowResult,
|
||||||
|
GenerateWorkflowProposal,
|
||||||
GenerateWorkflowHandler,
|
GenerateWorkflowHandler,
|
||||||
GenerateWorkflowHelpers
|
GenerateWorkflowHelpers
|
||||||
} from './types/generate-workflow';
|
} from './types/generate-workflow';
|
||||||
|
|||||||
@@ -1561,11 +1561,7 @@ export class N8NDocumentationMCPServer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.generateWorkflowHandler(
|
const result = await this.generateWorkflowHandler(args, ctx, helpers);
|
||||||
{ description: args.description, skip_cache: args.skip_cache },
|
|
||||||
ctx,
|
|
||||||
helpers
|
|
||||||
);
|
|
||||||
return result ?? { success: false, error: 'Handler returned no result' };
|
return result ?? { success: false, error: 'Handler returned no result' };
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const message = err instanceof Error ? err.message : String(err);
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
|||||||
@@ -4,58 +4,84 @@ export const n8nGenerateWorkflowDoc: ToolDocumentation = {
|
|||||||
name: 'n8n_generate_workflow',
|
name: 'n8n_generate_workflow',
|
||||||
category: 'workflow_management',
|
category: 'workflow_management',
|
||||||
essentials: {
|
essentials: {
|
||||||
description: 'Generate an n8n workflow from a natural language description using AI. Creates and deploys a ready-to-use workflow to your n8n instance.',
|
description: 'Generate workflows from natural language. Three-step flow:\n' +
|
||||||
keyParameters: ['description', 'skip_cache'],
|
'1. Call with description → get proposals\n' +
|
||||||
|
'2. Call with deploy_id → deploy a proposal, OR skip_cache=true → fresh generation preview\n' +
|
||||||
|
'3. Call with confirm_deploy=true → deploy the preview',
|
||||||
|
keyParameters: ['description', 'skip_cache', 'deploy_id', 'confirm_deploy'],
|
||||||
example: 'n8n_generate_workflow({description: "Send a Slack message every morning at 9am"})',
|
example: 'n8n_generate_workflow({description: "Send a Slack message every morning at 9am"})',
|
||||||
performance: 'Network-dependent (2-15s depending on cache hit vs fresh generation)',
|
performance: 'Network-dependent (2-15s depending on cache hit vs fresh generation)',
|
||||||
tips: [
|
tips: [
|
||||||
'Include trigger type (webhook, schedule, manual) in the description',
|
'Include trigger type (webhook, schedule, manual) in the description',
|
||||||
'Mention specific services to integrate (Slack, Gmail, Google Sheets, etc.)',
|
'Mention specific services to integrate (Slack, Gmail, Google Sheets, etc.)',
|
||||||
'Use skip_cache=true to force fresh AI generation instead of cached templates',
|
'Review proposals before deploying — use deploy_id to pick one',
|
||||||
|
'Use skip_cache=true to generate fresh, then confirm_deploy=true to deploy',
|
||||||
'Available exclusively on the hosted version of n8n-mcp'
|
'Available exclusively on the hosted version of n8n-mcp'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
full: {
|
full: {
|
||||||
description: 'Generates an n8n workflow from a natural language description using AI. On the hosted service, this tool first searches a cache of 73,000+ pre-built workflows for a match, and falls back to AI-powered fresh generation for custom workflows. Generated workflows are automatically validated and error-corrected before deployment. On self-hosted instances, this tool returns a message directing users to the hosted service.',
|
description: 'Generates n8n workflows from natural language using a multi-step flow. ' +
|
||||||
|
'Step 1: Call with description to get up to 5 proposals (not deployed). ' +
|
||||||
|
'Step 2a: Call with deploy_id to deploy a chosen proposal. ' +
|
||||||
|
'Step 2b: Call with skip_cache=true to generate a fresh workflow (returns preview, not deployed). ' +
|
||||||
|
'Step 3: Call with confirm_deploy=true to deploy the preview. ' +
|
||||||
|
'On self-hosted instances, returns a message directing users to the hosted service.',
|
||||||
parameters: {
|
parameters: {
|
||||||
description: { type: 'string', required: true, description: 'Clear description of what the workflow should do. Include: trigger type (webhook, schedule, manual), services to integrate (Slack, Gmail, etc.), and the logic/flow.' },
|
description: { type: 'string', required: true, description: 'Clear description of what the workflow should do. Include: trigger type (webhook, schedule, manual), services to integrate (Slack, Gmail, etc.), and the logic/flow.' },
|
||||||
skip_cache: { type: 'boolean', description: 'Set to true to bypass the workflow cache and force fresh AI generation. Default: false (uses cached workflows when a good match exists).' }
|
skip_cache: { type: 'boolean', description: 'Set to true to skip proposals and generate a fresh workflow from scratch. Returns a preview — call again with confirm_deploy=true to deploy it.' },
|
||||||
|
deploy_id: { type: 'string', description: 'ID of a proposal to deploy. Get proposal IDs from a previous call that returned status "proposals".' },
|
||||||
|
confirm_deploy: { type: 'boolean', description: 'Set to true to deploy the workflow from the last generation preview.' }
|
||||||
},
|
},
|
||||||
returns: 'Object with success, source (cache/generated), workflow_id, workflow_name, workflow_url, node_count, node_summary, and message. On self-hosted instances, returns hosted_only: true with information about the hosted service.',
|
returns: 'Object with success, status (proposals/preview/deployed/error), and context-dependent fields. ' +
|
||||||
|
'For proposals: proposals[] with id, name, description, flow_summary, credentials_needed. ' +
|
||||||
|
'For preview: workflow structure details. ' +
|
||||||
|
'For deployed: workflow_id, workflow_name, workflow_url, node_count, node_summary. ' +
|
||||||
|
'On self-hosted instances, returns hosted_only: true.',
|
||||||
examples: [
|
examples: [
|
||||||
`// Generate a simple scheduled workflow
|
`// Step 1: Get proposals
|
||||||
n8n_generate_workflow({
|
n8n_generate_workflow({
|
||||||
description: "Send a Slack message every morning at 9am with a daily standup reminder"
|
description: "Send a Slack message every morning at 9am with a daily standup reminder"
|
||||||
})`,
|
})
|
||||||
`// Generate with specific services
|
// Returns: { status: "proposals", proposals: [{ id: "uuid-1", name: "...", ... }, ...] }`,
|
||||||
|
`// Step 2a: Deploy a chosen proposal
|
||||||
n8n_generate_workflow({
|
n8n_generate_workflow({
|
||||||
description: "When a new row is added to Google Sheets, create a task in Notion and notify via email"
|
description: "Send a Slack message every morning at 9am",
|
||||||
})`,
|
deploy_id: "uuid-1"
|
||||||
`// Force fresh generation (skip cache)
|
})
|
||||||
|
// Returns: { status: "deployed", workflow_id: "123", ... }`,
|
||||||
|
`// Step 2b: Fresh generation (skip cache)
|
||||||
n8n_generate_workflow({
|
n8n_generate_workflow({
|
||||||
description: "Webhook that receives JSON data, transforms it, and posts to a REST API",
|
description: "Webhook that receives JSON data, transforms it, and posts to a REST API",
|
||||||
skip_cache: true
|
skip_cache: true
|
||||||
})`
|
})
|
||||||
|
// Returns: { status: "preview", ... }`,
|
||||||
|
`// Step 3: Deploy the preview
|
||||||
|
n8n_generate_workflow({
|
||||||
|
description: "Webhook that receives JSON data, transforms it, and posts to a REST API",
|
||||||
|
confirm_deploy: true
|
||||||
|
})
|
||||||
|
// Returns: { status: "deployed", workflow_id: "456", ... }`
|
||||||
],
|
],
|
||||||
useCases: [
|
useCases: [
|
||||||
'Quickly create workflows from natural language descriptions',
|
'Quickly create workflows from natural language descriptions',
|
||||||
'Generate complex multi-service integrations',
|
'Review proposals before deploying to maintain quality',
|
||||||
'Bootstrap automation projects with AI-generated workflows',
|
'Generate complex multi-service integrations with agent oversight',
|
||||||
'Create workflows without deep knowledge of n8n node configuration'
|
'Create workflows without deep knowledge of n8n node configuration'
|
||||||
],
|
],
|
||||||
performance: 'Cache hit: ~2s. Fresh generation: 5-15s. Both within typical MCP client timeout.',
|
performance: 'Proposals: ~2s. Fresh generation: 5-15s. Deploy: ~3s. All within typical MCP client timeout.',
|
||||||
bestPractices: [
|
bestPractices: [
|
||||||
'Be specific about trigger type and services in the description',
|
'Be specific about trigger type and services in the description',
|
||||||
'Review generated workflows before activating',
|
'Review proposals before deploying — pick the best match with deploy_id',
|
||||||
'Use n8n_validate_workflow to check the generated workflow',
|
'Use skip_cache only when proposals do not match your needs',
|
||||||
'Configure credentials in n8n UI before activating',
|
'After deployment, use n8n_validate_workflow to verify the result',
|
||||||
'Use skip_cache only when cached results do not match your needs'
|
'Configure credentials in n8n UI before activating'
|
||||||
],
|
],
|
||||||
pitfalls: [
|
pitfalls: [
|
||||||
'**Hosted-only feature** — self-hosted instances receive a redirect message',
|
'**Hosted-only feature** — self-hosted instances receive a redirect message',
|
||||||
|
'Proposals are NOT deployed — you must call again with deploy_id or confirm_deploy',
|
||||||
'Generated workflows are created in INACTIVE state',
|
'Generated workflows are created in INACTIVE state',
|
||||||
'Credentials must be configured manually in the n8n UI',
|
'Credentials must be configured manually in the n8n UI',
|
||||||
'Complex workflows may need manual adjustments after generation'
|
'Session state for pending proposals/preview is per MCP session'
|
||||||
],
|
],
|
||||||
relatedTools: ['n8n_create_workflow', 'n8n_deploy_template', 'n8n_validate_workflow', 'n8n_autofix_workflow', 'search_templates']
|
relatedTools: ['n8n_create_workflow', 'n8n_deploy_template', 'n8n_validate_workflow', 'n8n_autofix_workflow', 'search_templates']
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -657,9 +657,10 @@ export const n8nManagementTools: ToolDefinition[] = [
|
|||||||
{
|
{
|
||||||
name: 'n8n_generate_workflow',
|
name: 'n8n_generate_workflow',
|
||||||
description: 'Generate an n8n workflow from a natural language description using AI. ' +
|
description: 'Generate an n8n workflow from a natural language description using AI. ' +
|
||||||
'Describe what the workflow should do (trigger type, services, logic) and this tool ' +
|
'Call with just a description to get workflow proposals. ' +
|
||||||
'will create and deploy a ready-to-use workflow to your n8n instance. ' +
|
'Then call again with deploy_id to deploy a chosen proposal, ' +
|
||||||
'Set skip_cache=true to force fresh generation instead of using pre-built templates.',
|
'or set skip_cache=true to generate a fresh workflow. ' +
|
||||||
|
'Use confirm_deploy=true to deploy a previously generated workflow.',
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@@ -670,8 +671,17 @@ export const n8nManagementTools: ToolDefinition[] = [
|
|||||||
},
|
},
|
||||||
skip_cache: {
|
skip_cache: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Set to true to bypass the workflow cache and force fresh AI generation. ' +
|
description: 'Set to true to skip proposals and generate a fresh workflow from scratch. ' +
|
||||||
'Default: false (uses cached workflows when a good match exists).'
|
'Returns a preview — call again with confirm_deploy=true to deploy it.'
|
||||||
|
},
|
||||||
|
deploy_id: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'ID of a proposal to deploy. Get proposal IDs from a previous call ' +
|
||||||
|
'that returned status "proposals".'
|
||||||
|
},
|
||||||
|
confirm_deploy: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Set to true to deploy the workflow from the last generation preview.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['description'],
|
required: ['description'],
|
||||||
|
|||||||
@@ -3,11 +3,23 @@ import { InstanceContext } from './instance-context';
|
|||||||
export interface GenerateWorkflowArgs {
|
export interface GenerateWorkflowArgs {
|
||||||
description: string;
|
description: string;
|
||||||
skip_cache?: boolean;
|
skip_cache?: boolean;
|
||||||
|
deploy_id?: string;
|
||||||
|
confirm_deploy?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GenerateWorkflowProposal {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
flow_summary: string;
|
||||||
|
credentials_needed: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenerateWorkflowResult {
|
export interface GenerateWorkflowResult {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
source?: 'cache' | 'generated';
|
source?: 'cache' | 'generated';
|
||||||
|
status?: 'proposals' | 'preview' | 'deployed' | 'error';
|
||||||
|
proposals?: GenerateWorkflowProposal[];
|
||||||
workflow_id?: string;
|
workflow_id?: string;
|
||||||
workflow_name?: string;
|
workflow_name?: string;
|
||||||
workflow_url?: string;
|
workflow_url?: string;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type {
|
|||||||
GenerateWorkflowHandler,
|
GenerateWorkflowHandler,
|
||||||
GenerateWorkflowArgs,
|
GenerateWorkflowArgs,
|
||||||
GenerateWorkflowResult,
|
GenerateWorkflowResult,
|
||||||
|
GenerateWorkflowProposal,
|
||||||
GenerateWorkflowHelpers,
|
GenerateWorkflowHelpers,
|
||||||
} from '@/types/generate-workflow';
|
} from '@/types/generate-workflow';
|
||||||
|
|
||||||
@@ -18,6 +19,8 @@ describe('n8n_generate_workflow', () => {
|
|||||||
it('has correct input schema', () => {
|
it('has correct input schema', () => {
|
||||||
expect(tool!.inputSchema.properties).toHaveProperty('description');
|
expect(tool!.inputSchema.properties).toHaveProperty('description');
|
||||||
expect(tool!.inputSchema.properties).toHaveProperty('skip_cache');
|
expect(tool!.inputSchema.properties).toHaveProperty('skip_cache');
|
||||||
|
expect(tool!.inputSchema.properties).toHaveProperty('deploy_id');
|
||||||
|
expect(tool!.inputSchema.properties).toHaveProperty('confirm_deploy');
|
||||||
expect(tool!.inputSchema.required).toEqual(['description']);
|
expect(tool!.inputSchema.required).toEqual(['description']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,13 +81,69 @@ describe('n8n_generate_workflow', () => {
|
|||||||
expect(failure.success).toBe(false);
|
expect(failure.success).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GenerateWorkflowArgs has description and optional skip_cache', () => {
|
it('GenerateWorkflowResult supports proposal status', () => {
|
||||||
|
const proposals: GenerateWorkflowResult = {
|
||||||
|
success: true,
|
||||||
|
status: 'proposals',
|
||||||
|
proposals: [
|
||||||
|
{
|
||||||
|
id: 'uuid-1',
|
||||||
|
name: 'Slack Reminder',
|
||||||
|
description: 'Send scheduled Slack messages',
|
||||||
|
flow_summary: 'Schedule Trigger → Set → Slack',
|
||||||
|
credentials_needed: ['slackApi'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
expect(proposals.status).toBe('proposals');
|
||||||
|
expect(proposals.proposals).toHaveLength(1);
|
||||||
|
expect(proposals.proposals![0].id).toBe('uuid-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('GenerateWorkflowResult supports preview and deployed status', () => {
|
||||||
|
const preview: GenerateWorkflowResult = {
|
||||||
|
success: true,
|
||||||
|
status: 'preview',
|
||||||
|
node_summary: 'Webhook → HTTP Request → Slack',
|
||||||
|
};
|
||||||
|
expect(preview.status).toBe('preview');
|
||||||
|
|
||||||
|
const deployed: GenerateWorkflowResult = {
|
||||||
|
success: true,
|
||||||
|
status: 'deployed',
|
||||||
|
workflow_id: '123',
|
||||||
|
workflow_name: 'My Workflow',
|
||||||
|
};
|
||||||
|
expect(deployed.status).toBe('deployed');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('GenerateWorkflowProposal has required fields', () => {
|
||||||
|
const proposal: GenerateWorkflowProposal = {
|
||||||
|
id: 'uuid-123',
|
||||||
|
name: 'Test Workflow',
|
||||||
|
description: 'A test workflow',
|
||||||
|
flow_summary: 'Trigger → Action',
|
||||||
|
credentials_needed: ['slackApi', 'gmailOAuth2'],
|
||||||
|
};
|
||||||
|
expect(proposal.id).toBe('uuid-123');
|
||||||
|
expect(proposal.credentials_needed).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('GenerateWorkflowArgs has description and optional fields', () => {
|
||||||
const minimal: GenerateWorkflowArgs = { description: 'test' };
|
const minimal: GenerateWorkflowArgs = { description: 'test' };
|
||||||
expect(minimal.description).toBe('test');
|
expect(minimal.description).toBe('test');
|
||||||
expect(minimal.skip_cache).toBeUndefined();
|
expect(minimal.skip_cache).toBeUndefined();
|
||||||
|
expect(minimal.deploy_id).toBeUndefined();
|
||||||
|
expect(minimal.confirm_deploy).toBeUndefined();
|
||||||
|
|
||||||
const withSkip: GenerateWorkflowArgs = { description: 'test', skip_cache: true };
|
const withSkip: GenerateWorkflowArgs = { description: 'test', skip_cache: true };
|
||||||
expect(withSkip.skip_cache).toBe(true);
|
expect(withSkip.skip_cache).toBe(true);
|
||||||
|
|
||||||
|
const withDeploy: GenerateWorkflowArgs = { description: 'test', deploy_id: 'uuid-1' };
|
||||||
|
expect(withDeploy.deploy_id).toBe('uuid-1');
|
||||||
|
|
||||||
|
const withConfirm: GenerateWorkflowArgs = { description: 'test', confirm_deploy: true };
|
||||||
|
expect(withConfirm.confirm_deploy).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user