mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 19:32:15 +00:00
feat(MCP Server Trigger Node): Support for Streamable HTTP transport in MCP Server (#15833)
This commit is contained in:
committed by
GitHub
parent
eff0571f42
commit
8d6e796b92
@@ -5,7 +5,7 @@ import { NodeConnectionTypes, Node } from 'n8n-workflow';
|
||||
|
||||
import { getConnectedTools, nodeNameToToolName } from '@utils/helpers';
|
||||
|
||||
import type { CompressionResponse } from './FlushingSSEServerTransport';
|
||||
import type { CompressionResponse } from './FlushingTransport';
|
||||
import { McpServerManager } from './McpServer';
|
||||
|
||||
const MCP_SSE_SETUP_PATH = 'sse';
|
||||
@@ -20,9 +20,10 @@ export class McpTrigger extends Node {
|
||||
dark: 'file:../mcp.dark.svg',
|
||||
},
|
||||
group: ['trigger'],
|
||||
version: [1, 1.1],
|
||||
version: [1, 1.1, 2],
|
||||
description: 'Expose n8n tools as an MCP Server endpoint',
|
||||
activationMessage: 'You can now connect your MCP Clients to the SSE URL.',
|
||||
activationMessage:
|
||||
'You can now connect your MCP Clients to the URL, using SSE or Streamable HTTP transports.',
|
||||
defaults: {
|
||||
name: 'MCP Server Trigger',
|
||||
},
|
||||
@@ -109,7 +110,7 @@ export class McpTrigger extends Node {
|
||||
httpMethod: 'GET',
|
||||
responseMode: 'onReceived',
|
||||
isFullPath: true,
|
||||
path: `={{$parameter["path"]}}/${MCP_SSE_SETUP_PATH}`,
|
||||
path: `={{$parameter["path"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_SETUP_PATH}' : ''}}`,
|
||||
nodeType: 'mcp',
|
||||
ndvHideMethod: true,
|
||||
ndvHideUrl: false,
|
||||
@@ -119,7 +120,7 @@ export class McpTrigger extends Node {
|
||||
httpMethod: 'POST',
|
||||
responseMode: 'onReceived',
|
||||
isFullPath: true,
|
||||
path: `={{$parameter["path"]}}/${MCP_SSE_MESSAGES_PATH}`,
|
||||
path: `={{$parameter["path"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_MESSAGES_PATH}' : ''}}`,
|
||||
nodeType: 'mcp',
|
||||
ndvHideMethod: true,
|
||||
ndvHideUrl: true,
|
||||
@@ -151,22 +152,32 @@ export class McpTrigger extends Node {
|
||||
if (webhookName === 'setup') {
|
||||
// Sets up the transport and opens the long-lived connection. This resp
|
||||
// will stay streaming, and is the channel that sends the events
|
||||
const postUrl = req.path.replace(
|
||||
new RegExp(`/${MCP_SSE_SETUP_PATH}$`),
|
||||
`/${MCP_SSE_MESSAGES_PATH}`,
|
||||
);
|
||||
await mcpServerManager.createServerAndTransport(serverName, postUrl, resp);
|
||||
|
||||
// Prior to version 2.0, we use different paths for the setup and messages.
|
||||
const postUrl =
|
||||
node.typeVersion < 2
|
||||
? req.path.replace(new RegExp(`/${MCP_SSE_SETUP_PATH}$`), `/${MCP_SSE_MESSAGES_PATH}`)
|
||||
: req.path;
|
||||
await mcpServerManager.createServerWithSSETransport(serverName, postUrl, resp);
|
||||
|
||||
return { noWebhookResponse: true };
|
||||
} else if (webhookName === 'default') {
|
||||
// This is the command-channel, and is actually executing the tools. This
|
||||
// sends the response back through the long-lived connection setup in the
|
||||
// 'setup' call
|
||||
const connectedTools = await getConnectedTools(context, true);
|
||||
// Here we handle POST requests. These can be either
|
||||
// 1) Client calls in an established session using the SSE transport, or
|
||||
// 2) Client calls in an established session using the StreamableHTTPServerTransport
|
||||
// 3) Session setup requests using the StreamableHTTPServerTransport
|
||||
|
||||
const wasToolCall = await mcpServerManager.handlePostMessage(req, resp, connectedTools);
|
||||
|
||||
if (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };
|
||||
// Check if there is a session and a transport is already established
|
||||
const sessionId = mcpServerManager.getSessionId(req);
|
||||
if (sessionId && mcpServerManager.getTransport(sessionId)) {
|
||||
const connectedTools = await getConnectedTools(context, true);
|
||||
const wasToolCall = await mcpServerManager.handlePostMessage(req, resp, connectedTools);
|
||||
if (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };
|
||||
} else {
|
||||
// If no session is established, this is a setup request
|
||||
// for the StreamableHTTPServerTransport, so we create a new transport
|
||||
await mcpServerManager.createServerWithStreamableHTTPTransport(serverName, resp, req);
|
||||
}
|
||||
return { noWebhookResponse: true };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user