From b42b35a983ca4689659e060d4f2affeb51af3319 Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Thu, 27 Mar 2025 17:22:32 +0300
Subject: [PATCH 01/10] fix(): SSE client handling of nested path URLs

Fix issue with SSE client failing when connecting to servers with nested paths (e.g., http://domain/path1/path2/sse). Previously, the client worked only with simple URLs like http://domain/sse.

The fix extracts the base path segment between domain and /sse endpoint using regex, then correctly constructs the response URL by preserving the path structure. This ensures proper communication with MCP servers hosted under non-root paths.

Without this fix, clients couldn't connect to SSE servers deployed under nested paths, as the endpoint URLs for posting messages were constructed incorrectly.
---
 src/mcp/client/sse.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index 4f6241a72..a95428616 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -2,6 +2,7 @@
 from contextlib import asynccontextmanager
 from typing import Any
 from urllib.parse import urljoin, urlparse
+import re
 
 import anyio
 import httpx
@@ -61,7 +62,9 @@ async def sse_reader(
                                 logger.debug(f"Received SSE event: {sse.event}")
                                 match sse.event:
                                     case "endpoint":
-                                        endpoint_url = urljoin(url, sse.data)
+                                        base_path = re.search(r"https?://[^/]+/(.+)/sse$", url)
+                                        base_path = base_path.group(1) if base_path else ""
+                                        endpoint_url = urljoin(url, base_path + sse.data)
                                         logger.info(
                                             f"Received endpoint URL: {endpoint_url}"
                                         )

From 5a4d42053b48d1101f482b2de66699a5b8933c31 Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Thu, 27 Mar 2025 17:43:59 +0300
Subject: [PATCH 02/10] style: format max-line

---
 src/mcp/client/sse.py | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index a95428616..ffbb4ba7d 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -62,9 +62,15 @@ async def sse_reader(
                                 logger.debug(f"Received SSE event: {sse.event}")
                                 match sse.event:
                                     case "endpoint":
-                                        base_path = re.search(r"https?://[^/]+/(.+)/sse$", url)
-                                        base_path = base_path.group(1) if base_path else ""
-                                        endpoint_url = urljoin(url, base_path + sse.data)
+                                        base_path = re.search(
+                                            r"https?://[^/]+/(.+)/sse$", url
+                                        )
+                                        base_path = (
+                                            base_path.group(1) if base_path else ""
+                                        )
+                                        endpoint_url = urljoin(
+                                            url, base_path + sse.data
+                                        )
                                         logger.info(
                                             f"Received endpoint URL: {endpoint_url}"
                                         )

From 21a775f21e12e2a03b7141acc4bc8d8ac99bf82e Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Fri, 28 Mar 2025 08:11:35 +0300
Subject: [PATCH 03/10] fix: imports

---
 src/mcp/client/sse.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index ffbb4ba7d..f78228524 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -1,8 +1,8 @@
 import logging
+import re
 from contextlib import asynccontextmanager
 from typing import Any
 from urllib.parse import urljoin, urlparse
-import re
 
 import anyio
 import httpx

From 9a58b30886d3e044a2a206de31e287a4d7c962e1 Mon Sep 17 00:00:00 2001
From: Jonathan Lima <jonathan.lima@securityscorecard.io>
Date: Mon, 7 Apr 2025 17:38:24 -0300
Subject: [PATCH 04/10] fixing /mcp case prefix on langchain

---
 src/mcp/client/sse.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index f78228524..298361326 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -62,20 +62,22 @@ async def sse_reader(
                                 logger.debug(f"Received SSE event: {sse.event}")
                                 match sse.event:
                                     case "endpoint":
+                                        url_parsed = urlparse(url)
+
                                         base_path = re.search(
-                                            r"https?://[^/]+/(.+)/sse$", url
+                                            r"https?://[^/]+/(.+?)(?:/mcp)?/sse$", url
                                         )
                                         base_path = (
                                             base_path.group(1) if base_path else ""
                                         )
                                         endpoint_url = urljoin(
-                                            url, base_path + sse.data
+                                            url_parsed.scheme + "://" + url_parsed.netloc,
+                                            base_path + sse.data
                                         )
                                         logger.info(
                                             f"Received endpoint URL: {endpoint_url}"
                                         )
 
-                                        url_parsed = urlparse(url)
                                         endpoint_parsed = urlparse(endpoint_url)
                                         if (
                                             url_parsed.netloc != endpoint_parsed.netloc

From 8e76e8a5c6fb48a7513e5173041694cafc26901d Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Tue, 8 Apr 2025 10:45:23 +0300
Subject: [PATCH 05/10] style: Added noqa to avoid max-line of code

---
 src/mcp/client/sse.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index 298361326..c41c414ed 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -71,7 +71,7 @@ async def sse_reader(
                                             base_path.group(1) if base_path else ""
                                         )
                                         endpoint_url = urljoin(
-                                            url_parsed.scheme + "://" + url_parsed.netloc,
+                                            url_parsed.scheme + "://" + url_parsed.netloc,  # noqa: E501
                                             base_path + sse.data
                                         )
                                         logger.info(

From e6d5b00991a9abcfe2469e2fed929d0113ad6e3a Mon Sep 17 00:00:00 2001
From: sebin1213 <73850629+sebin1213@users.noreply.github.com>
Date: Wed, 9 Apr 2025 02:02:49 +0000
Subject: [PATCH 06/10] Fix generate accurate session_uri for nested SSE paths

---
 src/mcp/client/sse.py | 16 +++-------------
 src/mcp/server/sse.py |  7 +++++--
 2 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py
index c41c414ed..0194c02a5 100644
--- a/src/mcp/client/sse.py
+++ b/src/mcp/client/sse.py
@@ -1,5 +1,4 @@
 import logging
-import re
 from contextlib import asynccontextmanager
 from typing import Any
 from urllib.parse import urljoin, urlparse
@@ -62,21 +61,12 @@ async def sse_reader(
                                 logger.debug(f"Received SSE event: {sse.event}")
                                 match sse.event:
                                     case "endpoint":
-                                        url_parsed = urlparse(url)
-
-                                        base_path = re.search(
-                                            r"https?://[^/]+/(.+?)(?:/mcp)?/sse$", url
-                                        )
-                                        base_path = (
-                                            base_path.group(1) if base_path else ""
-                                        )
-                                        endpoint_url = urljoin(
-                                            url_parsed.scheme + "://" + url_parsed.netloc,  # noqa: E501
-                                            base_path + sse.data
-                                        )
+                                        endpoint_url = urljoin(url, sse.data)
                                         logger.info(
                                             f"Received endpoint URL: {endpoint_url}"
                                         )
+                                        
+                                        url_parsed = urlparse(url)
 
                                         endpoint_parsed = urlparse(endpoint_url)
                                         if (
diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py
index d051c25bf..dbb40bed0 100644
--- a/src/mcp/server/sse.py
+++ b/src/mcp/server/sse.py
@@ -94,8 +94,11 @@ async def connect_sse(self, scope: Scope, receive: Receive, send: Send):
         read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
         write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
 
-        session_id = uuid4()
-        session_uri = f"{quote(self._endpoint)}?session_id={session_id.hex}"
+        request_path = scope["path"]
+        match = re.match(r"^/([^/]+(?:/mcp)?)/sse$", request_path)
+        mount_prefix = match.group(1) if match else ""
+        session_uri = f"/{quote(mount_prefix)}{quote(self._endpoint)}?session_id={session_id.hex}"
+
         self._read_stream_writers[session_id] = read_stream_writer
         logger.debug(f"Created new session with ID: {session_id}")
 

From 1ac7b63fe648fb2c8bcf87bed0797da79650881e Mon Sep 17 00:00:00 2001
From: sebin1213 <73850629+sebin1213@users.noreply.github.com>
Date: Wed, 9 Apr 2025 11:13:29 +0900
Subject: [PATCH 07/10] Fix generate accurate session_uri for nested SSE paths

---
 src/mcp/server/sse.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py
index dbb40bed0..a51190376 100644
--- a/src/mcp/server/sse.py
+++ b/src/mcp/server/sse.py
@@ -94,6 +94,7 @@ async def connect_sse(self, scope: Scope, receive: Receive, send: Send):
         read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
         write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
 
+        session_id = uuid4()
         request_path = scope["path"]
         match = re.match(r"^/([^/]+(?:/mcp)?)/sse$", request_path)
         mount_prefix = match.group(1) if match else ""

From 7cece5e8e6afeb97eb4e81988acb948a4d512ac5 Mon Sep 17 00:00:00 2001
From: sebin1213 <73850629+sebin1213@users.noreply.github.com>
Date: Wed, 9 Apr 2025 13:15:47 +0900
Subject: [PATCH 08/10] Fix generate accurate session_uri for nested SSE paths

---
 src/mcp/server/sse.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py
index a51190376..ad6059c3d 100644
--- a/src/mcp/server/sse.py
+++ b/src/mcp/server/sse.py
@@ -37,6 +37,7 @@ async def handle_sse(request):
 from urllib.parse import quote
 from uuid import UUID, uuid4
 
+import re
 import anyio
 from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
 from pydantic import ValidationError

From 3728328497814e046293e5ffc8ac8571968e9e2d Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Wed, 9 Apr 2025 22:32:26 +0300
Subject: [PATCH 09/10] style: format to avoid max-line validation error

---
 src/mcp/server/sse.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py
index ad6059c3d..15c90f838 100644
--- a/src/mcp/server/sse.py
+++ b/src/mcp/server/sse.py
@@ -97,9 +97,12 @@ async def connect_sse(self, scope: Scope, receive: Receive, send: Send):
 
         session_id = uuid4()
         request_path = scope["path"]
+        
         match = re.match(r"^/([^/]+(?:/mcp)?)/sse$", request_path)
         mount_prefix = match.group(1) if match else ""
-        session_uri = f"/{quote(mount_prefix)}{quote(self._endpoint)}?session_id={session_id.hex}"
+        
+        session_uri = f"/{quote(mount_prefix)}{quote(self._endpoint)}"
+        session_uri += f"?session_id={session_id.hex}"
 
         self._read_stream_writers[session_id] = read_stream_writer
         logger.debug(f"Created new session with ID: {session_id}")

From e1ca588e07e83a8a2178582a48235935861b2f98 Mon Sep 17 00:00:00 2001
From: eyeonyou <example@example.com>
Date: Wed, 9 Apr 2025 22:35:30 +0300
Subject: [PATCH 10/10] style: reorganize imports

---
 src/mcp/server/sse.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py
index 15c90f838..6ec4c165a 100644
--- a/src/mcp/server/sse.py
+++ b/src/mcp/server/sse.py
@@ -32,12 +32,12 @@ async def handle_sse(request):
 """
 
 import logging
+import re
 from contextlib import asynccontextmanager
 from typing import Any
 from urllib.parse import quote
 from uuid import UUID, uuid4
 
-import re
 import anyio
 from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
 from pydantic import ValidationError