938a9b89 by Ean Schuessler

Fix JsonOutput usage to resolve Groovy JSON service configuration error

- Replace JsonBuilder with JsonOutput.toJson() to avoid ServiceConfigurationError
- Fixes ExceptionInInitializerError with FastStringServiceFactory
- MCP server now properly handles JSON-RPC responses and SSE events
- All MCP functionality working: ping, tools/list, screen discovery and execution
1 parent c0bdac05
...@@ -156,11 +156,11 @@ try { ...@@ -156,11 +156,11 @@ try {
156 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED) 156 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED)
157 response.setContentType("application/json") 157 response.setContentType("application/json")
158 response.setHeader("WWW-Authenticate", "Basic realm=\"Moqui MCP\"") 158 response.setHeader("WWW-Authenticate", "Basic realm=\"Moqui MCP\"")
159 response.writer.write(new JsonBuilder([ 159 response.writer.write(JsonOutput.toJson([
160 jsonrpc: "2.0", 160 jsonrpc: "2.0",
161 error: [code: -32003, message: "Authentication required. Use Basic auth with valid Moqui credentials."], 161 error: [code: -32003, message: "Authentication required. Use Basic auth with valid Moqui credentials."],
162 id: null 162 id: null
163 ]).toString()) 163 ]))
164 return 164 return
165 } 165 }
166 166
...@@ -254,11 +254,11 @@ try { ...@@ -254,11 +254,11 @@ try {
254 logger.warn("Enhanced MCP Access Forbidden (no authz): " + e.message) 254 logger.warn("Enhanced MCP Access Forbidden (no authz): " + e.message)
255 response.setStatus(HttpServletResponse.SC_FORBIDDEN) 255 response.setStatus(HttpServletResponse.SC_FORBIDDEN)
256 response.setContentType("application/json") 256 response.setContentType("application/json")
257 response.writer.write(new JsonBuilder([ 257 response.writer.write(JsonOutput.toJson([
258 jsonrpc: "2.0", 258 jsonrpc: "2.0",
259 error: [code: -32001, message: "Access Forbidden: " + e.message], 259 error: [code: -32001, message: "Access Forbidden: " + e.message],
260 id: null 260 id: null
261 ]).toString()) 261 ]))
262 } catch (ArtifactTarpitException e) { 262 } catch (ArtifactTarpitException e) {
263 logger.warn("Enhanced MCP Too Many Requests (tarpit): " + e.message) 263 logger.warn("Enhanced MCP Too Many Requests (tarpit): " + e.message)
264 response.setStatus(429) 264 response.setStatus(429)
...@@ -266,20 +266,20 @@ try { ...@@ -266,20 +266,20 @@ try {
266 response.addIntHeader("Retry-After", e.getRetryAfterSeconds()) 266 response.addIntHeader("Retry-After", e.getRetryAfterSeconds())
267 } 267 }
268 response.setContentType("application/json") 268 response.setContentType("application/json")
269 response.writer.write(new JsonBuilder([ 269 response.writer.write(JsonOutput.toJson([
270 jsonrpc: "2.0", 270 jsonrpc: "2.0",
271 error: [code: -32002, message: "Too Many Requests: " + e.message], 271 error: [code: -32002, message: "Too Many Requests: " + e.message],
272 id: null 272 id: null
273 ]).toString()) 273 ]))
274 } catch (Throwable t) { 274 } catch (Throwable t) {
275 logger.error("Error in Enhanced MCP request", t) 275 logger.error("Error in Enhanced MCP request", t)
276 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR) 276 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
277 response.setContentType("application/json") 277 response.setContentType("application/json")
278 response.writer.write(new JsonBuilder([ 278 response.writer.write(JsonOutput.toJson([
279 jsonrpc: "2.0", 279 jsonrpc: "2.0",
280 error: [code: -32603, message: "Internal error: " + t.message], 280 error: [code: -32603, message: "Internal error: " + t.message],
281 id: null 281 id: null
282 ]).toString()) 282 ]))
283 } finally { 283 } finally {
284 ec.destroy() 284 ec.destroy()
285 } 285 }
...@@ -398,7 +398,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}") ...@@ -398,7 +398,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}")
398 // Set MCP session ID header per specification BEFORE sending any data 398 // Set MCP session ID header per specification BEFORE sending any data
399 response.setHeader("Mcp-Session-Id", visit.visitId.toString()) 399 response.setHeader("Mcp-Session-Id", visit.visitId.toString())
400 400
401 sendSseEvent(response.writer, "connect", new JsonBuilder(connectData).toString(), 0) 401 sendSseEvent(response.writer, "connect", JsonOutput.toJson(connectData), 0)
402 402
403 // Send endpoint info for message posting (for compatibility) 403 // Send endpoint info for message posting (for compatibility)
404 sendSseEvent(response.writer, "endpoint", "/mcp", 1) 404 sendSseEvent(response.writer, "endpoint", "/mcp", 1)
...@@ -415,7 +415,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}") ...@@ -415,7 +415,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}")
415 sessionId: visit.visitId, 415 sessionId: visit.visitId,
416 architecture: "Visit-based sessions" 416 architecture: "Visit-based sessions"
417 ] 417 ]
418 sendSseEvent(response.writer, "ping", new JsonBuilder(pingData).toString(), pingCount + 2) 418 sendSseEvent(response.writer, "ping", JsonOutput.toJson(pingData), pingCount + 2)
419 pingCount++ 419 pingCount++
420 } 420 }
421 } 421 }
...@@ -433,7 +433,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}") ...@@ -433,7 +433,7 @@ logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}")
433 sessionId: visit.visitId, 433 sessionId: visit.visitId,
434 timestamp: System.currentTimeMillis() 434 timestamp: System.currentTimeMillis()
435 ] 435 ]
436 sendSseEvent(response.writer, "disconnect", new JsonBuilder(closeData).toString(), -1) 436 sendSseEvent(response.writer, "disconnect", JsonOutput.toJson(closeData), -1)
437 } catch (Exception e) { 437 } catch (Exception e) {
438 // Ignore errors during cleanup 438 // Ignore errors during cleanup
439 } 439 }
......