Skip to content

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

Open
Vasanthdev2004 wants to merge 1 commit into
mainfrom
fix/822-mcp-check-reports-failures
Open

fix(cli): report MCP servers that failed to start (#822)#827
Vasanthdev2004 wants to merge 1 commit 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 accurately report when a server is unreachable, including the underlying connection error when available.
    • Prevented unreachable servers from being incorrectly reported as reachable or showing available tools.
    • Added consistent unreachable status reporting for JSON output.

`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. A test covers 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; the test verifies failed startup behavior.

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

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Linked Issues check ✅ Passed The change reads Runtime.Skipped() and reports unreachable servers with the recorded error, matching issue #822.
Out of Scope Changes check ✅ Passed The PR only adds the skipped-server handling and a targeted test for the reported failure case.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 on lines +243 to +251
if code := runWithDeps([]string{"mcp", "check", "broken"}, &out, &errBuf, deps); code == exitSuccess {
t.Fatalf("mcp check must fail for a server that did not start; stdout=%q stderr=%q", out.String(), errBuf.String())
}
if got := out.String(); strings.Contains(got, "is reachable") {
t.Fatalf("mcp check reported a failed server as reachable: %q", got)
}
if got := errBuf.String(); !strings.Contains(got, "not reachable") {
t.Fatalf("want an unreachable error naming the server, got %q", got)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover the JSON unreachable response.

This only exercises text output. Add a --json case that decodes stdout and asserts serverName, status: "unreachable", and a non-empty redacted error; the PR changes that contract too.

As per coding guidelines, “**/*_test.go: Keep tests beside their source files … and add a regression test for behavior changes.”

🤖 Prompt for 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.

In `@internal/cli/mcp_trust_edge_test.go` around lines 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.

Source: Coding guidelines

@github-actions

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: 0ba5c65b0fa3
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.

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

2 participants