#15496·langflow

lfx-mcp cannot supply global variables: LangflowClient drops X-LANGFLOW-GLOBAL-VAR-* from env

Author: Harshit0105Created Oct 1, 2026Updated Oct 1, 2026
Labelsbugjira

Bug Description

Passing global variables per request via X-LANGFLOW-GLOBAL-VAR-* headers is a documented feature of /api/v1/run. It is unreachable through lfx-mcp.

lfx-mcp is a stdio MCP server, so the only configuration channel a client has is StdioServerParameters.env — there is no headers field for a subprocess. But LangflowClient in src/lfx/src/lfx/mcp/client.py reads just two environment variables and builds a closed header set:

python
self.server_url = (server_url or os.environ.get("LANGFLOW_SERVER_URL", "http://localhost:7860")).rstrip("/")
self.api_key = api_key or os.environ.get("LANGFLOW_API_KEY")

def _headers(self) -> dict[str, str]:
    headers = {"Content-Type": "application/json"}
    if self.access_token:
        headers["Authorization"] = f"Bearer {self.access_token}"
    if self.api_key:
        headers["x-api-key"] = self.api_key
    return headers

So an X-LANGFLOW-GLOBAL-VAR-* entry in a client config's env sits unread in the process environment. lfx-mcp runs flows through POST /api/v1/run/{flow_id}, and that request carries no forwarded variables.

The result is a silent fallback rather than an error: the flow resolves the variable from the stored global variables instead of the per-request value, so a caller intending to run one flow with a different tenant, region or environment per call gets the stored value every time, with nothing in the logs to say an override was dropped.

This affects any per-request variable — a tenant or workspace id, a target environment, a per-caller endpoint. There is currently no way to supply one through lfx-mcp.

Scope note, since this is easy to confuse with the in-process path: the project MCP server (/api/v1/mcp/project/{id}/sse) handles these headers correctly via extract_global_variables_from_headers, and connecting through mcp-proxy --headers works as documented. This report is only about lfx-mcp, which never reaches that code — it is an MCP server that is itself an HTTP client of Langflow.

Not a regression: _headers() has never forwarded these. Confirmed unchanged on main as of today.

Reproduction

Steps to reproduce the behavior:

  1. Create a global variable named ENVIRONMENT with the stored value production, and build a flow that uses it — e.g. an API Request component sending {"X-Env": "ENVIRONMENT"}, or a custom component calling await self.get_variable("ENVIRONMENT").

  2. Confirm the per-request override works over plain HTTP, so the flow itself is not in question:

bash
curl -X POST http://localhost:7860/api/v1/run/<flow_id> \
  -H "x-api-key: sk-..." \
  -H "X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT: staging" \
  -H "Content-Type: application/json" \
  -d '{"input_value": "hi"}'

The flow sees staging — the per-request value wins over the stored production.

  1. Configure lfx-mcp in an MCP client, passing the same variable through env — the only channel a stdio server has:
json
{
  "mcpServers": {
    "langflow": {
      "command": "uvx",
      "args": ["--from", "lfx", "lfx-mcp"],
      "env": {
        "LANGFLOW_SERVER_URL": "http://localhost:7860",
        "LANGFLOW_API_KEY": "sk-...",
        "X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT": "staging"
      }
    }
  }
}
  1. Run the same flow through the MCP tool. The flow sees production — the stored value — not staging. No warning is emitted.

Minimal confirmation without a flow — the headers that actually leave the process:

python
import os
from lfx.mcp.client import LangflowClient

os.environ["X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT"] = "staging"
os.environ["LANGFLOW_API_KEY"] = "sk-test"

print(LangflowClient(server_url="http://localhost:7860")._headers())

Actual output:

{'Content-Type': 'application/json', 'x-api-key': 'sk-test'}

X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT is absent, so step 3's value never reaches the server.

Expected behavior

A flow run through lfx-mcp should resolve global variables the same way the equivalent direct call does — step 2 and step 4 of the reproduction should agree.

Concretely, LangflowClient._headers() should forward every X-LANGFLOW-GLOBAL-VAR-* environment variable as the header of the same name, leaving the existing auth headers untouched:

{'Content-Type': 'application/json', 'x-api-key': 'sk-test', 'X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT': 'staging'}

The prefix is a sufficient allowlist — nothing else in the environment (LANGFLOW_API_KEY, UV_INDEX_URL, cloud credentials) should be forwarded. Empty values should be skipped, so an unset placeholder in a client config does not send a blank value downstream.

This would make the documented per-request global variable feature usable from lfx-mcp, which is otherwise the only Langflow entrypoint where it cannot be used at all.

Happy to open a PR; I have the fix and tests ready.

Who can help?

@ogabrielluiz

Operating System

macOS 26.3.1

Langflow Version

lfx 1.12.4 (also present on main)

Python Version

3.11

Screenshot

No response

Flow File

N/A — not flow-specific; reproduces with any flow referencing a global variable.