Skip to content

Agents

self-host is built to be driven by an agent through plain commands. Paste this one sentence into Claude Code, Codex, OpenCode, OpenClaw or any coding agent:

text
Install the self-host skill from github.com/ajnart/self-host and help me run my own movie server.

Or let the binary write the skill for every agent on the machine: ~/.agents/skills, plus Claude Code, Codex, OpenCode, Pi, Gemini and Hermes when they are installed (Omarchy’s agents read the same folders). self-host skill remove deletes only what it wrote.

bash
self-host skill install

Or use the skills CLI (needs Bun or Node.js):

bash
bunx --bun skills@latest add ajnart/self-host --skill self-host# or: npx --yes skills add ajnart/self-host --skill self-host

The one public skill only routes to the guide built into the binary; installing it deploys nothing. Invoke it with /self-host in Claude Code and OpenClaw, $self-host in Codex. Agents can also start from llms.txt.

bash
self-host skill

prints the agent guide that matches the installed binary: every command it registers, the JSON events, exit codes, Access procedures and the rules below. Run it again after self-host self-update.

Loading the skill conveys intent, never approval. Every change follows the same order:

  1. Inspect with self-host doctor --json, self-host apps info <app> --json and self-host status --json.
  2. Plan: show the person the one self-host install line and what it will do.
  3. Approval: wait for an explicit yes. Anything reachable from the internet needs its own yes that names the risk.
  4. Apply with --yes, which authorizes; it is never a preview flag.
  5. Verify with self-host status --json. A running container or an HTTP 200 is not acceptance: check that the App does its job.
  1. Run self-host status --json first. It answers “where is X?”: each App’s description, addresses and state, plus home, dashboard and profile. With no Project yet it exits 1 with “no Project yet”; run self-host profile --json instead.
  2. If the Profile’s experience is empty, ask once: “Have you run your own server or used Docker before, or is this all new to you?” Save the answer with self-host profile set experience new or self-host profile set experience advanced. A skipped question means new.
  3. New: one question at a time, plain words, a sentence before and after every change, and no talk of Docker, ports or Compose unless Docker must be installed. Advanced: terse, with the exact flags.
  4. At the end of every setup, give the Recap from self-host status --json: each App in plain words with its Address, where the Home folder is, and how to sign in with self-host credentials, never quoting a secret. Then offer self-host share, which prints a postable install line and site link for the Catalog Apps only.
bash
self-host doctor --jsonself-host apps list --jsonself-host apps info ntfy --json# only after approval:self-host install ntfy --exposure local --yes --jsonself-host status --json
  • install, setup, start, stop, restart, update, remove, config set, backup, restore and doctor print one JSON event per line: run.start, step.start, step.ok, step.skip, step.warn, step.fail, step.manual, command, info, pull.progress and run.end.
  • status, profile, debug, credentials, apps list, apps info, logs and host report print one JSON document.
  • Existing keys are stable; new fields are additive.

A step.fail event carries what the agent needs to finish the step by hand:

json
{  "event": "step.fail",  "app": "sonarr",  "step": "download-client",  "error": "qBittorrent refused login",  "url": "http://192.168.1.20:8989",  "credential": "admin",  "hint": "Add qBittorrent under Settings › Download Clients."}
Code Meaning
0 Success.
1 Error. Read the error field of the last run.end or step.fail.
2 Setup incomplete: everything is installed, but at least one Setup step failed.
3 Only Manual steps remain: finish them in the browser, then retry Setup.

After a failure, read self-host debug <app> --json, do what the hint says, then rerun self-host setup <app>. Finished steps are skipped, so reruns are safe.

  • --set app.key=value (repeatable) answers non-secret inputs; --set jellyfin.port=8097 picks a port.
  • --set-file app.key=/path reads a private input from an owner-only file, and =- reads stdin. Never put a secret in a command line, a reply or a file you write. Values land only in the Project’s secrets.env.
  • self-host credentials reveals the shared Admin login and per-App API keys. Use it privately and keep its output out of chat, logs and screenshots.

Set SELF_HOST_HOME to an absolute directory and SELF_HOST_COMPOSE_PROJECT to a unique lowercase name, and keep both the same for every later command.

When the person wants an App that self-host apps list does not have, offer the closest Catalog Apps, then tell the maintainers once:

bash
self-host apps request "<name>" --url <homepage>

For software they want to run anyway, add an Unmanaged app: a Compose file under ~/.self-host/extra/<name>/compose.yml. The CLI lists it with its Address, starts, stops, updates and backs it up, but runs no Setup for it.

self-host · Apache-2.0 · home · apps · docs · github · discord · llms.txt · telemetry