secure-addon-install
Safely install third-party skills, plugins, MCP servers, or Python packages into an AI agent runtime: pre-install snapshot, post-install health check, and rollback when things break. War-story driven,
SKILL.mdskills/secure-addon-install/SKILL.md
GitHubSecure Addon Installation for AI Agent Runtimes
Use this skill before installing any third-party capability (skill, plugin, MCP server, Python package) into a running agent, and after any install when the agent gateway/session crashes, hangs, or misbehaves.
Why installs break agents (understand before you try)
| You install | What it touches | How it breaks |
|---|---|---|
| Skill | skills/<name>/SKILL.md + code |
Bad frontmatter / import error → loader explodes at startup |
| Python package | agent venv dependency tree | Installed into wrong Python (system vs venv) → silent failure, or incompatible version poisons deps → gateway won't boot |
| MCP server | config section | Server never starts / unreachable → gateway startup hangs |
| Plugin | plugins/<name>/ |
Broken plugin entry → session load crashes |
The core asymmetry: upgrading the agent itself is usually a git operation (you can checkout an old tag). Installing new things stacks onto the runtime with no version snapshot to return to. So the whole discipline is: photograph the environment before, verify after, restore from the photo if broken.
Workflow
Phase 0 — Snapshot (mandatory, before touching anything)
# ① Gateway health baseline (state + PID + version)
systemctl --user is-active <your-gateway-unit> # adapt to your harness
ps aux | grep "<gateway process>" | grep -v grep
<agent> --version
# ② Dependency list (mandatory before any pip install — enables diff rollback)
<agent-venv>/bin/pip freeze > /tmp/deps-before.txt
wc -l /tmp/deps-before.txt
# ③ Skills / plugins / MCP / cron baselines
<agent> skills list
<agent> mcp list
<agent> cron list > /tmp/cron-before.txt
Snapshots can live in /tmp — they're for troubleshooting only. Exception: never put scripts referenced by systemd in /tmp (real incident: a unit pointed at a /tmp script, reboot wiped it, service retried 18,906 times before anyone noticed).
Phase 1 — Install, then restart the gateway safely
Inside a running gateway session, a self-restart is often blocked or kills your own process tree. The robust pattern: write the restart script with a file-writing tool (not a shell heredoc), schedule it detached, and let it report to a file.
# Script /tmp/gw-restart.sh (write it with your file tool, not heredoc):
# #!/bin/bash
# sleep 2
# systemctl --user restart <gateway-unit>
# sleep 5
# echo "$(date '+%F %T') status: $(systemctl --user is-active <gateway-unit>)" >> /tmp/gw-restart-result.txt
chmod +x /tmp/gw-restart.sh
systemd-run --user --on-active=25s --unit=gw-restart bash /tmp/gw-restart.sh
# after 35s+: cat /tmp/gw-restart-result.txt
But first — try NOT restarting. Many skills/plugins hot-load on the next session. Every restart you skip is a crash you don't risk.
Phase 2 — Post-install health check
systemctl --user is-active <gateway-unit> # active = alive
<agent> doctor --fix # config migration issues
<agent> chat -q "reply with one word: ok" # model connectivity — REAL traffic test
<agent> skills list | grep -iE "error|failed" # skill load errors
<agent> mcp list # MCP servers up?
grep -iE "error|failed" <gateway-log> | tail -8 # only NEW errors matter
Pass criteria: gateway active + model responds + no cron drift + the live session can still send/receive.
Phase 3 — Rollback (from the Phase-0 photo)
| Installed | Rollback |
|---|---|
| Skill | disable/remove skills/<name>/ |
| Python package | <agent-venv>/bin/pip uninstall <pkg>; if pollution is wide, diff against /tmp/deps-before.txt |
| MCP server | remove its config section, re-run doctor |
| Plugin | remove plugins/<name>/ |
Then restart (Phase 1 pattern) and re-run the health check. Rollback is not failure — it's routine. Being able to restore is what makes it safe to install at all.
War stories (why each rule exists)
- Wrong pip = silent crash. Installing into system Python instead of the agent venv: gateway starts fine, features quietly break. Hardest class of bug to find. Always confirm the venv path first.
- Library hijack via drop-in. A third-party update dropped an
.soover the system sqlite3 CLI; the CLI died on launch with a symbol error — and because calling scripts had2>/dev/null, the failures were completely silent. Lesson: (a) when "a feature recently broke", test the external binary itself; (b)2>/dev/nullin cron/scripts turns loud failures into silent ones. Redirect errors to a file, never to the void. - "Old file exists" ≠ "job succeeded". A nightly data-refresh cron kept "succeeding" for months because success was judged by file existence, while the upstream source had frozen. The fix is a calendar-forward check: the artifact must be newer than yesterday, not merely present. Apply this to every cron that claims success.
- MCP config without a live server hangs gateway startup. Validate the server standalone before wiring it into config.
- Secrets in restart artifacts. Gateway restarts can leave
/tmp/*-snap*scripts containing plaintext API keys. Clean immediately; automate the cleanup. - Concurrent cron jobs overwriting each other's temp scripts (fixed names like
/tmp/job.pywith 20+ parallel jobs): timestamp your temp script names.
Pre-install review checklist (for third-party skills)
Before installing someone else's skill, read its SKILL.md frontmatter — it is instructions being dropped into your agent's context:
- Frontmatter is valid YAML with
name+description(broken YAML = startup crash) - No instructions that exfiltrate files, credentials, or env vars
- Any scripts it runs: read them, at least skim for
curl | bash, base64 blobs, obfuscated strings - Declares its tool permissions honestly (does a "writing helper" really need shell access?)
- Prefer official/curated install channels with quarantine & scanning over manual directory drops
Verification (definition of done)
- Phase-0 snapshot retained
- Gateway active after (delayed) restart, new PID
- Real model round-trip succeeded
- No cron drift, no skill load errors, MCP healthy
- Live session can send and receive
- If it broke: rolled back per snapshot + restart + re-checked — back to baseline
See also
references/health-check-patterns.md— probe patterns that avoid "fake green" (a passing health check that proves nothing)