Skip to main content
Header forwarding passes specific headers from agent requests through to MCP servers. Use for distributed tracing, tenant context, or custom metadata that needs to reach the upstream server. You can also rename headers inline using object entries, so client-side header names can differ from what the upstream server expects.

When to Use

Your agent includes headers with context that the MCP server needs. Maybe a trace ID for distributed tracing. Maybe a tenant ID for multi-tenant servers. Maybe custom metadata your server expects. Without header forwarding, these headers stop at Portkey. With it, they pass through to the MCP server. Common scenarios:
  • Distributed tracing. Forward x-request-id, x-trace-id, x-correlation-id to correlate logs across services.
  • Multi-tenancy. Forward x-tenant-id, x-org-id for tenant-scoped operations.
  • User context. Forward x-user-id, x-user-role for upstream authorization.
  • Custom metadata. Forward application-specific headers your MCP server expects.

Configuration

Configure forward_headers when adding or editing an MCP server in the MCP Registry.

Shorthand (string array)

Forward only the headers you specify. No renaming support in this form:
{
  "forward_headers": ["x-request-id", "x-trace-id", "x-tenant-id"]
}
Other headers from the agent request are dropped.

Allowlist mode

The same behavior with explicit configuration. Entries in the headers array can be:
  • A string — forwards the header as-is.
  • An object { "from": "<client_header>", "to": "<upstream_header>" } — forwards the header with its name changed.
{
  "forward_headers": {
    "mode": "allowlist",
    "headers": [
      "x-trace-id",
      { "from": "x-tenant-id", "to": "X-Organization-Id" },
      { "from": "x-env", "to": "X-Deploy-Environment" }
    ]
  }
}
In this example, x-trace-id is forwarded as-is, x-tenant-id arrives at the upstream as X-Organization-Id, and x-env arrives as X-Deploy-Environment.

All-except mode

Forward everything except headers you exclude. String entries are excluded; object entries rename forwarded headers:
{
  "forward_headers": {
    "mode": "all-except",
    "headers": [
      "host",
      "connection",
      { "from": "x-tenant-id", "to": "X-Org-Id" }
    ]
  }
}
Here, host and connection are excluded. All other headers are forwarded. Additionally, x-tenant-id is renamed to X-Org-Id before reaching the upstream server.
Use all-except mode carefully. It forwards more headers than you might expect, which could leak information or cause conflicts. Prefer explicit allowlists when possible.

Security

Protected Headers

These headers are never forwarded regardless of your configuration:
HeaderReason
cookieSession data should not leak
set-cookieResponse header, not request
x-api-keyCould leak API keys
x-portkey-api-keyPortkey authentication
api-keyCould leak API keys
apikeyCould leak API keys
x-auth-tokenCould leak tokens
x-access-tokenCould leak tokens
x-user-claimsIdentity spoofing prevention
x-user-jwtIdentity spoofing prevention
In all-except mode, these are automatically added to the blocklist. You cannot override this behavior.

Header mapping validation

When using object entries for header renaming, both the source (from) and target (to) header names are validated against the protected headers blocklist. If either name is protected, the mapping is rejected and the header is not forwarded. Header matching on the source name is case-insensitive.
// This mapping is rejected — x-api-key is protected
{ "from": "x-api-key", "to": "X-Custom-Key" }

// This mapping is also rejected — the target is protected
{ "from": "x-custom", "to": "x-auth-token" }

Identity Headers Are Protected

If you use Identity Forwarding, identity headers are also protected:
  • X-User-Claims
  • X-User-JWT
This prevents clients from spoofing user identity by sending fake identity headers.

Header Priority

When multiple sources provide headers, they merge in this order (later values override earlier ones):
PrioritySourceDescription
1 (lowest)Forwarded headersHeaders from the agent request
2Auth headersheaders configured on the MCP server
3Passthrough headerspassthrough_headers configured on the server
4 (highest)Identity headersHeaders from Identity Forwarding
Why this order matters:
  • Authentication headers configured on the server cannot be overridden by agents
  • Static passthrough headers take precedence over agent headers
  • Identity headers always win—agents cannot spoof user identity
Example:
Agent sends:        X-Custom: agent-value
Server config:      X-Custom: server-value (in passthrough_headers)
Result: MCP server receives X-Custom: server-value (server config wins).

Agent Configuration

Include headers in your MCP client configuration:
{
  "mcpServers": {
    "linear": {
      "url": "https://mcp.portkey.ai/linear/mcp",
      "headers": {
        "x-portkey-api-key": "pk_xxx",
        "x-request-id": "req-12345",
        "x-tenant-id": "tenant-abc"
      }
    }
  }
}
Or set headers per request in code:
import uuid

headers = {
    "x-portkey-api-key": "pk_xxx",
    "x-request-id": str(uuid.uuid4()),
    "x-trace-id": current_trace_id,
    "x-tenant-id": "tenant-abc"
}

async with streamablehttp_client(url, headers=headers) as (read, write, _):
    # x-request-id, x-trace-id, and x-tenant-id forwarded to MCP server
    ...

Example: Distributed Tracing

You want to correlate MCP requests with your application’s traces. Server configuration:
{
  "forward_headers": ["x-request-id", "x-trace-id", "traceparent"]
}
Agent request:
{
  "headers": {
    "x-portkey-api-key": "pk_xxx",
    "x-request-id": "req-abc123",
    "x-trace-id": "trace-xyz789",
    "traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"
  }
}
MCP server receives:
x-request-id: req-abc123
x-trace-id: trace-xyz789
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
Now your MCP server logs include the same trace IDs as your application.

Example: Multi-Tenant Server

Your internal MCP server needs tenant context to scope data access. Server configuration:
{
  "forward_headers": ["x-tenant-id", "x-org-id"]
}
Agent request:
{
  "headers": {
    "x-portkey-api-key": "pk_xxx",
    "x-tenant-id": "tenant-acme",
    "x-org-id": "org-12345"
  }
}
MCP server receives:
x-tenant-id: tenant-acme
x-org-id: org-12345
Your server uses these headers to filter data to the correct tenant.

Example: Header renaming

Your agent sends x-tenant-id but your upstream MCP server expects X-Organization-Id. Server configuration:
{
  "forward_headers": {
    "mode": "allowlist",
    "headers": [
      "x-request-id",
      { "from": "x-tenant-id", "to": "X-Organization-Id" }
    ]
  }
}
Agent request:
{
  "headers": {
    "x-portkey-api-key": "pk_xxx",
    "x-request-id": "req-abc123",
    "x-tenant-id": "tenant-acme"
  }
}
MCP server receives:
x-request-id: req-abc123
X-Organization-Id: tenant-acme
The x-tenant-id header is renamed to X-Organization-Id before reaching the upstream server.

Combining with Identity Forwarding

Header forwarding and identity forwarding serve different purposes:
FeaturePurposeSource
Header ForwardingPass metadata (traces, tenants)Agent request
Identity ForwardingPass authenticated user claimsPortkey (from validated token)
Use both together:
{
  "forward_headers": ["x-request-id", "x-trace-id"],
  "user_identity_forwarding": {
    "method": "claims_header",
    "include_claims": ["sub", "email", "workspace_id"]
  }
}
The MCP server receives:
  • x-request-id and x-trace-id from the agent (for tracing)
  • X-User-Claims from Portkey (for user identity)

TopicDescription
Identity ForwardingPass authenticated user claims to MCP servers
Custom AuthConfigure static headers for MCP servers
Last modified on April 17, 2026