fix(smolmachines): run claude mcp add as node so config lands in node's home
provision_supervise dispatched `claude mcp add --scope user` through `smolvm machine_exec`, which runs as root by default. The MCP entry got written to root's ~/.claude.json — but the agent's claude reads /home/node/.claude.json, so `/mcp` showed "No MCP servers configured" inside the bottle. Wrap the exec in `runuser -u node -- env HOME=/home/node ...` so the config writes to the right home. Same pattern as the interactive exec_claude / Bottle.exec wrappers — `smolvm machine_exec` is always root, so any command that touches user state has to switch UID + set HOME explicitly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -487,11 +487,15 @@ class TestProvisionSupervise(unittest.TestCase):
|
||||
_supervise.provision_supervise(plan, "claude-bottle-demo-abc12")
|
||||
ex.assert_called_once()
|
||||
argv = ex.call_args.args[1]
|
||||
# claude mcp add --scope user --transport http supervise <url>
|
||||
# — URL is the agent-side endpoint (host loopback +
|
||||
# discovered port), not the docker bridge IP.
|
||||
# `claude mcp add --scope user` writes to ~/.claude.json,
|
||||
# and the agent is the `node` user — switch UID + set
|
||||
# HOME so the config lands in /home/node/.claude.json,
|
||||
# not root's. URL is the agent-side endpoint (host
|
||||
# loopback + discovered port), not the docker bridge IP.
|
||||
self.assertEqual(
|
||||
[
|
||||
"runuser", "-u", "node", "--",
|
||||
"env", "HOME=/home/node",
|
||||
"claude", "mcp", "add",
|
||||
"--scope", "user",
|
||||
"--transport", "http",
|
||||
|
||||
Reference in New Issue
Block a user