# How to Configure Custom Headers for MCP Server Authentication in Dify Plugins

> Learn to configure custom headers for MCP server authentication in Dify plugins. Easily attach headers to HTTP requests for secure authorization with junjiem/dify-plugin-agent-mcp_sse.

- Repository: [Junjie.M/dify-plugin-agent-mcp_sse](https://github.com/junjiem/dify-plugin-agent-mcp_sse)
- Tags: how-to-guide
- Published: 2026-03-05

---

**The MCP client classes in the `junjiem/dify-plugin-agent-mcp_sse` repository accept a `headers` dictionary that is automatically attached to every HTTP request sent to an MCP server, enabling authentication via standard HTTP headers.**

The `junjiem/dify-plugin-agent-mcp_sse` plugin provides Dify agents with the ability to connect to MCP (Model Context Protocol) servers using either SSE or Streamable HTTP transports. When these servers require authentication, you must configure custom headers to pass credentials such as Bearer tokens or API keys. This guide explains exactly how the header injection mechanism works and how to configure it properly.

## Understanding the MCP Client Architecture

The plugin implements two concrete client classes—`McpSseClient` and `McpStreamableHttpClient`—that handle the underlying HTTP communication. Both classes utilize the `httpx` library for HTTP requests and support custom header injection during initialization.

### Where Headers Are Read

The factory method `McpClients.init_client` (located in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py), lines 49‑62) extracts the optional `headers` field from each server's configuration dictionary. This factory inspects the `transport` type (`sse` or `streamable_http`) and instantiates the appropriate client class, forwarding the headers parameter directly to the constructor.

### How Headers Are Applied

Both client implementations pass the received headers dictionary to the underlying `httpx.Client` instance upon initialization:

- **SSE Client**: In [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) (lines 94‑95), the `McpSseClient` creates an `httpx.Client(headers=self._headers)`, ensuring all SSE connections include the custom headers.
- **Streamable HTTP Client**: In [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) (lines 41‑43), the `McpStreamableHttpClient` similarly initializes `httpx.Client(headers=self._headers)` for all RPC method calls.

Because the headers are bound to the `httpx.Client` instance, every subsequent operation—including `initialize`, `list_tools`, and `call_tool`—automatically includes the configured authentication headers.

## Configuring Custom Headers in Your Dify Plugin

You can supply custom headers through the Dify plugin configuration interface using either YAML syntax (for declarative setup) or Python dictionaries (for programmatic instantiation).

### YAML Configuration Example

When configuring the plugin through Dify's interface or a configuration file, structure your `mcpServers` entry with a `headers` sub-dictionary:

```yaml
mcpServers:
  my_secure_server:
    url: "https://mcp.example.com/api"
    transport: "sse"  # or "streamable_http"

    headers:
      Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
      X-API-Key: "sk_live_1234567890abcdef"
      X-Custom-Header: "custom-value"
    timeout: 60
    sse_read_timeout: 120  # Only required for SSE transport

```

The `headers` object supports any valid HTTP header name. Standard authentication patterns include `Authorization` for Bearer tokens or `X-API-Key` for service-specific credentials.

### Python Dictionary Configuration

If you are instantiating the `McpClients` class directly within Python code, pass the headers as part of the server configuration dictionary:

```python
from utils.mcp_client import McpClients

servers_config = {
    "my_secure_server": {
        "url": "https://mcp.example.com/api",
        "transport": "streamable_http",
        "headers": {
            "Authorization": "Bearer <your-access-token>",
            "X-Request-ID": "unique-trace-id-12345"
        },
        "timeout": 30,
    }
}

# Initialize clients with custom headers

clients = McpClients(servers_config, resources_as_tools=True)

```

Upon instantiation, the `McpClients` factory iterates through the configuration, detects the `headers` key, and passes it to the respective `McpSseClient` or `McpStreamableHttpClient` constructor.

## Supported Authentication Header Patterns

The implementation supports any headers compatible with Python's `httpx` library. Common authentication patterns include:

- **Bearer Token Authentication**: Use the `Authorization` header with a `Bearer` prefix for OAuth 2.0 or JWT-based authentication.
- **API Key Authentication**: Use custom headers such as `X-API-Key` or `api-key` depending on the MCP server's requirements.
- **Custom Corporate Headers**: Include headers like `X-Request-ID`, `X-Correlation-ID`, or `X-Client-Version` for tracing and audit purposes.

Since the headers are passed directly to the underlying HTTP client without transformation, you can implement any authentication scheme that relies on HTTP headers.

## Summary

- The `junjiem/dify-plugin-agent-mcp_sse` plugin supports custom headers through the `headers` configuration key in `mcpServers` definitions.
- The `McpClients.init_client` factory in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) (lines 49‑62) extracts headers and passes them to `McpSseClient` or `McpStreamableHttpClient`.
- Both client implementations bind the headers to an `httpx.Client` instance (lines 41‑43 for HTTP, lines 94‑95 for SSE), ensuring automatic inclusion in all RPC calls.
- Configuration supports standard authentication patterns including `Authorization` (Bearer tokens) and custom headers like `X-API-Key`.

## Frequently Asked Questions

### What file contains the header configuration logic for MCP clients?

The header configuration logic resides in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py). Specifically, the `McpClients.init_client` factory method (lines 49‑62) reads the `headers` field from the server configuration, and the client constructors (lines 41‑43 for `McpStreamableHttpClient` and lines 94‑95 for `McpSseClient`) apply these headers to the underlying `httpx.Client`.

### Can I use both SSE and Streamable HTTP transports with custom headers?

Yes. Both transport implementations support custom headers identically. When you specify `transport: "sse"` or `transport: "streamable_http"` in your configuration, the `init_client` factory instantiates the appropriate class (`McpSseClient` or `McpStreamableHttpClient`) and passes the `headers` dictionary to both. The headers are then bound to the HTTP client in both cases.

### How do I rotate or update authentication headers without restarting the Dify plugin?

The current implementation in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) initializes headers during client instantiation and binds them to the `httpx.Client`. To update headers dynamically, you would need to reinitialize the `McpClients` instance with updated configuration dictionaries containing the new header values. There is no built-in method to hot-swap headers on an active client connection; creating a new client instance with the updated `headers` configuration is the recommended approach.

### Are there any restrictions on header names or values?

No specific restrictions are imposed by the plugin code beyond what Python's `httpx` library and HTTP standards enforce. You can use standard headers like `Authorization` or `X-API-Key`, as well as custom `X-` prefixed headers. The values are passed directly to `httpx.Client(headers=...)` without sanitization or transformation, so ensure your values are valid HTTP header strings (e.g., no newlines or non-ASCII characters unless properly encoded).