Skip to content

mcpx: CLI never notices a running daemon from an older binary (no daemon-version check) #265

Closed

Description

@dezren39

Problem

The mcpx CLI in this repo never notices when the daemon it connected to was started by a different (older) binary. After an upgrade, a daemon started by the old binary keeps running, the new CLI talks to it over the socket/url ladder rungs, and a command or field the old daemon lacks fails confusingly instead of saying why.

This is the same defect as dezren39/darwin-nix#344 (fixed there by dezren39/nix PR #386, merged 2026-10-18); this repo's pkgs/mcpx copy does not have that fix.

Evidence (verified on main 2d56eb2, 2026-10-18)

  • The daemon already reports its version: pkgs/mcpx/internal/daemon/server.go handleHealth returns "version": s.version in the GET /v1/health answer.
  • The CLI never reads that field:
    • No DaemonVersion() method in pkgs/mcpx/internal/cli/client.go — the neighbouring Endpoint() parses only endpoint from the same /v1/health answer.
    • No pkgs/mcpx/internal/cli/versioncheck.go exists (no daemonVersionNotice, daemonVersionWarning, or checkDaemonVersion anywhere in pkgs/mcpx/internal/cli/).
    • App.ensure() in pkgs/mcpx/internal/cli/commands.go:81 caches the client/ladder and returns without any version comparison.
  • Therefore a version mismatch is silent on every command that reuses an already-running daemon via the socket or url rungs (Connect in pkgs/mcpx/internal/cli/connect.go).

Why it matters

Upgrades are the normal path (mcpx upgrade, package updates). Without the notice, the first symptom of a stale daemon is a confusing per-command failure, with no hint that mcpx restart --daemon is the fix.

Suggested fix (mirrors dezren39/nix PR #386)

  1. Add Client.DaemonVersion(ctx) in client.go: GET /v1/health, parse version; an older daemon reporting none yields "" with no error (absence is not a mismatch).
  2. Add versioncheck.go: daemonVersionNotice(cli, daemon, remote) — empty when equal or either side empty; otherwise one line naming both versions, with mcpx restart --daemon advice locally and "restart it where it runs" for a remote daemon. checkDaemonVersion only runs for socket/url ladder rungs (spawn/inline daemons run this binary by construction) and is best-effort (a failed health read stays silent).
  3. Call a.checkDaemonVersion(ctx, c, ladder) in ensure() after a successful connect.
  4. Port the regression tests from dezren39/nix (versioncheck_test.go): notice table cases, health-server warning cases (mismatch / matching / no-version / unreachable), and the spawned-daemon skip.

Acceptance criteria

  • With a daemon reporting a different version reached via socket/url, a CLI command prints exactly one stderr notice naming both versions and the restart command.
  • Equal versions, a daemon reporting no version, and spawn/inline daemons produce no notice and no extra health call failure mode.
  • New versioncheck tests pass; go test ./internal/cli/ in pkgs/mcpx is green; ablation (removing the ensure() call) makes the wiring test fail.

Activity

  1. added a commit that references this issue on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions