This is page 3 of 3. Use http://codebase.md/leonardsellem/n8n-mcp-server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .babelrc
├── .env.example
├── .eslintrc.json
├── .github
│ └── workflows
│ ├── claude-code-review.yml
│ ├── claude.yml
│ ├── docker-publish.yml
│ └── release-package.yml
├── .gitignore
├── AGENTS.md
├── babel.config.cjs
├── CLAUDE.md
├── Dockerfile
├── docs
│ ├── .gitkeep
│ ├── api
│ │ ├── dynamic-resources.md
│ │ ├── execution-tools.md
│ │ ├── index.md
│ │ ├── static-resources.md
│ │ └── workflow-tools.md
│ ├── development
│ │ ├── architecture.md
│ │ ├── extending.md
│ │ ├── index.md
│ │ └── testing.md
│ ├── examples
│ │ ├── advanced-scenarios.md
│ │ ├── basic-examples.md
│ │ ├── index.md
│ │ └── integration-examples.md
│ ├── images
│ │ ├── architecture.png.placeholder
│ │ └── n8n-api-key.png.placeholder
│ ├── index.md
│ └── setup
│ ├── configuration.md
│ ├── index.md
│ ├── installation.md
│ └── troubleshooting.md
├── jest.config.cjs
├── LICENSE
├── manual_verify_update.mjs
├── n8n-openapi.yml
├── package-lock.json
├── package.json
├── README.md
├── requirements.txt
├── run-tests.js
├── smithery.yaml
├── src
│ ├── .gitkeep
│ ├── api
│ │ ├── client.ts
│ │ └── n8n-client.ts
│ ├── config
│ │ ├── environment.ts
│ │ └── server.ts
│ ├── errors
│ │ ├── error-codes.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── resources
│ │ ├── dynamic
│ │ │ ├── execution.ts
│ │ │ └── workflow.ts
│ │ ├── index.ts
│ │ └── static
│ │ ├── execution-stats.ts
│ │ └── workflows.ts
│ ├── tools
│ │ ├── execution
│ │ │ ├── base-handler.ts
│ │ │ ├── delete.ts
│ │ │ ├── get.ts
│ │ │ ├── handler.ts
│ │ │ ├── index.ts
│ │ │ ├── list.ts
│ │ │ └── run.ts
│ │ └── workflow
│ │ ├── activate.ts
│ │ ├── base-handler.ts
│ │ ├── create.ts
│ │ ├── deactivate.ts
│ │ ├── delete.ts
│ │ ├── get.ts
│ │ ├── handler.ts
│ │ ├── index.ts
│ │ ├── list.ts
│ │ └── update.ts
│ ├── types
│ │ └── index.ts
│ └── utils
│ ├── execution-formatter.ts
│ └── resource-formatter.ts
├── tests
│ ├── jest-globals.d.ts
│ ├── mocks
│ │ ├── axios-mock.ts
│ │ └── n8n-fixtures.ts
│ ├── README.md
│ ├── test-setup.ts
│ ├── tsconfig.json
│ └── unit
│ ├── api
│ │ ├── client.test.ts.bak
│ │ └── simple-client.test.ts
│ ├── config
│ │ ├── environment.test.ts
│ │ ├── environment.test.ts.bak
│ │ └── simple-environment.test.ts
│ ├── resources
│ │ └── dynamic
│ │ └── workflow.test.ts
│ ├── tools
│ │ └── workflow
│ │ ├── list.test.ts.bak
│ │ └── simple-tool.test.ts
│ └── utils
│ ├── execution-formatter.test.ts
│ └── resource-formatter.test.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/docs/examples/integration-examples.md:
--------------------------------------------------------------------------------
```markdown
1 | # Integration Examples
2 |
3 | This page provides examples of integrating the n8n MCP Server with other systems and AI assistant platforms.
4 |
5 | ## AI Assistant Integration Examples
6 |
7 | ### Claude AI Assistant Integration
8 |
9 | #### Example: Setting Up n8n MCP Server with Claude
10 |
11 | ```javascript
12 | // Register the n8n MCP Server with Claude using the MCP Installer
13 | const installationResult = await useMcpTool('mcp-installer', 'install_repo_mcp_server', {
14 | name: 'n8n-mcp-server',
15 | env: [
16 | "N8N_API_URL=http://localhost:5678/api/v1",
17 | "N8N_API_KEY=your_n8n_api_key_here",
18 | "DEBUG=false"
19 | ]
20 | });
21 |
22 | // Once registered, Claude can interact with n8n
23 | // Here's an example conversation:
24 |
25 | // User: "Show me my active workflows in n8n"
26 | // Claude: (uses workflow_list tool to retrieve and display active workflows)
27 |
28 | // User: "Execute my 'Daily Report' workflow"
29 | // Claude: (uses execution_run tool to start the workflow and provide status)
30 | ```
31 |
32 | #### Example: Using n8n to Extend Claude's Capabilities
33 |
34 | ```javascript
35 | // Using n8n as a bridge to external systems
36 | // This example shows how Claude can access a database through n8n
37 |
38 | // User: "Show me the top 5 customers from my database"
39 | // Claude would:
40 |
41 | // 1. Find the appropriate workflow
42 | const workflows = await useMcpTool('n8n-mcp-server', 'workflow_list', {});
43 | const dbQueryWorkflow = workflows.find(w =>
44 | w.name.toLowerCase().includes('database query') ||
45 | w.name.toLowerCase().includes('db query')
46 | );
47 |
48 | if (!dbQueryWorkflow) {
49 | return "I couldn't find a database query workflow. Would you like me to help you create one?";
50 | }
51 |
52 | // 2. Execute the workflow with the appropriate parameters
53 | const execution = await useMcpTool('n8n-mcp-server', 'execution_run', {
54 | workflowId: dbQueryWorkflow.id,
55 | data: {
56 | query: "SELECT * FROM customers ORDER BY total_purchases DESC LIMIT 5",
57 | format: "table"
58 | },
59 | waitForCompletion: true
60 | });
61 |
62 | // 3. Present the results to the user
63 | if (execution.status !== "success") {
64 | return "There was an error querying the database. Error: " + (execution.error || "Unknown error");
65 | }
66 |
67 | // Format the results as a table
68 | const customers = execution.data.resultData.runData.lastNode[0].data.json;
69 | let response = "# Top 5 Customers\n\n";
70 | response += "| Customer Name | Email | Total Purchases |\n";
71 | response += "|--------------|-------|----------------|\n";
72 |
73 | customers.forEach(customer => {
74 | response += `| ${customer.name} | ${customer.email} | $${customer.total_purchases.toFixed(2)} |\n`;
75 | });
76 |
77 | return response;
78 | ```
79 |
80 | ### OpenAI Assistant Integration
81 |
82 | #### Example: Connecting n8n MCP Server to OpenAI Assistant
83 |
84 | ```javascript
85 | // This is a conceptual example of how an OpenAI Assistant might interact with the n8n MCP Server
86 |
87 | // In an OpenAI Assistant Function definition:
88 | {
89 | "name": "n8n_workflow_list",
90 | "description": "List all workflows in n8n",
91 | "parameters": {
92 | "type": "object",
93 | "properties": {
94 | "active": {
95 | "type": "boolean",
96 | "description": "Filter by active status (optional)"
97 | }
98 | }
99 | }
100 | }
101 |
102 | // The function would call the n8n MCP Server:
103 | async function n8n_workflow_list(params) {
104 | // Call the n8n MCP Server API
105 | const response = await fetch('http://localhost:3000/n8n-mcp/tools/workflow_list', {
106 | method: 'POST',
107 | headers: {
108 | 'Content-Type': 'application/json',
109 | 'Authorization': 'Bearer YOUR_AUTH_TOKEN'
110 | },
111 | body: JSON.stringify(params)
112 | });
113 |
114 | return await response.json();
115 | }
116 |
117 | // The OpenAI Assistant would then use this function when asked about n8n workflows
118 | ```
119 |
120 | ## Integration with External Systems
121 |
122 | ### n8n to Git Integration
123 |
124 | #### Example: Using n8n MCP Server to Manage Workflow Versioning in Git
125 |
126 | ```javascript
127 | // User request: "Backup all my workflows to my Git repository"
128 |
129 | // The assistant first creates a workflow for Git backup
130 | const backupWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
131 | name: "Workflow Git Backup",
132 | active: false,
133 | nodes: [
134 | {
135 | name: "Manual Trigger",
136 | type: "n8n-nodes-base.manualTrigger",
137 | position: [100, 300],
138 | parameters: {}
139 | },
140 | {
141 | name: "Get All Workflows",
142 | type: "n8n-nodes-base.n8n",
143 | position: [300, 300],
144 | parameters: {
145 | resource: "workflow",
146 | operation: "getAll"
147 | }
148 | },
149 | {
150 | name: "Format For Git",
151 | type: "n8n-nodes-base.function",
152 | position: [500, 300],
153 | parameters: {
154 | functionCode: `
155 | // Convert workflows to individual JSON files
156 | const workflows = items;
157 | const outputItems = [];
158 |
159 | for (const workflow of workflows) {
160 | // Create a sanitized filename
161 | const filename = workflow.json.name
162 | .replace(/[^a-zA-Z0-9]/g, '_')
163 | .toLowerCase() + '.json';
164 |
165 | outputItems.push({
166 | json: {
167 | filename: filename,
168 | content: JSON.stringify(workflow.json, null, 2),
169 | commit_message: \`Backup workflow: \${workflow.json.name}\`
170 | }
171 | });
172 | }
173 |
174 | return outputItems;
175 | `
176 | }
177 | },
178 | {
179 | name: "Git Commit",
180 | type: "n8n-nodes-base.git",
181 | position: [700, 300],
182 | parameters: {
183 | repository: "{{$env.GIT_REPO_PATH}}",
184 | directory: "workflows",
185 | operation: "commit",
186 | message: "Automated workflow backup {{$now.format('YYYY-MM-DD HH:mm')}}",
187 | filePath: "={{$json.filename}}",
188 | fileContent: "={{$json.content}}"
189 | }
190 | },
191 | {
192 | name: "Git Push",
193 | type: "n8n-nodes-base.git",
194 | position: [900, 300],
195 | parameters: {
196 | repository: "{{$env.GIT_REPO_PATH}}",
197 | operation: "push"
198 | }
199 | }
200 | ],
201 | connections: {
202 | "Manual Trigger": {
203 | main: [
204 | [
205 | {
206 | node: "Get All Workflows",
207 | type: "main",
208 | index: 0
209 | }
210 | ]
211 | ]
212 | },
213 | "Get All Workflows": {
214 | main: [
215 | [
216 | {
217 | node: "Format For Git",
218 | type: "main",
219 | index: 0
220 | }
221 | ]
222 | ]
223 | },
224 | "Format For Git": {
225 | main: [
226 | [
227 | {
228 | node: "Git Commit",
229 | type: "main",
230 | index: 0
231 | }
232 | ]
233 | ]
234 | },
235 | "Git Commit": {
236 | main: [
237 | [
238 | {
239 | node: "Git Push",
240 | type: "main",
241 | index: 0
242 | }
243 | ]
244 | ]
245 | }
246 | }
247 | });
248 |
249 | return `
250 | # Git Backup Workflow Created
251 |
252 | I've created a new workflow that will backup all your n8n workflows to Git.
253 |
254 | **Workflow ID:** ${backupWorkflow.id}
255 |
256 | ## Configuration Needed:
257 | 1. The workflow is currently **inactive** - activate it once configured
258 | 2. Set the environment variable \`GIT_REPO_PATH\` to point to your Git repository
259 | 3. Ensure the Git repository is properly configured with credentials
260 |
261 | ## How It Works:
262 | - When executed, this workflow retrieves all n8n workflows
263 | - Converts each workflow to a JSON file
264 | - Commits each file to the specified Git repository
265 | - Pushes the changes to the remote repository
266 |
267 | ## Usage:
268 | You can run this workflow manually whenever you want to backup your workflows,
269 | or add a Schedule Trigger to automate regular backups.
270 | `;
271 | ```
272 |
273 | ### CRM Integration
274 |
275 | #### Example: Setting Up a Two-Way Sync Between n8n and a CRM
276 |
277 | ```javascript
278 | // User request: "Help me set up a sync between n8n and my HubSpot CRM"
279 |
280 | // First check for existing credentials
281 | const workflows = await useMcpTool('n8n-mcp-server', 'workflow_list', {});
282 | const hubspotWorkflows = workflows.filter(w =>
283 | w.name.toLowerCase().includes('hubspot')
284 | );
285 |
286 | let credentialsMessage = "";
287 | if (hubspotWorkflows.length > 0) {
288 | credentialsMessage = "I noticed you already have HubSpot workflows. I'll assume you have HubSpot credentials set up.";
289 | } else {
290 | credentialsMessage = "You'll need to set up HubSpot credentials in n8n before activating this workflow.";
291 | }
292 |
293 | // Create the sync workflow
294 | const syncWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
295 | name: "HubSpot Two-Way Sync",
296 | active: false,
297 | nodes: [
298 | {
299 | name: "Schedule Trigger",
300 | type: "n8n-nodes-base.scheduleTrigger",
301 | position: [100, 300],
302 | parameters: {
303 | cronExpression: "0 */2 * * *" // Every 2 hours
304 | }
305 | },
306 | {
307 | name: "Get HubSpot Contacts",
308 | type: "n8n-nodes-base.hubspot",
309 | position: [300, 200],
310 | parameters: {
311 | resource: "contact",
312 | operation: "getAll",
313 | returnAll: true,
314 | additionalFields: {
315 | formattedDate: true
316 | }
317 | }
318 | },
319 | {
320 | name: "Get n8n Contacts",
321 | type: "n8n-nodes-base.function",
322 | position: [300, 400],
323 | parameters: {
324 | functionCode: `
325 | // This function would retrieve contacts from your internal database
326 | // For example purposes, we're using a placeholder
327 | // In reality, you might use another n8n node to fetch from your database
328 |
329 | return [
330 | {
331 | json: {
332 | internalContacts: [
333 | // Example internal contacts
334 | // In a real scenario, these would come from your database
335 | ]
336 | }
337 | }
338 | ];
339 | `
340 | }
341 | },
342 | {
343 | name: "Compare & Identify Changes",
344 | type: "n8n-nodes-base.function",
345 | position: [500, 300],
346 | parameters: {
347 | functionCode: `
348 | const hubspotContacts = $input.first();
349 | const internalContacts = $input.last().json.internalContacts;
350 |
351 | // Identify new/updated contacts in HubSpot
352 | const hubspotUpdates = hubspotContacts.json.map(contact => {
353 | // Find matching internal contact by email
354 | const internalMatch = internalContacts.find(
355 | ic => ic.email === contact.properties.email
356 | );
357 |
358 | if (!internalMatch) {
359 | return {
360 | json: {
361 | type: 'new_in_hubspot',
362 | contact: contact,
363 | action: 'create_in_internal'
364 | }
365 | };
366 | }
367 |
368 | // Check if HubSpot contact is newer
369 | const hubspotUpdated = new Date(contact.properties.lastmodifieddate);
370 | const internalUpdated = new Date(internalMatch.updated_at);
371 |
372 | if (hubspotUpdated > internalUpdated) {
373 | return {
374 | json: {
375 | type: 'updated_in_hubspot',
376 | contact: contact,
377 | action: 'update_in_internal'
378 | }
379 | };
380 | }
381 |
382 | return null;
383 | }).filter(item => item !== null);
384 |
385 | // Identify new/updated contacts in internal system
386 | const internalUpdates = internalContacts.map(contact => {
387 | // Find matching HubSpot contact by email
388 | const hubspotMatch = hubspotContacts.json.find(
389 | hc => hc.properties.email === contact.email
390 | );
391 |
392 | if (!hubspotMatch) {
393 | return {
394 | json: {
395 | type: 'new_in_internal',
396 | contact: contact,
397 | action: 'create_in_hubspot'
398 | }
399 | };
400 | }
401 |
402 | // Check if internal contact is newer
403 | const internalUpdated = new Date(contact.updated_at);
404 | const hubspotUpdated = new Date(hubspotMatch.properties.lastmodifieddate);
405 |
406 | if (internalUpdated > hubspotUpdated) {
407 | return {
408 | json: {
409 | type: 'updated_in_internal',
410 | contact: contact,
411 | action: 'update_in_hubspot'
412 | }
413 | };
414 | }
415 |
416 | return null;
417 | }).filter(item => item !== null);
418 |
419 | // Combine all changes
420 | return [...hubspotUpdates, ...internalUpdates];
421 | `
422 | }
423 | },
424 | {
425 | name: "Route Updates",
426 | type: "n8n-nodes-base.switch",
427 | position: [700, 300],
428 | parameters: {
429 | rules: {
430 | conditions: [
431 | {
432 | value1: "={{$json.action}}",
433 | operation: "equal",
434 | value2: "update_in_hubspot"
435 | },
436 | {
437 | value1: "={{$json.action}}",
438 | operation: "equal",
439 | value2: "create_in_hubspot"
440 | },
441 | {
442 | value1: "={{$json.action}}",
443 | operation: "equal",
444 | value2: "update_in_internal"
445 | },
446 | {
447 | value1: "={{$json.action}}",
448 | operation: "equal",
449 | value2: "create_in_internal"
450 | }
451 | ]
452 | }
453 | }
454 | },
455 | {
456 | name: "Update HubSpot Contact",
457 | type: "n8n-nodes-base.hubspot",
458 | position: [900, 100],
459 | parameters: {
460 | resource: "contact",
461 | operation: "update",
462 | contactId: "={{$json.contact.hubspot_id || $json.hubspotId}}",
463 | additionalFields: {
464 | properties: {
465 | firstname: "={{$json.contact.first_name}}",
466 | lastname: "={{$json.contact.last_name}}",
467 | email: "={{$json.contact.email}}",
468 | phone: "={{$json.contact.phone}}",
469 | // Add additional fields as needed
470 | }
471 | }
472 | }
473 | },
474 | {
475 | name: "Create HubSpot Contact",
476 | type: "n8n-nodes-base.hubspot",
477 | position: [900, 250],
478 | parameters: {
479 | resource: "contact",
480 | operation: "create",
481 | additionalFields: {
482 | properties: {
483 | firstname: "={{$json.contact.first_name}}",
484 | lastname: "={{$json.contact.last_name}}",
485 | email: "={{$json.contact.email}}",
486 | phone: "={{$json.contact.phone}}",
487 | // Add additional fields as needed
488 | }
489 | }
490 | }
491 | },
492 | {
493 | name: "Update Internal Contact",
494 | type: "n8n-nodes-base.function",
495 | position: [900, 400],
496 | parameters: {
497 | functionCode: `
498 | // This function would update contacts in your internal database
499 | // In reality, you might use another n8n node like a database connector
500 | const contact = $input.first().json.contact;
501 |
502 | // Process the HubSpot contact into internal format
503 | const internalFormat = {
504 | first_name: contact.properties.firstname,
505 | last_name: contact.properties.lastname,
506 | email: contact.properties.email,
507 | phone: contact.properties.phone,
508 | hubspot_id: contact.id,
509 | updated_at: new Date().toISOString()
510 | };
511 |
512 | // In a real implementation, you would update your database
513 | // For this example, we just return what would be updated
514 | return [{
515 | json: {
516 | action: "updated_internal_contact",
517 | contact: internalFormat
518 | }
519 | }];
520 | `
521 | }
522 | },
523 | {
524 | name: "Create Internal Contact",
525 | type: "n8n-nodes-base.function",
526 | position: [900, 550],
527 | parameters: {
528 | functionCode: `
529 | // This function would create new contacts in your internal database
530 | // In reality, you might use another n8n node like a database connector
531 | const contact = $input.first().json.contact;
532 |
533 | // Process the HubSpot contact into internal format
534 | const internalFormat = {
535 | first_name: contact.properties.firstname,
536 | last_name: contact.properties.lastname,
537 | email: contact.properties.email,
538 | phone: contact.properties.phone,
539 | hubspot_id: contact.id,
540 | created_at: new Date().toISOString(),
541 | updated_at: new Date().toISOString()
542 | };
543 |
544 | // In a real implementation, you would insert into your database
545 | // For this example, we just return what would be created
546 | return [{
547 | json: {
548 | action: "created_internal_contact",
549 | contact: internalFormat
550 | }
551 | }];
552 | `
553 | }
554 | },
555 | {
556 | name: "Sync Report",
557 | type: "n8n-nodes-base.function",
558 | position: [1100, 300],
559 | parameters: {
560 | functionCode: `
561 | // Collect all results from previous nodes
562 | const updateHubspot = $input.itemsFrom('Update HubSpot Contact');
563 | const createHubspot = $input.itemsFrom('Create HubSpot Contact');
564 | const updateInternal = $input.itemsFrom('Update Internal Contact');
565 | const createInternal = $input.itemsFrom('Create Internal Contact');
566 |
567 | // Generate sync summary
568 | return [{
569 | json: {
570 | summary: "Sync Complete",
571 | timestamp: new Date().toISOString(),
572 | stats: {
573 | hubspot_updated: updateHubspot.length,
574 | hubspot_created: createHubspot.length,
575 | internal_updated: updateInternal.length,
576 | internal_created: createInternal.length,
577 | total_changes: updateHubspot.length + createHubspot.length +
578 | updateInternal.length + createInternal.length
579 | }
580 | }
581 | }];
582 | `
583 | }
584 | }
585 | ],
586 | connections: {
587 | "Schedule Trigger": {
588 | main: [
589 | [
590 | {
591 | node: "Get HubSpot Contacts",
592 | type: "main",
593 | index: 0
594 | },
595 | {
596 | node: "Get n8n Contacts",
597 | type: "main",
598 | index: 0
599 | }
600 | ]
601 | ]
602 | },
603 | "Get HubSpot Contacts": {
604 | main: [
605 | [
606 | {
607 | node: "Compare & Identify Changes",
608 | type: "main",
609 | index: 0
610 | }
611 | ]
612 | ]
613 | },
614 | "Get n8n Contacts": {
615 | main: [
616 | [
617 | {
618 | node: "Compare & Identify Changes",
619 | type: "main",
620 | index: 1
621 | }
622 | ]
623 | ]
624 | },
625 | "Compare & Identify Changes": {
626 | main: [
627 | [
628 | {
629 | node: "Route Updates",
630 | type: "main",
631 | index: 0
632 | }
633 | ]
634 | ]
635 | },
636 | "Route Updates": {
637 | main: [
638 | [
639 | {
640 | node: "Update HubSpot Contact",
641 | type: "main",
642 | index: 0
643 | }
644 | ],
645 | [
646 | {
647 | node: "Create HubSpot Contact",
648 | type: "main",
649 | index: 0
650 | }
651 | ],
652 | [
653 | {
654 | node: "Update Internal Contact",
655 | type: "main",
656 | index: 0
657 | }
658 | ],
659 | [
660 | {
661 | node: "Create Internal Contact",
662 | type: "main",
663 | index: 0
664 | }
665 | ]
666 | ]
667 | },
668 | "Update HubSpot Contact": {
669 | main: [
670 | [
671 | {
672 | node: "Sync Report",
673 | type: "main",
674 | index: 0
675 | }
676 | ]
677 | ]
678 | },
679 | "Create HubSpot Contact": {
680 | main: [
681 | [
682 | {
683 | node: "Sync Report",
684 | type: "main",
685 | index: 0
686 | }
687 | ]
688 | ]
689 | },
690 | "Update Internal Contact": {
691 | main: [
692 | [
693 | {
694 | node: "Sync Report",
695 | type: "main",
696 | index: 0
697 | }
698 | ]
699 | ]
700 | },
701 | "Create Internal Contact": {
702 | main: [
703 | [
704 | {
705 | node: "Sync Report",
706 | type: "main",
707 | index: 0
708 | }
709 | ]
710 | ]
711 | }
712 | }
713 | });
714 |
715 | return `
716 | # HubSpot Two-Way Sync Workflow Created
717 |
718 | I've created a new workflow that will synchronize contacts between HubSpot and your internal system.
719 |
720 | **Workflow ID:** ${syncWorkflow.id}
721 |
722 | ## Configuration Needed:
723 | 1. The workflow is currently **inactive** - activate it once configured
724 | 2. ${credentialsMessage}
725 | 3. You'll need to customize the "Get n8n Contacts", "Update Internal Contact", and "Create Internal Contact" nodes to work with your specific database or storage system
726 |
727 | ## How It Works:
728 | - Runs every 2 hours (configurable)
729 | - Retrieves contacts from both HubSpot and your internal system
730 | - Compares the data to identify new or updated contacts in either system
731 | - Creates or updates contacts to keep both systems in sync
732 | - Generates a sync report with statistics
733 |
734 | ## Customization:
735 | You may need to modify the field mappings in the function nodes to match your specific data structure
736 | and add any additional fields that need to be synchronized between the systems.
737 | `;
738 | ```
739 |
740 | ### Slack Integration
741 |
742 | #### Example: Creating a Workflow to Send n8n Notifications to Slack
743 |
744 | ```javascript
745 | // User request: "Create a workflow that sends n8n execution notifications to Slack"
746 |
747 | // Create the notification workflow
748 | const notificationWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
749 | name: "n8n Execution Notifications to Slack",
750 | active: false,
751 | nodes: [
752 | {
753 | name: "Webhook",
754 | type: "n8n-nodes-base.webhook",
755 | position: [100, 300],
756 | parameters: {
757 | path: "n8n-notification",
758 | responseMode: "onReceived",
759 | options: {
760 | responseData: "noData"
761 | }
762 | }
763 | },
764 | {
765 | name: "Format Slack Message",
766 | type: "n8n-nodes-base.function",
767 | position: [300, 300],
768 | parameters: {
769 | functionCode: `
770 | // Parse webhook data from n8n
771 | const data = $input.first().json;
772 | const workflow = data.workflow;
773 | const execution = data.execution;
774 |
775 | // Determine status color
776 | let color = "#36a64f"; // Green for success
777 | let icon = "✅";
778 |
779 | if (execution.status === "error") {
780 | color = "#ff0000"; // Red for error
781 | icon = "❌";
782 | } else if (execution.status === "warning") {
783 | color = "#ffcc00"; // Yellow for warning
784 | icon = "⚠️";
785 | }
786 |
787 | // Create Slack message blocks
788 | const blocks = [
789 | {
790 | "type": "header",
791 | "text": {
792 | "type": "plain_text",
793 | "text": \`\${icon} Workflow \${execution.status === "success" ? "Succeeded" : "Failed"}: \${workflow.name}\`,
794 | "emoji": true
795 | }
796 | },
797 | {
798 | "type": "divider"
799 | },
800 | {
801 | "type": "section",
802 | "fields": [
803 | {
804 | "type": "mrkdwn",
805 | "text": \`*Status:*\\n\${execution.status}\`
806 | },
807 | {
808 | "type": "mrkdwn",
809 | "text": \`*Execution Time:*\\n\${new Date(execution.startedAt).toLocaleString()}\`
810 | },
811 | {
812 | "type": "mrkdwn",
813 | "text": \`*Duration:*\\n\${Math.round((new Date(execution.finishedAt) - new Date(execution.startedAt)) / 1000)} seconds\`
814 | },
815 | {
816 | "type": "mrkdwn",
817 | "text": \`*Mode:*\\n\${execution.mode}\`
818 | }
819 | ]
820 | }
821 | ];
822 |
823 | // Add error details if present
824 | if (execution.status === "error" && execution.error) {
825 | blocks.push(
826 | {
827 | "type": "divider"
828 | },
829 | {
830 | "type": "section",
831 | "text": {
832 | "type": "mrkdwn",
833 | "text": "*Error Details:*"
834 | }
835 | },
836 | {
837 | "type": "section",
838 | "text": {
839 | "type": "mrkdwn",
840 | "text": \`\\\`\\\`\${execution.error.message || "Unknown error"}\\\`\\\`\`
841 | }
842 | }
843 | );
844 | }
845 |
846 | // Add link to n8n execution
847 | blocks.push(
848 | {
849 | "type": "divider"
850 | },
851 | {
852 | "type": "section",
853 | "text": {
854 | "type": "mrkdwn",
855 | "text": \`<\${data.n8nUrl}/workflow/\${workflow.id}|View Workflow> | <\${data.n8nUrl}/execution/\${execution.id}|View Execution>\`
856 | }
857 | }
858 | );
859 |
860 | return [{
861 | json: {
862 | blocks: blocks,
863 | text: \`\${icon} Workflow \${execution.status === "success" ? "Succeeded" : "Failed"}: \${workflow.name}\`,
864 | channel: "#n8n-notifications"
865 | }
866 | }];
867 | `
868 | }
869 | },
870 | {
871 | name: "Send to Slack",
872 | type: "n8n-nodes-base.slack",
873 | position: [500, 300],
874 | parameters: {
875 | token: "{{$env.SLACK_TOKEN}}",
876 | text: "={{$json.text}}",
877 | channel: "={{$json.channel}}",
878 | otherOptions: {
879 | blocks: "={{$json.blocks}}"
880 | }
881 | }
882 | }
883 | ],
884 | connections: {
885 | "Webhook": {
886 | main: [
887 | [
888 | {
889 | node: "Format Slack Message",
890 | type: "main",
891 | index: 0
892 | }
893 | ]
894 | ]
895 | },
896 | "Format Slack Message": {
897 | main: [
898 | [
899 | {
900 | node: "Send to Slack",
901 | type: "main",
902 | index: 0
903 | }
904 | ]
905 | ]
906 | }
907 | }
908 | });
909 |
910 | // Create workflow to set up webhook in n8n settings
911 | const setupWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
912 | name: "Configure n8n Execution Notifications",
913 | active: false,
914 | nodes: [
915 | {
916 | name: "Manual Trigger",
917 | type: "n8n-nodes-base.manualTrigger",
918 | position: [100, 300],
919 | parameters: {}
920 | },
921 | {
922 | name: "n8n Settings",
923 | type: "n8n-nodes-base.n8n",
924 | position: [300, 300],
925 | parameters: {
926 | resource: "settings",
927 | operation: "update",
928 | values: {
929 | executionTimeout: 120,
930 | saveManualExecutions: true,
931 | saveDataErrorExecution: "all",
932 | saveDataSuccessExecution: "all",
933 | saveExecutionProgress: true,
934 | executeTimeout: 120,
935 | maxExecutionTimeout: 300,
936 | workflowCallerIdsAllowed: [],
937 | timezone: "UTC",
938 | executionMode: "regular",
939 | pushBackend: "websocket",
940 | webhookDebugEnabled: false,
941 | webhookUrl: "={{$json.webhookUrl}}",
942 | logLevel: "info"
943 | }
944 | }
945 | },
946 | {
947 | name: "Create Instructions",
948 | type: "n8n-nodes-base.function",
949 | position: [500, 300],
950 | parameters: {
951 | functionCode: `
952 | const webhookNode = $input.itemsFrom('Webhook')? $input.itemsFrom('Webhook')[0] : { json: { webhookUrl: "unknown" } };
953 | const webhookUrl = webhookNode.json.webhookUrl;
954 |
955 | return [{
956 | json: {
957 | instructions: \`
958 | # n8n to Slack Notification Setup
959 |
960 | I've created two workflows:
961 |
962 | 1. **n8n Execution Notifications to Slack** - This workflow receives execution notifications from n8n and sends them to Slack
963 | - ID: ${notificationWorkflow.id}
964 | - Webhook URL: \${webhookUrl}
965 |
966 | 2. **Configure n8n Execution Notifications** - This workflow configures n8n settings to send notifications
967 | - ID: ${setupWorkflow.id}
968 |
969 | ## Next Steps:
970 |
971 | 1. Create a Slack app and obtain a token with the following permissions:
972 | - chat:write
973 | - chat:write.public
974 |
975 | 2. Set the environment variable \`SLACK_TOKEN\` with your Slack token
976 |
977 | 3. Run the "Configure n8n Execution Notifications" workflow after setting the \`webhookUrl\` parameter to:
978 | \${webhookUrl}
979 |
980 | 4. Activate the "n8n Execution Notifications to Slack" workflow
981 |
982 | 5. Customize the channel in the "Format Slack Message" node if needed (default is #n8n-notifications)
983 |
984 | Once completed, you'll receive Slack notifications whenever a workflow execution succeeds or fails!
985 | \`
986 | }
987 | }];
988 | `
989 | }
990 | }
991 | ],
992 | connections: {
993 | "Manual Trigger": {
994 | main: [
995 | [
996 | {
997 | node: "n8n Settings",
998 | type: "main",
999 | index: 0
1000 | }
1001 | ]
1002 | ]
1003 | },
1004 | "n8n Settings": {
1005 | main: [
1006 | [
1007 | {
1008 | node: "Create Instructions",
1009 | type: "main",
1010 | index: 0
1011 | }
1012 | ]
1013 | ]
1014 | }
1015 | }
1016 | });
1017 |
1018 | // Execute the workflow to get the webhook URL
1019 | const execution = await useMcpTool('n8n-mcp-server', 'execution_run', {
1020 | workflowId: notificationWorkflow.id,
1021 | waitForCompletion: true
1022 | });
1023 |
1024 | // Extract webhook URL from the execution
1025 | let webhookUrl = "undefined";
1026 | if (execution.status === "success" && execution.data?.resultData?.runData?.Webhook?.[0]?.data?.webhookUrl) {
1027 | webhookUrl = execution.data.resultData.runData.Webhook[0].data.webhookUrl;
1028 | }
1029 |
1030 | return `
1031 | # n8n to Slack Notification Setup
1032 |
1033 | I've created two workflows:
1034 |
1035 | 1. **n8n Execution Notifications to Slack** - This workflow receives execution notifications from n8n and sends them to Slack
1036 | - ID: ${notificationWorkflow.id}
1037 | - Webhook URL: ${webhookUrl}
1038 |
1039 | 2. **Configure n8n Execution Notifications** - This workflow configures n8n settings to send notifications
1040 | - ID: ${setupWorkflow.id}
1041 |
1042 | ## Next Steps:
1043 |
1044 | 1. Create a Slack app and obtain a token with the following permissions:
1045 | - chat:write
1046 | - chat:write.public
1047 |
1048 | 2. Set the environment variable \`SLACK_TOKEN\` with your Slack token
1049 |
1050 | 3. Run the "Configure n8n Execution Notifications" workflow after setting the \`webhookUrl\` parameter to:
1051 | ${webhookUrl}
1052 |
1053 | 4. Activate the "n8n Execution Notifications to Slack" workflow
1054 |
1055 | 5. Customize the channel in the "Format Slack Message" node if needed (default is #n8n-notifications)
1056 |
1057 | Once completed, you'll receive Slack notifications whenever a workflow execution completes!
1058 | ```
1059 | # Integration Examples
1060 |
1061 | This page provides examples of integrating the n8n MCP Server with other systems and AI assistant platforms.
1062 |
1063 | ## AI Assistant Integration Examples
1064 |
1065 | ### Claude AI Assistant Integration
1066 |
1067 | #### Example: Setting Up n8n MCP Server with Claude
1068 |
1069 | ```javascript
1070 | // Register the n8n MCP Server with Claude using the MCP Installer
1071 | const installationResult = await useMcpTool('mcp-installer', 'install_repo_mcp_server', {
1072 | name: 'n8n-mcp-server',
1073 | env: [
1074 | "N8N_API_URL=http://localhost:5678/api/v1",
1075 | "N8N_API_KEY=your_n8n_api_key_here",
1076 | "DEBUG=false"
1077 | ]
1078 | });
1079 |
1080 | // Once registered, Claude can interact with n8n
1081 | // Here's an example conversation:
1082 |
1083 | // User: "Show me my active workflows in n8n"
1084 | // Claude: (uses workflow_list tool to retrieve and display active workflows)
1085 |
1086 | // User: "Execute my 'Daily Report' workflow"
1087 | // Claude: (uses execution_run tool to start the workflow and provide status)
1088 | ```
1089 |
1090 | #### Example: Using n8n to Extend Claude's Capabilities
1091 |
1092 | ```javascript
1093 | // Using n8n as a bridge to external systems
1094 | // This example shows how Claude can access a database through n8n
1095 |
1096 | // User: "Show me the top 5 customers from my database"
1097 | // Claude would:
1098 |
1099 | // 1. Find the appropriate workflow
1100 | const workflows = await useMcpTool('n8n-mcp-server', 'workflow_list', {});
1101 | const dbQueryWorkflow = workflows.find(w =>
1102 | w.name.toLowerCase().includes('database query') ||
1103 | w.name.toLowerCase().includes('db query')
1104 | );
1105 |
1106 | if (!dbQueryWorkflow) {
1107 | return "I couldn't find a database query workflow. Would you like me to help you create one?";
1108 | }
1109 |
1110 | // 2. Execute the workflow with the appropriate parameters
1111 | const execution = await useMcpTool('n8n-mcp-server', 'execution_run', {
1112 | workflowId: dbQueryWorkflow.id,
1113 | data: {
1114 | query: "SELECT * FROM customers ORDER BY total_purchases DESC LIMIT 5",
1115 | format: "table"
1116 | },
1117 | waitForCompletion: true
1118 | });
1119 |
1120 | // 3. Present the results to the user
1121 | if (execution.status !== "success") {
1122 | return "There was an error querying the database. Error: " + (execution.error || "Unknown error");
1123 | }
1124 |
1125 | // Format the results as a table
1126 | const customers = execution.data.resultData.runData.lastNode[0].data.json;
1127 | let response = "# Top 5 Customers\n\n";
1128 | response += "| Customer Name | Email | Total Purchases |\n";
1129 | response += "|--------------|-------|----------------|\n";
1130 |
1131 | customers.forEach(customer => {
1132 | response += `| ${customer.name} | ${customer.email} | $${customer.total_purchases.toFixed(2)} |\n`;
1133 | });
1134 |
1135 | return response;
1136 | ```
1137 |
1138 | ### OpenAI Assistant Integration
1139 |
1140 | #### Example: Connecting n8n MCP Server to OpenAI Assistant
1141 |
1142 | ```javascript
1143 | // This is a conceptual example of how an OpenAI Assistant might interact with the n8n MCP Server
1144 |
1145 | // In an OpenAI Assistant Function definition:
1146 | {
1147 | "name": "n8n_workflow_list",
1148 | "description": "List all workflows in n8n",
1149 | "parameters": {
1150 | "type": "object",
1151 | "properties": {
1152 | "active": {
1153 | "type": "boolean",
1154 | "description": "Filter by active status (optional)"
1155 | }
1156 | }
1157 | }
1158 | }
1159 |
1160 | // The function would call the n8n MCP Server:
1161 | async function n8n_workflow_list(params) {
1162 | // Call the n8n MCP Server API
1163 | const response = await fetch('http://localhost:3000/n8n-mcp/tools/workflow_list', {
1164 | method: 'POST',
1165 | headers: {
1166 | 'Content-Type': 'application/json',
1167 | 'Authorization': 'Bearer YOUR_AUTH_TOKEN'
1168 | },
1169 | body: JSON.stringify(params)
1170 | });
1171 |
1172 | return await response.json();
1173 | }
1174 |
1175 | // The OpenAI Assistant would then use this function when asked about n8n workflows
1176 | ```
1177 |
1178 | ## Integration with External Systems
1179 |
1180 | ### n8n to Git Integration
1181 |
1182 | #### Example: Using n8n MCP Server to Manage Workflow Versioning in Git
1183 |
1184 | ```javascript
1185 | // User request: "Backup all my workflows to my Git repository"
1186 |
1187 | // The assistant first creates a workflow for Git backup
1188 | const backupWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
1189 | name: "Workflow Git Backup",
1190 | active: false,
1191 | nodes: [
1192 | {
1193 | name: "Manual Trigger",
1194 | type: "n8n-nodes-base.manualTrigger",
1195 | position: [100, 300],
1196 | parameters: {}
1197 | },
1198 | {
1199 | name: "Get All Workflows",
1200 | type: "n8n-nodes-base.n8n",
1201 | position: [300, 300],
1202 | parameters: {
1203 | resource: "workflow",
1204 | operation: "getAll"
1205 | }
1206 | },
1207 | {
1208 | name: "Format For Git",
1209 | type: "n8n-nodes-base.function",
1210 | position: [500, 300],
1211 | parameters: {
1212 | functionCode: `
1213 | // Convert workflows to individual JSON files
1214 | const workflows = items;
1215 | const outputItems = [];
1216 |
1217 | for (const workflow of workflows) {
1218 | // Create a sanitized filename
1219 | const filename = workflow.json.name
1220 | .replace(/[^a-zA-Z0-9]/g, '_')
1221 | .toLowerCase() + '.json';
1222 |
1223 | outputItems.push({
1224 | json: {
1225 | filename: filename,
1226 | content: JSON.stringify(workflow.json, null, 2),
1227 | commit_message: \`Backup workflow: \${workflow.json.name}\`
1228 | }
1229 | });
1230 | }
1231 |
1232 | return outputItems;
1233 | `
1234 | }
1235 | },
1236 | {
1237 | name: "Git Commit",
1238 | type: "n8n-nodes-base.git",
1239 | position: [700, 300],
1240 | parameters: {
1241 | repository: "{{$env.GIT_REPO_PATH}}",
1242 | directory: "workflows",
1243 | operation: "commit",
1244 | message: "Automated workflow backup {{$now.format('YYYY-MM-DD HH:mm')}}",
1245 | filePath: "={{$json.filename}}",
1246 | fileContent: "={{$json.content}}"
1247 | }
1248 | },
1249 | {
1250 | name: "Git Push",
1251 | type: "n8n-nodes-base.git",
1252 | position: [900, 300],
1253 | parameters: {
1254 | repository: "{{$env.GIT_REPO_PATH}}",
1255 | operation: "push"
1256 | }
1257 | }
1258 | ],
1259 | connections: {
1260 | "Manual Trigger": {
1261 | main: [
1262 | [
1263 | {
1264 | node: "Get All Workflows",
1265 | type: "main",
1266 | index: 0
1267 | }
1268 | ]
1269 | ]
1270 | },
1271 | "Get All Workflows": {
1272 | main: [
1273 | [
1274 | {
1275 | node: "Format For Git",
1276 | type: "main",
1277 | index: 0
1278 | }
1279 | ]
1280 | ]
1281 | },
1282 | "Format For Git": {
1283 | main: [
1284 | [
1285 | {
1286 | node: "Git Commit",
1287 | type: "main",
1288 | index: 0
1289 | }
1290 | ]
1291 | ]
1292 | },
1293 | "Git Commit": {
1294 | main: [
1295 | [
1296 | {
1297 | node: "Git Push",
1298 | type: "main",
1299 | index: 0
1300 | }
1301 | ]
1302 | ]
1303 | }
1304 | }
1305 | });
1306 |
1307 | return `
1308 | # Git Backup Workflow Created
1309 |
1310 | I've created a new workflow that will backup all your n8n workflows to Git.
1311 |
1312 | **Workflow ID:** ${backupWorkflow.id}
1313 |
1314 | ## Configuration Needed:
1315 | 1. The workflow is currently **inactive** - activate it once configured
1316 | 2. Set the environment variable \`GIT_REPO_PATH\` to point to your Git repository
1317 | 3. Ensure the Git repository is properly configured with credentials
1318 |
1319 | ## How It Works:
1320 | - When executed, this workflow retrieves all n8n workflows
1321 | - Converts each workflow to a JSON file
1322 | - Commits each file to the specified Git repository
1323 | - Pushes the changes to the remote repository
1324 |
1325 | ## Usage:
1326 | You can run this workflow manually whenever you want to backup your workflows,
1327 | or add a Schedule Trigger to automate regular backups.
1328 | `;
1329 | ```
1330 |
1331 | ### CRM Integration
1332 |
1333 | #### Example: Setting Up a Two-Way Sync Between n8n and a CRM
1334 |
1335 | ```javascript
1336 | // User request: "Help me set up a sync between n8n and my HubSpot CRM"
1337 |
1338 | // First check for existing credentials
1339 | const workflows = await useMcpTool('n8n-mcp-server', 'workflow_list', {});
1340 | const hubspotWorkflows = workflows.filter(w =>
1341 | w.name.toLowerCase().includes('hubspot')
1342 | );
1343 |
1344 | let credentialsMessage = "";
1345 | if (hubspotWorkflows.length > 0) {
1346 | credentialsMessage = "I noticed you already have HubSpot workflows. I'll assume you have HubSpot credentials set up.";
1347 | } else {
1348 | credentialsMessage = "You'll need to set up HubSpot credentials in n8n before activating this workflow.";
1349 | }
1350 |
1351 | // Create the sync workflow
1352 | const syncWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
1353 | name: "HubSpot Two-Way Sync",
1354 | active: false,
1355 | nodes: [
1356 | {
1357 | name: "Schedule Trigger",
1358 | type: "n8n-nodes-base.scheduleTrigger",
1359 | position: [100, 300],
1360 | parameters: {
1361 | cronExpression: "0 */2 * * *" // Every 2 hours
1362 | }
1363 | },
1364 | {
1365 | name: "Get HubSpot Contacts",
1366 | type: "n8n-nodes-base.hubspot",
1367 | position: [300, 200],
1368 | parameters: {
1369 | resource: "contact",
1370 | operation: "getAll",
1371 | returnAll: true,
1372 | additionalFields: {
1373 | formattedDate: true
1374 | }
1375 | }
1376 | },
1377 | {
1378 | name: "Get n8n Contacts",
1379 | type: "n8n-nodes-base.function",
1380 | position: [300, 400],
1381 | parameters: {
1382 | functionCode: `
1383 | // This function would retrieve contacts from your internal database
1384 | // For example purposes, we're using a placeholder
1385 | // In reality, you might use another n8n node to fetch from your database
1386 |
1387 | return [
1388 | {
1389 | json: {
1390 | internalContacts: [
1391 | // Example internal contacts
1392 | // In a real scenario, these would come from your database
1393 | ]
1394 | }
1395 | }
1396 | ];
1397 | `
1398 | }
1399 | },
1400 | {
1401 | name: "Compare & Identify Changes",
1402 | type: "n8n-nodes-base.function",
1403 | position: [500, 300],
1404 | parameters: {
1405 | functionCode: `
1406 | const hubspotContacts = $input.first();
1407 | const internalContacts = $input.last().json.internalContacts;
1408 |
1409 | // Identify new/updated contacts in HubSpot
1410 | const hubspotUpdates = hubspotContacts.json.map(contact => {
1411 | // Find matching internal contact by email
1412 | const internalMatch = internalContacts.find(
1413 | ic => ic.email === contact.properties.email
1414 | );
1415 |
1416 | if (!internalMatch) {
1417 | return {
1418 | json: {
1419 | type: 'new_in_hubspot',
1420 | contact: contact,
1421 | action: 'create_in_internal'
1422 | }
1423 | };
1424 | }
1425 |
1426 | // Check if HubSpot contact is newer
1427 | const hubspotUpdated = new Date(contact.properties.lastmodifieddate);
1428 | const internalUpdated = new Date(internalMatch.updated_at);
1429 |
1430 | if (hubspotUpdated > internalUpdated) {
1431 | return {
1432 | json: {
1433 | type: 'updated_in_hubspot',
1434 | contact: contact,
1435 | action: 'update_in_internal'
1436 | }
1437 | };
1438 | }
1439 |
1440 | return null;
1441 | }).filter(item => item !== null);
1442 |
1443 | // Identify new/updated contacts in internal system
1444 | const internalUpdates = internalContacts.map(contact => {
1445 | // Find matching HubSpot contact by email
1446 | const hubspotMatch = hubspotContacts.json.find(
1447 | hc => hc.properties.email === contact.email
1448 | );
1449 |
1450 | if (!hubspotMatch) {
1451 | return {
1452 | json: {
1453 | type: 'new_in_internal',
1454 | contact: contact,
1455 | action: 'create_in_hubspot'
1456 | }
1457 | };
1458 | }
1459 |
1460 | // Check if internal contact is newer
1461 | const internalUpdated = new Date(contact.updated_at);
1462 | const hubspotUpdated = new Date(hubspotMatch.properties.lastmodifieddate);
1463 |
1464 | if (internalUpdated > hubspotUpdated) {
1465 | return {
1466 | json: {
1467 | type: 'updated_in_internal',
1468 | contact: contact,
1469 | action: 'update_in_hubspot'
1470 | }
1471 | };
1472 | }
1473 |
1474 | return null;
1475 | }).filter(item => item !== null);
1476 |
1477 | // Combine all changes
1478 | return [...hubspotUpdates, ...internalUpdates];
1479 | `
1480 | }
1481 | },
1482 | {
1483 | name: "Route Updates",
1484 | type: "n8n-nodes-base.switch",
1485 | position: [700, 300],
1486 | parameters: {
1487 | rules: {
1488 | conditions: [
1489 | {
1490 | value1: "={{$json.action}}",
1491 | operation: "equal",
1492 | value2: "update_in_hubspot"
1493 | },
1494 | {
1495 | value1: "={{$json.action}}",
1496 | operation: "equal",
1497 | value2: "create_in_hubspot"
1498 | },
1499 | {
1500 | value1: "={{$json.action}}",
1501 | operation: "equal",
1502 | value2: "update_in_internal"
1503 | },
1504 | {
1505 | value1: "={{$json.action}}",
1506 | operation: "equal",
1507 | value2: "create_in_internal"
1508 | }
1509 | ]
1510 | }
1511 | }
1512 | },
1513 | {
1514 | name: "Update HubSpot Contact",
1515 | type: "n8n-nodes-base.hubspot",
1516 | position: [900, 100],
1517 | parameters: {
1518 | resource: "contact",
1519 | operation: "update",
1520 | contactId: "={{$json.contact.hubspot_id || $json.hubspotId}}",
1521 | additionalFields: {
1522 | properties: {
1523 | firstname: "={{$json.contact.first_name}}",
1524 | lastname: "={{$json.contact.last_name}}",
1525 | email: "={{$json.contact.email}}",
1526 | phone: "={{$json.contact.phone}}",
1527 | // Add additional fields as needed
1528 | }
1529 | }
1530 | }
1531 | },
1532 | {
1533 | name: "Create HubSpot Contact",
1534 | type: "n8n-nodes-base.hubspot",
1535 | position: [900, 250],
1536 | parameters: {
1537 | resource: "contact",
1538 | operation: "create",
1539 | additionalFields: {
1540 | properties: {
1541 | firstname: "={{$json.contact.first_name}}",
1542 | lastname: "={{$json.contact.last_name}}",
1543 | email: "={{$json.contact.email}}",
1544 | phone: "={{$json.contact.phone}}",
1545 | // Add additional fields as needed
1546 | }
1547 | }
1548 | }
1549 | },
1550 | {
1551 | name: "Update Internal Contact",
1552 | type: "n8n-nodes-base.function",
1553 | position: [900, 400],
1554 | parameters: {
1555 | functionCode: `
1556 | // This function would update contacts in your internal database
1557 | // In reality, you might use another n8n node like a database connector
1558 | const contact = $input.first().json.contact;
1559 |
1560 | // Process the HubSpot contact into internal format
1561 | const internalFormat = {
1562 | first_name: contact.properties.firstname,
1563 | last_name: contact.properties.lastname,
1564 | email: contact.properties.email,
1565 | phone: contact.properties.phone,
1566 | hubspot_id: contact.id,
1567 | updated_at: new Date().toISOString()
1568 | };
1569 |
1570 | // In a real implementation, you would update your database
1571 | // For this example, we just return what would be updated
1572 | return [{
1573 | json: {
1574 | action: "updated_internal_contact",
1575 | contact: internalFormat
1576 | }
1577 | }];
1578 | `
1579 | }
1580 | },
1581 | {
1582 | name: "Create Internal Contact",
1583 | type: "n8n-nodes-base.function",
1584 | position: [900, 550],
1585 | parameters: {
1586 | functionCode: `
1587 | // This function would create new contacts in your internal database
1588 | // In reality, you might use another n8n node like a database connector
1589 | const contact = $input.first().json.contact;
1590 |
1591 | // Process the HubSpot contact into internal format
1592 | const internalFormat = {
1593 | first_name: contact.properties.firstname,
1594 | last_name: contact.properties.lastname,
1595 | email: contact.properties.email,
1596 | phone: contact.properties.phone,
1597 | hubspot_id: contact.id,
1598 | created_at: new Date().toISOString(),
1599 | updated_at: new Date().toISOString()
1600 | };
1601 |
1602 | // In a real implementation, you would insert into your database
1603 | // For this example, we just return what would be created
1604 | return [{
1605 | json: {
1606 | action: "created_internal_contact",
1607 | contact: internalFormat
1608 | }
1609 | }];
1610 | `
1611 | }
1612 | },
1613 | {
1614 | name: "Sync Report",
1615 | type: "n8n-nodes-base.function",
1616 | position: [1100, 300],
1617 | parameters: {
1618 | functionCode: `
1619 | // Collect all results from previous nodes
1620 | const updateHubspot = $input.itemsFrom('Update HubSpot Contact');
1621 | const createHubspot = $input.itemsFrom('Create HubSpot Contact');
1622 | const updateInternal = $input.itemsFrom('Update Internal Contact');
1623 | const createInternal = $input.itemsFrom('Create Internal Contact');
1624 |
1625 | // Generate sync summary
1626 | return [{
1627 | json: {
1628 | summary: "Sync Complete",
1629 | timestamp: new Date().toISOString(),
1630 | stats: {
1631 | hubspot_updated: updateHubspot.length,
1632 | hubspot_created: createHubspot.length,
1633 | internal_updated: updateInternal.length,
1634 | internal_created: createInternal.length,
1635 | total_changes: updateHubspot.length + createHubspot.length +
1636 | updateInternal.length + createInternal.length
1637 | }
1638 | }
1639 | }];
1640 | `
1641 | }
1642 | }
1643 | ],
1644 | connections: {
1645 | "Schedule Trigger": {
1646 | main: [
1647 | [
1648 | {
1649 | node: "Get HubSpot Contacts",
1650 | type: "main",
1651 | index: 0
1652 | },
1653 | {
1654 | node: "Get n8n Contacts",
1655 | type: "main",
1656 | index: 0
1657 | }
1658 | ]
1659 | ]
1660 | },
1661 | "Get HubSpot Contacts": {
1662 | main: [
1663 | [
1664 | {
1665 | node: "Compare & Identify Changes",
1666 | type: "main",
1667 | index: 0
1668 | }
1669 | ]
1670 | ]
1671 | },
1672 | "Get n8n Contacts": {
1673 | main: [
1674 | [
1675 | {
1676 | node: "Compare & Identify Changes",
1677 | type: "main",
1678 | index: 1
1679 | }
1680 | ]
1681 | ]
1682 | },
1683 | "Compare & Identify Changes": {
1684 | main: [
1685 | [
1686 | {
1687 | node: "Route Updates",
1688 | type: "main",
1689 | index: 0
1690 | }
1691 | ]
1692 | ]
1693 | },
1694 | "Route Updates": {
1695 | main: [
1696 | [
1697 | {
1698 | node: "Update HubSpot Contact",
1699 | type: "main",
1700 | index: 0
1701 | }
1702 | ],
1703 | [
1704 | {
1705 | node: "Create HubSpot Contact",
1706 | type: "main",
1707 | index: 0
1708 | }
1709 | ],
1710 | [
1711 | {
1712 | node: "Update Internal Contact",
1713 | type: "main",
1714 | index: 0
1715 | }
1716 | ],
1717 | [
1718 | {
1719 | node: "Create Internal Contact",
1720 | type: "main",
1721 | index: 0
1722 | }
1723 | ]
1724 | ]
1725 | },
1726 | "Update HubSpot Contact": {
1727 | main: [
1728 | [
1729 | {
1730 | node: "Sync Report",
1731 | type: "main",
1732 | index: 0
1733 | }
1734 | ]
1735 | ]
1736 | },
1737 | "Create HubSpot Contact": {
1738 | main: [
1739 | [
1740 | {
1741 | node: "Sync Report",
1742 | type: "main",
1743 | index: 0
1744 | }
1745 | ]
1746 | ]
1747 | },
1748 | "Update Internal Contact": {
1749 | main: [
1750 | [
1751 | {
1752 | node: "Sync Report",
1753 | type: "main",
1754 | index: 0
1755 | }
1756 | ]
1757 | ]
1758 | },
1759 | "Create Internal Contact": {
1760 | main: [
1761 | [
1762 | {
1763 | node: "Sync Report",
1764 | type: "main",
1765 | index: 0
1766 | }
1767 | ]
1768 | ]
1769 | }
1770 | }
1771 | });
1772 |
1773 | return `
1774 | # HubSpot Two-Way Sync Workflow Created
1775 |
1776 | I've created a new workflow that will synchronize contacts between HubSpot and your internal system.
1777 |
1778 | **Workflow ID:** ${syncWorkflow.id}
1779 |
1780 | ## Configuration Needed:
1781 | 1. The workflow is currently **inactive** - activate it once configured
1782 | 2. ${credentialsMessage}
1783 | 3. You'll need to customize the "Get n8n Contacts", "Update Internal Contact", and "Create Internal Contact" nodes to work with your specific database or storage system
1784 |
1785 | ## How It Works:
1786 | - Runs every 2 hours (configurable)
1787 | - Retrieves contacts from both HubSpot and your internal system
1788 | - Compares the data to identify new or updated contacts in either system
1789 | - Creates or updates contacts to keep both systems in sync
1790 | - Generates a sync report with statistics
1791 |
1792 | ## Customization:
1793 | You may need to modify the field mappings in the function nodes to match your specific data structure
1794 | and add any additional fields that need to be synchronized between the systems.
1795 | `;
1796 | ```
1797 |
1798 | ### Slack Integration
1799 |
1800 | #### Example: Creating a Workflow to Send n8n Notifications to Slack
1801 |
1802 | ```javascript
1803 | // User request: "Create a workflow that sends n8n execution notifications to Slack"
1804 |
1805 | // Create the notification workflow
1806 | const notificationWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
1807 | name: "n8n Execution Notifications to Slack",
1808 | active: false,
1809 | nodes: [
1810 | {
1811 | name: "Webhook",
1812 | type: "n8n-nodes-base.webhook",
1813 | position: [100, 300],
1814 | parameters: {
1815 | path: "n8n-notification",
1816 | responseMode: "onReceived",
1817 | options: {
1818 | responseData: "noData"
1819 | }
1820 | }
1821 | },
1822 | {
1823 | name: "Format Slack Message",
1824 | type: "n8n-nodes-base.function",
1825 | position: [300, 300],
1826 | parameters: {
1827 | functionCode: `
1828 | // Parse webhook data from n8n
1829 | const data = $input.first().json;
1830 | const workflow = data.workflow;
1831 | const execution = data.execution;
1832 |
1833 | // Determine status color
1834 | let color = "#36a64f"; // Green for success
1835 | let icon = "✅";
1836 |
1837 | if (execution.status === "error") {
1838 | color = "#ff0000"; // Red for error
1839 | icon = "❌";
1840 | } else if (execution.status === "warning") {
1841 | color = "#ffcc00"; // Yellow for warning
1842 | icon = "⚠️";
1843 | }
1844 |
1845 | // Create Slack message blocks
1846 | const blocks = [
1847 | {
1848 | "type": "header",
1849 | "text": {
1850 | "type": "plain_text",
1851 | "text": \`\${icon} Workflow \${execution.status === "success" ? "Succeeded" : "Failed"}: \${workflow.name}\`,
1852 | "emoji": true
1853 | }
1854 | },
1855 | {
1856 | "type": "divider"
1857 | },
1858 | {
1859 | "type": "section",
1860 | "fields": [
1861 | {
1862 | "type": "mrkdwn",
1863 | "text": \`*Status:*\\n\${execution.status}\`
1864 | },
1865 | {
1866 | "type": "mrkdwn",
1867 | "text": \`*Execution Time:*\\n\${new Date(execution.startedAt).toLocaleString()}\`
1868 | },
1869 | {
1870 | "type": "mrkdwn",
1871 | "text": \`*Duration:*\\n\${Math.round((new Date(execution.finishedAt) - new Date(execution.startedAt)) / 1000)} seconds\`
1872 | },
1873 | {
1874 | "type": "mrkdwn",
1875 | "text": \`*Mode:*\\n\${execution.mode}\`
1876 | }
1877 | ]
1878 | }
1879 | ];
1880 |
1881 | // Add error details if present
1882 | if (execution.status === "error" && execution.error) {
1883 | blocks.push(
1884 | {
1885 | "type": "divider"
1886 | },
1887 | {
1888 | "type": "section",
1889 | "text": {
1890 | "type": "mrkdwn",
1891 | "text": "*Error Details:*"
1892 | }
1893 | },
1894 | {
1895 | "type": "section",
1896 | "text": {
1897 | "type": "mrkdwn",
1898 | "text": \`\\\`\\\`\${execution.error.message || "Unknown error"}\\\`\\\`\`
1899 | }
1900 | }
1901 | );
1902 | }
1903 |
1904 | // Add link to n8n execution
1905 | blocks.push(
1906 | {
1907 | "type": "divider"
1908 | },
1909 | {
1910 | "type": "section",
1911 | "text": {
1912 | "type": "mrkdwn",
1913 | "text": \`<\${data.n8nUrl}/workflow/\${workflow.id}|View Workflow> | <\${data.n8nUrl}/execution/\${execution.id}|View Execution>\`
1914 | }
1915 | }
1916 | );
1917 |
1918 | return [{
1919 | json: {
1920 | blocks: blocks,
1921 | text: \`\${icon} Workflow \${execution.status === "success" ? "Succeeded" : "Failed"}: \${workflow.name}\`,
1922 | channel: "#n8n-notifications"
1923 | }
1924 | }];
1925 | `
1926 | }
1927 | },
1928 | {
1929 | name: "Send to Slack",
1930 | type: "n8n-nodes-base.slack",
1931 | position: [500, 300],
1932 | parameters: {
1933 | token: "{{$env.SLACK_TOKEN}}",
1934 | text: "={{$json.text}}",
1935 | channel: "={{$json.channel}}",
1936 | otherOptions: {
1937 | blocks: "={{$json.blocks}}"
1938 | }
1939 | }
1940 | }
1941 | ],
1942 | connections: {
1943 | "Webhook": {
1944 | main: [
1945 | [
1946 | {
1947 | node: "Format Slack Message",
1948 | type: "main",
1949 | index: 0
1950 | }
1951 | ]
1952 | ]
1953 | },
1954 | "Format Slack Message": {
1955 | main: [
1956 | [
1957 | {
1958 | node: "Send to Slack",
1959 | type: "main",
1960 | index: 0
1961 | }
1962 | ]
1963 | ]
1964 | }
1965 | }
1966 | });
1967 |
1968 | // Create workflow to set up webhook in n8n settings
1969 | const setupWorkflow = await useMcpTool('n8n-mcp-server', 'workflow_create', {
1970 | name: "Configure n8n Execution Notifications",
1971 | active: false,
1972 | nodes: [
1973 | {
1974 | name: "Manual Trigger",
1975 | type: "n8n-nodes-base.manualTrigger",
1976 | position: [100, 300],
1977 | parameters: {}
1978 | },
1979 | {
1980 | name: "n8n Settings",
1981 | type: "n8n-nodes-base.n8n",
1982 | position: [300, 300],
1983 | parameters: {
1984 | resource: "settings",
1985 | operation: "update",
1986 | values: {
1987 | executionTimeout: 120,
1988 | saveManualExecutions: true,
1989 | saveDataErrorExecution: "all",
1990 | saveDataSuccessExecution: "all",
1991 | saveExecutionProgress: true,
1992 | executeTimeout: 120,
1993 | maxExecutionTimeout: 300,
1994 | workflowCallerIdsAllowed: [],
1995 | timezone: "UTC",
1996 | executionMode: "regular",
1997 | pushBackend: "websocket",
1998 | webhookDebugEnabled: false,
1999 | webhookUrl: "={{$json.webhookUrl}}",
2000 | logLevel: "info"
2001 | }
2002 | }
2003 | },
2004 | {
2005 | name: "Create Instructions",
2006 | type: "n8n-nodes-base.function",
2007 | position: [500, 300],
2008 | parameters: {
2009 | functionCode: `
2010 | const webhookNode = $input.itemsFrom('Webhook')? $input.itemsFrom('Webhook')[0] : { json: { webhookUrl: "unknown" } };
2011 | const webhookUrl = webhookNode.json.webhookUrl;
2012 |
2013 | return [{
2014 | json: {
2015 | instructions: \`
2016 | # n8n to Slack Notification Setup
2017 |
2018 | I've created two workflows:
2019 |
2020 | 1. **n8n Execution Notifications to Slack** - This workflow receives execution notifications from n8n and sends them to Slack
2021 | - ID: ${notificationWorkflow.id}
2022 | - Webhook URL: \${webhookUrl}
2023 |
2024 | 2. **Configure n8n Execution Notifications** - This workflow configures n8n settings to send notifications
2025 | - ID: ${setupWorkflow.id}
2026 |
2027 | ## Next Steps:
2028 |
2029 | 1. Create a Slack app and obtain a token with the following permissions:
2030 | - chat:write
2031 | - chat:write.public
2032 |
2033 | 2. Set the environment variable \`SLACK_TOKEN\` with your Slack token
2034 |
2035 | 3. Run the "Configure n8n Execution Notifications" workflow after setting the \`webhookUrl\` parameter to:
2036 | \${webhookUrl}
2037 |
2038 | 4. Activate the "n8n Execution Notifications to Slack" workflow
2039 |
2040 | 5. Customize the channel in the "Format Slack Message" node if needed (default is #n8n-notifications)
2041 |
2042 | Once completed, you'll receive Slack notifications whenever a workflow execution succeeds or fails!
2043 | \`
2044 | }
2045 | }];
2046 | `
2047 | }
2048 | }
2049 | ],
2050 | connections: {
2051 | "Manual Trigger": {
2052 | main: [
2053 | [
2054 | {
2055 | node: "n8n Settings",
2056 | type: "main",
2057 | index: 0
2058 | }
2059 | ]
2060 | ]
2061 | },
2062 | "n8n Settings": {
2063 | main: [
2064 | [
2065 | {
2066 | node: "Create Instructions",
2067 | type: "main",
2068 | index: 0
2069 | }
2070 | ]
2071 | ]
2072 | }
2073 | }
2074 | });
2075 |
2076 | // Execute the workflow to get the webhook URL
2077 | const execution = await useMcpTool('n8n-mcp-server', 'execution_run', {
2078 | workflowId: notificationWorkflow.id,
2079 | waitForCompletion: true
2080 | });
2081 |
2082 | // Extract webhook URL from the execution
2083 | let webhookUrl = "undefined";
2084 | if (execution.status === "success" && execution.data?.resultData?.runData?.Webhook?.[0]?.data?.webhookUrl) {
2085 | webhookUrl = execution.data.resultData.runData.Webhook[0].data.webhookUrl;
2086 | }
2087 |
2088 | return `
2089 | # n8n to Slack Notification Setup
2090 |
2091 | I've created two workflows:
2092 |
2093 | 1. **n8n Execution Notifications to Slack** - This workflow receives execution notifications from n8n and sends them to Slack
2094 | - ID: ${notificationWorkflow.id}
2095 | - Webhook URL: ${webhookUrl}
2096 |
2097 | 2. **Configure n8n Execution Notifications** - This workflow configures n8n settings to send notifications
2098 | - ID: ${setupWorkflow.id}
2099 |
2100 | ## Next Steps:
2101 |
2102 | 1. Create a Slack app and obtain a token with the following permissions:
2103 | - chat:write
2104 | - chat:write.public
2105 |
2106 | 2. Set the environment variable \`SLACK_TOKEN\` with your Slack token
2107 |
2108 | 3. Run the "Configure n8n Execution Notifications" workflow after setting the \`webhookUrl\` parameter to:
2109 | ${webhookUrl}
2110 |
2111 | 4. Activate the "n8n Execution Notifications to Slack" workflow
2112 |
2113 | 5. Customize the channel in the "Format Slack Message" node if needed (default is #n8n-notifications)
2114 |
2115 | Once completed, you
2116 |
```
--------------------------------------------------------------------------------
/n8n-openapi.yml:
--------------------------------------------------------------------------------
```yaml
1 | openapi: 3.0.0
2 | info:
3 | title: n8n Public API
4 | description: n8n Public API
5 | termsOfService: https://n8n.io/legal/terms
6 | contact:
7 | email: [email protected]
8 | license:
9 | name: Sustainable Use License
10 | url: https://github.com/n8n-io/n8n/blob/master/LICENSE.md
11 | version: 1.1.1
12 | servers:
13 | - url: /api/v1
14 | security:
15 | - ApiKeyAuth: []
16 | tags:
17 | - name: User
18 | description: Operations about users
19 | - name: Audit
20 | description: Operations about security audit
21 | - name: Execution
22 | description: Operations about executions
23 | - name: Workflow
24 | description: Operations about workflows
25 | - name: Credential
26 | description: Operations about credentials
27 | - name: Tags
28 | description: Operations about tags
29 | - name: SourceControl
30 | description: Operations about source control
31 | - name: Variables
32 | description: Operations about variables
33 | - name: Projects
34 | description: Operations about projects
35 | externalDocs:
36 | description: n8n API documentation
37 | url: https://docs.n8n.io/api/
38 | paths:
39 | /audit:
40 | post:
41 | x-eov-operation-id: generateAudit
42 | x-eov-operation-handler: v1/handlers/audit/audit.handler
43 | tags:
44 | - Audit
45 | summary: Generate an audit
46 | description: Generate a security audit for your n8n instance.
47 | requestBody:
48 | required: false
49 | content:
50 | application/json:
51 | schema:
52 | type: object
53 | properties:
54 | additionalOptions:
55 | type: object
56 | properties:
57 | daysAbandonedWorkflow:
58 | type: integer
59 | description: Days for a workflow to be considered abandoned if not executed
60 | categories:
61 | type: array
62 | items:
63 | type: string
64 | enum:
65 | - credentials
66 | - database
67 | - nodes
68 | - filesystem
69 | - instance
70 | responses:
71 | '200':
72 | description: Operation successful.
73 | content:
74 | application/json:
75 | schema:
76 | $ref: '#/components/schemas/audit'
77 | '401':
78 | $ref: '#/components/responses/unauthorized'
79 | '500':
80 | description: Internal server error.
81 | /credentials:
82 | post:
83 | x-eov-operation-id: createCredential
84 | x-eov-operation-handler: v1/handlers/credentials/credentials.handler
85 | tags:
86 | - Credential
87 | summary: Create a credential
88 | description: Creates a credential that can be used by nodes of the specified type.
89 | requestBody:
90 | description: Credential to be created.
91 | required: true
92 | content:
93 | application/json:
94 | schema:
95 | $ref: '#/components/schemas/credential'
96 | responses:
97 | '200':
98 | description: Operation successful.
99 | content:
100 | application/json:
101 | schema:
102 | $ref: '#/components/schemas/create-credential-response'
103 | '401':
104 | $ref: '#/components/responses/unauthorized'
105 | '415':
106 | description: Unsupported media type.
107 | /credentials/{id}:
108 | delete:
109 | x-eov-operation-id: deleteCredential
110 | x-eov-operation-handler: v1/handlers/credentials/credentials.handler
111 | tags:
112 | - Credential
113 | summary: Delete credential by ID
114 | description: Deletes a credential from your instance. You must be the owner of the credentials
115 | operationId: deleteCredential
116 | parameters:
117 | - name: id
118 | in: path
119 | description: The credential ID that needs to be deleted
120 | required: true
121 | schema:
122 | type: string
123 | responses:
124 | '200':
125 | description: Operation successful.
126 | content:
127 | application/json:
128 | schema:
129 | $ref: '#/components/schemas/credential'
130 | '401':
131 | $ref: '#/components/responses/unauthorized'
132 | '404':
133 | $ref: '#/components/responses/notFound'
134 | /credentials/schema/{credentialTypeName}:
135 | get:
136 | x-eov-operation-id: getCredentialType
137 | x-eov-operation-handler: v1/handlers/credentials/credentials.handler
138 | tags:
139 | - Credential
140 | summary: Show credential data schema
141 | parameters:
142 | - name: credentialTypeName
143 | in: path
144 | description: The credential type name that you want to get the schema for
145 | required: true
146 | schema:
147 | type: string
148 | responses:
149 | '200':
150 | description: Operation successful.
151 | content:
152 | application/json:
153 | schema:
154 | type: object
155 | examples:
156 | freshdeskApi:
157 | value:
158 | additionalProperties: false
159 | type: object
160 | properties:
161 | apiKey:
162 | type: string
163 | domain:
164 | type: string
165 | required:
166 | - apiKey
167 | - domain
168 | slackOAuth2Api:
169 | value:
170 | additionalProperties: false
171 | type: object
172 | properties:
173 | clientId:
174 | type: string
175 | clientSecret:
176 | type: string
177 | required:
178 | - clientId
179 | - clientSecret
180 | '401':
181 | $ref: '#/components/responses/unauthorized'
182 | '404':
183 | $ref: '#/components/responses/notFound'
184 | /executions:
185 | get:
186 | x-eov-operation-id: getExecutions
187 | x-eov-operation-handler: v1/handlers/executions/executions.handler
188 | tags:
189 | - Execution
190 | summary: Retrieve all executions
191 | description: Retrieve all executions from your instance.
192 | parameters:
193 | - $ref: '#/components/parameters/includeData'
194 | - name: status
195 | in: query
196 | description: Status to filter the executions by.
197 | required: false
198 | schema:
199 | type: string
200 | enum:
201 | - error
202 | - success
203 | - waiting
204 | - name: workflowId
205 | in: query
206 | description: Workflow to filter the executions by.
207 | required: false
208 | schema:
209 | type: string
210 | example: '1000'
211 | - name: projectId
212 | in: query
213 | required: false
214 | explode: false
215 | allowReserved: true
216 | schema:
217 | type: string
218 | example: VmwOO9HeTEj20kxM
219 | - $ref: '#/components/parameters/limit'
220 | - $ref: '#/components/parameters/cursor'
221 | responses:
222 | '200':
223 | description: Operation successful.
224 | content:
225 | application/json:
226 | schema:
227 | $ref: '#/components/schemas/executionList'
228 | '401':
229 | $ref: '#/components/responses/unauthorized'
230 | '404':
231 | $ref: '#/components/responses/notFound'
232 | /executions/{id}:
233 | get:
234 | x-eov-operation-id: getExecution
235 | x-eov-operation-handler: v1/handlers/executions/executions.handler
236 | tags:
237 | - Execution
238 | summary: Retrieve an execution
239 | description: Retrieve an execution from your instance.
240 | parameters:
241 | - $ref: '#/components/parameters/executionId'
242 | - $ref: '#/components/parameters/includeData'
243 | responses:
244 | '200':
245 | description: Operation successful.
246 | content:
247 | application/json:
248 | schema:
249 | $ref: '#/components/schemas/execution'
250 | '401':
251 | $ref: '#/components/responses/unauthorized'
252 | '404':
253 | $ref: '#/components/responses/notFound'
254 | delete:
255 | x-eov-operation-id: deleteExecution
256 | x-eov-operation-handler: v1/handlers/executions/executions.handler
257 | tags:
258 | - Execution
259 | summary: Delete an execution
260 | description: Deletes an execution from your instance.
261 | parameters:
262 | - $ref: '#/components/parameters/executionId'
263 | responses:
264 | '200':
265 | description: Operation successful.
266 | content:
267 | application/json:
268 | schema:
269 | $ref: '#/components/schemas/execution'
270 | '401':
271 | $ref: '#/components/responses/unauthorized'
272 | '404':
273 | $ref: '#/components/responses/notFound'
274 | /tags:
275 | post:
276 | x-eov-operation-id: createTag
277 | x-eov-operation-handler: v1/handlers/tags/tags.handler
278 | tags:
279 | - Tags
280 | summary: Create a tag
281 | description: Create a tag in your instance.
282 | requestBody:
283 | description: Created tag object.
284 | content:
285 | application/json:
286 | schema:
287 | $ref: '#/components/schemas/tag'
288 | required: true
289 | responses:
290 | '201':
291 | description: A tag object
292 | content:
293 | application/json:
294 | schema:
295 | $ref: '#/components/schemas/tag'
296 | '400':
297 | $ref: '#/components/responses/badRequest'
298 | '401':
299 | $ref: '#/components/responses/unauthorized'
300 | '409':
301 | $ref: '#/components/responses/conflict'
302 | get:
303 | x-eov-operation-id: getTags
304 | x-eov-operation-handler: v1/handlers/tags/tags.handler
305 | tags:
306 | - Tags
307 | summary: Retrieve all tags
308 | description: Retrieve all tags from your instance.
309 | parameters:
310 | - $ref: '#/components/parameters/limit'
311 | - $ref: '#/components/parameters/cursor'
312 | responses:
313 | '200':
314 | description: Operation successful.
315 | content:
316 | application/json:
317 | schema:
318 | $ref: '#/components/schemas/tagList'
319 | '401':
320 | $ref: '#/components/responses/unauthorized'
321 | /tags/{id}:
322 | get:
323 | x-eov-operation-id: getTag
324 | x-eov-operation-handler: v1/handlers/tags/tags.handler
325 | tags:
326 | - Tags
327 | summary: Retrieves a tag
328 | description: Retrieves a tag.
329 | parameters:
330 | - $ref: '#/components/parameters/tagId'
331 | responses:
332 | '200':
333 | description: Operation successful.
334 | content:
335 | application/json:
336 | schema:
337 | $ref: '#/components/schemas/tag'
338 | '401':
339 | $ref: '#/components/responses/unauthorized'
340 | '404':
341 | $ref: '#/components/responses/notFound'
342 | delete:
343 | x-eov-operation-id: deleteTag
344 | x-eov-operation-handler: v1/handlers/tags/tags.handler
345 | tags:
346 | - Tags
347 | summary: Delete a tag
348 | description: Deletes a tag.
349 | parameters:
350 | - $ref: '#/components/parameters/tagId'
351 | responses:
352 | '200':
353 | description: Operation successful.
354 | content:
355 | application/json:
356 | schema:
357 | $ref: '#/components/schemas/tag'
358 | '401':
359 | $ref: '#/components/responses/unauthorized'
360 | '403':
361 | $ref: '#/components/responses/forbidden'
362 | '404':
363 | $ref: '#/components/responses/notFound'
364 | put:
365 | x-eov-operation-id: updateTag
366 | x-eov-operation-handler: v1/handlers/tags/tags.handler
367 | tags:
368 | - Tags
369 | summary: Update a tag
370 | description: Update a tag.
371 | parameters:
372 | - $ref: '#/components/parameters/tagId'
373 | requestBody:
374 | description: Updated tag object.
375 | content:
376 | application/json:
377 | schema:
378 | $ref: '#/components/schemas/tag'
379 | required: true
380 | responses:
381 | '200':
382 | description: Tag object
383 | content:
384 | application/json:
385 | schema:
386 | $ref: '#/components/schemas/tag'
387 | '400':
388 | $ref: '#/components/responses/badRequest'
389 | '401':
390 | $ref: '#/components/responses/unauthorized'
391 | '404':
392 | $ref: '#/components/responses/notFound'
393 | '409':
394 | $ref: '#/components/responses/conflict'
395 | /workflows:
396 | post:
397 | x-eov-operation-id: createWorkflow
398 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
399 | tags:
400 | - Workflow
401 | summary: Create a workflow
402 | description: Create a workflow in your instance.
403 | requestBody:
404 | description: Created workflow object.
405 | content:
406 | application/json:
407 | schema:
408 | $ref: '#/components/schemas/workflow'
409 | required: true
410 | responses:
411 | '200':
412 | description: A workflow object
413 | content:
414 | application/json:
415 | schema:
416 | $ref: '#/components/schemas/workflow'
417 | '400':
418 | $ref: '#/components/responses/badRequest'
419 | '401':
420 | $ref: '#/components/responses/unauthorized'
421 | get:
422 | x-eov-operation-id: getWorkflows
423 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
424 | tags:
425 | - Workflow
426 | summary: Retrieve all workflows
427 | description: Retrieve all workflows from your instance.
428 | parameters:
429 | - name: active
430 | in: query
431 | schema:
432 | type: boolean
433 | example: true
434 | - name: tags
435 | in: query
436 | required: false
437 | explode: false
438 | allowReserved: true
439 | schema:
440 | type: string
441 | example: test,production
442 | - name: name
443 | in: query
444 | required: false
445 | explode: false
446 | allowReserved: true
447 | schema:
448 | type: string
449 | example: My Workflow
450 | - name: projectId
451 | in: query
452 | required: false
453 | explode: false
454 | allowReserved: true
455 | schema:
456 | type: string
457 | example: VmwOO9HeTEj20kxM
458 | - name: excludePinnedData
459 | in: query
460 | required: false
461 | description: Set this to avoid retrieving pinned data
462 | schema:
463 | type: boolean
464 | example: true
465 | - $ref: '#/components/parameters/limit'
466 | - $ref: '#/components/parameters/cursor'
467 | responses:
468 | '200':
469 | description: Operation successful.
470 | content:
471 | application/json:
472 | schema:
473 | $ref: '#/components/schemas/workflowList'
474 | '401':
475 | $ref: '#/components/responses/unauthorized'
476 | /workflows/{id}:
477 | get:
478 | x-eov-operation-id: getWorkflow
479 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
480 | tags:
481 | - Workflow
482 | summary: Retrieves a workflow
483 | description: Retrieves a workflow.
484 | parameters:
485 | - name: excludePinnedData
486 | in: query
487 | required: false
488 | description: Set this to avoid retrieving pinned data
489 | schema:
490 | type: boolean
491 | example: true
492 | - $ref: '#/components/parameters/workflowId'
493 | responses:
494 | '200':
495 | description: Operation successful.
496 | content:
497 | application/json:
498 | schema:
499 | $ref: '#/components/schemas/workflow'
500 | '401':
501 | $ref: '#/components/responses/unauthorized'
502 | '404':
503 | $ref: '#/components/responses/notFound'
504 | delete:
505 | x-eov-operation-id: deleteWorkflow
506 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
507 | tags:
508 | - Workflow
509 | summary: Delete a workflow
510 | description: Deletes a workflow.
511 | parameters:
512 | - $ref: '#/components/parameters/workflowId'
513 | responses:
514 | '200':
515 | description: Operation successful.
516 | content:
517 | application/json:
518 | schema:
519 | $ref: '#/components/schemas/workflow'
520 | '401':
521 | $ref: '#/components/responses/unauthorized'
522 | '404':
523 | $ref: '#/components/responses/notFound'
524 | put:
525 | x-eov-operation-id: updateWorkflow
526 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
527 | tags:
528 | - Workflow
529 | summary: Update a workflow
530 | description: Update a workflow.
531 | parameters:
532 | - $ref: '#/components/parameters/workflowId'
533 | requestBody:
534 | description: Updated workflow object.
535 | content:
536 | application/json:
537 | schema:
538 | $ref: '#/components/schemas/workflow'
539 | required: true
540 | responses:
541 | '200':
542 | description: Workflow object
543 | content:
544 | application/json:
545 | schema:
546 | $ref: '#/components/schemas/workflow'
547 | '400':
548 | $ref: '#/components/responses/badRequest'
549 | '401':
550 | $ref: '#/components/responses/unauthorized'
551 | '404':
552 | $ref: '#/components/responses/notFound'
553 | /workflows/{id}/activate:
554 | post:
555 | x-eov-operation-id: activateWorkflow
556 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
557 | tags:
558 | - Workflow
559 | summary: Activate a workflow
560 | description: Active a workflow.
561 | parameters:
562 | - $ref: '#/components/parameters/workflowId'
563 | responses:
564 | '200':
565 | description: Workflow object
566 | content:
567 | application/json:
568 | schema:
569 | $ref: '#/components/schemas/workflow'
570 | '401':
571 | $ref: '#/components/responses/unauthorized'
572 | '404':
573 | $ref: '#/components/responses/notFound'
574 | /workflows/{id}/deactivate:
575 | post:
576 | x-eov-operation-id: deactivateWorkflow
577 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
578 | tags:
579 | - Workflow
580 | summary: Deactivate a workflow
581 | description: Deactivate a workflow.
582 | parameters:
583 | - $ref: '#/components/parameters/workflowId'
584 | responses:
585 | '200':
586 | description: Workflow object
587 | content:
588 | application/json:
589 | schema:
590 | $ref: '#/components/schemas/workflow'
591 | '401':
592 | $ref: '#/components/responses/unauthorized'
593 | '404':
594 | $ref: '#/components/responses/notFound'
595 | /workflows/{id}/transfer:
596 | put:
597 | x-eov-operation-id: transferWorkflow
598 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
599 | tags:
600 | - Workflow
601 | summary: Transfer a workflow to another project.
602 | description: Transfer a workflow to another project.
603 | parameters:
604 | - $ref: '#/components/parameters/workflowId'
605 | requestBody:
606 | description: Destination project information for the workflow transfer.
607 | content:
608 | application/json:
609 | schema:
610 | type: object
611 | properties:
612 | destinationProjectId:
613 | type: string
614 | description: The ID of the project to transfer the workflow to.
615 | required:
616 | - destinationProjectId
617 | required: true
618 | responses:
619 | '200':
620 | description: Operation successful.
621 | '400':
622 | $ref: '#/components/responses/badRequest'
623 | '401':
624 | $ref: '#/components/responses/unauthorized'
625 | '404':
626 | $ref: '#/components/responses/notFound'
627 | /credentials/{id}/transfer:
628 | put:
629 | x-eov-operation-id: transferCredential
630 | x-eov-operation-handler: v1/handlers/credentials/credentials.handler
631 | tags:
632 | - Workflow
633 | summary: Transfer a credential to another project.
634 | description: Transfer a credential to another project.
635 | parameters:
636 | - $ref: '#/components/parameters/credentialId'
637 | requestBody:
638 | description: Destination project for the credential transfer.
639 | content:
640 | application/json:
641 | schema:
642 | type: object
643 | properties:
644 | destinationProjectId:
645 | type: string
646 | description: The ID of the project to transfer the credential to.
647 | required:
648 | - destinationProjectId
649 | required: true
650 | responses:
651 | '200':
652 | description: Operation successful.
653 | '400':
654 | $ref: '#/components/responses/badRequest'
655 | '401':
656 | $ref: '#/components/responses/unauthorized'
657 | '404':
658 | $ref: '#/components/responses/notFound'
659 | /workflows/{id}/tags:
660 | get:
661 | x-eov-operation-id: getWorkflowTags
662 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
663 | tags:
664 | - Workflow
665 | summary: Get workflow tags
666 | description: Get workflow tags.
667 | parameters:
668 | - $ref: '#/components/parameters/workflowId'
669 | responses:
670 | '200':
671 | description: List of tags
672 | content:
673 | application/json:
674 | schema:
675 | $ref: '#/components/schemas/workflowTags'
676 | '400':
677 | $ref: '#/components/responses/badRequest'
678 | '401':
679 | $ref: '#/components/responses/unauthorized'
680 | '404':
681 | $ref: '#/components/responses/notFound'
682 | put:
683 | x-eov-operation-id: updateWorkflowTags
684 | x-eov-operation-handler: v1/handlers/workflows/workflows.handler
685 | tags:
686 | - Workflow
687 | summary: Update tags of a workflow
688 | description: Update tags of a workflow.
689 | parameters:
690 | - $ref: '#/components/parameters/workflowId'
691 | requestBody:
692 | description: List of tags
693 | content:
694 | application/json:
695 | schema:
696 | $ref: '#/components/schemas/tagIds'
697 | required: true
698 | responses:
699 | '200':
700 | description: List of tags after add the tag
701 | content:
702 | application/json:
703 | schema:
704 | $ref: '#/components/schemas/workflowTags'
705 | '400':
706 | $ref: '#/components/responses/badRequest'
707 | '401':
708 | $ref: '#/components/responses/unauthorized'
709 | '404':
710 | $ref: '#/components/responses/notFound'
711 | /users:
712 | get:
713 | x-eov-operation-id: getUsers
714 | x-eov-operation-handler: v1/handlers/users/users.handler.ee
715 | tags:
716 | - User
717 | summary: Retrieve all users
718 | description: Retrieve all users from your instance. Only available for the instance owner.
719 | parameters:
720 | - $ref: '#/components/parameters/limit'
721 | - $ref: '#/components/parameters/cursor'
722 | - $ref: '#/components/parameters/includeRole'
723 | - name: projectId
724 | in: query
725 | required: false
726 | explode: false
727 | allowReserved: true
728 | schema:
729 | type: string
730 | example: VmwOO9HeTEj20kxM
731 | responses:
732 | '200':
733 | description: Operation successful.
734 | content:
735 | application/json:
736 | schema:
737 | $ref: '#/components/schemas/userList'
738 | '401':
739 | $ref: '#/components/responses/unauthorized'
740 | post:
741 | x-eov-operation-id: createUser
742 | x-eov-operation-handler: v1/handlers/users/users.handler.ee
743 | tags:
744 | - User
745 | summary: Create multiple users
746 | description: Create one or more users.
747 | requestBody:
748 | description: Array of users to be created.
749 | required: true
750 | content:
751 | application/json:
752 | schema:
753 | type: array
754 | items:
755 | type: object
756 | properties:
757 | email:
758 | type: string
759 | format: email
760 | role:
761 | type: string
762 | enum:
763 | - global:admin
764 | - global:member
765 | required:
766 | - email
767 | responses:
768 | '200':
769 | description: Operation successful.
770 | content:
771 | application/json:
772 | schema:
773 | type: object
774 | properties:
775 | user:
776 | type: object
777 | properties:
778 | id:
779 | type: string
780 | email:
781 | type: string
782 | inviteAcceptUrl:
783 | type: string
784 | emailSent:
785 | type: boolean
786 | error:
787 | type: string
788 | '401':
789 | $ref: '#/components/responses/unauthorized'
790 | '403':
791 | $ref: '#/components/responses/forbidden'
792 | /users/{id}:
793 | get:
794 | x-eov-operation-id: getUser
795 | x-eov-operation-handler: v1/handlers/users/users.handler.ee
796 | tags:
797 | - User
798 | summary: Get user by ID/Email
799 | description: Retrieve a user from your instance. Only available for the instance owner.
800 | parameters:
801 | - $ref: '#/components/parameters/userIdentifier'
802 | - $ref: '#/components/parameters/includeRole'
803 | responses:
804 | '200':
805 | description: Operation successful.
806 | content:
807 | application/json:
808 | schema:
809 | $ref: '#/components/schemas/user'
810 | '401':
811 | $ref: '#/components/responses/unauthorized'
812 | delete:
813 | x-eov-operation-id: deleteUser
814 | x-eov-operation-handler: v1/handlers/users/users.handler.ee
815 | tags:
816 | - User
817 | summary: Delete a user
818 | description: Delete a user from your instance.
819 | parameters:
820 | - $ref: '#/components/parameters/userIdentifier'
821 | responses:
822 | '204':
823 | description: Operation successful.
824 | '401':
825 | $ref: '#/components/responses/unauthorized'
826 | '403':
827 | $ref: '#/components/responses/forbidden'
828 | '404':
829 | $ref: '#/components/responses/notFound'
830 | /users/{id}/role:
831 | patch:
832 | x-eov-operation-id: changeRole
833 | x-eov-operation-handler: v1/handlers/users/users.handler.ee
834 | tags:
835 | - User
836 | summary: Change a user's global role
837 | description: Change a user's global role
838 | parameters:
839 | - $ref: '#/components/parameters/userIdentifier'
840 | requestBody:
841 | description: New role for the user
842 | required: true
843 | content:
844 | application/json:
845 | schema:
846 | type: object
847 | properties:
848 | newRoleName:
849 | type: string
850 | enum:
851 | - global:admin
852 | - global:member
853 | required:
854 | - newRoleName
855 | responses:
856 | '200':
857 | description: Operation successful.
858 | '401':
859 | $ref: '#/components/responses/unauthorized'
860 | '403':
861 | $ref: '#/components/responses/forbidden'
862 | '404':
863 | $ref: '#/components/responses/notFound'
864 | /source-control/pull:
865 | post:
866 | x-eov-operation-id: pull
867 | x-eov-operation-handler: v1/handlers/source-control/source-control.handler
868 | tags:
869 | - SourceControl
870 | summary: Pull changes from the remote repository
871 | description: Requires the Source Control feature to be licensed and connected to a repository.
872 | requestBody:
873 | description: Pull options
874 | required: true
875 | content:
876 | application/json:
877 | schema:
878 | $ref: '#/components/schemas/pull'
879 | responses:
880 | '200':
881 | description: Import result
882 | content:
883 | application/json:
884 | schema:
885 | $ref: '#/components/schemas/importResult'
886 | '400':
887 | $ref: '#/components/responses/badRequest'
888 | '409':
889 | $ref: '#/components/responses/conflict'
890 | /variables:
891 | post:
892 | x-eov-operation-id: createVariable
893 | x-eov-operation-handler: v1/handlers/variables/variables.handler
894 | tags:
895 | - Variables
896 | summary: Create a variable
897 | description: Create a variable in your instance.
898 | requestBody:
899 | description: Payload for variable to create.
900 | content:
901 | application/json:
902 | schema:
903 | $ref: '#/components/schemas/variable'
904 | required: true
905 | responses:
906 | '201':
907 | description: Operation successful.
908 | '400':
909 | $ref: '#/components/responses/badRequest'
910 | '401':
911 | $ref: '#/components/responses/unauthorized'
912 | get:
913 | x-eov-operation-id: getVariables
914 | x-eov-operation-handler: v1/handlers/variables/variables.handler
915 | tags:
916 | - Variables
917 | summary: Retrieve variables
918 | description: Retrieve variables from your instance.
919 | parameters:
920 | - $ref: '#/components/parameters/limit'
921 | - $ref: '#/components/parameters/cursor'
922 | responses:
923 | '200':
924 | description: Operation successful.
925 | content:
926 | application/json:
927 | schema:
928 | $ref: '#/components/schemas/variableList'
929 | '401':
930 | $ref: '#/components/responses/unauthorized'
931 | /variables/{id}:
932 | delete:
933 | x-eov-operation-id: deleteVariable
934 | x-eov-operation-handler: v1/handlers/variables/variables.handler
935 | tags:
936 | - Variables
937 | summary: Delete a variable
938 | description: Delete a variable from your instance.
939 | parameters:
940 | - $ref: '#/components/parameters/variableId'
941 | responses:
942 | '204':
943 | description: Operation successful.
944 | '401':
945 | $ref: '#/components/responses/unauthorized'
946 | '404':
947 | $ref: '#/components/responses/notFound'
948 | /projects:
949 | post:
950 | x-eov-operation-id: createProject
951 | x-eov-operation-handler: v1/handlers/projects/projects.handler
952 | tags:
953 | - Projects
954 | summary: Create a project
955 | description: Create a project in your instance.
956 | requestBody:
957 | description: Payload for project to create.
958 | content:
959 | application/json:
960 | schema:
961 | $ref: '#/components/schemas/project'
962 | required: true
963 | responses:
964 | '201':
965 | description: Operation successful.
966 | '400':
967 | $ref: '#/components/responses/badRequest'
968 | '401':
969 | $ref: '#/components/responses/unauthorized'
970 | get:
971 | x-eov-operation-id: getProjects
972 | x-eov-operation-handler: v1/handlers/projects/projects.handler
973 | tags:
974 | - Projects
975 | summary: Retrieve projects
976 | description: Retrieve projects from your instance.
977 | parameters:
978 | - $ref: '#/components/parameters/limit'
979 | - $ref: '#/components/parameters/cursor'
980 | responses:
981 | '200':
982 | description: Operation successful.
983 | content:
984 | application/json:
985 | schema:
986 | $ref: '#/components/schemas/projectList'
987 | '401':
988 | $ref: '#/components/responses/unauthorized'
989 | /projects/{projectId}:
990 | delete:
991 | x-eov-operation-id: deleteProject
992 | x-eov-operation-handler: v1/handlers/projects/projects.handler
993 | tags:
994 | - Projects
995 | summary: Delete a project
996 | description: Delete a project from your instance.
997 | parameters:
998 | - $ref: '#/components/parameters/projectId'
999 | responses:
1000 | '204':
1001 | description: Operation successful.
1002 | '401':
1003 | $ref: '#/components/responses/unauthorized'
1004 | '403':
1005 | $ref: '#/components/responses/forbidden'
1006 | '404':
1007 | $ref: '#/components/responses/notFound'
1008 | put:
1009 | x-eov-operation-id: updateProject
1010 | x-eov-operation-handler: v1/handlers/projects/projects.handler
1011 | tags:
1012 | - Project
1013 | summary: Update a project
1014 | description: Update a project.
1015 | requestBody:
1016 | description: Updated project object.
1017 | content:
1018 | application/json:
1019 | schema:
1020 | $ref: '#/components/schemas/project'
1021 | required: true
1022 | responses:
1023 | '204':
1024 | description: Operation successful.
1025 | '400':
1026 | $ref: '#/components/responses/badRequest'
1027 | '401':
1028 | $ref: '#/components/responses/unauthorized'
1029 | '403':
1030 | $ref: '#/components/responses/forbidden'
1031 | '404':
1032 | $ref: '#/components/responses/notFound'
1033 | components:
1034 | schemas:
1035 | audit:
1036 | type: object
1037 | properties:
1038 | Credentials Risk Report:
1039 | type: object
1040 | example:
1041 | risk: credentials
1042 | sections:
1043 | - title: Credentials not used in any workflow
1044 | description: These credentials are not used in any workflow. Keeping unused credentials in your instance is an unneeded security risk.
1045 | recommendation: Consider deleting these credentials if you no longer need them.
1046 | location:
1047 | - kind: credential
1048 | id: '1'
1049 | name: My Test Account
1050 | Database Risk Report:
1051 | type: object
1052 | example:
1053 | risk: database
1054 | sections:
1055 | - title: Expressions in "Execute Query" fields in SQL nodes
1056 | description: This SQL node has an expression in the "Query" field of an "Execute Query" operation. Building a SQL query with an expression may lead to a SQL injection attack.
1057 | recommendation: Consider using the "Query Parameters" field to pass parameters to the query
1058 | or validating the input of the expression in the "Query" field.: null
1059 | location:
1060 | - kind: node
1061 | workflowId: '1'
1062 | workflowName: My Workflow
1063 | nodeId: 51eb5852-ce0b-4806-b4ff-e41322a4041a
1064 | nodeName: MySQL
1065 | nodeType: n8n-nodes-base.mySql
1066 | Filesystem Risk Report:
1067 | type: object
1068 | example:
1069 | risk: filesystem
1070 | sections:
1071 | - title: Nodes that interact with the filesystem
1072 | description: This node reads from and writes to any accessible file in the host filesystem. Sensitive file content may be manipulated through a node operation.
1073 | recommendation: Consider protecting any sensitive files in the host filesystem
1074 | or refactoring the workflow so that it does not require host filesystem interaction.: null
1075 | location:
1076 | - kind: node
1077 | workflowId: '1'
1078 | workflowName: My Workflow
1079 | nodeId: 51eb5852-ce0b-4806-b4ff-e41322a4041a
1080 | nodeName: Ready Binary file
1081 | nodeType: n8n-nodes-base.readBinaryFile
1082 | Nodes Risk Report:
1083 | type: object
1084 | example:
1085 | risk: nodes
1086 | sections:
1087 | - title: Community nodes
1088 | description: This node is sourced from the community. Community nodes are not vetted by the n8n team and have full access to the host system.
1089 | recommendation: Consider reviewing the source code in any community nodes installed in this n8n instance
1090 | and uninstalling any community nodes no longer used.: null
1091 | location:
1092 | - kind: community
1093 | nodeType: n8n-nodes-test.test
1094 | packageUrl: https://www.npmjs.com/package/n8n-nodes-test
1095 | Instance Risk Report:
1096 | type: object
1097 | example:
1098 | risk: execution
1099 | sections:
1100 | - title: Unprotected webhooks in instance
1101 | description: These webhook nodes have the "Authentication" field set to "None" and are not directly connected to a node to validate the payload. Every unprotected webhook allows your workflow to be called by any third party who knows the webhook URL.
1102 | recommendation: Consider setting the "Authentication" field to an option other than "None"
1103 | or validating the payload with one of the following nodes.: null
1104 | location:
1105 | - kind: community
1106 | nodeType: n8n-nodes-test.test
1107 | packageUrl: https://www.npmjs.com/package/n8n-nodes-test
1108 | credential:
1109 | required:
1110 | - name
1111 | - type
1112 | - data
1113 | type: object
1114 | properties:
1115 | id:
1116 | type: string
1117 | readOnly: true
1118 | example: R2DjclaysHbqn778
1119 | name:
1120 | type: string
1121 | example: Joe's Github Credentials
1122 | type:
1123 | type: string
1124 | example: github
1125 | data:
1126 | type: object
1127 | writeOnly: true
1128 | example:
1129 | token: ada612vad6fa5df4adf5a5dsf4389adsf76da7s
1130 | createdAt:
1131 | type: string
1132 | format: date-time
1133 | readOnly: true
1134 | example: '2022-04-29T11:02:29.842Z'
1135 | updatedAt:
1136 | type: string
1137 | format: date-time
1138 | readOnly: true
1139 | example: '2022-04-29T11:02:29.842Z'
1140 | create-credential-response:
1141 | required:
1142 | - id
1143 | - name
1144 | - type
1145 | - createdAt
1146 | - updatedAt
1147 | type: object
1148 | properties:
1149 | id:
1150 | type: string
1151 | readOnly: true
1152 | example: vHxaz5UaCghVYl9C
1153 | name:
1154 | type: string
1155 | example: John's Github account
1156 | type:
1157 | type: string
1158 | example: github
1159 | createdAt:
1160 | type: string
1161 | format: date-time
1162 | readOnly: true
1163 | example: '2022-04-29T11:02:29.842Z'
1164 | updatedAt:
1165 | type: string
1166 | format: date-time
1167 | readOnly: true
1168 | example: '2022-04-29T11:02:29.842Z'
1169 | execution:
1170 | type: object
1171 | properties:
1172 | id:
1173 | type: number
1174 | example: 1000
1175 | data:
1176 | type: object
1177 | finished:
1178 | type: boolean
1179 | example: true
1180 | mode:
1181 | type: string
1182 | enum:
1183 | - cli
1184 | - error
1185 | - integrated
1186 | - internal
1187 | - manual
1188 | - retry
1189 | - trigger
1190 | - webhook
1191 | retryOf:
1192 | type: number
1193 | nullable: true
1194 | retrySuccessId:
1195 | type: number
1196 | nullable: true
1197 | example: '2'
1198 | startedAt:
1199 | type: string
1200 | format: date-time
1201 | stoppedAt:
1202 | type: string
1203 | format: date-time
1204 | workflowId:
1205 | type: number
1206 | example: '1000'
1207 | waitTill:
1208 | type: string
1209 | nullable: true
1210 | format: date-time
1211 | customData:
1212 | type: object
1213 | executionList:
1214 | type: object
1215 | properties:
1216 | data:
1217 | type: array
1218 | items:
1219 | $ref: '#/components/schemas/execution'
1220 | nextCursor:
1221 | type: string
1222 | description: Paginate through executions by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1223 | nullable: true
1224 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1225 | tag:
1226 | type: object
1227 | additionalProperties: false
1228 | required:
1229 | - name
1230 | properties:
1231 | id:
1232 | type: string
1233 | readOnly: true
1234 | example: 2tUt1wbLX592XDdX
1235 | name:
1236 | type: string
1237 | example: Production
1238 | createdAt:
1239 | type: string
1240 | format: date-time
1241 | readOnly: true
1242 | updatedAt:
1243 | type: string
1244 | format: date-time
1245 | readOnly: true
1246 | tagList:
1247 | type: object
1248 | properties:
1249 | data:
1250 | type: array
1251 | items:
1252 | $ref: '#/components/schemas/tag'
1253 | nextCursor:
1254 | type: string
1255 | description: Paginate through tags by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1256 | nullable: true
1257 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1258 | node:
1259 | type: object
1260 | additionalProperties: false
1261 | properties:
1262 | id:
1263 | type: string
1264 | example: 0f5532f9-36ba-4bef-86c7-30d607400b15
1265 | name:
1266 | type: string
1267 | example: Jira
1268 | webhookId:
1269 | type: string
1270 | disabled:
1271 | type: boolean
1272 | notesInFlow:
1273 | type: boolean
1274 | notes:
1275 | type: string
1276 | type:
1277 | type: string
1278 | example: n8n-nodes-base.Jira
1279 | typeVersion:
1280 | type: number
1281 | example: 1
1282 | executeOnce:
1283 | type: boolean
1284 | example: false
1285 | alwaysOutputData:
1286 | type: boolean
1287 | example: false
1288 | retryOnFail:
1289 | type: boolean
1290 | example: false
1291 | maxTries:
1292 | type: number
1293 | waitBetweenTries:
1294 | type: number
1295 | continueOnFail:
1296 | type: boolean
1297 | example: false
1298 | description: use onError instead
1299 | deprecated: true
1300 | onError:
1301 | type: string
1302 | example: stopWorkflow
1303 | position:
1304 | type: array
1305 | items:
1306 | type: number
1307 | example:
1308 | - -100
1309 | - 80
1310 | parameters:
1311 | type: object
1312 | example:
1313 | additionalProperties: {}
1314 | credentials:
1315 | type: object
1316 | example:
1317 | jiraSoftwareCloudApi:
1318 | id: '35'
1319 | name: jiraApi
1320 | createdAt:
1321 | type: string
1322 | format: date-time
1323 | readOnly: true
1324 | updatedAt:
1325 | type: string
1326 | format: date-time
1327 | readOnly: true
1328 | workflowSettings:
1329 | type: object
1330 | additionalProperties: false
1331 | properties:
1332 | saveExecutionProgress:
1333 | type: boolean
1334 | saveManualExecutions:
1335 | type: boolean
1336 | saveDataErrorExecution:
1337 | type: string
1338 | enum:
1339 | - all
1340 | - none
1341 | saveDataSuccessExecution:
1342 | type: string
1343 | enum:
1344 | - all
1345 | - none
1346 | executionTimeout:
1347 | type: number
1348 | example: 3600
1349 | maxLength: 3600
1350 | errorWorkflow:
1351 | type: string
1352 | example: VzqKEW0ShTXA5vPj
1353 | description: The ID of the workflow that contains the error trigger node.
1354 | timezone:
1355 | type: string
1356 | example: America/New_York
1357 | executionOrder:
1358 | type: string
1359 | example: v1
1360 | workflow:
1361 | type: object
1362 | additionalProperties: false
1363 | required:
1364 | - name
1365 | - nodes
1366 | - connections
1367 | - settings
1368 | properties:
1369 | id:
1370 | type: string
1371 | readOnly: true
1372 | example: 2tUt1wbLX592XDdX
1373 | name:
1374 | type: string
1375 | example: Workflow 1
1376 | active:
1377 | type: boolean
1378 | readOnly: true
1379 | createdAt:
1380 | type: string
1381 | format: date-time
1382 | readOnly: true
1383 | updatedAt:
1384 | type: string
1385 | format: date-time
1386 | readOnly: true
1387 | nodes:
1388 | type: array
1389 | items:
1390 | $ref: '#/components/schemas/node'
1391 | connections:
1392 | type: object
1393 | example:
1394 | main:
1395 | - node: Jira
1396 | type: main
1397 | index: 0
1398 | settings:
1399 | $ref: '#/components/schemas/workflowSettings'
1400 | staticData:
1401 | example:
1402 | lastId: 1
1403 | anyOf:
1404 | - type: string
1405 | format: jsonString
1406 | nullable: true
1407 | - type: object
1408 | nullable: true
1409 | tags:
1410 | type: array
1411 | items:
1412 | $ref: '#/components/schemas/tag'
1413 | readOnly: true
1414 | workflowList:
1415 | type: object
1416 | properties:
1417 | data:
1418 | type: array
1419 | items:
1420 | $ref: '#/components/schemas/workflow'
1421 | nextCursor:
1422 | type: string
1423 | description: Paginate through workflows by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1424 | nullable: true
1425 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1426 | workflowTags:
1427 | type: array
1428 | items:
1429 | $ref: '#/components/schemas/tag'
1430 | tagIds:
1431 | type: array
1432 | items:
1433 | type: object
1434 | additionalProperties: false
1435 | required:
1436 | - id
1437 | properties:
1438 | id:
1439 | type: string
1440 | example: 2tUt1wbLX592XDdX
1441 | user:
1442 | required:
1443 | - email
1444 | type: object
1445 | properties:
1446 | id:
1447 | type: string
1448 | readOnly: true
1449 | example: 123e4567-e89b-12d3-a456-426614174000
1450 | email:
1451 | type: string
1452 | format: email
1453 | example: [email protected]
1454 | firstName:
1455 | maxLength: 32
1456 | type: string
1457 | description: User's first name
1458 | readOnly: true
1459 | example: john
1460 | lastName:
1461 | maxLength: 32
1462 | type: string
1463 | description: User's last name
1464 | readOnly: true
1465 | example: Doe
1466 | isPending:
1467 | type: boolean
1468 | description: Whether the user finished setting up their account in response to the invitation (true) or not (false).
1469 | readOnly: true
1470 | createdAt:
1471 | type: string
1472 | description: Time the user was created.
1473 | format: date-time
1474 | readOnly: true
1475 | updatedAt:
1476 | type: string
1477 | description: Last time the user was updated.
1478 | format: date-time
1479 | readOnly: true
1480 | role:
1481 | type: string
1482 | example: owner
1483 | readOnly: true
1484 | userList:
1485 | type: object
1486 | properties:
1487 | data:
1488 | type: array
1489 | items:
1490 | $ref: '#/components/schemas/user'
1491 | nextCursor:
1492 | type: string
1493 | description: Paginate through users by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1494 | nullable: true
1495 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1496 | pull:
1497 | type: object
1498 | properties:
1499 | force:
1500 | type: boolean
1501 | example: true
1502 | variables:
1503 | type: object
1504 | example:
1505 | foo: bar
1506 | importResult:
1507 | type: object
1508 | additionalProperties: true
1509 | properties:
1510 | variables:
1511 | type: object
1512 | properties:
1513 | added:
1514 | type: array
1515 | items:
1516 | type: string
1517 | changed:
1518 | type: array
1519 | items:
1520 | type: string
1521 | credentials:
1522 | type: array
1523 | items:
1524 | type: object
1525 | properties:
1526 | id:
1527 | type: string
1528 | name:
1529 | type: string
1530 | type:
1531 | type: string
1532 | workflows:
1533 | type: array
1534 | items:
1535 | type: object
1536 | properties:
1537 | id:
1538 | type: string
1539 | name:
1540 | type: string
1541 | tags:
1542 | type: object
1543 | properties:
1544 | tags:
1545 | type: array
1546 | items:
1547 | type: object
1548 | properties:
1549 | id:
1550 | type: string
1551 | name:
1552 | type: string
1553 | mappings:
1554 | type: array
1555 | items:
1556 | type: object
1557 | properties:
1558 | workflowId:
1559 | type: string
1560 | tagId:
1561 | type: string
1562 | variable:
1563 | type: object
1564 | additionalProperties: false
1565 | required:
1566 | - key
1567 | - value
1568 | properties:
1569 | id:
1570 | type: string
1571 | readOnly: true
1572 | key:
1573 | type: string
1574 | value:
1575 | type: string
1576 | example: test
1577 | type:
1578 | type: string
1579 | readOnly: true
1580 | variableList:
1581 | type: object
1582 | properties:
1583 | data:
1584 | type: array
1585 | items:
1586 | $ref: '#/components/schemas/variable'
1587 | nextCursor:
1588 | type: string
1589 | description: Paginate through variables by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1590 | nullable: true
1591 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1592 | project:
1593 | type: object
1594 | additionalProperties: false
1595 | required:
1596 | - name
1597 | properties:
1598 | id:
1599 | type: string
1600 | readOnly: true
1601 | name:
1602 | type: string
1603 | type:
1604 | type: string
1605 | readOnly: true
1606 | projectList:
1607 | type: object
1608 | properties:
1609 | data:
1610 | type: array
1611 | items:
1612 | $ref: '#/components/schemas/project'
1613 | nextCursor:
1614 | type: string
1615 | description: Paginate through projects by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
1616 | nullable: true
1617 | example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
1618 | error:
1619 | required:
1620 | - message
1621 | type: object
1622 | properties:
1623 | code:
1624 | type: string
1625 | message:
1626 | type: string
1627 | description:
1628 | type: string
1629 | role:
1630 | readOnly: true
1631 | type: object
1632 | properties:
1633 | id:
1634 | type: number
1635 | readOnly: true
1636 | example: 1
1637 | name:
1638 | type: string
1639 | example: owner
1640 | readOnly: true
1641 | scope:
1642 | type: string
1643 | readOnly: true
1644 | example: global
1645 | createdAt:
1646 | type: string
1647 | description: Time the role was created.
1648 | format: date-time
1649 | readOnly: true
1650 | updatedAt:
1651 | type: string
1652 | description: Last time the role was updated.
1653 | format: date-time
1654 | readOnly: true
1655 | credentialType:
1656 | type: object
1657 | properties:
1658 | displayName:
1659 | type: string
1660 | readOnly: true
1661 | example: Email
1662 | name:
1663 | type: string
1664 | readOnly: true
1665 | example: email
1666 | type:
1667 | type: string
1668 | readOnly: true
1669 | example: string
1670 | default:
1671 | type: string
1672 | readOnly: true
1673 | example: string
1674 | Error:
1675 | $ref: '#/components/schemas/error'
1676 | Role:
1677 | $ref: '#/components/schemas/role'
1678 | Execution:
1679 | $ref: '#/components/schemas/execution'
1680 | Node:
1681 | $ref: '#/components/schemas/node'
1682 | Tag:
1683 | $ref: '#/components/schemas/tag'
1684 | Workflow:
1685 | $ref: '#/components/schemas/workflow'
1686 | WorkflowSettings:
1687 | $ref: '#/components/schemas/workflowSettings'
1688 | ExecutionList:
1689 | $ref: '#/components/schemas/executionList'
1690 | WorkflowList:
1691 | $ref: '#/components/schemas/workflowList'
1692 | Credential:
1693 | $ref: '#/components/schemas/credential'
1694 | CredentialType:
1695 | $ref: '#/components/schemas/credentialType'
1696 | Audit:
1697 | $ref: '#/components/schemas/audit'
1698 | Pull:
1699 | $ref: '#/components/schemas/pull'
1700 | ImportResult:
1701 | $ref: '#/components/schemas/importResult'
1702 | UserList:
1703 | $ref: '#/components/schemas/userList'
1704 | User:
1705 | $ref: '#/components/schemas/user'
1706 | responses:
1707 | unauthorized:
1708 | description: Unauthorized
1709 | notFound:
1710 | description: The specified resource was not found.
1711 | badRequest:
1712 | description: The request is invalid or provides malformed data.
1713 | conflict:
1714 | description: Conflict
1715 | forbidden:
1716 | description: Forbidden
1717 | NotFound:
1718 | $ref: '#/components/responses/notFound'
1719 | Unauthorized:
1720 | $ref: '#/components/responses/unauthorized'
1721 | BadRequest:
1722 | $ref: '#/components/responses/badRequest'
1723 | Conflict:
1724 | $ref: '#/components/responses/conflict'
1725 | Forbidden:
1726 | $ref: '#/components/responses/forbidden'
1727 | parameters:
1728 | includeData:
1729 | name: includeData
1730 | in: query
1731 | description: Whether or not to include the execution's detailed data.
1732 | required: false
1733 | schema:
1734 | type: boolean
1735 | limit:
1736 | name: limit
1737 | in: query
1738 | description: The maximum number of items to return.
1739 | required: false
1740 | schema:
1741 | type: number
1742 | example: 100
1743 | default: 100
1744 | maximum: 250
1745 | cursor:
1746 | name: cursor
1747 | in: query
1748 | description: Paginate by setting the cursor parameter to the nextCursor attribute returned by the previous request's response. Default value fetches the first "page" of the collection. See pagination for more detail.
1749 | required: false
1750 | style: form
1751 | schema:
1752 | type: string
1753 | executionId:
1754 | name: id
1755 | in: path
1756 | description: The ID of the execution.
1757 | required: true
1758 | schema:
1759 | type: number
1760 | tagId:
1761 | name: id
1762 | in: path
1763 | description: The ID of the tag.
1764 | required: true
1765 | schema:
1766 | type: string
1767 | workflowId:
1768 | name: id
1769 | in: path
1770 | description: The ID of the workflow.
1771 | required: true
1772 | schema:
1773 | type: string
1774 | credentialId:
1775 | name: id
1776 | in: path
1777 | description: The ID of the credential.
1778 | required: true
1779 | schema:
1780 | type: string
1781 | includeRole:
1782 | name: includeRole
1783 | in: query
1784 | description: Whether to include the user's role or not.
1785 | required: false
1786 | schema:
1787 | type: boolean
1788 | example: true
1789 | default: false
1790 | userIdentifier:
1791 | name: id
1792 | in: path
1793 | description: The ID or email of the user.
1794 | required: true
1795 | schema:
1796 | type: string
1797 | format: identifier
1798 | variableId:
1799 | name: id
1800 | in: path
1801 | description: The ID of the variable.
1802 | required: true
1803 | schema:
1804 | type: string
1805 | projectId:
1806 | name: projectId
1807 | in: path
1808 | description: The ID of the project.
1809 | required: true
1810 | schema:
1811 | type: string
1812 | Cursor:
1813 | $ref: '#/components/parameters/cursor'
1814 | Limit:
1815 | $ref: '#/components/parameters/limit'
1816 | ExecutionId:
1817 | $ref: '#/components/parameters/executionId'
1818 | WorkflowId:
1819 | $ref: '#/components/parameters/workflowId'
1820 | TagId:
1821 | $ref: '#/components/parameters/tagId'
1822 | IncludeData:
1823 | $ref: '#/components/parameters/includeData'
1824 | UserIdentifier:
1825 | $ref: '#/components/parameters/userIdentifier'
1826 | IncludeRole:
1827 | $ref: '#/components/parameters/includeRole'
1828 | securitySchemes:
1829 | ApiKeyAuth:
1830 | type: apiKey
1831 | in: header
1832 | name: X-N8N-API-KEY
1833 |
```