Skip to content

Commit 8c36b94

Browse files
committed
feat(MCPService): enhance parseArgs to support GET requests with query parameters unit-mesh/autodev-workbench#89
1 parent 5d3f029 commit 8c36b94

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

core/src/main/kotlin/cc/unitmesh/devti/mcp/host/HostMCPService.kt

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import java.nio.charset.StandardCharsets
1717
import kotlin.reflect.KClass
1818
import kotlin.reflect.full.primaryConstructor
1919
import kotlin.reflect.full.starProjectedType
20+
import kotlin.text.get
2021

2122
class MCPService : RestService() {
2223
private val serviceName = "mcp"
@@ -102,16 +103,55 @@ class MCPService : RestService() {
102103

103104
@Suppress("UNCHECKED_CAST")
104105
private fun <T : Any> parseArgs(request: FullHttpRequest, klass: KClass<T>): T {
105-
val body = request.content().toString(StandardCharsets.UTF_8)
106-
if (body.isEmpty()) {
107-
return NoArgs as T
108-
}
109-
return when (klass) {
110-
NoArgs::class -> NoArgs as T
111-
else -> {
112-
json.decodeFromString(serializer(klass.starProjectedType), body) as T
106+
if (request.method() == HttpMethod.POST) {
107+
val body = request.content().toString(StandardCharsets.UTF_8)
108+
if (body.isEmpty()) {
109+
return NoArgs as T
110+
}
111+
return when (klass) {
112+
NoArgs::class -> NoArgs as T
113+
else -> {
114+
json.decodeFromString(serializer(klass.starProjectedType), body) as T
115+
}
116+
}
117+
} else if (request.method() == HttpMethod.GET) {
118+
val queryDecoder = QueryStringDecoder(request.uri())
119+
val params = queryDecoder.parameters()
120+
121+
if (params.isEmpty()) {
122+
return NoArgs as T
123+
}
124+
125+
return when (klass) {
126+
NoArgs::class -> NoArgs as T
127+
else -> {
128+
val constructor = klass.primaryConstructor
129+
?: error("Class ${klass.simpleName} must have a primary constructor")
130+
131+
val args = constructor.parameters.associateWith { param ->
132+
val paramName = param.name ?: error("Parameter must have a name")
133+
val paramValues = params[paramName]
134+
135+
when {
136+
paramValues == null || paramValues.isEmpty() -> {
137+
if (param.type.isMarkedNullable) null
138+
else error("Required parameter $paramName is missing")
139+
}
140+
param.type.classifier == List::class -> paramValues
141+
param.type.classifier == Boolean::class -> paramValues[0].toBoolean()
142+
param.type.classifier == Int::class -> paramValues[0].toInt()
143+
param.type.classifier == Long::class -> paramValues[0].toLong()
144+
param.type.classifier == Double::class -> paramValues[0].toDouble()
145+
else -> paramValues[0]
146+
}
147+
}
148+
149+
constructor.callBy(args)
150+
}
113151
}
114152
}
153+
154+
return NoArgs as T
115155
}
116156

117157
private fun <Args : Any> toolHandle(tool: McpTool<Args>, project: Project, args: Any): Response {

0 commit comments

Comments
 (0)