feat(MCP Server Trigger Node): Cleanup MCP server management, use sanitized trigger node's name as name for the MCP server (#15751)

This commit is contained in:
Yiorgis Gozadinos
2025-05-29 15:07:17 +02:00
committed by GitHub
parent 1daf0ff169
commit 07a636eed6
4 changed files with 142 additions and 88 deletions

View File

@@ -3,11 +3,10 @@ import { validateWebhookAuthentication } from 'n8n-nodes-base/dist/nodes/Webhook
import type { INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
import { NodeConnectionTypes, Node } from 'n8n-workflow';
import { getConnectedTools } from '@utils/helpers';
import { getConnectedTools, nodeNameToToolName } from '@utils/helpers';
import type { CompressionResponse } from './FlushingSSEServerTransport';
import { McpServerSingleton } from './McpServer';
import type { McpServer } from './McpServer';
import { McpServerManager } from './McpServer';
const MCP_SSE_SETUP_PATH = 'sse';
const MCP_SSE_MESSAGES_PATH = 'messages';
@@ -21,7 +20,7 @@ export class McpTrigger extends Node {
dark: 'file:../mcp.dark.svg',
},
group: ['trigger'],
version: 1,
version: [1, 1.1],
description: 'Expose n8n tools as an MCP Server endpoint',
activationMessage: 'You can now connect your MCP Clients to the SSE URL.',
defaults: {
@@ -143,8 +142,11 @@ export class McpTrigger extends Node {
}
throw error;
}
const node = context.getNode();
// Get a url/tool friendly name for the server, based on the node name
const serverName = node.typeVersion > 1 ? nodeNameToToolName(node) : 'n8n-mcp-server';
const mcpServer: McpServer = McpServerSingleton.instance(context.logger);
const mcpServerManager: McpServerManager = McpServerManager.instance(context.logger);
if (webhookName === 'setup') {
// Sets up the transport and opens the long-lived connection. This resp
@@ -153,7 +155,7 @@ export class McpTrigger extends Node {
new RegExp(`/${MCP_SSE_SETUP_PATH}$`),
`/${MCP_SSE_MESSAGES_PATH}`,
);
await mcpServer.connectTransport(postUrl, resp);
await mcpServerManager.createServerAndTransport(serverName, postUrl, resp);
return { noWebhookResponse: true };
} else if (webhookName === 'default') {
@@ -162,7 +164,7 @@ export class McpTrigger extends Node {
// 'setup' call
const connectedTools = await getConnectedTools(context, true);
const wasToolCall = await mcpServer.handlePostMessage(req, resp, connectedTools);
const wasToolCall = await mcpServerManager.handlePostMessage(req, resp, connectedTools);
if (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };
return { noWebhookResponse: true };