Skip to content

mcpx: daemon discovery and mirroring ignore MCPX_STATE_DIR — env-default daemon missed by custom listings and its record leaks into the real default dir #305

Closed

Description

@dezren39

Summary

mcpx daemon discovery and mirroring ignore MCPX_STATE_DIR in this repo's pkgs/mcpx copy — the same defect fixed in dezren39/nix as #407 (PR #410), never ported here.

ResolvePaths honours MCPX_STATE_DIR first (pkgs/mcpx/internal/daemon/paths.go:39), so the daemon a plain invocation talks to lives in the env-named directory. But the two places that need to know that treat only the XDG default as "default":

  1. DaemonSearchDirs(primary) (paths.go:248) returns only [primary, DefaultStateDir()]. A listing (mcpx daemons, mcpx stop --all — internal/cli/commands.go:1553) whose own state came from a config file or --paths-state flag therefore never searches the env directory.
  2. mirrorInfoPath() (paths.go:308) returns a mirror path for the env directory, because it only exempts p.State == DefaultStateDir(). The env-default daemon — e.g. a sandboxed daemon whose MCPX_STATE_DIR points inside a sandbox/temp tree — therefore mirrors its record into the real XDG default directory, where a non-sandboxed listing can see it and stop it. That is exactly the leak mirroring was supposed to avoid for default daemons.

Reproduction (verified on main 8fc1fb3)

Ported dezren39/nix PR #410's two regression tests to this copy, unmodified otherwise:

  • TestDaemonSearchDirsIncludesTheEnvStateDir — FAIL: DaemonSearchDirs(custom) = [custom, <xdg>/mcpx], missing the MCPX_STATE_DIR directory entirely.
  • TestWriteInfoDoesNotMirrorTheEnvDefaultDaemon — FAIL: env-default daemon leaked a mirror into the default dir: [{PID:… Socket:<envDir>/daemon.sock …}] — a Paths{State: def}.ListDaemons() in the XDG default returns the env daemon's record.

Both tests pass in dezren39/nix on the fixed code.

Why it matters

Acceptance criteria

Activity

  1. added a commit that references this issue on Oct 20, 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