From 84dc167ca4c0cfb44d1f293a14e735f4062297f9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Dec 2025 14:15:52 +0000 Subject: [PATCH 1/2] feat(flutter_runtime_mcp): include full logs in flutterStop response When stopping a Flutter instance, the tool now returns all buffered stdout and stderr output from the session. This helps agents see what might have failed during build or runtime errors. --- .../lib/src/flutter_runtime_server.dart | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart b/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart index 01cc966e..04aedc02 100644 --- a/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart +++ b/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart @@ -315,7 +315,7 @@ Instance ID: $instanceId // Flutter Stop server.tool( 'flutterStop', - description: 'Stop a running Flutter instance', + description: 'Stop a running Flutter instance. Returns full stdout and stderr logs from the session, useful for debugging build failures or runtime errors.', toolInputSchema: ToolInputSchema( properties: { 'instanceId': {'type': 'string', 'description': 'UUID of the Flutter instance to stop'}, @@ -333,6 +333,10 @@ Instance ID: $instanceId } try { + // Capture buffered output before stopping + final bufferedOutput = instance.bufferedOutput; + final bufferedErrors = instance.bufferedErrors; + await instance.stop(); _instances.remove(instanceId); @@ -342,17 +346,31 @@ Instance ID: $instanceId await SyntheticMainGenerator.cleanup(workingDir); } - return CallToolResult.fromContent( - content: [ - TextContent( - text: - ''' -Flutter instance stopped successfully. + // Build full output including all buffered logs + final outputBuffer = StringBuffer(); + outputBuffer.writeln('Flutter instance stopped successfully.'); + outputBuffer.writeln(); + outputBuffer.writeln('Instance ID: $instanceId'); + outputBuffer.writeln(); + outputBuffer.writeln('=== Full Flutter Output ==='); + outputBuffer.writeln(); -Instance ID: $instanceId -''', - ), - ], + // Append all buffered output + for (final line in bufferedOutput) { + outputBuffer.writeln(line); + } + + // Append any errors + if (bufferedErrors.isNotEmpty) { + outputBuffer.writeln(); + outputBuffer.writeln('=== Errors ==='); + for (final line in bufferedErrors) { + outputBuffer.writeln(line); + } + } + + return CallToolResult.fromContent( + content: [TextContent(text: outputBuffer.toString())], ); } catch (e, stackTrace) { await _reportError(e, stackTrace, 'flutterStop', instanceId: instanceId); From 6cdc7ffe64fbfd5bbb5932fe5dbf083f4a6b1b41 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Dec 2025 14:24:57 +0000 Subject: [PATCH 2/2] fix(flutter_runtime_mcp): show full logs only on startup failure Simplify flutterStart success response to show only essential info (instance ID, working directory, command, VM Service URI). Full logs are only included when startup fails, helping agents debug issues without cluttering successful responses. Reverts the flutterStop changes from the previous commit as those were not intended. --- .../lib/src/flutter_runtime_server.dart | 59 ++++--------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart b/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart index 04aedc02..3411450d 100644 --- a/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart +++ b/packages/flutter_runtime_mcp/lib/src/flutter_runtime_server.dart @@ -182,7 +182,7 @@ class FlutterRuntimeServer extends McpServerBase { return CallToolResult.fromContent(content: [TextContent(text: outputBuffer.toString())]); } - // Build full output with header and all buffered lines + // Success - return concise info without full logs final outputBuffer = StringBuffer(); outputBuffer.writeln('Flutter instance started successfully!'); outputBuffer.writeln(); @@ -195,23 +195,6 @@ class FlutterRuntimeServer extends McpServerBase { if (instance.deviceId != null) { outputBuffer.writeln('Device ID: ${instance.deviceId}'); } - outputBuffer.writeln(); - outputBuffer.writeln('=== Flutter Output ==='); - outputBuffer.writeln(); - - // Append all buffered output - for (final line in instance.bufferedOutput) { - outputBuffer.writeln(line); - } - - // Append any errors - if (instance.bufferedErrors.isNotEmpty) { - outputBuffer.writeln(); - outputBuffer.writeln('=== Errors ==='); - for (final line in instance.bufferedErrors) { - outputBuffer.writeln(line); - } - } return CallToolResult.fromContent(content: [TextContent(text: outputBuffer.toString())]); } catch (e, stackTrace) { @@ -315,7 +298,7 @@ Instance ID: $instanceId // Flutter Stop server.tool( 'flutterStop', - description: 'Stop a running Flutter instance. Returns full stdout and stderr logs from the session, useful for debugging build failures or runtime errors.', + description: 'Stop a running Flutter instance', toolInputSchema: ToolInputSchema( properties: { 'instanceId': {'type': 'string', 'description': 'UUID of the Flutter instance to stop'}, @@ -333,10 +316,6 @@ Instance ID: $instanceId } try { - // Capture buffered output before stopping - final bufferedOutput = instance.bufferedOutput; - final bufferedErrors = instance.bufferedErrors; - await instance.stop(); _instances.remove(instanceId); @@ -346,31 +325,17 @@ Instance ID: $instanceId await SyntheticMainGenerator.cleanup(workingDir); } - // Build full output including all buffered logs - final outputBuffer = StringBuffer(); - outputBuffer.writeln('Flutter instance stopped successfully.'); - outputBuffer.writeln(); - outputBuffer.writeln('Instance ID: $instanceId'); - outputBuffer.writeln(); - outputBuffer.writeln('=== Full Flutter Output ==='); - outputBuffer.writeln(); - - // Append all buffered output - for (final line in bufferedOutput) { - outputBuffer.writeln(line); - } - - // Append any errors - if (bufferedErrors.isNotEmpty) { - outputBuffer.writeln(); - outputBuffer.writeln('=== Errors ==='); - for (final line in bufferedErrors) { - outputBuffer.writeln(line); - } - } - return CallToolResult.fromContent( - content: [TextContent(text: outputBuffer.toString())], + content: [ + TextContent( + text: + ''' +Flutter instance stopped successfully. + +Instance ID: $instanceId +''', + ), + ], ); } catch (e, stackTrace) { await _reportError(e, stackTrace, 'flutterStop', instanceId: instanceId);