# How the Dify MCP Plugin Handles HTTP Redirect Following with follow_redirects=True

> Discover how the Dify MCP plugin automatically follows HTTP redirects with follow_redirects=True, ensuring secure endpoint validation to prevent open-redirect attacks. Learn more today!

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

---

**The Dify MCP plugin enables automatic HTTP redirect handling by passing `follow_redirects=True` to all httpx client calls in both `McpSseClient` and `McpStreamableHttpClient`, while validating endpoint origins to prevent open-redirect attacks.**

The `junjiem/dify-plugin-tools-mcp_sse` repository implements Model Context Protocol (MCP) client functionality for Dify, requiring robust HTTP communication with potentially complex server configurations. Understanding how the plugin handles HTTP redirect following with `follow_redirects=True` is essential for deploying MCP servers behind reverse proxies, load balancers, or HTTPS termination layers.

## How HTTP Redirect Following Works in the MCP Plugin

The plugin uses **httpx** as its underlying HTTP transport layer. Both transport implementations—`McpSseClient` for Server-Sent Events and `McpStreamableHttpClient` for standard HTTP—explicitly enable redirect handling by passing `follow_redirects=True` to the underlying httpx calls.

### SSE Transport: McpSseClient

In [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py), the `McpSseClient` class handles Server-Sent Events connections. The method `_listen_messages` creates the SSE listener at **line 214** with `follow_redirects=True`, ensuring that 3xx responses during the initial SSE endpoint connection are automatically followed before event streaming begins.

When posting JSON-RPC messages, the `send_message` method at **line 259** passes `follow_redirects=True` to the httpx `post` call. This ensures that redirects (such as 307 Temporary Redirect) are followed when sending messages to the resolved endpoint.

### Streamable HTTP Transport: McpStreamableHttpClient

For standard HTTP POST requests, the `McpStreamableHttpClient.send_message` method at **line 360** passes `follow_redirects=True` to the httpx client. This guarantees that redirections—including those changing host or scheme—are transparently handled during JSON-RPC message transmission.

## Security Validation for HTTP Redirects

While automatic redirect following improves connectivity, the plugin implements security measures to prevent open-redirect vulnerabilities. In `McpSseClient._listen_messages`, after a redirect occurs, the code validates that the **origin** of the redirected endpoint matches the original connection origin.

If the redirect points to a different host or scheme, the client raises a `ValueError` with the message: `<server> - Endpoint origin does not match connection origin: <new_url>`. This prevents attackers from exploiting redirect parameters to send requests to malicious external domains.

## Practical Code Examples

### Example 1: SSE Client with Automatic Redirect Handling

```python
from utils.mcp_client import McpClients

# Configure server that may redirect (e.g., http → https)

servers = {
    "my_server": {
        "url": "http://example-mcp.local/api",
        "transport": "sse"
    }
}

clients = McpClients(servers_config=servers)
tools = clients.fetch_tools()  # Redirects followed automatically at line 214

result = clients.execute_tool("my_tool", {"param": "value"})
print(result)

```

No manual redirect handling is required; the underlying `McpSseClient` manages all 3xx responses transparently.

### Example 2: Streamable HTTP Client

```python
servers = {
    "my_server": {
        "url": "http://example-mcp.local/api",
        "transport": "streamable_http"
    }
}

clients = McpClients(servers_config=servers)

# POST requests follow redirects automatically (line 360)

tools = clients.fetch_tools()

```

### Example 3: Handling Origin Mismatch Errors

```python

# If the server redirects to a different origin, the client raises:

# ValueError: my_server - Endpoint origin does not match connection origin: https://malicious-site.com/api

# This security check in _listen_messages prevents open-redirect attacks

# while allowing legitimate same-origin redirects

```

## Source File References

The HTTP redirect following implementation is contained in the following files within the `junjiem/dify-plugin-tools-mcp_sse` repository:

- **[`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py)** – Core transport implementation containing `McpSseClient` (line 214 for SSE connections, line 259 for POST requests) and `McpStreamableHttpClient` (line 360 for POST requests)
- **[`provider/mcp_tool.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/provider/mcp_tool.py)** – High-level wrapper that bridges the MCP client to the Dify plugin system
- **[`main/main.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/main/main.py)** – Entry point that initializes and registers `McpClients`

## Summary

- The Dify MCP plugin uses **httpx** with `follow_redirects=True` for all HTTP communications in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py)
- **SSE connections** (`McpSseClient._listen_messages`, line 214) automatically follow redirects during endpoint establishment
- **POST requests** in both SSE (line 259) and Streamable HTTP (line 360) clients transparently handle 3xx responses
- **Origin validation** prevents open-redirect attacks by ensuring redirected endpoints match the original connection origin
- No manual redirect handling is required when using `McpClients.fetch_tools()` or `execute_tool()`

## Frequently Asked Questions

### What happens if an MCP server returns a 307 Temporary Redirect?

The plugin automatically follows the redirect to the new URL specified in the Location header. For SSE connections in `McpSseClient._listen_messages` (line 214) and POST requests in both client types (lines 259 and 360), the httpx client handles the redirection transparently, including preserving the HTTP method and body for 307/308 redirects.

### Does the plugin follow redirects to different domains?

No. While the plugin enables `follow_redirects=True` to handle legitimate redirects, it implements origin validation in `McpSseClient._listen_messages`. If a redirect points to a different host or scheme than the original connection, the client raises a `ValueError` stating that the endpoint origin does not match the connection origin, preventing potential open-redirect security vulnerabilities.

### Which HTTP client library does the Dify MCP plugin use?

The plugin uses **httpx** as its underlying HTTP transport layer. Both `McpSseClient` and `McpStreamableHttpClient` classes in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py) instantiate httpx clients and pass `follow_redirects=True` to ensure robust handling of HTTP redirects in MCP server environments.

### Do I need to configure redirect handling manually when using McpClients?

No manual configuration is required. When you instantiate `McpClients` with your server configuration and call methods like `fetch_tools()` or `execute_tool()`, the underlying `McpSseClient` or `McpStreamableHttpClient` automatically handles all HTTP redirects using the `follow_redirects=True` setting configured in the source code at lines 214, 259, and 360 of [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py).