n8n-mcp 2.10.9 → 2.11.1

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.
Files changed (71) hide show
  1. package/.env.example +21 -1
  2. package/README.md +95 -18
  3. package/data/nodes.db +0 -0
  4. package/dist/mcp/server.d.ts +2 -0
  5. package/dist/mcp/server.d.ts.map +1 -1
  6. package/dist/mcp/server.js +122 -32
  7. package/dist/mcp/server.js.map +1 -1
  8. package/dist/mcp/tool-docs/index.d.ts.map +1 -1
  9. package/dist/mcp/tool-docs/index.js +1 -0
  10. package/dist/mcp/tool-docs/index.js.map +1 -1
  11. package/dist/mcp/tool-docs/templates/index.d.ts +1 -0
  12. package/dist/mcp/tool-docs/templates/index.d.ts.map +1 -1
  13. package/dist/mcp/tool-docs/templates/index.js +3 -1
  14. package/dist/mcp/tool-docs/templates/index.js.map +1 -1
  15. package/dist/mcp/tool-docs/templates/search-templates-by-metadata.d.ts +3 -0
  16. package/dist/mcp/tool-docs/templates/search-templates-by-metadata.d.ts.map +1 -0
  17. package/dist/mcp/tool-docs/templates/search-templates-by-metadata.js +120 -0
  18. package/dist/mcp/tool-docs/templates/search-templates-by-metadata.js.map +1 -0
  19. package/dist/mcp/tool-docs/templates/search-templates.d.ts.map +1 -1
  20. package/dist/mcp/tool-docs/templates/search-templates.js +12 -4
  21. package/dist/mcp/tool-docs/templates/search-templates.js.map +1 -1
  22. package/dist/mcp/tools.d.ts.map +1 -1
  23. package/dist/mcp/tools.js +132 -4
  24. package/dist/mcp/tools.js.map +1 -1
  25. package/dist/scripts/fetch-templates.d.ts +1 -1
  26. package/dist/scripts/fetch-templates.d.ts.map +1 -1
  27. package/dist/scripts/fetch-templates.js +167 -44
  28. package/dist/scripts/fetch-templates.js.map +1 -1
  29. package/dist/scripts/generate-metadata-only.d.ts +3 -0
  30. package/dist/scripts/generate-metadata-only.d.ts.map +1 -0
  31. package/dist/scripts/generate-metadata-only.js +146 -0
  32. package/dist/scripts/generate-metadata-only.js.map +1 -0
  33. package/dist/scripts/generate-metadata-sync.d.ts +3 -0
  34. package/dist/scripts/generate-metadata-sync.d.ts.map +1 -0
  35. package/dist/scripts/generate-metadata-sync.js +136 -0
  36. package/dist/scripts/generate-metadata-sync.js.map +1 -0
  37. package/dist/scripts/test-batch-processing.d.ts +3 -0
  38. package/dist/scripts/test-batch-processing.d.ts.map +1 -0
  39. package/dist/scripts/test-batch-processing.js +144 -0
  40. package/dist/scripts/test-batch-processing.js.map +1 -0
  41. package/dist/scripts/test-metadata-generation.d.ts +3 -0
  42. package/dist/scripts/test-metadata-generation.d.ts.map +1 -0
  43. package/dist/scripts/test-metadata-generation.js +96 -0
  44. package/dist/scripts/test-metadata-generation.js.map +1 -0
  45. package/dist/scripts/validation-summary.js +1 -1
  46. package/dist/scripts/validation-summary.js.map +1 -1
  47. package/dist/templates/batch-processor.d.ts +35 -0
  48. package/dist/templates/batch-processor.d.ts.map +1 -0
  49. package/dist/templates/batch-processor.js +280 -0
  50. package/dist/templates/batch-processor.js.map +1 -0
  51. package/dist/templates/metadata-generator.d.ts +52 -0
  52. package/dist/templates/metadata-generator.d.ts.map +1 -0
  53. package/dist/templates/metadata-generator.js +254 -0
  54. package/dist/templates/metadata-generator.js.map +1 -0
  55. package/dist/templates/template-fetcher.d.ts +1 -0
  56. package/dist/templates/template-fetcher.d.ts.map +1 -1
  57. package/dist/templates/template-fetcher.js +23 -19
  58. package/dist/templates/template-fetcher.js.map +1 -1
  59. package/dist/templates/template-repository.d.ts +58 -5
  60. package/dist/templates/template-repository.d.ts.map +1 -1
  61. package/dist/templates/template-repository.js +408 -25
  62. package/dist/templates/template-repository.js.map +1 -1
  63. package/dist/templates/template-service.d.ts +53 -5
  64. package/dist/templates/template-service.d.ts.map +1 -1
  65. package/dist/templates/template-service.js +176 -21
  66. package/dist/templates/template-service.js.map +1 -1
  67. package/dist/utils/template-node-resolver.d.ts +2 -0
  68. package/dist/utils/template-node-resolver.d.ts.map +1 -0
  69. package/dist/utils/template-node-resolver.js +161 -0
  70. package/dist/utils/template-node-resolver.js.map +1 -0
  71. 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
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
4
  [![GitHub stars](https://img.shields.io/github/stars/czlonkowski/n8n-mcp?style=social)](https://github.com/czlonkowski/n8n-mcp)
5
- [![Version](https://img.shields.io/badge/version-2.10.9-blue.svg)](https://github.com/czlonkowski/n8n-mcp)
5
+ [![Version](https://img.shields.io/badge/version-2.11.1-blue.svg)](https://github.com/czlonkowski/n8n-mcp)
6
6
  [![npm version](https://img.shields.io/npm/v/n8n-mcp.svg)](https://www.npmjs.com/package/n8n-mcp)
7
7
  [![codecov](https://codecov.io/gh/czlonkowski/n8n-mcp/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/czlonkowski/n8n-mcp)
8
8
  [![Tests](https://img.shields.io/badge/tests-1728%20passing-brightgreen.svg)](https://github.com/czlonkowski/n8n-mcp/actions)
@@ -357,38 +357,55 @@ 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** - Find the right nodes:
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
- 3. **Configuration Phase** - Get node details efficiently:
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
- 4. **Pre-Validation Phase** - Validate BEFORE building:
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
- 5. **Building Phase** - Create the workflow:
379
- - Use validated configurations from step 4
390
+ 6. **Building Phase** - Create or customize the workflow:
391
+ - If using template: `get_template(templateId, {mode: "full"})`
392
+ - **MANDATORY ATTRIBUTION**: When using a template, ALWAYS inform the user:
393
+ - "This workflow is based on a template by **[author.name]** (@[author.username])"
394
+ - "View the original template at: [url]"
395
+ - Example: "This workflow is based on a template by **David Ashby** (@cfomodz). View the original at: https://n8n.io/workflows/2414"
396
+ - Customize template or build from validated configurations
380
397
  - Connect nodes with proper structure
381
398
  - Add error handling where appropriate
382
399
  - Use expressions like $json, $node["NodeName"].json
383
400
  - Build the workflow in an artifact for easy editing downstream (unless the user asked to create in n8n instance)
384
401
 
385
- 6. **Workflow Validation Phase** - Validate complete workflow:
402
+ 7. **Workflow Validation Phase** - Validate complete workflow:
386
403
  - `validate_workflow(workflow)` - Complete validation including connections
387
404
  - `validate_workflow_connections(workflow)` - Check structure and AI tool connections
388
405
  - `validate_workflow_expressions(workflow)` - Validate all n8n expressions
389
406
  - Fix any issues found before deployment
390
407
 
391
- 7. **Deployment Phase** (if n8n API configured):
408
+ 8. **Deployment Phase** (if n8n API configured):
392
409
  - `n8n_create_workflow(workflow)` - Deploy validated workflow
393
410
  - `n8n_validate_workflow({id: 'workflow-id'})` - Post-deployment validation
394
411
  - `n8n_update_partial_workflow()` - Make incremental updates using diffs
@@ -396,6 +413,9 @@ You are an expert in n8n automation software using n8n-MCP tools. Your role is t
396
413
 
397
414
  ## Key Insights
398
415
 
416
+ - **TEMPLATES FIRST** - Always check for existing templates before building from scratch (2,500+ available!)
417
+ - **ATTRIBUTION REQUIRED** - Always credit template authors with name, username, and link to n8n.io
418
+ - **SMART FILTERING** - Use metadata filters to find templates matching user skill level and time constraints
399
419
  - **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
420
  - **VALIDATE EARLY AND OFTEN** - Catch errors before they reach deployment
401
421
  - **USE DIFF UPDATES** - Use n8n_update_partial_workflow for 80-90% token savings
@@ -434,27 +454,50 @@ You are an expert in n8n automation software using n8n-MCP tools. Your role is t
434
454
 
435
455
  ## Example Workflow
436
456
 
437
- ### 1. Discovery & Configuration
457
+ ### Smart Template-First Approach
458
+
459
+ #### 1. Find existing templates
460
+ // Find simple Slack templates for marketers
461
+ const templates = search_templates_by_metadata({
462
+ requiredService: 'slack',
463
+ complexity: 'simple',
464
+ targetAudience: 'marketers',
465
+ maxSetupMinutes: 30
466
+ })
467
+
468
+ // Or search by text
469
+ search_templates('slack notification')
470
+
471
+ // Or get curated templates
472
+ get_templates_for_task('slack_integration')
473
+
474
+ #### 2. Use and customize template
475
+ const workflow = get_template(templates.items[0].id, {mode: 'full'})
476
+ validate_workflow(workflow)
477
+
478
+ ### Building from Scratch (if no suitable template)
479
+
480
+ #### 1. Discovery & Configuration
438
481
  search_nodes({query: 'slack'})
439
482
  get_node_essentials('n8n-nodes-base.slack')
440
483
 
441
- ### 2. Pre-Validation
484
+ #### 2. Pre-Validation
442
485
  validate_node_minimal('n8n-nodes-base.slack', {resource:'message', operation:'send'})
443
486
  validate_node_operation('n8n-nodes-base.slack', fullConfig, 'runtime')
444
487
 
445
- ### 3. Build Workflow
488
+ #### 3. Build Workflow
446
489
  // Create workflow JSON with validated configs
447
490
 
448
- ### 4. Workflow Validation
491
+ #### 4. Workflow Validation
449
492
  validate_workflow(workflowJson)
450
493
  validate_workflow_connections(workflowJson)
451
494
  validate_workflow_expressions(workflowJson)
452
495
 
453
- ### 5. Deploy (if configured)
496
+ #### 5. Deploy (if configured)
454
497
  n8n_create_workflow(validatedWorkflow)
455
498
  n8n_validate_workflow({id: createdWorkflowId})
456
499
 
457
- ### 6. Update Using Diffs
500
+ #### 6. Update Using Diffs
458
501
  n8n_update_partial_workflow({
459
502
  workflowId: id,
460
503
  operations: [
@@ -464,15 +507,24 @@ n8n_update_partial_workflow({
464
507
 
465
508
  ## Important Rules
466
509
 
467
- - ALWAYS validate before building
468
- - ALWAYS validate after building
469
- - NEVER deploy unvalidated workflows
510
+ - ALWAYS check for existing templates before building from scratch
511
+ - LEVERAGE metadata filters to find skill-appropriate templates
512
+ - **ALWAYS ATTRIBUTE TEMPLATES**: When using any template, you MUST share the author's name, username, and link to the original template on n8n.io
513
+ - VALIDATE templates before deployment (they may need updates)
470
514
  - USE diff operations for updates (80-90% token savings)
471
515
  - STATE validation results clearly
472
516
  - FIX all errors before proceeding
517
+
518
+ ## Template Discovery Tips
519
+
520
+ - **97.5% of templates have metadata** - Use smart filtering!
521
+ - **Filter combinations work best** - Combine complexity + setup time + service
522
+ - **Templates save 70-90% development time** - Always check first
523
+ - **Metadata is AI-generated** - Occasionally imprecise but highly useful
524
+ - **Use `includeMetadata: false` for fast browsing** - Add metadata only when needed
473
525
  ```
474
526
 
475
- Save these instructions in your Claude Project for optimal n8n workflow assistance with comprehensive validation.
527
+ Save these instructions in your Claude Project for optimal n8n workflow assistance with intelligent template discovery.
476
528
 
477
529
  ## 🚨 Important: Sharing Guidelines
478
530
 
@@ -524,6 +576,14 @@ Once connected, Claude can use these powerful tools:
524
576
  - **`list_ai_tools`** - List all AI-capable nodes (ANY node can be used as AI tool!)
525
577
  - **`get_node_as_tool_info`** - Get guidance on using any node as an AI tool
526
578
 
579
+ ### Template Tools
580
+ - **`list_templates`** - Browse all templates with descriptions and optional metadata (2,500+ templates)
581
+ - **`search_templates`** - Text search across template names and descriptions
582
+ - **`search_templates_by_metadata`** - Advanced filtering by complexity, setup time, services, audience
583
+ - **`list_node_templates`** - Find templates using specific nodes
584
+ - **`get_template`** - Get complete workflow JSON for import
585
+ - **`get_templates_for_task`** - Curated templates for common automation tasks
586
+
527
587
  ### Advanced Tools
528
588
  - **`get_node_for_task`** - Pre-configured node settings for common tasks
529
589
  - **`list_tasks`** - Discover available task templates
@@ -807,6 +867,23 @@ See [Automated Release Guide](./docs/AUTOMATED_RELEASES.md) for complete details
807
867
  - [Anthropic](https://anthropic.com) for the Model Context Protocol
808
868
  - All contributors and users of this project
809
869
 
870
+ ### Template Attribution
871
+
872
+ All workflow templates in this project are fetched from n8n's public template gallery at [n8n.io/workflows](https://n8n.io/workflows). Each template includes:
873
+ - Full attribution to the original creator (name and username)
874
+ - Direct link to the source template on n8n.io
875
+ - Original workflow ID for reference
876
+
877
+ The AI agent instructions in this project contain mandatory attribution requirements. When using any template, the AI will automatically:
878
+ - Share the template author's name and username
879
+ - Provide a direct link to the original template on n8n.io
880
+ - Display attribution in the format: "This workflow is based on a template by **[author]** (@[username]). View the original at: [url]"
881
+
882
+ Template creators retain all rights to their workflows. This project indexes templates to improve discoverability through AI assistants. If you're a template creator and have concerns about your template being indexed, please open an issue.
883
+
884
+ Special thanks to the prolific template contributors whose work helps thousands of users automate their workflows, including:
885
+ **David Ashby** (@cfomodz), **Yaron Been** (@yaron-nofluff), **Jimleuk** (@jimleuk), **Davide** (@n3witalia), **David Olusola** (@dae221), **Ranjan Dailata** (@ranjancse), **Airtop** (@cesar-at-airtop), **Joseph LePage** (@joe), **Don Jayamaha Jr** (@don-the-gem-dealer), **Angel Menendez** (@djangelic), and the entire n8n community of creators!
886
+
810
887
  ---
811
888
 
812
889
  <div align="center">
package/data/nodes.db CHANGED
Binary file
@@ -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;
@@ -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;YAsQf,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;YAuCrB,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,iBAAiB;YAqBjB,WAAW;YAmBX,eAAe;YAqBf,mBAAmB;IAuBjC,OAAO,CAAC,kBAAkB;YAiBZ,gBAAgB;YA6GhB,2BAA2B;YAiE3B,2BAA2B;IAyEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
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;YA+Rf,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"}
@@ -592,21 +592,44 @@ 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 = args.limit !== undefined ? Number(args.limit) || 10 : 10;
598
- return this.listNodeTemplates(args.nodeTypes, templateLimit);
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
- return this.getTemplate(templateId);
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 = args.limit !== undefined ? Number(args.limit) || 20 : 20;
606
- return this.searchTemplates(args.query, searchLimit);
613
+ const searchLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
614
+ const searchOffset = Math.max(Number(args.offset) || 0, 0);
615
+ const searchFields = args.fields;
616
+ return this.searchTemplates(args.query, searchLimit, searchOffset, searchFields);
607
617
  case 'get_templates_for_task':
608
618
  this.validateToolParams(name, args, ['task']);
609
- return this.getTemplatesForTask(args.task);
619
+ const taskLimit = Math.min(Math.max(Number(args.limit) || 10, 1), 100);
620
+ const taskOffset = Math.max(Number(args.offset) || 0, 0);
621
+ return this.getTemplatesForTask(args.task, taskLimit, taskOffset);
622
+ case 'search_templates_by_metadata':
623
+ const metadataLimit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
624
+ const metadataOffset = Math.max(Number(args.offset) || 0, 0);
625
+ return this.searchTemplatesByMetadata({
626
+ category: args.category,
627
+ complexity: args.complexity,
628
+ maxSetupMinutes: args.maxSetupMinutes ? Number(args.maxSetupMinutes) : undefined,
629
+ minSetupMinutes: args.minSetupMinutes ? Number(args.minSetupMinutes) : undefined,
630
+ requiredService: args.requiredService,
631
+ targetAudience: args.targetAudience
632
+ }, metadataLimit, metadataOffset);
610
633
  case 'validate_workflow':
611
634
  this.validateToolParams(name, args, ['workflow']);
612
635
  return this.validateWorkflow(args.workflow, args.options);
@@ -1262,8 +1285,17 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
1262
1285
  FROM nodes
1263
1286
  GROUP BY package_name
1264
1287
  `).all();
1288
+ const templateStats = this.db.prepare(`
1289
+ SELECT
1290
+ COUNT(*) as total_templates,
1291
+ AVG(views) as avg_views,
1292
+ MIN(views) as min_views,
1293
+ MAX(views) as max_views
1294
+ FROM templates
1295
+ `).get();
1265
1296
  return {
1266
1297
  totalNodes: stats.total,
1298
+ totalTemplates: templateStats.total_templates || 0,
1267
1299
  statistics: {
1268
1300
  aiTools: stats.ai_tools,
1269
1301
  triggers: stats.triggers,
@@ -1272,6 +1304,12 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
1272
1304
  documentationCoverage: Math.round((stats.with_docs / stats.total) * 100) + '%',
1273
1305
  uniquePackages: stats.packages,
1274
1306
  uniqueCategories: stats.categories,
1307
+ templates: {
1308
+ total: templateStats.total_templates || 0,
1309
+ avgViews: Math.round(templateStats.avg_views || 0),
1310
+ minViews: templateStats.min_views || 0,
1311
+ maxViews: templateStats.max_views || 0
1312
+ }
1275
1313
  },
1276
1314
  packageBreakdown: packages.map(pkg => ({
1277
1315
  package: pkg.package_name,
@@ -1810,76 +1848,128 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
1810
1848
  transportType: transport.constructor.name
1811
1849
  });
1812
1850
  }
1813
- async listNodeTemplates(nodeTypes, limit = 10) {
1851
+ async listTemplates(limit = 10, offset = 0, sortBy = 'views', includeMetadata = false) {
1852
+ await this.ensureInitialized();
1853
+ if (!this.templateService)
1854
+ throw new Error('Template service not initialized');
1855
+ const result = await this.templateService.listTemplates(limit, offset, sortBy, includeMetadata);
1856
+ return {
1857
+ ...result,
1858
+ tip: result.items.length > 0 ?
1859
+ `Use get_template(templateId) to get full workflow details. Total: ${result.total} templates available.` :
1860
+ "No templates found. Run 'npm run fetch:templates' to update template database"
1861
+ };
1862
+ }
1863
+ async listNodeTemplates(nodeTypes, limit = 10, offset = 0) {
1814
1864
  await this.ensureInitialized();
1815
1865
  if (!this.templateService)
1816
1866
  throw new Error('Template service not initialized');
1817
- const templates = await this.templateService.listNodeTemplates(nodeTypes, limit);
1818
- if (templates.length === 0) {
1867
+ const result = await this.templateService.listNodeTemplates(nodeTypes, limit, offset);
1868
+ if (result.items.length === 0 && offset === 0) {
1819
1869
  return {
1870
+ ...result,
1820
1871
  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: []
1872
+ tip: "Try searching with more common nodes or run 'npm run fetch:templates' to update template database"
1823
1873
  };
1824
1874
  }
1825
1875
  return {
1826
- templates,
1827
- count: templates.length,
1828
- tip: `Use get_template(templateId) to get the full workflow JSON for any template`
1876
+ ...result,
1877
+ tip: `Showing ${result.items.length} of ${result.total} templates. Use offset for pagination.`
1829
1878
  };
1830
1879
  }
1831
- async getTemplate(templateId) {
1880
+ async getTemplate(templateId, mode = 'full') {
1832
1881
  await this.ensureInitialized();
1833
1882
  if (!this.templateService)
1834
1883
  throw new Error('Template service not initialized');
1835
- const template = await this.templateService.getTemplate(templateId);
1884
+ const template = await this.templateService.getTemplate(templateId, mode);
1836
1885
  if (!template) {
1837
1886
  return {
1838
1887
  error: `Template ${templateId} not found`,
1839
- tip: "Use list_node_templates or search_templates to find available templates"
1888
+ tip: "Use list_templates, list_node_templates or search_templates to find available templates"
1840
1889
  };
1841
1890
  }
1891
+ const usage = mode === 'nodes_only' ? "Node list for quick overview" :
1892
+ mode === 'structure' ? "Workflow structure without full details" :
1893
+ "Complete workflow JSON ready to import into n8n";
1842
1894
  return {
1895
+ mode,
1843
1896
  template,
1844
- usage: "Import this workflow JSON directly into n8n or use it as a reference for building workflows"
1897
+ usage
1845
1898
  };
1846
1899
  }
1847
- async searchTemplates(query, limit = 20) {
1900
+ async searchTemplates(query, limit = 20, offset = 0, fields) {
1848
1901
  await this.ensureInitialized();
1849
1902
  if (!this.templateService)
1850
1903
  throw new Error('Template service not initialized');
1851
- const templates = await this.templateService.searchTemplates(query, limit);
1852
- if (templates.length === 0) {
1904
+ const result = await this.templateService.searchTemplates(query, limit, offset, fields);
1905
+ if (result.items.length === 0 && offset === 0) {
1853
1906
  return {
1907
+ ...result,
1854
1908
  message: `No templates found matching: "${query}"`,
1855
- tip: "Try different keywords or run 'npm run fetch:templates' to update template database",
1856
- templates: []
1909
+ tip: "Try different keywords or run 'npm run fetch:templates' to update template database"
1857
1910
  };
1858
1911
  }
1859
1912
  return {
1860
- templates,
1861
- count: templates.length,
1862
- query
1913
+ ...result,
1914
+ query,
1915
+ tip: `Found ${result.total} templates matching "${query}". Showing ${result.items.length}.`
1863
1916
  };
1864
1917
  }
1865
- async getTemplatesForTask(task) {
1918
+ async getTemplatesForTask(task, limit = 10, offset = 0) {
1866
1919
  await this.ensureInitialized();
1867
1920
  if (!this.templateService)
1868
1921
  throw new Error('Template service not initialized');
1869
- const templates = await this.templateService.getTemplatesForTask(task);
1922
+ const result = await this.templateService.getTemplatesForTask(task, limit, offset);
1870
1923
  const availableTasks = this.templateService.listAvailableTasks();
1871
- if (templates.length === 0) {
1924
+ if (result.items.length === 0 && offset === 0) {
1872
1925
  return {
1926
+ ...result,
1873
1927
  message: `No templates found for task: ${task}`,
1874
1928
  availableTasks,
1875
1929
  tip: "Try a different task or use search_templates for custom searches"
1876
1930
  };
1877
1931
  }
1878
1932
  return {
1933
+ ...result,
1879
1934
  task,
1880
- templates,
1881
- count: templates.length,
1882
- description: this.getTaskDescription(task)
1935
+ description: this.getTaskDescription(task),
1936
+ tip: `${result.total} templates available for ${task}. Showing ${result.items.length}.`
1937
+ };
1938
+ }
1939
+ async searchTemplatesByMetadata(filters, limit = 20, offset = 0) {
1940
+ await this.ensureInitialized();
1941
+ if (!this.templateService)
1942
+ throw new Error('Template service not initialized');
1943
+ const result = await this.templateService.searchTemplatesByMetadata(filters, limit, offset);
1944
+ const filterSummary = [];
1945
+ if (filters.category)
1946
+ filterSummary.push(`category: ${filters.category}`);
1947
+ if (filters.complexity)
1948
+ filterSummary.push(`complexity: ${filters.complexity}`);
1949
+ if (filters.maxSetupMinutes)
1950
+ filterSummary.push(`max setup: ${filters.maxSetupMinutes} min`);
1951
+ if (filters.minSetupMinutes)
1952
+ filterSummary.push(`min setup: ${filters.minSetupMinutes} min`);
1953
+ if (filters.requiredService)
1954
+ filterSummary.push(`service: ${filters.requiredService}`);
1955
+ if (filters.targetAudience)
1956
+ filterSummary.push(`audience: ${filters.targetAudience}`);
1957
+ if (result.items.length === 0 && offset === 0) {
1958
+ const availableCategories = await this.templateService.getAvailableCategories();
1959
+ const availableAudiences = await this.templateService.getAvailableTargetAudiences();
1960
+ return {
1961
+ ...result,
1962
+ message: `No templates found with filters: ${filterSummary.join(', ')}`,
1963
+ availableCategories: availableCategories.slice(0, 10),
1964
+ availableAudiences: availableAudiences.slice(0, 5),
1965
+ tip: "Try broader filters or different categories. Use list_templates to see all templates."
1966
+ };
1967
+ }
1968
+ return {
1969
+ ...result,
1970
+ filters,
1971
+ filterSummary: filterSummary.join(', '),
1972
+ tip: `Found ${result.total} templates matching filters. Showing ${result.items.length}. Each includes AI-generated metadata.`
1883
1973
  };
1884
1974
  }
1885
1975
  getTaskDescription(task) {