n8n
Version:
n8n Workflow Automation Tool
284 lines • 19.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.McpService = void 0;
const backend_common_1 = require("@n8n/backend-common");
const config_1 = require("@n8n/config");
const db_1 = require("@n8n/db");
const di_1 = require("@n8n/di");
const n8n_core_1 = require("n8n-core");
const n8n_workflow_1 = require("n8n-workflow");
const data_table_1 = require("./tools/data-table");
const execute_workflow_tool_1 = require("./tools/execute-workflow.tool");
const get_execution_tool_1 = require("./tools/get-execution.tool");
const search_executions_tool_1 = require("./tools/search-executions.tool");
const get_workflow_details_tool_1 = require("./tools/get-workflow-details.tool");
const list_credentials_tool_1 = require("./tools/list-credentials.tool");
const publish_workflow_tool_1 = require("./tools/publish-workflow.tool");
const search_folders_tool_1 = require("./tools/search-folders.tool");
const search_projects_tool_1 = require("./tools/search-projects.tool");
const search_workflows_tool_1 = require("./tools/search-workflows.tool");
const unpublish_workflow_tool_1 = require("./tools/unpublish-workflow.tool");
const create_workflow_from_code_tool_1 = require("./tools/workflow-builder/create-workflow-from-code.tool");
const delete_workflow_tool_1 = require("./tools/workflow-builder/delete-workflow.tool");
const update_workflow_tool_1 = require("./tools/workflow-builder/update-workflow.tool");
const get_suggested_workflow_nodes_tool_1 = require("./tools/workflow-builder/get-suggested-workflow-nodes.tool");
const get_workflow_node_types_tool_1 = require("./tools/workflow-builder/get-workflow-node-types.tool");
const get_workflow_sdk_reference_tool_1 = require("./tools/workflow-builder/get-workflow-sdk-reference.tool");
const mcp_instructions_1 = require("./tools/workflow-builder/mcp-instructions");
const search_workflow_nodes_tool_1 = require("./tools/workflow-builder/search-workflow-nodes.tool");
const sdk_reference_content_1 = require("./tools/workflow-builder/sdk-reference-content");
const validate_workflow_code_tool_1 = require("./tools/workflow-builder/validate-workflow-code.tool");
const node_catalog_1 = require("../../node-catalog");
const active_executions_1 = require("../../active-executions");
const collaboration_service_1 = require("../../collaboration/collaboration.service");
const credentials_service_1 = require("../../credentials/credentials.service");
const data_table_proxy_service_1 = require("../../modules/data-table/data-table-proxy.service");
const node_types_1 = require("../../node-types");
const project_service_ee_1 = require("../../services/project.service.ee");
const role_service_1 = require("../../services/role.service");
const url_service_1 = require("../../services/url.service");
const telemetry_1 = require("../../telemetry");
const workflow_runner_1 = require("../../workflow-runner");
const workflow_creation_service_1 = require("../../workflows/workflow-creation.service");
const workflow_finder_service_1 = require("../../workflows/workflow-finder.service");
const workflow_service_1 = require("../../workflows/workflow.service");
const prepare_workflow_pin_data_tool_1 = require("./tools/prepare-workflow-pin-data.tool");
const test_workflow_tool_1 = require("./tools/test-workflow.tool");
const execution_service_1 = require("../../executions/execution.service");
let McpService = class McpService {
constructor(logger, executionsConfig, _instanceSettings, workflowFinderService, workflowService, urlService, credentialsService, activeExecutions, globalConfig, telemetry, workflowRunner, roleService, projectService, nodeCatalogService, workflowCreationService, nodeTypes, projectRepository, folderRepository, sharedWorkflowRepository, executionRepository, executionService, dataTableProxyService, collaborationService) {
this.logger = logger;
this.executionsConfig = executionsConfig;
this.workflowFinderService = workflowFinderService;
this.workflowService = workflowService;
this.urlService = urlService;
this.credentialsService = credentialsService;
this.activeExecutions = activeExecutions;
this.globalConfig = globalConfig;
this.telemetry = telemetry;
this.workflowRunner = workflowRunner;
this.roleService = roleService;
this.projectService = projectService;
this.nodeCatalogService = nodeCatalogService;
this.workflowCreationService = workflowCreationService;
this.nodeTypes = nodeTypes;
this.projectRepository = projectRepository;
this.folderRepository = folderRepository;
this.sharedWorkflowRepository = sharedWorkflowRepository;
this.executionRepository = executionRepository;
this.executionService = executionService;
this.dataTableProxyService = dataTableProxyService;
this.collaborationService = collaborationService;
this.pendingResponses = new Map();
}
async getServer(user) {
const { McpServer } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/mcp.js')));
const builderEnabled = this.globalConfig.endpoints.mcpBuilderEnabled;
const server = new McpServer({
name: 'n8n MCP Server',
version: builderEnabled ? '1.1.0' : '1.0.0',
}, {
instructions: (0, mcp_instructions_1.getMcpInstructions)(builderEnabled),
});
const workflowSearchTool = (0, search_workflows_tool_1.createSearchWorkflowsTool)(user, this.workflowService, this.telemetry);
server.registerTool(workflowSearchTool.name, workflowSearchTool.config, workflowSearchTool.handler);
const executeWorkflowTool = (0, execute_workflow_tool_1.createExecuteWorkflowTool)(user, this.workflowFinderService, this.workflowRunner, this.telemetry, this);
server.registerTool(executeWorkflowTool.name, executeWorkflowTool.config, executeWorkflowTool.handler);
const getExecutionTool = (0, get_execution_tool_1.createGetExecutionTool)(user, this.executionRepository, this.workflowFinderService, this.telemetry);
server.registerTool(getExecutionTool.name, getExecutionTool.config, getExecutionTool.handler);
const searchExecutionsTool = (0, search_executions_tool_1.createSearchExecutionsTool)(user, this.executionService, this.workflowFinderService, this.telemetry);
server.registerTool(searchExecutionsTool.name, searchExecutionsTool.config, searchExecutionsTool.handler);
const workflowDetailsTool = (0, get_workflow_details_tool_1.createWorkflowDetailsTool)(user, this.urlService.getWebhookBaseUrl(), this.workflowFinderService, this.credentialsService, {
webhook: this.globalConfig.endpoints.webhook,
webhookTest: this.globalConfig.endpoints.webhookTest,
}, this.telemetry, this.roleService, this.projectService);
server.registerTool(workflowDetailsTool.name, workflowDetailsTool.config, workflowDetailsTool.handler);
const publishWorkflowTool = (0, publish_workflow_tool_1.createPublishWorkflowTool)(user, this.workflowFinderService, this.workflowService, this.telemetry, this.collaborationService);
server.registerTool(publishWorkflowTool.name, publishWorkflowTool.config, publishWorkflowTool.handler);
const unpublishWorkflowTool = (0, unpublish_workflow_tool_1.createUnpublishWorkflowTool)(user, this.workflowFinderService, this.workflowService, this.telemetry, this.collaborationService);
server.registerTool(unpublishWorkflowTool.name, unpublishWorkflowTool.config, unpublishWorkflowTool.handler);
const prepareTestPinDataTool = (0, prepare_workflow_pin_data_tool_1.createPrepareTestPinDataTool)(user, this.workflowFinderService, this.executionService, this.nodeTypes, this.telemetry, this.logger);
server.registerTool(prepareTestPinDataTool.name, prepareTestPinDataTool.config, prepareTestPinDataTool.handler);
const testWorkflowTool = (0, test_workflow_tool_1.createTestWorkflowTool)(user, this.workflowFinderService, this.activeExecutions, this.workflowRunner, this.nodeTypes, this.telemetry, this);
server.registerTool(testWorkflowTool.name, testWorkflowTool.config, testWorkflowTool.handler);
const listCredentialsTool = (0, list_credentials_tool_1.createListCredentialsTool)(user, this.credentialsService, this.telemetry);
server.registerTool(listCredentialsTool.name, listCredentialsTool.config, listCredentialsTool.handler);
const dataTableOps = this.dataTableProxyService.makeDataTableOperationsForUser(user);
const searchDataTablesTool = (0, data_table_1.createSearchDataTablesTool)(user, dataTableOps, this.telemetry);
server.registerTool(searchDataTablesTool.name, searchDataTablesTool.config, searchDataTablesTool.handler);
const createDataTableTool = (0, data_table_1.createCreateDataTableTool)(user, dataTableOps, this.telemetry);
server.registerTool(createDataTableTool.name, createDataTableTool.config, createDataTableTool.handler);
const renameDataTableTool = (0, data_table_1.createRenameDataTableTool)(user, dataTableOps, this.telemetry);
server.registerTool(renameDataTableTool.name, renameDataTableTool.config, renameDataTableTool.handler);
const addDataTableColumnTool = (0, data_table_1.createAddDataTableColumnTool)(user, dataTableOps, this.telemetry);
server.registerTool(addDataTableColumnTool.name, addDataTableColumnTool.config, addDataTableColumnTool.handler);
const deleteDataTableColumnTool = (0, data_table_1.createDeleteDataTableColumnTool)(user, dataTableOps, this.telemetry);
server.registerTool(deleteDataTableColumnTool.name, deleteDataTableColumnTool.config, deleteDataTableColumnTool.handler);
const renameDataTableColumnTool = (0, data_table_1.createRenameDataTableColumnTool)(user, dataTableOps, this.telemetry);
server.registerTool(renameDataTableColumnTool.name, renameDataTableColumnTool.config, renameDataTableColumnTool.handler);
const addDataTableRowsTool = (0, data_table_1.createAddDataTableRowsTool)(user, dataTableOps, this.telemetry);
server.registerTool(addDataTableRowsTool.name, addDataTableRowsTool.config, addDataTableRowsTool.handler);
if (builderEnabled) {
await this.registerBuilderTools(server, user);
}
return server;
}
async registerBuilderTools(server, user) {
await this.nodeCatalogService.initialize();
const searchNodesTool = (0, search_workflow_nodes_tool_1.createSearchWorkflowNodesTool)(user, this.nodeCatalogService, this.telemetry);
server.registerTool(searchNodesTool.name, searchNodesTool.config, searchNodesTool.handler);
const getNodeTypesTool = (0, get_workflow_node_types_tool_1.createGetWorkflowNodeTypesTool)(user, this.nodeCatalogService, this.telemetry);
server.registerTool(getNodeTypesTool.name, getNodeTypesTool.config, getNodeTypesTool.handler);
const suggestedNodesTool = (0, get_suggested_workflow_nodes_tool_1.createGetSuggestedWorkflowNodesTool)(user, this.nodeCatalogService, this.telemetry);
server.registerTool(suggestedNodesTool.name, suggestedNodesTool.config, suggestedNodesTool.handler);
const validateTool = (0, validate_workflow_code_tool_1.createValidateWorkflowCodeTool)(user, this.telemetry);
server.registerTool(validateTool.name, validateTool.config, validateTool.handler);
const createTool = (0, create_workflow_from_code_tool_1.createCreateWorkflowFromCodeTool)(user, this.workflowCreationService, this.workflowFinderService, this.urlService, this.telemetry, this.nodeTypes, this.credentialsService, this.projectRepository);
server.registerTool(createTool.name, createTool.config, createTool.handler);
const searchProjectsTool = (0, search_projects_tool_1.createSearchProjectsTool)(user, this.projectRepository, this.telemetry);
server.registerTool(searchProjectsTool.name, searchProjectsTool.config, searchProjectsTool.handler);
const searchFoldersTool = (0, search_folders_tool_1.createSearchFoldersTool)(user, this.folderRepository, this.projectService, this.telemetry);
server.registerTool(searchFoldersTool.name, searchFoldersTool.config, searchFoldersTool.handler);
const archiveTool = (0, delete_workflow_tool_1.createArchiveWorkflowTool)(user, this.workflowFinderService, this.workflowService, this.telemetry, this.collaborationService);
server.registerTool(archiveTool.name, archiveTool.config, archiveTool.handler);
const updateTool = (0, update_workflow_tool_1.createUpdateWorkflowTool)(user, this.workflowFinderService, this.workflowService, this.urlService, this.telemetry, this.nodeTypes, this.credentialsService, this.sharedWorkflowRepository, this.collaborationService);
server.registerTool(updateTool.name, updateTool.config, updateTool.handler);
server.resource('workflow-sdk-reference', 'n8n://workflow-sdk/reference', {
description: 'Required n8n Workflow SDK reference for building workflows from code. Read this before writing workflow code.',
}, async () => ({
contents: [
{
uri: 'n8n://workflow-sdk/reference',
mimeType: 'text/plain',
text: (0, sdk_reference_content_1.getSdkReferenceContent)(),
},
],
}));
const sdkRefTool = (0, get_workflow_sdk_reference_tool_1.createGetWorkflowSdkReferenceTool)(user, this.telemetry);
server.registerTool(sdkRefTool.name, sdkRefTool.config, sdkRefTool.handler);
}
get isQueueMode() {
return this.executionsConfig.mode === 'queue';
}
createPendingResponse(executionId) {
const deferred = (0, n8n_workflow_1.createDeferredPromise)();
this.pendingResponses.set(executionId, {
executionId,
promise: deferred,
createdAt: new Date(),
});
return deferred;
}
handleWorkerResponse(executionId, runData) {
const pending = this.pendingResponses.get(executionId);
if (!pending) {
this.logger.warn('Received MCP response for unknown execution', { executionId });
return;
}
pending.promise.resolve(runData);
this.pendingResponses.delete(executionId);
}
removePendingResponse(executionId) {
if (this.pendingResponses.has(executionId)) {
this.pendingResponses.delete(executionId);
this.logger.debug('Removed pending MCP response', { executionId });
}
}
cancelPendingExecution(executionId, reason = 'MCP execution cancelled') {
const pending = this.pendingResponses.get(executionId);
if (!pending) {
this.logger.debug('No pending MCP execution to cancel', { executionId });
return;
}
this.logger.debug('Cancelling pending MCP execution', { executionId, reason });
const cancellationError = new n8n_workflow_1.ManualExecutionCancelledError(executionId);
pending.promise.reject(cancellationError);
this.pendingResponses.delete(executionId);
if (this.activeExecutions.has(executionId)) {
this.activeExecutions.stopExecution(executionId, cancellationError);
}
}
cancelAllPendingExecutions(reason = 'MCP service shutdown') {
const executionIds = Array.from(this.pendingResponses.keys());
this.logger.debug('Cancelling all pending MCP executions', {
count: executionIds.length,
reason,
});
for (const executionId of executionIds) {
this.cancelPendingExecution(executionId, reason);
}
}
get pendingExecutionCount() {
return this.pendingResponses.size;
}
};
exports.McpService = McpService;
exports.McpService = McpService = __decorate([
(0, di_1.Service)(),
__metadata("design:paramtypes", [backend_common_1.Logger,
config_1.ExecutionsConfig,
n8n_core_1.InstanceSettings,
workflow_finder_service_1.WorkflowFinderService,
workflow_service_1.WorkflowService,
url_service_1.UrlService,
credentials_service_1.CredentialsService,
active_executions_1.ActiveExecutions,
config_1.GlobalConfig,
telemetry_1.Telemetry,
workflow_runner_1.WorkflowRunner,
role_service_1.RoleService,
project_service_ee_1.ProjectService,
node_catalog_1.NodeCatalogService,
workflow_creation_service_1.WorkflowCreationService,
node_types_1.NodeTypes,
db_1.ProjectRepository,
db_1.FolderRepository,
db_1.SharedWorkflowRepository,
db_1.ExecutionRepository,
execution_service_1.ExecutionService,
data_table_proxy_service_1.DataTableProxyService,
collaboration_service_1.CollaborationService])
], McpService);
//# sourceMappingURL=mcp.service.js.map