1919 */
2020package org .sonar .mcp .log ;
2121
22+ import io .modelcontextprotocol .server .McpSyncServer ;
23+ import io .modelcontextprotocol .spec .McpSchema ;
24+ import jakarta .annotation .Nullable ;
25+ import java .io .PrintWriter ;
26+ import java .io .StringWriter ;
2227import org .sonarsource .sonarlint .core .rpc .protocol .client .log .LogLevel ;
2328import org .sonarsource .sonarlint .core .rpc .protocol .client .log .LogParams ;
2429
@@ -29,6 +34,12 @@ public static McpLogger getInstance() {
2934 return INSTANCE ;
3035 }
3136
37+ private McpSyncServer syncServer ;
38+
39+ public void setOutput (@ Nullable McpSyncServer syncServer ) {
40+ this .syncServer = syncServer ;
41+ }
42+
3243 public void log (LogParams params ) {
3344 var stackTrace = params .getStackTrace ();
3445 if (stackTrace != null ) {
@@ -42,11 +53,33 @@ public void info(String message) {
4253
4354 public void error (String message , Throwable throwable ) {
4455 log (message , LogLevel .ERROR );
45- throwable .printStackTrace ();
56+ log (stackTraceToString (throwable ), LogLevel .ERROR );
57+ }
58+
59+ private void log (String message , LogLevel level ) {
60+ if (syncServer != null ) {
61+ // We rely on a deprecated API for now, I opened a discussion in https://github.com/modelcontextprotocol/java-sdk/issues/131
62+ try {
63+ syncServer .loggingNotification (new McpSchema .LoggingMessageNotification (toMcpLevel (level ), "sonar-mcp-server" , message ));
64+ } catch (Exception e ) {
65+ // we still print on stdout; some MCP clients print non-JSON message as an error, which is better than nothing
66+ e .printStackTrace ();
67+ }
68+ }
69+ }
70+
71+ private static McpSchema .LoggingLevel toMcpLevel (LogLevel level ) {
72+ return switch (level ) {
73+ case ERROR -> McpSchema .LoggingLevel .ERROR ;
74+ case WARN -> McpSchema .LoggingLevel .WARNING ;
75+ case INFO -> McpSchema .LoggingLevel .INFO ;
76+ case DEBUG , TRACE -> McpSchema .LoggingLevel .DEBUG ;
77+ };
4678 }
4779
48- private static void log (String message , LogLevel level ) {
49- // will be properly implemented in SLCORE-1345
50- System .out .println ("[" + level .name () + "] " + message );
80+ static String stackTraceToString (Throwable t ) {
81+ var stringWriter = new StringWriter ();
82+ t .printStackTrace (new PrintWriter (stringWriter ));
83+ return stringWriter .toString ();
5184 }
5285}
0 commit comments