[object Object]

← back to Mp3 Agentabrams

launchd: two opt-in plists for reboot-survival + tailscale access

066f36574045c7c2d1e61e3a571f0c9476421237 · 2026-05-13 08:36:31 -0700 · steve

Mirrors the ollama-tailscale-bridge pattern:

  com.steve.mp3-agentabrams-server          → node server.js on 127.0.0.1:9696
  com.steve.mp3-agentabrams-tailscale-bridge → socat 100.65.187.120:9696 -> 127.0.0.1:9696

Both: RunAtLoad=true, KeepAlive=true, plutil-lint clean. Logs land in
project logs/. Server plist deliberately omits MP3_HOST so server.js
keeps defaulting to loopback — Tailscale access is layered on top via
the separate bridge plist, never by exposing the server directly.

To enable on Mac2:
  cp launchd/com.steve.mp3-agentabrams-server.plist ~/Library/LaunchAgents/
  cp launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist ~/Library/LaunchAgents/
  launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-server.plist
  launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-tailscale-bridge.plist

Verified post-load:
  loopback 127.0.0.1:9696       = 200
  tailscale 100.65.187.120:9696 = 200
  home LAN 192.168.1.53:9696    = refused

If Tailscale IP ever changes (tailscale ip -4), update bind= in the
tailscale-bridge plist and launchctl unload+load.

Files touched

Diff

commit 066f36574045c7c2d1e61e3a571f0c9476421237
Author: steve <steve@designerwallcoverings.com>
Date:   Wed May 13 08:36:31 2026 -0700

    launchd: two opt-in plists for reboot-survival + tailscale access
    
    Mirrors the ollama-tailscale-bridge pattern:
    
      com.steve.mp3-agentabrams-server          → node server.js on 127.0.0.1:9696
      com.steve.mp3-agentabrams-tailscale-bridge → socat 100.65.187.120:9696 -> 127.0.0.1:9696
    
    Both: RunAtLoad=true, KeepAlive=true, plutil-lint clean. Logs land in
    project logs/. Server plist deliberately omits MP3_HOST so server.js
    keeps defaulting to loopback — Tailscale access is layered on top via
    the separate bridge plist, never by exposing the server directly.
    
    To enable on Mac2:
      cp launchd/com.steve.mp3-agentabrams-server.plist ~/Library/LaunchAgents/
      cp launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist ~/Library/LaunchAgents/
      launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-server.plist
      launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-tailscale-bridge.plist
    
    Verified post-load:
      loopback 127.0.0.1:9696       = 200
      tailscale 100.65.187.120:9696 = 200
      home LAN 192.168.1.53:9696    = refused
    
    If Tailscale IP ever changes (tailscale ip -4), update bind= in the
    tailscale-bridge plist and launchctl unload+load.
---
 launchd/com.steve.mp3-agentabrams-server.plist     | 53 ++++++++++++++++++++++
 ...om.steve.mp3-agentabrams-tailscale-bridge.plist | 52 +++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/launchd/com.steve.mp3-agentabrams-server.plist b/launchd/com.steve.mp3-agentabrams-server.plist
new file mode 100644
index 0000000..283a377
--- /dev/null
+++ b/launchd/com.steve.mp3-agentabrams-server.plist
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+  com.steve.mp3-agentabrams-server — keep the mp3 catalog server alive on Mac2.
+
+  OPT-IN:
+    cp launchd/com.steve.mp3-agentabrams-server.plist ~/Library/LaunchAgents/
+    launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-server.plist
+
+  To disable:
+    launchctl unload -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-server.plist
+    rm ~/Library/LaunchAgents/com.steve.mp3-agentabrams-server.plist
+
+  Server stays loopback-only (MP3_HOST defaults to 127.0.0.1 per server.js).
+  Tailscale access is layered on top via the separate -tailscale-bridge plist.
+-->
+<plist version="1.0">
+<dict>
+  <key>Label</key>
+  <string>com.steve.mp3-agentabrams-server</string>
+
+  <key>ProgramArguments</key>
+  <array>
+    <string>/usr/local/bin/node</string>
+    <string>/Users/stevestudio2/Projects/mp3-agentabrams/server.js</string>
+  </array>
+
+  <key>WorkingDirectory</key>
+  <string>/Users/stevestudio2/Projects/mp3-agentabrams</string>
+
+  <key>RunAtLoad</key>
+  <true/>
+
+  <key>KeepAlive</key>
+  <true/>
+
+  <key>StandardOutPath</key>
+  <string>/Users/stevestudio2/Projects/mp3-agentabrams/logs/server.stdout.log</string>
+  <key>StandardErrorPath</key>
+  <string>/Users/stevestudio2/Projects/mp3-agentabrams/logs/server.stderr.log</string>
+
+  <key>EnvironmentVariables</key>
+  <dict>
+    <key>PATH</key>
+    <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
+    <key>HOME</key>
+    <string>/Users/stevestudio2</string>
+    <key>MP3_PORT</key>
+    <string>9696</string>
+    <!-- DO NOT set MP3_HOST here — let server.js default it to 127.0.0.1. -->
+  </dict>
+</dict>
+</plist>
diff --git a/launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist b/launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist
new file mode 100644
index 0000000..518daae
--- /dev/null
+++ b/launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+  com.steve.mp3-agentabrams-tailscale-bridge
+
+  Mirrors the same pattern as com.steve.ollama-tailscale-bridge: bind socat on
+  the Tailscale IP and forward to the loopback server. Lets devices on the
+  tailnet (e.g. Steve's iPhone in Tucson) reach the mp3 catalog without
+  exposing it to the home LAN or the public internet.
+
+  OPT-IN:
+    cp launchd/com.steve.mp3-agentabrams-tailscale-bridge.plist ~/Library/LaunchAgents/
+    launchctl load -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-tailscale-bridge.plist
+
+  To disable:
+    launchctl unload -w ~/Library/LaunchAgents/com.steve.mp3-agentabrams-tailscale-bridge.plist
+    rm ~/Library/LaunchAgents/com.steve.mp3-agentabrams-tailscale-bridge.plist
+
+  CHECK if Mac2's Tailscale IP ever changes:
+    tailscale ip -4
+  If the IP differs from 100.65.187.120, update bind= below.
+-->
+<plist version="1.0">
+<dict>
+  <key>Label</key>
+  <string>com.steve.mp3-agentabrams-tailscale-bridge</string>
+
+  <key>ProgramArguments</key>
+  <array>
+    <string>/opt/homebrew/bin/socat</string>
+    <string>TCP-LISTEN:9696,bind=100.65.187.120,fork,reuseaddr</string>
+    <string>TCP:127.0.0.1:9696</string>
+  </array>
+
+  <key>RunAtLoad</key>
+  <true/>
+
+  <key>KeepAlive</key>
+  <true/>
+
+  <key>StandardOutPath</key>
+  <string>/Users/stevestudio2/Projects/mp3-agentabrams/logs/socat.stdout.log</string>
+  <key>StandardErrorPath</key>
+  <string>/Users/stevestudio2/Projects/mp3-agentabrams/logs/socat.stderr.log</string>
+
+  <key>EnvironmentVariables</key>
+  <dict>
+    <key>PATH</key>
+    <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
+  </dict>
+</dict>
+</plist>

← adfdb26 server: lock to loopback (127.0.0.1) — was silently bound to  ·  back to Mp3 Agentabrams  ·  broaden .gitignore to cover snapshot/backup/editor cruft a0211fd →