n8n-mcp 2.10.9 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +21 -1
- package/README.md +72 -18
- package/data/nodes.db +0 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +121 -32
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-docs/index.d.ts.map +1 -1
- package/dist/mcp/tool-docs/index.js +1 -0
- package/dist/mcp/tool-docs/index.js.map +1 -1
- package/dist/mcp/tool-docs/templates/index.d.ts +1 -0
- package/dist/mcp/tool-docs/templates/index.d.ts.map +1 -1
- package/dist/mcp/tool-docs/templates/index.js +3 -1
- package/dist/mcp/tool-docs/templates/index.js.map +1 -1
- package/dist/mcp/tool-docs/templates/search-templates-by-metadata.d.ts +3 -0
- package/dist/mcp/tool-docs/templates/search-templates-by-metadata.d.ts.map +1 -0
- package/dist/mcp/tool-docs/templates/search-templates-by-metadata.js +120 -0
- package/dist/mcp/tool-docs/templates/search-templates-by-metadata.js.map +1 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +124 -4
- package/dist/mcp/tools.js.map +1 -1
- package/dist/scripts/fetch-templates.d.ts +1 -1
- package/dist/scripts/fetch-templates.d.ts.map +1 -1
- package/dist/scripts/fetch-templates.js +167 -44
- package/dist/scripts/fetch-templates.js.map +1 -1
- package/dist/scripts/generate-metadata-only.d.ts +3 -0
- package/dist/scripts/generate-metadata-only.d.ts.map +1 -0
- package/dist/scripts/generate-metadata-only.js +146 -0
- package/dist/scripts/generate-metadata-only.js.map +1 -0
- package/dist/scripts/generate-metadata-sync.d.ts +3 -0
- package/dist/scripts/generate-metadata-sync.d.ts.map +1 -0
- package/dist/scripts/generate-metadata-sync.js +136 -0
- package/dist/scripts/generate-metadata-sync.js.map +1 -0
- package/dist/scripts/test-batch-processing.d.ts +3 -0
- package/dist/scripts/test-batch-processing.d.ts.map +1 -0
- package/dist/scripts/test-batch-processing.js +144 -0
- package/dist/scripts/test-batch-processing.js.map +1 -0
- package/dist/scripts/test-metadata-generation.d.ts +3 -0
- package/dist/scripts/test-metadata-generation.d.ts.map +1 -0
- package/dist/scripts/test-metadata-generation.js +96 -0
- package/dist/scripts/test-metadata-generation.js.map +1 -0
- package/dist/scripts/validation-summary.js +1 -1
- package/dist/scripts/validation-summary.js.map +1 -1
- package/dist/templates/batch-processor.d.ts +35 -0
- package/dist/templates/batch-processor.d.ts.map +1 -0
- package/dist/templates/batch-processor.js +280 -0
- package/dist/templates/batch-processor.js.map +1 -0
- package/dist/templates/metadata-generator.d.ts +52 -0
- package/dist/templates/metadata-generator.d.ts.map +1 -0
- package/dist/templates/metadata-generator.js +254 -0
- package/dist/templates/metadata-generator.js.map +1 -0
- package/dist/templates/template-fetcher.d.ts +1 -0
- package/dist/templates/template-fetcher.d.ts.map +1 -1
- package/dist/templates/template-fetcher.js +23 -19
- package/dist/templates/template-fetcher.js.map +1 -1
- package/dist/templates/template-repository.d.ts +58 -5
- package/dist/templates/template-repository.d.ts.map +1 -1
- package/dist/templates/template-repository.js +408 -25
- package/dist/templates/template-repository.js.map +1 -1
- package/dist/templates/template-service.d.ts +50 -5
- package/dist/templates/template-service.d.ts.map +1 -1
- package/dist/templates/template-service.js +163 -21
- package/dist/templates/template-service.js.map +1 -1
- package/dist/utils/template-node-resolver.d.ts +2 -0
- package/dist/utils/template-node-resolver.d.ts.map +1 -0
- package/dist/utils/template-node-resolver.js +161 -0
- package/dist/utils/template-node-resolver.js.map +1 -0
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -86,4 +86,24 @@ AUTH_TOKEN=your-secure-token-here
|
|
|
86
86
|
# N8N_API_TIMEOUT=30000
|
|
87
87
|
|
|
88
88
|
# Maximum number of API request retries (default: 3)
|
|
89
|
-
# N8N_API_MAX_RETRIES=3
|
|
89
|
+
# N8N_API_MAX_RETRIES=3
|
|
90
|
+
|
|
91
|
+
# =========================
|
|
92
|
+
# OPENAI API CONFIGURATION
|
|
93
|
+
# =========================
|
|
94
|
+
# Optional: Enable AI-powered template metadata generation
|
|
95
|
+
# Provides structured metadata for improved template discovery
|
|
96
|
+
|
|
97
|
+
# OpenAI API Key (get from https://platform.openai.com/api-keys)
|
|
98
|
+
# OPENAI_API_KEY=
|
|
99
|
+
|
|
100
|
+
# OpenAI Model for metadata generation (default: gpt-4o-mini)
|
|
101
|
+
# OPENAI_MODEL=gpt-4o-mini
|
|
102
|
+
|
|
103
|
+
# Batch size for metadata generation (default: 100)
|
|
104
|
+
# Templates are processed in batches using OpenAI's Batch API for 50% cost savings
|
|
105
|
+
# OPENAI_BATCH_SIZE=100
|
|
106
|
+
|
|
107
|
+
# Enable metadata generation during template fetch (default: false)
|
|
108
|
+
# Set to true to automatically generate metadata when running fetch:templates
|
|
109
|
+
# METADATA_GENERATION_ENABLED=false
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
4
|
[](https://github.com/czlonkowski/n8n-mcp)
|
|
5
|
-
[](https://github.com/czlonkowski/n8n-mcp)
|
|
6
6
|
[](https://www.npmjs.com/package/n8n-mcp)
|
|
7
7
|
[](https://codecov.io/gh/czlonkowski/n8n-mcp)
|
|
8
8
|
[](https://github.com/czlonkowski/n8n-mcp/actions)
|
|
@@ -357,38 +357,51 @@ You are an expert in n8n automation software using n8n-MCP tools. Your role is t
|
|
|
357
357
|
|
|
358
358
|
1. **ALWAYS start new conversation with**: `tools_documentation()` to understand best practices and available tools.
|
|
359
359
|
|
|
360
|
-
2. **Discovery Phase**
|
|
360
|
+
2. **Template Discovery Phase**
|
|
361
|
+
- `search_templates_by_metadata({complexity: "simple"})` - Find skill-appropriate templates
|
|
362
|
+
- `get_templates_for_task('webhook_processing')` - Get curated templates by task
|
|
363
|
+
- `search_templates('slack notification')` - Text search for specific needs
|
|
364
|
+
- `list_node_templates(['n8n-nodes-base.slack'])` - Find templates using specific nodes
|
|
365
|
+
|
|
366
|
+
**Template filtering strategies**:
|
|
367
|
+
- **For beginners**: `complexity: "simple"` and `maxSetupMinutes: 30`
|
|
368
|
+
- **By role**: `targetAudience: "marketers"` or `"developers"` or `"analysts"`
|
|
369
|
+
- **By time**: `maxSetupMinutes: 15` for quick wins
|
|
370
|
+
- **By service**: `requiredService: "openai"` to find compatible templates
|
|
371
|
+
|
|
372
|
+
3. **Discovery Phase** - Find the right nodes (if no suitable template):
|
|
361
373
|
- Think deeply about user request and the logic you are going to build to fulfill it. Ask follow-up questions to clarify the user's intent, if something is unclear. Then, proceed with the rest of your instructions.
|
|
362
374
|
- `search_nodes({query: 'keyword'})` - Search by functionality
|
|
363
375
|
- `list_nodes({category: 'trigger'})` - Browse by category
|
|
364
376
|
- `list_ai_tools()` - See AI-capable nodes (remember: ANY node can be an AI tool!)
|
|
365
377
|
|
|
366
|
-
|
|
378
|
+
4. **Configuration Phase** - Get node details efficiently:
|
|
367
379
|
- `get_node_essentials(nodeType)` - Start here! Only 10-20 essential properties
|
|
368
380
|
- `search_node_properties(nodeType, 'auth')` - Find specific properties
|
|
369
381
|
- `get_node_for_task('send_email')` - Get pre-configured templates
|
|
370
382
|
- `get_node_documentation(nodeType)` - Human-readable docs when needed
|
|
371
383
|
- It is good common practice to show a visual representation of the workflow architecture to the user and asking for opinion, before moving forward.
|
|
372
384
|
|
|
373
|
-
|
|
385
|
+
5. **Pre-Validation Phase** - Validate BEFORE building:
|
|
374
386
|
- `validate_node_minimal(nodeType, config)` - Quick required fields check
|
|
375
387
|
- `validate_node_operation(nodeType, config, profile)` - Full operation-aware validation
|
|
376
388
|
- Fix any validation errors before proceeding
|
|
377
389
|
|
|
378
|
-
|
|
379
|
-
-
|
|
390
|
+
6. **Building Phase** - Create or customize the workflow:
|
|
391
|
+
- If using template: `get_template(templateId, {mode: "full"})`
|
|
392
|
+
- Customize template or build from validated configurations
|
|
380
393
|
- Connect nodes with proper structure
|
|
381
394
|
- Add error handling where appropriate
|
|
382
395
|
- Use expressions like $json, $node["NodeName"].json
|
|
383
396
|
- Build the workflow in an artifact for easy editing downstream (unless the user asked to create in n8n instance)
|
|
384
397
|
|
|
385
|
-
|
|
398
|
+
7. **Workflow Validation Phase** - Validate complete workflow:
|
|
386
399
|
- `validate_workflow(workflow)` - Complete validation including connections
|
|
387
400
|
- `validate_workflow_connections(workflow)` - Check structure and AI tool connections
|
|
388
401
|
- `validate_workflow_expressions(workflow)` - Validate all n8n expressions
|
|
389
402
|
- Fix any issues found before deployment
|
|
390
403
|
|
|
391
|
-
|
|
404
|
+
8. **Deployment Phase** (if n8n API configured):
|
|
392
405
|
- `n8n_create_workflow(workflow)` - Deploy validated workflow
|
|
393
406
|
- `n8n_validate_workflow({id: 'workflow-id'})` - Post-deployment validation
|
|
394
407
|
- `n8n_update_partial_workflow()` - Make incremental updates using diffs
|
|
@@ -396,6 +409,8 @@ You are an expert in n8n automation software using n8n-MCP tools. Your role is t
|
|
|
396
409
|
|
|
397
410
|
## Key Insights
|
|
398
411
|
|
|
412
|
+
- **TEMPLATES FIRST** - Always check for existing templates before building from scratch (2,500+ available!)
|
|
413
|
+
- **SMART FILTERING** - Use metadata filters to find templates matching user skill level and time constraints
|
|
399
414
|
- **USE CODE NODE ONLY WHEN IT IS NECESSARY** - always prefer to use standard nodes over code node. Use code node only when you are sure you need it.
|
|
400
415
|
- **VALIDATE EARLY AND OFTEN** - Catch errors before they reach deployment
|
|
401
416
|
- **USE DIFF UPDATES** - Use n8n_update_partial_workflow for 80-90% token savings
|
|
@@ -434,27 +449,50 @@ You are an expert in n8n automation software using n8n-MCP tools. Your role is t
|
|
|
434
449
|
|
|
435
450
|
## Example Workflow
|
|
436
451
|
|
|
437
|
-
###
|
|
452
|
+
### Smart Template-First Approach
|
|
453
|
+
|
|
454
|
+
#### 1. Find existing templates
|
|
455
|
+
// Find simple Slack templates for marketers
|
|
456
|
+
const templates = search_templates_by_metadata({
|
|
457
|
+
requiredService: 'slack',
|
|
458
|
+
complexity: 'simple',
|
|
459
|
+
targetAudience: 'marketers',
|
|
460
|
+
maxSetupMinutes: 30
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
// Or search by text
|
|
464
|
+
search_templates('slack notification')
|
|
465
|
+
|
|
466
|
+
// Or get curated templates
|
|
467
|
+
get_templates_for_task('slack_integration')
|
|
468
|
+
|
|
469
|
+
#### 2. Use and customize template
|
|
470
|
+
const workflow = get_template(templates.items[0].id, {mode: 'full'})
|
|
471
|
+
validate_workflow(workflow)
|
|
472
|
+
|
|
473
|
+
### Building from Scratch (if no suitable template)
|
|
474
|
+
|
|
475
|
+
#### 1. Discovery & Configuration
|
|
438
476
|
search_nodes({query: 'slack'})
|
|
439
477
|
get_node_essentials('n8n-nodes-base.slack')
|
|
440
478
|
|
|
441
|
-
|
|
479
|
+
#### 2. Pre-Validation
|
|
442
480
|
validate_node_minimal('n8n-nodes-base.slack', {resource:'message', operation:'send'})
|
|
443
481
|
validate_node_operation('n8n-nodes-base.slack', fullConfig, 'runtime')
|
|
444
482
|
|
|
445
|
-
|
|
483
|
+
#### 3. Build Workflow
|
|
446
484
|
// Create workflow JSON with validated configs
|
|
447
485
|
|
|
448
|
-
|
|
486
|
+
#### 4. Workflow Validation
|
|
449
487
|
validate_workflow(workflowJson)
|
|
450
488
|
validate_workflow_connections(workflowJson)
|
|
451
489
|
validate_workflow_expressions(workflowJson)
|
|
452
490
|
|
|
453
|
-
|
|
491
|
+
#### 5. Deploy (if configured)
|
|
454
492
|
n8n_create_workflow(validatedWorkflow)
|
|
455
493
|
n8n_validate_workflow({id: createdWorkflowId})
|
|
456
494
|
|
|
457
|
-
|
|
495
|
+
#### 6. Update Using Diffs
|
|
458
496
|
n8n_update_partial_workflow({
|
|
459
497
|
workflowId: id,
|
|
460
498
|
operations: [
|
|
@@ -464,15 +502,23 @@ n8n_update_partial_workflow({
|
|
|
464
502
|
|
|
465
503
|
## Important Rules
|
|
466
504
|
|
|
467
|
-
- ALWAYS
|
|
468
|
-
-
|
|
469
|
-
-
|
|
505
|
+
- ALWAYS check for existing templates before building from scratch
|
|
506
|
+
- LEVERAGE metadata filters to find skill-appropriate templates
|
|
507
|
+
- VALIDATE templates before deployment (they may need updates)
|
|
470
508
|
- USE diff operations for updates (80-90% token savings)
|
|
471
509
|
- STATE validation results clearly
|
|
472
510
|
- FIX all errors before proceeding
|
|
511
|
+
|
|
512
|
+
## Template Discovery Tips
|
|
513
|
+
|
|
514
|
+
- **97.5% of templates have metadata** - Use smart filtering!
|
|
515
|
+
- **Filter combinations work best** - Combine complexity + setup time + service
|
|
516
|
+
- **Templates save 70-90% development time** - Always check first
|
|
517
|
+
- **Metadata is AI-generated** - Occasionally imprecise but highly useful
|
|
518
|
+
- **Use `includeMetadata: false` for fast browsing** - Add metadata only when needed
|
|
473
519
|
```
|
|
474
520
|
|
|
475
|
-
Save these instructions in your Claude Project for optimal n8n workflow assistance with
|
|
521
|
+
Save these instructions in your Claude Project for optimal n8n workflow assistance with intelligent template discovery.
|
|
476
522
|
|
|
477
523
|
## 🚨 Important: Sharing Guidelines
|
|
478
524
|
|
|
@@ -524,6 +570,14 @@ Once connected, Claude can use these powerful tools:
|
|
|
524
570
|
- **`list_ai_tools`** - List all AI-capable nodes (ANY node can be used as AI tool!)
|
|
525
571
|
- **`get_node_as_tool_info`** - Get guidance on using any node as an AI tool
|
|
526
572
|
|
|
573
|
+
### Template Tools
|
|
574
|
+
- **`list_templates`** - Browse all templates with descriptions and optional metadata (2,500+ templates)
|
|
575
|
+
- **`search_templates`** - Text search across template names and descriptions
|
|
576
|
+
- **`search_templates_by_metadata`** - Advanced filtering by complexity, setup time, services, audience
|
|
577
|
+
- **`list_node_templates`** - Find templates using specific nodes
|
|
578
|
+
- **`get_template`** - Get complete workflow JSON for import
|
|
579
|
+
- **`get_templates_for_task`** - Curated templates for common automation tasks
|
|
580
|
+
|
|
527
581
|
### Advanced Tools
|
|
528
582
|
- **`get_node_for_task`** - Pre-configured node settings for common tasks
|
|
529
583
|
- **`list_tasks`** - Discover available task templates
|
package/data/nodes.db
CHANGED
|
Binary file
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -43,10 +43,12 @@ export declare class N8NDocumentationMCPServer {
|
|
|
43
43
|
private validateNodeMinimal;
|
|
44
44
|
private getToolsDocumentation;
|
|
45
45
|
connect(transport: any): Promise<void>;
|
|
46
|
+
private listTemplates;
|
|
46
47
|
private listNodeTemplates;
|
|
47
48
|
private getTemplate;
|
|
48
49
|
private searchTemplates;
|
|
49
50
|
private getTemplatesForTask;
|
|
51
|
+
private searchTemplatesByMetadata;
|
|
50
52
|
private getTaskDescription;
|
|
51
53
|
private validateWorkflow;
|
|
52
54
|
private validateWorkflowConnections;
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAuDA,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;;YA4DjB,kBAAkB;YAkBlB,wBAAwB;YAgBxB,iBAAiB;IAO/B,OAAO,CAAC,aAAa;IA0NrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IAoE1B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,qBAAqB;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAuDA,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;;YA4DjB,kBAAkB;YAkBlB,wBAAwB;YAgBxB,iBAAiB;IAO/B,OAAO,CAAC,aAAa;IA0NrB,OAAO,CAAC,wBAAwB;IAoFhC,OAAO,CAAC,kBAAkB;IAoE1B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,qBAAqB;YA8Rf,SAAS;YA2DT,WAAW;YAiEX,WAAW;YAsCX,cAAc;YAiId,gBAAgB;IAqD9B,OAAO,CAAC,mBAAmB;IAwE3B,OAAO,CAAC,eAAe;YAsBT,eAAe;IAqE7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,uBAAuB;IA0D/B,OAAO,CAAC,iBAAiB;YAqFX,WAAW;YAgCX,oBAAoB;YAyEpB,qBAAqB;YAwDrB,iBAAiB;YA+EjB,oBAAoB;YAsDpB,cAAc;IAqC5B,OAAO,CAAC,gBAAgB;YAiBV,SAAS;YA6CT,kBAAkB;YA+DlB,uBAAuB;YAsDvB,iBAAiB;IAqE/B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IAwD/B,OAAO,CAAC,iBAAiB;YAoDX,mBAAmB;YAkGnB,qBAAqB;IAS7B,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAS9B,aAAa;YAcb,iBAAiB;YAoBjB,WAAW;YAwBX,eAAe;YAqBf,mBAAmB;YAwBnB,yBAAyB;IA4CvC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6GhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -592,21 +592,43 @@ class N8NDocumentationMCPServer {
|
|
|
592
592
|
case 'get_node_as_tool_info':
|
|
593
593
|
this.validateToolParams(name, args, ['nodeType']);
|
|
594
594
|
return this.getNodeAsToolInfo(args.nodeType);
|
|
595
|
+
case 'list_templates':
|
|
596
|
+
const listLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
|
|
597
|
+
const listOffset = Math.max(Number(args.offset) || 0, 0);
|
|
598
|
+
const sortBy = args.sortBy || 'views';
|
|
599
|
+
const includeMetadata = Boolean(args.includeMetadata);
|
|
600
|
+
return this.listTemplates(listLimit, listOffset, sortBy, includeMetadata);
|
|
595
601
|
case 'list_node_templates':
|
|
596
602
|
this.validateToolParams(name, args, ['nodeTypes']);
|
|
597
|
-
const templateLimit =
|
|
598
|
-
|
|
603
|
+
const templateLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
|
|
604
|
+
const templateOffset = Math.max(Number(args.offset) || 0, 0);
|
|
605
|
+
return this.listNodeTemplates(args.nodeTypes, templateLimit, templateOffset);
|
|
599
606
|
case 'get_template':
|
|
600
607
|
this.validateToolParams(name, args, ['templateId']);
|
|
601
608
|
const templateId = Number(args.templateId);
|
|
602
|
-
|
|
609
|
+
const mode = args.mode || 'full';
|
|
610
|
+
return this.getTemplate(templateId, mode);
|
|
603
611
|
case 'search_templates':
|
|
604
612
|
this.validateToolParams(name, args, ['query']);
|
|
605
|
-
const searchLimit =
|
|
606
|
-
|
|
613
|
+
const searchLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
|
|
614
|
+
const searchOffset = Math.max(Number(args.offset) || 0, 0);
|
|
615
|
+
return this.searchTemplates(args.query, searchLimit, searchOffset);
|
|
607
616
|
case 'get_templates_for_task':
|
|
608
617
|
this.validateToolParams(name, args, ['task']);
|
|
609
|
-
|
|
618
|
+
const taskLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
|
|
619
|
+
const taskOffset = Math.max(Number(args.offset) || 0, 0);
|
|
620
|
+
return this.getTemplatesForTask(args.task, taskLimit, taskOffset);
|
|
621
|
+
case 'search_templates_by_metadata':
|
|
622
|
+
const metadataLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
|
|
623
|
+
const metadataOffset = Math.max(Number(args.offset) || 0, 0);
|
|
624
|
+
return this.searchTemplatesByMetadata({
|
|
625
|
+
category: args.category,
|
|
626
|
+
complexity: args.complexity,
|
|
627
|
+
maxSetupMinutes: args.maxSetupMinutes ? Number(args.maxSetupMinutes) : undefined,
|
|
628
|
+
minSetupMinutes: args.minSetupMinutes ? Number(args.minSetupMinutes) : undefined,
|
|
629
|
+
requiredService: args.requiredService,
|
|
630
|
+
targetAudience: args.targetAudience
|
|
631
|
+
}, metadataLimit, metadataOffset);
|
|
610
632
|
case 'validate_workflow':
|
|
611
633
|
this.validateToolParams(name, args, ['workflow']);
|
|
612
634
|
return this.validateWorkflow(args.workflow, args.options);
|
|
@@ -1262,8 +1284,17 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
1262
1284
|
FROM nodes
|
|
1263
1285
|
GROUP BY package_name
|
|
1264
1286
|
`).all();
|
|
1287
|
+
const templateStats = this.db.prepare(`
|
|
1288
|
+
SELECT
|
|
1289
|
+
COUNT(*) as total_templates,
|
|
1290
|
+
AVG(views) as avg_views,
|
|
1291
|
+
MIN(views) as min_views,
|
|
1292
|
+
MAX(views) as max_views
|
|
1293
|
+
FROM templates
|
|
1294
|
+
`).get();
|
|
1265
1295
|
return {
|
|
1266
1296
|
totalNodes: stats.total,
|
|
1297
|
+
totalTemplates: templateStats.total_templates || 0,
|
|
1267
1298
|
statistics: {
|
|
1268
1299
|
aiTools: stats.ai_tools,
|
|
1269
1300
|
triggers: stats.triggers,
|
|
@@ -1272,6 +1303,12 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
1272
1303
|
documentationCoverage: Math.round((stats.with_docs / stats.total) * 100) + '%',
|
|
1273
1304
|
uniquePackages: stats.packages,
|
|
1274
1305
|
uniqueCategories: stats.categories,
|
|
1306
|
+
templates: {
|
|
1307
|
+
total: templateStats.total_templates || 0,
|
|
1308
|
+
avgViews: Math.round(templateStats.avg_views || 0),
|
|
1309
|
+
minViews: templateStats.min_views || 0,
|
|
1310
|
+
maxViews: templateStats.max_views || 0
|
|
1311
|
+
}
|
|
1275
1312
|
},
|
|
1276
1313
|
packageBreakdown: packages.map(pkg => ({
|
|
1277
1314
|
package: pkg.package_name,
|
|
@@ -1810,76 +1847,128 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
1810
1847
|
transportType: transport.constructor.name
|
|
1811
1848
|
});
|
|
1812
1849
|
}
|
|
1813
|
-
async
|
|
1850
|
+
async listTemplates(limit = 10, offset = 0, sortBy = 'views', includeMetadata = false) {
|
|
1851
|
+
await this.ensureInitialized();
|
|
1852
|
+
if (!this.templateService)
|
|
1853
|
+
throw new Error('Template service not initialized');
|
|
1854
|
+
const result = await this.templateService.listTemplates(limit, offset, sortBy, includeMetadata);
|
|
1855
|
+
return {
|
|
1856
|
+
...result,
|
|
1857
|
+
tip: result.items.length > 0 ?
|
|
1858
|
+
`Use get_template(templateId) to get full workflow details. Total: ${result.total} templates available.` :
|
|
1859
|
+
"No templates found. Run 'npm run fetch:templates' to update template database"
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
async listNodeTemplates(nodeTypes, limit = 10, offset = 0) {
|
|
1814
1863
|
await this.ensureInitialized();
|
|
1815
1864
|
if (!this.templateService)
|
|
1816
1865
|
throw new Error('Template service not initialized');
|
|
1817
|
-
const
|
|
1818
|
-
if (
|
|
1866
|
+
const result = await this.templateService.listNodeTemplates(nodeTypes, limit, offset);
|
|
1867
|
+
if (result.items.length === 0 && offset === 0) {
|
|
1819
1868
|
return {
|
|
1869
|
+
...result,
|
|
1820
1870
|
message: `No templates found using nodes: ${nodeTypes.join(', ')}`,
|
|
1821
|
-
tip: "Try searching with more common nodes or run 'npm run fetch:templates' to update template database"
|
|
1822
|
-
templates: []
|
|
1871
|
+
tip: "Try searching with more common nodes or run 'npm run fetch:templates' to update template database"
|
|
1823
1872
|
};
|
|
1824
1873
|
}
|
|
1825
1874
|
return {
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
tip: `Use get_template(templateId) to get the full workflow JSON for any template`
|
|
1875
|
+
...result,
|
|
1876
|
+
tip: `Showing ${result.items.length} of ${result.total} templates. Use offset for pagination.`
|
|
1829
1877
|
};
|
|
1830
1878
|
}
|
|
1831
|
-
async getTemplate(templateId) {
|
|
1879
|
+
async getTemplate(templateId, mode = 'full') {
|
|
1832
1880
|
await this.ensureInitialized();
|
|
1833
1881
|
if (!this.templateService)
|
|
1834
1882
|
throw new Error('Template service not initialized');
|
|
1835
|
-
const template = await this.templateService.getTemplate(templateId);
|
|
1883
|
+
const template = await this.templateService.getTemplate(templateId, mode);
|
|
1836
1884
|
if (!template) {
|
|
1837
1885
|
return {
|
|
1838
1886
|
error: `Template ${templateId} not found`,
|
|
1839
|
-
tip: "Use list_node_templates or search_templates to find available templates"
|
|
1887
|
+
tip: "Use list_templates, list_node_templates or search_templates to find available templates"
|
|
1840
1888
|
};
|
|
1841
1889
|
}
|
|
1890
|
+
const usage = mode === 'nodes_only' ? "Node list for quick overview" :
|
|
1891
|
+
mode === 'structure' ? "Workflow structure without full details" :
|
|
1892
|
+
"Complete workflow JSON ready to import into n8n";
|
|
1842
1893
|
return {
|
|
1894
|
+
mode,
|
|
1843
1895
|
template,
|
|
1844
|
-
usage
|
|
1896
|
+
usage
|
|
1845
1897
|
};
|
|
1846
1898
|
}
|
|
1847
|
-
async searchTemplates(query, limit = 20) {
|
|
1899
|
+
async searchTemplates(query, limit = 20, offset = 0) {
|
|
1848
1900
|
await this.ensureInitialized();
|
|
1849
1901
|
if (!this.templateService)
|
|
1850
1902
|
throw new Error('Template service not initialized');
|
|
1851
|
-
const
|
|
1852
|
-
if (
|
|
1903
|
+
const result = await this.templateService.searchTemplates(query, limit, offset);
|
|
1904
|
+
if (result.items.length === 0 && offset === 0) {
|
|
1853
1905
|
return {
|
|
1906
|
+
...result,
|
|
1854
1907
|
message: `No templates found matching: "${query}"`,
|
|
1855
|
-
tip: "Try different keywords or run 'npm run fetch:templates' to update template database"
|
|
1856
|
-
templates: []
|
|
1908
|
+
tip: "Try different keywords or run 'npm run fetch:templates' to update template database"
|
|
1857
1909
|
};
|
|
1858
1910
|
}
|
|
1859
1911
|
return {
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
query
|
|
1912
|
+
...result,
|
|
1913
|
+
query,
|
|
1914
|
+
tip: `Found ${result.total} templates matching "${query}". Showing ${result.items.length}.`
|
|
1863
1915
|
};
|
|
1864
1916
|
}
|
|
1865
|
-
async getTemplatesForTask(task) {
|
|
1917
|
+
async getTemplatesForTask(task, limit = 10, offset = 0) {
|
|
1866
1918
|
await this.ensureInitialized();
|
|
1867
1919
|
if (!this.templateService)
|
|
1868
1920
|
throw new Error('Template service not initialized');
|
|
1869
|
-
const
|
|
1921
|
+
const result = await this.templateService.getTemplatesForTask(task, limit, offset);
|
|
1870
1922
|
const availableTasks = this.templateService.listAvailableTasks();
|
|
1871
|
-
if (
|
|
1923
|
+
if (result.items.length === 0 && offset === 0) {
|
|
1872
1924
|
return {
|
|
1925
|
+
...result,
|
|
1873
1926
|
message: `No templates found for task: ${task}`,
|
|
1874
1927
|
availableTasks,
|
|
1875
1928
|
tip: "Try a different task or use search_templates for custom searches"
|
|
1876
1929
|
};
|
|
1877
1930
|
}
|
|
1878
1931
|
return {
|
|
1932
|
+
...result,
|
|
1879
1933
|
task,
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1934
|
+
description: this.getTaskDescription(task),
|
|
1935
|
+
tip: `${result.total} templates available for ${task}. Showing ${result.items.length}.`
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1938
|
+
async searchTemplatesByMetadata(filters, limit = 20, offset = 0) {
|
|
1939
|
+
await this.ensureInitialized();
|
|
1940
|
+
if (!this.templateService)
|
|
1941
|
+
throw new Error('Template service not initialized');
|
|
1942
|
+
const result = await this.templateService.searchTemplatesByMetadata(filters, limit, offset);
|
|
1943
|
+
const filterSummary = [];
|
|
1944
|
+
if (filters.category)
|
|
1945
|
+
filterSummary.push(`category: ${filters.category}`);
|
|
1946
|
+
if (filters.complexity)
|
|
1947
|
+
filterSummary.push(`complexity: ${filters.complexity}`);
|
|
1948
|
+
if (filters.maxSetupMinutes)
|
|
1949
|
+
filterSummary.push(`max setup: ${filters.maxSetupMinutes} min`);
|
|
1950
|
+
if (filters.minSetupMinutes)
|
|
1951
|
+
filterSummary.push(`min setup: ${filters.minSetupMinutes} min`);
|
|
1952
|
+
if (filters.requiredService)
|
|
1953
|
+
filterSummary.push(`service: ${filters.requiredService}`);
|
|
1954
|
+
if (filters.targetAudience)
|
|
1955
|
+
filterSummary.push(`audience: ${filters.targetAudience}`);
|
|
1956
|
+
if (result.items.length === 0 && offset === 0) {
|
|
1957
|
+
const availableCategories = await this.templateService.getAvailableCategories();
|
|
1958
|
+
const availableAudiences = await this.templateService.getAvailableTargetAudiences();
|
|
1959
|
+
return {
|
|
1960
|
+
...result,
|
|
1961
|
+
message: `No templates found with filters: ${filterSummary.join(', ')}`,
|
|
1962
|
+
availableCategories: availableCategories.slice(0, 10),
|
|
1963
|
+
availableAudiences: availableAudiences.slice(0, 5),
|
|
1964
|
+
tip: "Try broader filters or different categories. Use list_templates to see all templates."
|
|
1965
|
+
};
|
|
1966
|
+
}
|
|
1967
|
+
return {
|
|
1968
|
+
...result,
|
|
1969
|
+
filters,
|
|
1970
|
+
filterSummary: filterSummary.join(', '),
|
|
1971
|
+
tip: `Found ${result.total} templates matching filters. Showing ${result.items.length}. Each includes AI-generated metadata.`
|
|
1883
1972
|
};
|
|
1884
1973
|
}
|
|
1885
1974
|
getTaskDescription(task) {
|