From 5ad3c8659ac09a1a0c8f5ca9f11d4702e8548fca Mon Sep 17 00:00:00 2001
From: olaservo <olahungerford@gmail.com>
Date: Fri, 2 May 2025 06:36:33 -0700
Subject: [PATCH] Add failing tests and updated package-lock.json

---
 package-lock.json      |   4 +-
 src/client/sse.test.ts | 153 +++++++++++++++++++++++++++++------------
 2 files changed, 111 insertions(+), 46 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 1165b751..3c6e2d90 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "@modelcontextprotocol/sdk",
-  "version": "1.9.0",
+  "version": "1.10.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "@modelcontextprotocol/sdk",
-      "version": "1.9.0",
+      "version": "1.10.2",
       "license": "MIT",
       "dependencies": {
         "content-type": "^1.0.5",
diff --git a/src/client/sse.test.ts b/src/client/sse.test.ts
index 77b28508..fc7a86c4 100644
--- a/src/client/sse.test.ts
+++ b/src/client/sse.test.ts
@@ -68,6 +68,71 @@ describe("SSEClientTransport", () => {
   });
 
   describe("connection handling", () => {
+    it("maintains custom path when constructing endpoint URL", async () => {
+      // Create a URL with a custom path
+      const customPathUrl = new URL("/custom/path/sse", baseUrl);
+      transport = new SSEClientTransport(customPathUrl);
+      
+      // Start the transport
+      await transport.start();
+
+      // Send a test message to verify the endpoint URL
+      const message: JSONRPCMessage = {
+        jsonrpc: "2.0",
+        id: "test-1",
+        method: "test",
+        params: {}
+      };
+
+      await transport.send(message);
+
+      // Verify the POST request maintains the custom path
+      expect(lastServerRequest.url).toBe("/custom/path/messages");
+    });
+
+    it("handles multiple levels of custom paths", async () => {
+      // Test with a deeper nested path
+      const nestedPathUrl = new URL("/api/v1/custom/deep/path/sse", baseUrl);
+      transport = new SSEClientTransport(nestedPathUrl);
+      
+      await transport.start();
+
+      const message: JSONRPCMessage = {
+        jsonrpc: "2.0",
+        id: "test-1",
+        method: "test",
+        params: {}
+      };
+
+      await transport.send(message);
+
+      // Verify the POST request maintains the full custom path
+      expect(lastServerRequest.url).toBe("/api/v1/custom/deep/path/messages");
+    });
+
+    it("maintains custom path for SSE connection", async () => {
+      const customPathUrl = new URL("/custom/path/sse", baseUrl);
+      transport = new SSEClientTransport(customPathUrl);
+      await transport.start();
+      expect(lastServerRequest.url).toBe("/custom/path/sse");
+    });
+
+    it("handles URLs with query parameters", async () => {
+      const urlWithQuery = new URL("/custom/path/sse?param=value", baseUrl);
+      transport = new SSEClientTransport(urlWithQuery);
+      await transport.start();
+      
+      const message: JSONRPCMessage = {
+        jsonrpc: "2.0",
+        id: "test-1",
+        method: "test",
+        params: {}
+      };
+      
+      await transport.send(message);
+      expect(lastServerRequest.url).toBe("/custom/path/messages");
+    });
+
     it("establishes SSE connection and receives endpoint", async () => {
       transport = new SSEClientTransport(baseUrl);
       await transport.start();
@@ -397,18 +462,18 @@ describe("SSEClientTransport", () => {
               return;
             }
 
-            res.writeHead(200, {
-              "Content-Type": "text/event-stream",
-              "Cache-Control": "no-cache, no-transform",
-              Connection: "keep-alive",
-            });
-            res.write("event: endpoint\n");
-            res.write(`data: ${baseUrl.href}\n\n`);
+          res.writeHead(200, {
+            "Content-Type": "text/event-stream",
+            "Cache-Control": "no-cache, no-transform",
+            Connection: "keep-alive",
+          });
+          res.write("event: endpoint\n");
+          res.write(`data: ${baseUrl.href}\n\n`);
             break;
 
           case "POST":
-            res.writeHead(401);
-            res.end();
+          res.writeHead(401);
+          res.end();
             break;
         }
       });
@@ -517,25 +582,25 @@ describe("SSEClientTransport", () => {
           return;
         }
 
-        const auth = req.headers.authorization;
-        if (auth === "Bearer expired-token") {
-          res.writeHead(401).end();
-          return;
-        }
+          const auth = req.headers.authorization;
+          if (auth === "Bearer expired-token") {
+            res.writeHead(401).end();
+            return;
+          }
 
-        if (auth === "Bearer new-token") {
-          res.writeHead(200, {
-            "Content-Type": "text/event-stream",
-            "Cache-Control": "no-cache, no-transform",
-            Connection: "keep-alive",
-          });
-          res.write("event: endpoint\n");
-          res.write(`data: ${baseUrl.href}\n\n`);
-          connectionAttempts++;
-          return;
-        }
+          if (auth === "Bearer new-token") {
+            res.writeHead(200, {
+              "Content-Type": "text/event-stream",
+              "Cache-Control": "no-cache, no-transform",
+              Connection: "keep-alive",
+            });
+            res.write("event: endpoint\n");
+            res.write(`data: ${baseUrl.href}\n\n`);
+            connectionAttempts++;
+            return;
+          }
 
-        res.writeHead(401).end();
+          res.writeHead(401).end();
       });
 
       await new Promise<void>(resolve => {
@@ -610,13 +675,13 @@ describe("SSEClientTransport", () => {
               return;
             }
 
-            res.writeHead(200, {
-              "Content-Type": "text/event-stream",
-              "Cache-Control": "no-cache, no-transform",
-              Connection: "keep-alive",
-            });
-            res.write("event: endpoint\n");
-            res.write(`data: ${baseUrl.href}\n\n`);
+          res.writeHead(200, {
+            "Content-Type": "text/event-stream",
+            "Cache-Control": "no-cache, no-transform",
+            Connection: "keep-alive",
+          });
+          res.write("event: endpoint\n");
+          res.write(`data: ${baseUrl.href}\n\n`);
             break;
 
           case "POST": {
@@ -625,19 +690,19 @@ describe("SSEClientTransport", () => {
               return;
             }
 
-            const auth = req.headers.authorization;
-            if (auth === "Bearer expired-token") {
-              res.writeHead(401).end();
-              return;
-            }
+          const auth = req.headers.authorization;
+          if (auth === "Bearer expired-token") {
+            res.writeHead(401).end();
+            return;
+          }
 
-            if (auth === "Bearer new-token") {
-              res.writeHead(200).end();
-              postAttempts++;
-              return;
-            }
+          if (auth === "Bearer new-token") {
+            res.writeHead(200).end();
+            postAttempts++;
+            return;
+          }
 
-            res.writeHead(401).end();
+          res.writeHead(401).end();
             break;
           }
         }