n8n - 💡(How to fix) Fix MCP Server Trigger discards incoming request headers, unlike Webhook Trigger

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

I am filing this as a bug because the MCP Server Trigger receives the HTTP request, but drops request metadata before workflow execution. This prevents valid MCP server use cases that require caller identity, and differs from the Webhook node behavior where request metadata is available.

Code Example

x-user-id: user_123
x-tenant-id: tenant_abc

---

{
  "headers": {
    "x-user-id": "user_123",
    "x-tenant-id": "tenant_abc"
  },
  "query": {},
  "mcp": {
    "sessionId": "...",
    "messageId": "...",
    "toolName": "..."
  }
}
RAW_BUFFERClick to expand / collapse

Bug Description

The MCP Server Trigger receives the underlying HTTP request, but custom incoming request headers are not exposed to the workflow, connected tools, or subworkflows.

I am filing this as a bug because the MCP Server Trigger receives the HTTP request, but drops request metadata before workflow execution. This prevents valid MCP server use cases that require caller identity, and differs from the Webhook node behavior where request metadata is available.

This is a problem for multi-user MCP clients where user identity is passed by the client or gateway as a request header, for example:

  • x-user-id
  • x-tenant-id
  • x-organization-id
  • x-session-id

The MCP request itself succeeds and the tool is executed, but the workflow has no way to read those incoming headers. Only the MCP tool arguments are available.

This prevents production MCP use cases such as:

  • per-user routing
  • tenant-aware workflows
  • user-level authorization
  • audit logging
  • billing or usage attribution
  • policy enforcement based on the calling user

This is especially problematic because the regular Webhook node exposes request metadata such as headers, query, and body, while the MCP Server Trigger does not expose equivalent request context.

Related closed issue: #16989

I originally commented there, but the issue is closed/stale and this is still reproducible, so I am opening a fresh issue with updated technical details.

To Reproduce

  1. Create a workflow with an MCP Server Trigger.
  2. Connect a simple tool to it, for example an HTTP Request Tool or any tool that returns the input it receives.
  3. Connect to the MCP Server Trigger from an MCP client using Streamable HTTP.
  4. Send a tool call with a custom HTTP header, for example:
x-user-id: user_123
x-tenant-id: tenant_abc
  1. The MCP tool call executes successfully.
  2. Inspect the workflow execution data and the connected tool/subworkflow input.

Actual result:

The MCP tool arguments are available, but the incoming request headers are not available anywhere in the workflow execution data.

For example, x-user-id and x-tenant-id cannot be read by expressions, tools, subworkflows, or downstream nodes.

Expected behavior

The MCP Server Trigger should expose incoming request metadata to the workflow, similar to the regular Webhook node.

At minimum, the workflow should be able to access request metadata like this:

{
  "headers": {
    "x-user-id": "user_123",
    "x-tenant-id": "tenant_abc"
  },
  "query": {},
  "mcp": {
    "sessionId": "...",
    "messageId": "...",
    "toolName": "..."
  }
}

The exact shape is flexible, but request headers need to be available to the workflow in some supported way.

Possible implementation options:

  1. Include request metadata in the workflowData returned by the MCP Server Trigger when a tool call occurs.
  2. Add an MCP Trigger option such as Expose Request Metadata.
  3. Pass request metadata into the tool execution context so connected workflow tools/subworkflows can access it.
  4. Expose selected headers only, for example through a node parameter allowlist, to avoid leaking sensitive headers by default.

Actual behavior

Only the MCP tool arguments are available.

Custom request headers such as x-user-id are discarded before workflow execution and cannot be accessed by the workflow.

Current code path observation from master:

  • McpTrigger.node.ts calls context.getRequestObject() and therefore has access to the request object.
  • For tool calls, the returned workflowData contains MCP tool call metadata such as mcpToolCall and mcpMessageId, but not req.headers.
  • McpServer.getSessionId() reads sessionId from the query string or mcp-session-id header, but custom headers are not propagated.
  • Tool execution ultimately receives only request.params.arguments.

This means the header exists at the HTTP layer but is not forwarded into workflow execution.

Debug Info

This is reproducible on current n8n versions using the MCP Server Trigger.

Relevant component:

  • Node: @n8n/n8n-nodes-langchain.mcpTrigger
  • Transport: Streamable HTTP
  • Use case: external chat/MCP client sends user identity in request headers

Code locations checked on current master:

  • packages/@n8n/nodes-langchain/nodes/mcp/McpTrigger/McpTrigger.node.ts
  • packages/@n8n/nodes-langchain/nodes/mcp/McpTrigger/McpServer.ts
  • packages/@n8n/nodes-langchain/nodes/mcp/McpTrigger/execution/DirectExecutionStrategy.ts

This appears to be a request metadata propagation issue, not a client issue. The client sends the header, the MCP request succeeds, but n8n does not expose the header to the workflow.

Minimal acceptance criteria:

A workflow triggered through MCP should be able to read a custom inbound header such as x-user-id during tool execution, without requiring an external reverse proxy to rewrite headers into MCP tool arguments.

Operating System

Ubuntu 24 / Docker

n8n Version

2.21.5

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The MCP Server Trigger should expose incoming request metadata to the workflow, similar to the regular Webhook node.

At minimum, the workflow should be able to access request metadata like this:

{
  "headers": {
    "x-user-id": "user_123",
    "x-tenant-id": "tenant_abc"
  },
  "query": {},
  "mcp": {
    "sessionId": "...",
    "messageId": "...",
    "toolName": "..."
  }
}

The exact shape is flexible, but request headers need to be available to the workflow in some supported way.

Possible implementation options:

  1. Include request metadata in the workflowData returned by the MCP Server Trigger when a tool call occurs.
  2. Add an MCP Trigger option such as Expose Request Metadata.
  3. Pass request metadata into the tool execution context so connected workflow tools/subworkflows can access it.
  4. Expose selected headers only, for example through a node parameter allowlist, to avoid leaking sensitive headers by default.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

n8n - 💡(How to fix) Fix MCP Server Trigger discards incoming request headers, unlike Webhook Trigger