Register ens-forecast-mcp, allow its tools in the shared session and document the weather_ro login it needs.
4.2 KiB
Always-on Remote Control
Reference copy of a machine setup: Claude Code Remote Control running as its own system user claude-rc, so my
projects' read-only MCP servers (now: negsplit, ens-forecast) can be used from the Claude app on the phone. One user and one
session (data) for all projects. The user holds only read-only database logins; Bash runs sandboxed without
network and can't read them (only the MCP servers, which run outside the sandbox, do). Nothing secret in this
folder: the ntfy topic lives only in /etc/claude-rc-notify.env.
Needs claude-code, bubblewrap, socat and each project's MCP server installed. Per project:
-
negsplit: the installed
negsplit(withpython-mcp) and thegarmin_rogrants from itssql/garmin_ro_grants.sql. A per-user query limit is a useful safety net (the session can lift it):mariadb -u root -p -e "ALTER USER 'garmin_ro'@'localhost' WITH MAX_STATEMENT_TIME 30;" -
ens-forecast: the installed
ens-forecast-mcp(withpython-mcpandpython-mysqlclient) and theweather_rogrant from itssql/weather_grants.sql; the same safety net:mariadb -u root -p -e "ALTER USER 'weather_ro'@'localhost' WITH MAX_STATEMENT_TIME 30;"
Setup
Run from this folder. User and folders:
doas useradd --system --create-home --home-dir /var/lib/claude-rc --shell /usr/bin/nologin claude-rc
doas chmod 700 /var/lib/claude-rc
doas install -d -o claude-rc -g claude-rc -m 700 /var/lib/claude-rc/.config /var/lib/claude-rc/.claude /var/lib/claude-rc/data /var/lib/claude-rc/data/.claude
doas install -o claude-rc -g claude-rc -m 644 mcp.json /var/lib/claude-rc/data/.mcp.json
doas install -o claude-rc -g claude-rc -m 644 project-settings.json /var/lib/claude-rc/data/.claude/settings.json
doas install -o claude-rc -g claude-rc -m 644 user-settings.json /var/lib/claude-rc/.claude/settings.json
strictAllowlist must stay in the user settings: in project settings it has no effect.
Each project's config holds only a [readonly] section. negsplit (garmin_ro):
doas install -d -o claude-rc -g claude-rc -m 700 /var/lib/claude-rc/.config/negsplit
doas install -o claude-rc -g claude-rc -m 600 config.toml /var/lib/claude-rc/.config/negsplit/config.toml
ens-forecast (weather_ro): only the [readonly] section of my own config, so the password never shows:
doas install -d -o claude-rc -g claude-rc -m 700 /var/lib/claude-rc/.config/ens-forecast
awk '/^\[/ { keep = ($0 == "[readonly]") } keep' ~/.config/ens-forecast/config.toml | doas install -o claude-rc -g claude-rc -m 600 /dev/stdin /var/lib/claude-rc/.config/ens-forecast/config.toml
Log in, trust the folder and enable Remote Control once, interactively:
doas -u claude-rc sh -c 'cd /var/lib/claude-rc/data && exec claude auth login'
doas -u claude-rc sh -c 'cd /var/lib/claude-rc/data && exec claude'
doas -u claude-rc sh -c 'cd /var/lib/claude-rc/data && exec claude remote-control --name data --spawn session'
ntfy topic for the failure alert (subscribe to it on ntfy.sh), then the units:
doas sh -c 'umask 077; printf "NTFY_TOPIC=claude-rc-%s\n" "$(openssl rand -hex 16)" > /etc/claude-rc-notify.env'
doas install -m 644 claude-rc.service claude-rc-notify.service claude-rc-recover.service claude-rc-recover.timer -t /etc/systemd/system/
doas systemctl daemon-reload
doas systemctl enable --now claude-rc.service claude-rc-recover.timer
The service restarts with a growing delay (30 s to 10 min); after about 50 minutes of failures it gives up and
sends the alert. The timer restarts it every 3 hours if it gave up, so a long network outage doesn't stop it for
good. After upgrading a project's MCP server, or changing mcp.json or the settings, restart claude-rc.service
so phone sessions use the new version.
Adding a project
Add its server to mcp.json and mcp__<server> to the allow list in project-settings.json (plus a Read rule
for its chart folder, if any), install its [readonly] config as above, reinstall the changed files and restart
the service.
Dead login
doas systemctl stop claude-rc.service
doas -u claude-rc sh -c 'cd /var/lib/claude-rc/data && exec claude auth login'
doas systemctl reset-failed claude-rc.service
doas systemctl start claude-rc.service