From 1b1917e342be1eaeedc2bd20243bf3860fa70bcc Mon Sep 17 00:00:00 2001 From: Dmitry Zhuravlev Date: Sun, 8 Mar 2026 16:22:33 +0100 Subject: [PATCH] IJPL-233396 misc [mcp-server]: improve execute_run_configuration output for agent consumption Default truncation kept the beginning of output (build logs) and discarded the end (test failures, stack traces). Switch default to TruncateMode.END. When truncation occurs, write full output to a temp file and return its path so agents can read_file the complete log. (cherry picked from commit 1ebbed734bb85d1d2d2e343da0c3a8c0aadfa6fe) GitOrigin-RevId: a964ca4b7dcb288481ddd75d996ff5c15a8c5e48 --- .../toolsets/general/ExecutionToolset.kt | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/plugins/mcp-server/src/com/intellij/mcpserver/toolsets/general/ExecutionToolset.kt b/plugins/mcp-server/src/com/intellij/mcpserver/toolsets/general/ExecutionToolset.kt index 6aeb56771342..6a9452fe511b 100644 --- a/plugins/mcp-server/src/com/intellij/mcpserver/toolsets/general/ExecutionToolset.kt +++ b/plugins/mcp-server/src/com/intellij/mcpserver/toolsets/general/ExecutionToolset.kt @@ -24,6 +24,7 @@ import com.intellij.mcpserver.util.TruncateMode import com.intellij.mcpserver.util.checkUserConfirmationIfNeeded import com.intellij.mcpserver.util.truncateText import com.intellij.openapi.application.EDT +import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.readAction import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.rethrowControlFlowException @@ -37,6 +38,7 @@ import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.EncodeDefault import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable +import java.nio.file.Files import kotlin.time.Duration.Companion.milliseconds private val logger = logger() @@ -157,14 +159,31 @@ class ExecutionToolset : McpToolset { mcpFail("Execution failed: ${e.message}") } } - val output = truncateText(outputBuilder.toString(), maxLinesCount = maxLinesCount, truncateMode = truncateMode) + val fullOutput = outputBuilder.toString() + val output = truncateText(fullOutput, maxLinesCount = maxLinesCount, truncateMode = truncateMode) + val fullOutputPath = if (output.length != fullOutput.length) createTmpFile(fullOutput) else null + return RunConfigurationResult( exitCode = exitCode, timedOut = exitCode == null, - output = output + output = output, + fullOutputPath = fullOutputPath, ) } + private fun createTmpFile(fullOutput: String): String? { + return try { + val tmpFile = Files.createTempFile(PathManager.getTempDir(), "run-config-output", ".log") + Files.writeString(tmpFile, fullOutput) + tmpFile.toAbsolutePath().toString() + } + catch (e: Exception) { + rethrowControlFlowException(e) + logger.trace { "Failed to write full output to temp file: ${e.message}" } + null + } + } + @Serializable data class RunConfigurationsList( val configurations: List, @@ -184,12 +203,15 @@ class ExecutionToolset : McpToolset { ) @Serializable - data class RunConfigurationResult( + data class RunConfigurationResult @JvmOverloads constructor( @EncodeDefault(mode = EncodeDefault.Mode.NEVER) val exitCode: Int? = null, @property:McpDescription(Constants.TIMED_OUT_DESCRIPTION) @EncodeDefault(mode = EncodeDefault.Mode.NEVER) val timedOut: Boolean? = false, - val output: String + val output: String, + @property:McpDescription("Path to a temp file containing the full untruncated output. Present only when output was truncated. Use read_file to access the complete log.") + @EncodeDefault(mode = EncodeDefault.Mode.NEVER) + val fullOutputPath: String? = null, ) -} \ No newline at end of file +}