Skip to content

fix(cli): report MCP servers that failed to start (#822) - #827

Open
Vasanthdev2004 wants to merge 2 commits into
mainfrom
fix/822-mcp-check-reports-failures
Open

fix(cli): report MCP servers that failed to start (#822)#827
Vasanthdev2004 wants to merge 2 commits into
mainfrom
fix/822-mcp-check-reports-failures

Conversation

@Vasanthdev2004

@Vasanthdev2004 Vasanthdev2004 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Fixes #822.

zero mcp check looked only at the error returned by registration and then printed "is reachable". RegisterTools is best-effort by design: a server that fails to connect is recorded on the runtime and registration returns nil, so one broken server cannot stop Zero launching. Right for startup, wrong here, since this is the command a user runs precisely when a server is misbehaving.

The failure data already existed as SkippedServer{Name, Err} and nothing in this path read it. It now fails with the recorded error, in both text and JSON.

The test spawns a genuinely missing command rather than stubbing the runtime. The defect was a mismatch between what registration returns and what it records, so a stub could have been written to pass either way. Reverting the fix makes it print:

MCP server broken is reachable. 0 tool(s) available.

Two files, 59 lines added.

One note for CI: TestBuildServeScopeKeepsLexicalPaths fails on my machine on clean main too, because creating a symlink needs a privilege an unelevated Windows shell does not hold. Unrelated to this change.

Summary by CodeRabbit

  • Bug Fixes
    • Improved MCP server checks to reliably detect unreachable servers and surface the underlying connection error when available.
    • Prevented unreachable servers from being incorrectly shown as reachable, including avoiding misleading tool counts.
    • Updated JSON output for mcp check to consistently report an unreachable status and related error details.
  • Tests
    • Added coverage to verify unreachable-server behavior and JSON output formatting for mcp check --json.

`zero mcp check` inspected only the error returned by registration and then
printed "is reachable". RegisterTools is best-effort by design, so a server
that fails to connect is recorded on the runtime and registration returns
nil. That is right for startup, where one bad server must not stop Zero
launching, and wrong here: this is the command a user runs when a server is
misbehaving, and it told them the broken server was fine.

The failure data already existed as SkippedServer{Name, Err}; nothing
consumed it in this path. The check now fails with the recorded error, in
both text and JSON output.

Covered by a test that spawns a genuinely missing command rather than
stubbing the runtime, because the defect was precisely a mismatch between
what registration returns and what it records. Reverting the fix makes it
print "MCP server broken is reachable. 0 tool(s) available."
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

mcp check now detects servers skipped during registration, reports them as unreachable with optional error details, and exits early. Tests cover text and JSON output for a stdio server whose executable cannot start.

Changes

MCP unreachable-server reporting

Layer / File(s) Summary
Detect and validate unreachable MCP servers
internal/cli/mcp_config.go, internal/cli/mcp_trust_edge_test.go
runMCPCheck reports matching skipped servers as unreachable in text or JSON and stops before the reachable-tools response; tests verify failure behavior and JSON fields.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPRuntime
  participant runMCPCheck
  participant CLIOutput
  MCPRuntime->>runMCPCheck: Return skipped server entry
  runMCPCheck->>CLIOutput: Emit unreachable text or JSON status
  runMCPCheck->>CLIOutput: Exit with failure
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change reads skipped MCP servers and reports unreachable errors in text and JSON, matching issue #822.
Out of Scope Changes check ✅ Passed The edits stay focused on MCP check failure reporting and regression tests, with no obvious unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: reporting MCP servers that failed to start as unreachable.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/822-mcp-check-reports-failures

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/cli/mcp_trust_edge_test.go`:
- Around line 243-251: The existing unreachable-server test only validates text
output; extend the test coverage around runWithDeps to exercise the --json
response for the broken server. Decode stdout as JSON and assert serverName,
status equal to "unreachable", and a non-empty redacted error field, while
preserving the existing failure and text-output assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 62b34002-a3a7-459c-b0f2-b99032ed2f7b

📥 Commits

Reviewing files that changed from the base of the PR and between 097c265 and 0ba5c65.

📒 Files selected for processing (2)
  • internal/cli/mcp_config.go
  • internal/cli/mcp_trust_edge_test.go

Comment thread internal/cli/mcp_trust_edge_test.go
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Tests: go test ./...
  • [pass] Build: go run ./cmd/zero-release build
  • [pass] Smoke build: go run ./cmd/zero-release smoke

Scope

Head: 41d8dbf54af1
Changed files (2): internal/cli/mcp_config.go, internal/cli/mcp_trust_edge_test.go

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

The text path was covered and the JSON path was not, though the change
adds its own return with a different payload: status "unreachable" plus a
redacted error, rather than status "ok" with a tool count. A caller
parsing that shape was relying on something nothing pinned.

Reverting the fix now fails both cases. The JSON one is the more useful
of the two, because the wrong output is still valid JSON and would decode
cleanly into a caller expecting success.
@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

Taken in 41d8dbf5. Fair catch: I added a --json return with its own payload and only tested the text path.

The JSON case is the more useful of the two, because reverting the fix leaves it emitting status: "ok" with a tool count, which is still valid JSON and decodes cleanly into a caller expecting success. Now asserts serverName, status: "unreachable", a non-empty error saying so, and that no tool count is implied.

Reverting the fix fails both cases.

@coderabbitai review

@Vasanthdev2004
Vasanthdev2004 requested review from anandh8x and jatmn July 30, 2026 08:34
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

@Vasanthdev2004 Thanks—the JSON assertions cover the important regression: valid JSON must not silently represent a failed server as successful. I’ll review the updated changes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zero mcp check reports success for a server that failed to start

3 participants