Skip to content

Commit 3ad9f12

Browse files
tpp-builderdevcrocod
authored andcommitted
fix SSEClientTransport endpoint process with none directory sse path
1 parent 1bd9734 commit 3ad9f12

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/SSEClientTransport.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,18 @@ public class SseClientTransport(
5555
private var job: Job? = null
5656

5757
private val baseUrl by lazy {
58-
session.call.request.url.toString().removeSuffix("/sse")
58+
val requestUrl = session.call.request.url.toString()
59+
val url = Url(requestUrl)
60+
var path = url.encodedPath
61+
if (path.isEmpty()) {
62+
url.protocolWithAuthority
63+
} else if (path.endsWith("/")) {
64+
url.protocolWithAuthority + path.removeSuffix("/")
65+
} else {
66+
// the last item is not a directory, so will not be taken into account
67+
path = path.substring(0, path.lastIndexOf("/"))
68+
url.protocolWithAuthority + path
69+
}
5970
}
6071

6172
override suspend fun start() {
@@ -95,8 +106,7 @@ public class SseClientTransport(
95106
val eventData = event.data ?: ""
96107

97108
// check url correctness
98-
val maybeEndpoint = Url(baseUrl + eventData)
99-
109+
val maybeEndpoint = Url("$baseUrl/${if (eventData.startsWith("/")) eventData.substring(1) else eventData}")
100110
endpoint.complete(maybeEndpoint.toString())
101111
} catch (e: Exception) {
102112
_onError(e)

src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/client/SseTransportTest.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,41 @@ class SseTransportTest : BaseTransportTest() {
8282
testClientRead(client)
8383
server.stopSuspend()
8484
}
85+
86+
@Test
87+
fun `test sse path not root path`() = runTest {
88+
val server = embeddedServer(CIO, port = PORT) {
89+
install(io.ktor.server.sse.SSE)
90+
val transports = ConcurrentMap<String, SseServerTransport>()
91+
routing {
92+
sse("/sse") {
93+
mcpSseTransport("/messages", transports).apply {
94+
onMessage {
95+
send(it)
96+
}
97+
98+
start()
99+
}
100+
}
101+
102+
post("/messages") {
103+
104+
mcpPostEndpoint(transports)
105+
}
106+
}
107+
}.start(wait = false)
108+
109+
val client = HttpClient {
110+
install(SSE)
111+
}.mcpSseTransport {
112+
url {
113+
host = "localhost"
114+
port = PORT
115+
pathSegments = listOf("sse")
116+
}
117+
}
118+
119+
testClientRead(client)
120+
server.stop()
121+
}
85122
}

0 commit comments

Comments
 (0)