Dev-ergonomics issue, not a user-facing bug. Surfaced repeatedly while doing live QA of #927 and #930, where it forced awkward workarounds and caused one accidental mutation of real user state.
The problem
The tray resolves its paths via homeDirectoryForCurrentUser, which ignores $HOME. So a tray built from a branch and run out of a /tmp bundle copy still reads and writes the real ~/.mcpproxy. There is no instance-root override.
Two concrete consequences observed:
1. The socket path is fixed. ~/.mcpproxy/mcpproxy.sock is the only path a dev tray will use, so an isolated core must be started with --tray-endpoint unix:///Users/<user>/.mcpproxy/mcpproxy.sock to be found at all. It also makes the socket a machine-wide exclusive resource: two QA runs cannot proceed in parallel, and one will silently attach to the other's core and produce garbage results. That happened during this batch and had to be resolved by explicit sequencing.
2. The autostart sidecar silently overwrites real user state. AutostartSidecarService.refresh() reads AutoStartService.isEnabled (the running bundle's SMAppService login-item state) and writes it to ~/.mcpproxy/tray-autostart.json on every app launch. A copied bundle under /tmp is not a registered login item, so it writes {"enabled":false} straight over the user's {"enabled":true}. Observed and restored by hand during QA; the value was wrong for about seven minutes. Impact while wrong is limited to the core's telemetry autostart reporting — the actual login-item registration is only ever read, never changed — but the write is silent and unexpected.
For a normal user with a single installed app, both behaviours are correct. The gap is that there is no supported way to run a second instance.
Suggested direction
#926 already made socketPath injectable for tests. Extending that to the sidecar path would fix the immediate hazard, but the cleaner fix is a single instance-root override — an env var (e.g. MCPPROXY_HOME) or launch argument that relocates the socket, the sidecar file, and anything else resolved under ~/.mcpproxy in one move.
That would make tray QA safe by construction rather than by discipline, and would let independent tray runs proceed in parallel instead of being serialized on a hardcoded path.
Dev-ergonomics issue, not a user-facing bug. Surfaced repeatedly while doing live QA of #927 and #930, where it forced awkward workarounds and caused one accidental mutation of real user state.
The problem
The tray resolves its paths via
homeDirectoryForCurrentUser, which ignores$HOME. So a tray built from a branch and run out of a/tmpbundle copy still reads and writes the real~/.mcpproxy. There is no instance-root override.Two concrete consequences observed:
1. The socket path is fixed.
~/.mcpproxy/mcpproxy.sockis the only path a dev tray will use, so an isolated core must be started with--tray-endpoint unix:///Users/<user>/.mcpproxy/mcpproxy.sockto be found at all. It also makes the socket a machine-wide exclusive resource: two QA runs cannot proceed in parallel, and one will silently attach to the other's core and produce garbage results. That happened during this batch and had to be resolved by explicit sequencing.2. The autostart sidecar silently overwrites real user state.
AutostartSidecarService.refresh()readsAutoStartService.isEnabled(the running bundle'sSMAppServicelogin-item state) and writes it to~/.mcpproxy/tray-autostart.jsonon every app launch. A copied bundle under/tmpis not a registered login item, so it writes{"enabled":false}straight over the user's{"enabled":true}. Observed and restored by hand during QA; the value was wrong for about seven minutes. Impact while wrong is limited to the core's telemetry autostart reporting — the actual login-item registration is only ever read, never changed — but the write is silent and unexpected.For a normal user with a single installed app, both behaviours are correct. The gap is that there is no supported way to run a second instance.
Suggested direction
#926 already made
socketPathinjectable for tests. Extending that to the sidecar path would fix the immediate hazard, but the cleaner fix is a single instance-root override — an env var (e.g.MCPPROXY_HOME) or launch argument that relocates the socket, the sidecar file, and anything else resolved under~/.mcpproxyin one move.That would make tray QA safe by construction rather than by discipline, and would let independent tray runs proceed in parallel instead of being serialized on a hardcoded path.