Skip to content

Commit 5247014

Browse files
committed
add origin header to streamable http client
1 parent 616476f commit 5247014

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

src/mcp/client/streamable_http.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from collections.abc import AsyncGenerator, Awaitable, Callable
88
from contextlib import asynccontextmanager
99
from dataclasses import dataclass
10+
from urllib.parse import urlparse
1011

1112
import anyio
1213
import httpx
@@ -72,13 +73,15 @@ class RequestContext:
7273
class StreamableHTTPTransport:
7374
"""StreamableHTTP client transport implementation."""
7475

75-
def __init__(self, url: str) -> None:
76+
def __init__(self, url: str, default_origin: str | None = None) -> None:
7677
"""Initialize the StreamableHTTP transport.
7778
7879
Args:
7980
url: The endpoint URL.
81+
default_origin: Optional Origin header value to include with requests.
8082
"""
8183
self.url = url
84+
self.default_origin = default_origin
8285
self.session_id: str | None = None
8386
self.protocol_version: str | None = None
8487

@@ -92,6 +95,8 @@ def _prepare_headers(self) -> dict[str, str]:
9295
"accept": "application/json, text/event-stream",
9396
"content-type": "application/json",
9497
}
98+
if self.default_origin:
99+
headers["origin"] = self.default_origin
95100
# Add session headers if available
96101
if self.session_id:
97102
headers[MCP_SESSION_ID] = self.session_id
@@ -547,7 +552,13 @@ async def streamable_http_client(
547552
# Create default client with recommended MCP timeouts
548553
client = create_mcp_http_client()
549554

550-
transport = StreamableHTTPTransport(url)
555+
default_origin = None
556+
if "origin" not in client.headers:
557+
parsed_url = urlparse(url)
558+
if parsed_url.scheme and parsed_url.netloc:
559+
default_origin = f"{parsed_url.scheme}://{parsed_url.netloc}"
560+
561+
transport = StreamableHTTPTransport(url, default_origin=default_origin)
551562

552563
logger.debug(f"Connecting to StreamableHTTP endpoint: {url}")
553564

tests/shared/test_streamable_http.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ def extract_protocol_version_from_sse(response: requests.Response) -> str:
9494
raise ValueError("Could not extract protocol version from SSE response") # pragma: no cover
9595

9696

97+
def test_streamable_http_transport_includes_default_origin_header():
98+
transport = StreamableHTTPTransport(
99+
"https://example.com/mcp",
100+
default_origin="https://example.com",
101+
)
102+
103+
assert transport._prepare_headers()["origin"] == "https://example.com"
104+
105+
106+
def test_streamable_http_transport_omits_origin_header_without_default_origin():
107+
transport = StreamableHTTPTransport("https://example.com/mcp")
108+
109+
assert "origin" not in transport._prepare_headers()
110+
111+
97112
# Simple in-memory event store for testing
98113
class SimpleEventStore(EventStore):
99114
"""Simple in-memory event store for testing."""

0 commit comments

Comments
 (0)