@@ -17,6 +17,7 @@ import java.nio.charset.StandardCharsets
17
17
import kotlin.reflect.KClass
18
18
import kotlin.reflect.full.primaryConstructor
19
19
import kotlin.reflect.full.starProjectedType
20
+ import kotlin.text.get
20
21
21
22
class MCPService : RestService () {
22
23
private val serviceName = " mcp"
@@ -102,16 +103,55 @@ class MCPService : RestService() {
102
103
103
104
@Suppress(" UNCHECKED_CAST" )
104
105
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
+ }
113
151
}
114
152
}
153
+
154
+ return NoArgs as T
115
155
}
116
156
117
157
private fun <Args : Any > toolHandle (tool : McpTool <Args >, project : Project , args : Any ): Response {
0 commit comments