You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The test, packages_get, and packages_check_licenses MCP tools run the CLI in-process and surface only a synthesized line such as "test" failed with exit code 69. in the CallToolResult. The actual command output — failing test names, assertion messages, compile errors, coverage details — is written by the in-process mason Logger to the MCP server's stdout/stderr, which under the stdio transport is shared with the JSON-RPC message stream. Non-MCP lines on stdout violate the stdio transport contract (the server MUST NOT write anything to stdout that is not a valid MCP message) and are dropped by the client, so the agent only ever sees the opaque exit code and cannot diagnose the failure.
Exit code 69 (ExitCode.unavailable) is especially unhelpful: the test command collapses every failure mode — compile error, failed assertion, unmet --min-coverage, thrown exception — into that single code (lib/src/commands/test/test.dart, lib/src/cli/test_cli_runner.dart).
Steps To Reproduce
Run the very_good_cli MCP test tool on a package whose tests fail (or fail to compile).
Observe the tool result: "test" failed with exit code 69. with no failing test names, error messages, or compile output.
Expected Behavior
The tool result should include the captured command output (the real failure detail) in the CallToolResultcontent, with isError: true, so the agent can act on it. Per the MCP spec, tool-execution failures are reported inside the result with isError: true and the human-readable detail in content — not as a bare status line.
Capture the in-process Logger output via an IOOverridesstdout/stderr redirect and include a bounded tail in content. Note: the Logger must be constructed inside the zone, since mason captures IOOverrides.current at construction time.
Or run the CLI as a subprocess with piped stdout/stderr (cleaner separation from the JSON-RPC stream, at the cost of in-process speed/testability).
Output should be size-bounded and scrubbed of secrets (e.g. --dart-define values, tokens in stack traces).
Optionally stream progress via the MCP logging capability (notifications/message) rather than the process stderr.
Description
The
test,packages_get, andpackages_check_licensesMCP tools run the CLI in-process and surface only a synthesized line such as"test" failed with exit code 69.in theCallToolResult. The actual command output — failing test names, assertion messages, compile errors, coverage details — is written by the in-process masonLoggerto the MCP server'sstdout/stderr, which under the stdio transport is shared with the JSON-RPC message stream. Non-MCP lines onstdoutviolate the stdio transport contract (the server MUST NOT write anything tostdoutthat is not a valid MCP message) and are dropped by the client, so the agent only ever sees the opaque exit code and cannot diagnose the failure.Exit code
69(ExitCode.unavailable) is especially unhelpful: thetestcommand collapses every failure mode — compile error, failed assertion, unmet--min-coverage, thrown exception — into that single code (lib/src/commands/test/test.dart,lib/src/cli/test_cli_runner.dart).Steps To Reproduce
testtool on a package whose tests fail (or fail to compile)."test" failed with exit code 69.with no failing test names, error messages, or compile output.Expected Behavior
The tool result should include the captured command output (the real failure detail) in the
CallToolResultcontent, withisError: true, so the agent can act on it. Per the MCP spec, tool-execution failures are reported inside the result withisError: trueand the human-readable detail incontent— not as a bare status line.Additional Context
_runToolCommandinlib/src/mcp/mcp_server.dart) as thedirectorybug (vgv-ai-flutter-plugin feat #70 doesn't work #1599 / fix(mcp): applydirectoryargument as the working directory #1600).testresult is opaque.Loggeroutput via anIOOverridesstdout/stderrredirect and include a bounded tail incontent. Note: theLoggermust be constructed inside the zone, since mason capturesIOOverrides.currentat construction time.stdout/stderr(cleaner separation from the JSON-RPC stream, at the cost of in-process speed/testability).--dart-definevalues, tokens in stack traces).loggingcapability (notifications/message) rather than the processstderr.