{
  "markdown": "# Claude Homelab\n\nCurrent release: 1.4.0.\n\nHomelab plugin hub for Claude Code, Codex, and Gemini. This repository is the source of truth for the `homelab-core` plugin, bundled skill-only integrations, agents, commands, and shared credential bootstrapping.\n\n## Overview\n\n`claude-homelab` serves three roles at once:\n\n- The `homelab-core` plugin published through the Claude marketplace\n- The canonical mono-repo for 16 bundled skill-only service integrations\n- The source for Codex and Gemini extension manifests that mirror the same workflow surface\n\nThe repo root is the plugin root. Do not edit generated copies in `~/.claude/` or `~/.claude/plugins/cache/` directly.\n\n## Installation\n\n### Claude marketplace\n\n```bash\n/plugin marketplace add jmagar/claude-homelab\n/plugin install homelab-core @jmagar-claude-homelab\n```\n\nAfter install, Claude Code downloads the plugin into `~/.claude/plugins/cache/`. No symlinks are created on this path.\n\n### Bash / symlink install\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/jmagar/claude-homelab/main/scripts/install.sh | bash\n```\n\nOr, if you already have the repo cloned:\n\n```bash\n./scripts/install.sh\n```\n\nThe installer:\n\n1. Checks prerequisites (`git`, `jq`, `curl`)\n2. Clones the repo to `~/claude-homelab` (or pulls if it exists)\n3. Runs `setup-creds.sh` — creates `~/.claude-homelab/.env` from `.env.example` with `chmod 600`\n4. Runs `setup-symlinks.sh` — symlinks skills, agents, and commands into `~/.claude/`\n5. Runs `verify.sh` — confirms every symlink and required file is in place\n6. Prints next steps\n\n## Credential Model\n\nAll credentials for every service live in a single file:\n\n```\n~/.claude-homelab/.env\n```\n\nThis file is created from `.env.example` at install time and is never committed. Set it up interactively after install:\n\n```bash\n# Interactive wizard (preferred)\n# Open Claude Code and run:\n/homelab-core:setup\n\n# Or configure manually\n$EDITOR ~/.claude-homelab/.env\n```\n\nSecurity requirements:\n\n- `~/.claude-homelab/.env` must have `chmod 600` (owner read/write only)\n- Never commit `.env` — it is gitignored\n- Never log credentials, even in debug mode\n- Use `.env.example` as the template (tracked in git, placeholder values only)\n\nAll service scripts load credentials via `scripts/load-env.sh`:\n\n```bash\nsource \"${CLAUDE_PLUGIN_ROOT:-$HOME/claude-homelab}/scripts/load-env.sh\"\nload_env_file || exit 1\nvalidate_env_vars \"SERVICE_URL\" \"SERVICE_API_KEY\"\n```\n\n### Environment Variable Reference\n\nVariables are grouped by service. Copy `.env.example` to `~/.claude-homelab/.env` and replace placeholder values.\n\n#### Media\n\n| Variable | Required | Description |\n|---|---|---|\n| `PLEX_URL` | yes | Plex server base URL |\n| `PLEX_TOKEN` | yes | Plex authentication token |\n| `OVERSEERR_URL` | yes | Overseerr base URL (skill) |\n| `OVERSEERR_API_KEY` | yes | Overseerr API key (skill) |\n| `RADARR_URL` | yes | Radarr base URL |\n| `RADARR_API_KEY` | yes | Radarr API key |\n| `RADARR_DEFAULT_QUALITY_PROFILE` | no | Default quality profile ID (default: `1`) |\n| `SONARR_URL` | yes | Sonarr base URL |\n| `SONARR_API_KEY` | yes | Sonarr API key |\n| `SONARR_DEFAULT_QUALITY_PROFILE` | no | Default quality profile ID (default: `1`) |\n| `PROWLARR_URL` | yes | Prowlarr base URL |\n| `PROWLARR_API_KEY` | yes | Prowlarr API key |\n| `TAUTULLI_URL` | yes | Tautulli base URL |\n| `TAUTULLI_API_KEY` | yes | Tautulli API key |\n\n#### Downloads\n\n| Variable | Required | Description |\n|---|---|---|\n| `SABNZBD_URL` | yes | SABnzbd base URL |\n| `SABNZBD_API_KEY` | yes | SABnzbd API key |\n| `QBITTORRENT_URL` | yes | qBittorrent WebUI URL |\n| `QBITTORRENT_USERNAME` | yes | qBittorrent username |\n| `QBITTORRENT_PASSWORD` | yes | qBittorrent password |\n\n#### Infrastructure\n\n| Variable | Required | Description |\n|---|---|---|\n| `UNRAID_SERVER1_NAME` | yes | Display name for first Unraid server |\n| `UNRAID_SERVER1_URL` | yes | Unraid GraphQL endpoint (skill) |\n| `UNRAID_SERVER1_API_KEY` | yes | Unraid API key (skill) |\n| `UNRAID_SERVER2_NAME` | no | Display name for second Unraid server |\n| `UNRAID_SERVER2_URL` | no | Second Unraid GraphQL endpoint |\n| `UNRAID_SERVER2_API_KEY` | no | Second Unraid API key |\n| `UNIFI_URL` | yes | UniFi controller URL (skill) |\n| `UNIFI_USERNAME` | yes | UniFi username |\n| `UNIFI_PASSWORD` | yes | UniFi password |\n| `UNIFI_SITE` | no | UniFi site name (default: `default`) |\n| `TAILSCALE_API_KEY` | yes | Tailscale API key |\n| `TAILSCALE_TAILNET` | yes | Tailscale tailnet name or `-` |\n| `ZFS_HOST` | yes | Host where ZFS commands run |\n| `SWAG_HOST` | yes | SWAG reverse proxy host |\n| `SWAG_CONTAINER_NAME` | no | SWAG container name (default: `swag`) |\n| `SWAG_APPDATA_PATH` | no | SWAG appdata path |\n| `SWAG_COMPOSE_PATH` | no | SWAG compose file path |\n\n#### Utilities and Document Management\n\n| Variable | Required | Description |\n|---|---|---|\n| `LINKDING_URL` | yes | Linkding bookmark manager URL |\n| `LINKDING_API_KEY` | yes | Linkding API token |\n| `MEMOS_URL` | yes | Memos server URL |\n| `MEMOS_API_TOKEN` | yes | Memos API token |\n| `BYTESTASH_URL` | yes | ByteStash snippet manager URL |\n| `BYTESTASH_API_KEY` | yes | ByteStash API key |\n| `PAPERLESS_URL` | yes | Paperless-ngx base URL |\n| `PAPERLESS_API_TOKEN` | yes | Paperless-ngx API token |\n| `RADICALE_URL` | yes | Radicale CalDAV/CardDAV URL |\n| `RADICALE_USERNAME` | yes | Radicale username |\n| `RADICALE_PASSWORD` | yes | Radicale password |\n| `GOTIFY_URL` | yes | Gotify push notification URL (skill) |\n| `GOTIFY_TOKEN` | yes | Gotify app token (skill) |\n\n#### Research and Dev Tools\n\n| Variable | Required | Description |\n|---|---|---|\n| `NOTEBOOKLM_COOKIE` | yes | NotebookLM session cookie |\n| `NOTEBOOKLM_AUTH_JSON` | no | Full auth JSON blob (alternative to cookie) |\n| `NOTEBOOKLM_LOG_LEVEL` | no | Log verbosity (default: `INFO`) |\n| `GITHUB_TOKEN` | yes | GitHub personal access token (gh-address-comments) |\n| `GLANCES_URL` | no | Glances web interface URL |\n| `GLANCES_USERNAME` | no | Glances username (if auth enabled) |\n| `GLANCES_PASSWORD` | no | Glances password (if auth enabled) |\n\n#### MCP Server Variables\n\nEach external MCP plugin has its own block of server-config vars. See `.env.example` for the full list. Key patterns:\n\n| Pattern | Description |\n|---|---|\n| `*_MCP_TOKEN` | Bearer token for MCP server auth |\n| `*_MCP_HOST` | Bind host (default: `0.0.0.0`) |\n| `*_MCP_PORT` | Listen port |\n| `*_MCP_TRANSPORT` | Transport protocol (`streamable-http` or `http`) |\n| `*_MCP_NO_AUTH` | Disable auth (set `true` for local-only installs) |\n| `*_MCP_ALLOW_DESTRUCTIVE` | Allow destructive operations (default: `false`) |\n| `ALLOW_DESTRUCTIVE` | Shared fallback for MCP repos that read this directly |\n| `ALLOW_YOLO` | Shared fallback — skip confirmation prompts |\n| `DOCKER_NETWORK` | Shared Docker network name |\n| `LOG_LEVEL` | Shared log verbosity |\n\n## Commands\n\n### Root Commands\n\n| Command | Argument | Description |\n|---|---|---|\n| `/check` | `[instructions]` | Read the latest screenshot from `~/Pictures/Screenshots` and describe it. Pass optional instructions (e.g., \"extract the text\", \"what error is shown\"). |\n| `/deploy` | `[plugin-name]` | Build and start MCP plugin containers via `docker compose up --build -d`. Deploys all external plugins by default. Pass a plugin name to deploy only that one. Reads compose files from `~/.claude/plugins/cache/claude-homelab/<name>/<version>/`. Skips `tests/` subdirs. Reports a status table with notes on failures. |\n| `/quick-push` | — | Standardized commit-and-push workflow. Checks branch (creates feature branch if on main), bumps version in all manifests, updates `CHANGELOG.md`, stages all changes, commits with co-authorship signature, pushes, then invokes `save-to-md` and writes Neo4j commit graph entries. |\n| `/save-to-md` | `[output-path]` | Document the full session as a Markdown file. Defaults to `docs/sessions/YYYY-MM-DD-description.md`. Creates Neo4j entities and relations for files, services, features, and bugs touched in the session. |\n| `/validate-plan` | `<plan-file-or-text>` | Audit a technical implementation plan against homelab standards. Checks for exposed secrets, correct credential loading pattern (`scripts/load-env.sh`), required docs (`README.md`, `SKILL.md`, references), `confirm=True` gate on destructive actions, and standard directory structure. Outputs a compliance table and required changes list. |\n\n### `/homelab:*` Commands\n\n| Command | Description |\n|---|---|\n| `/homelab:system-resources` | Snapshot CPU, RAM, temperatures, and load average. Identifies high-CPU processes, memory pressure, temperature anomalies, and provides optimization recommendations. Uses `uptime`, `free`, `top`, and `sensors`. |\n| `/homelab:docker-health` | Audit all Docker containers. Flags unexpected exits, restart loops, unhealthy containers, and resource over-use (CPU > 80%, memory > 90%). Provides per-container recommendations. |\n| `/homelab:disk-space` | Analyze disk usage across all mount points. Identifies filesystems above 80% or 95% usage, space hogs, log rotation issues, Docker volume orphans, and suggests cleanup targets. |\n| `/homelab:zfs-health` | Full ZFS health check. Reports pool state (ONLINE/DEGRADED/FAULTED), device errors, checksum errors, resilvering, scrub status, ARC hit ratio, snapshot accumulation, and per-dataset usage. Outputs a health score and prioritized action list. |\n\n### `/notebooklm:*` Commands\n\n| Command | Argument | Description |\n|---|---|---|\n| `/notebooklm:create` | `\"Title\" [url1] [url2] ...` | Create a new NotebookLM notebook. Optionally add URLs, PDFs, Google Docs, YouTube links, audio, video, or image files as sources. Reports the new notebook ID. |\n| `/notebooklm:ask` | `\"question\"` | Chat with NotebookLM about the current notebook. Options: `--json` for source citations, `-n <id>` to target a specific notebook. |\n| `/notebooklm:source` | `add <url\\|file> \\| list \\| wait <id> \\| fulltext <id> \\| add-research \"query\"` | Manage notebook sources. Add a URL or file, list current sources, wait for a source to finish processing, retrieve full text, or trigger web research. Supports `-n <id>` for targeting. |\n| `/notebooklm:generate` | `<type> [\"instructions\"]` | Generate an artifact. Types: `audio`, `video`, `quiz`, `report`, `mind-map`, `flashcards`, `slide-deck`, `infographic`, `data-table`. Each type has format, length, style, and difficulty options. |\n| `/notebooklm:download` | `<type> [output-path]` | Download a generated artifact to a local file. Supports `--all` and `--format json\\|md\\|html`. Artifact must be fully generated first. |\n| `/notebooklm:list` | `[notebooks\\|sources\\|artifacts]` | List notebooks (default), sources in the current notebook, or generated artifacts. Presents results in a table with IDs, names, and status. |\n| `/notebooklm:research` | `\"query\" [--mode fast\\|deep]` | Run web research and import results as notebook sources. Fast mode: 30 seconds to 2 minutes. Deep mode: 15 to 30+ minutes, use `--no-wait` and follow up with `notebooklm research wait --import-all`. |\n\n#### `/notebooklm:generate` Type Reference\n\n| Type | Key Options | Approximate Time |\n|---|---|---|\n| `audio` (podcast) | `--format deep-dive\\|brief\\|critique\\|debate`, `--length short\\|default\\|long` | 10–20 min |\n| `video` | `--format explainer\\|brief`, `--style auto\\|classic\\|whiteboard\\|kawaii\\|...` | 15–45 min |\n| `slide-deck` | `--format detailed\\|presenter`, `--length default\\|short` | 5–15 min |\n| `infographic` | `--orientation landscape\\|portrait\\|square`, `--detail concise\\|standard\\|detailed` | 5–15 min |\n| `report` | `--format briefing-doc\\|study-guide\\|blog-post\\|custom` | 5–15 min |\n| `mind-map` | — | Instant |\n| `data-table` | description required | 5–15 min |\n| `quiz` | `--difficulty easy\\|medium\\|hard`, `--quantity fewer\\|standard\\|more` | 5–15 min |\n| `flashcards` | `--difficulty easy\\|medium\\|hard`, `--quantity fewer\\|standard\\|more` | 5–15 min |\n\nAll types support `-s/--source`, `--language`, `--json`, and `--retry N`.\n\n## Skills\n\n18 skill directories live under `skills/`. Each is an independent unit with a `SKILL.md` (Claude-facing) and typically a `README.md`, `scripts/`, and `references/` directory.\n\n### Core Skills (2)\n\n| Skill | Invocation | Purpose |\n|---|---|---|\n| `homelab-setup` | `/homelab-core:setup` | Interactive credential setup wizard. Guides through configuring `~/.claude-homelab/.env` for each service the user runs. Creates the file from `.env.example` if missing. |\n| `homelab-health` | `/homelab-core:health` | Unified service health dashboard. Runs `scripts/check-health.sh` to curl-check every configured service and outputs a JSON health summary. |\n\n### Service Skills (16)\n\n| Skill | Category | Purpose |\n|---|---|---|\n| `plex` | media | Browse Plex libraries, search media, check active sessions and streams, view recently added content |\n| `radarr` | media | Manage Radarr movie library — search, add, monitor, and track download status |\n| `sonarr` | media | Manage Sonarr TV library — search, add series, monitor seasons and episodes |\n| `prowlarr` | media | Manage Prowlarr indexers — search across all indexers, test connectivity, view stats |\n| `tautulli` | media | Query Tautulli play history, user activity, library stats, and notification logs |\n| `sabnzbd` | downloads | Monitor SABnzbd queue, speed, and history; manage download jobs |\n| `qbittorrent` | downloads | Manage qBittorrent torrents — list, add, pause, resume, and remove downloads |\n| `tailscale` | infrastructure | Query Tailscale network status, list devices, check connectivity, and manage ACLs |\n| `zfs` | infrastructure | ZFS pool and dataset management — status, snapshots, scrubs, and space reporting |\n| `linkding` | utilities | Manage Linkding bookmarks — search, add, tag, and organize saved links |\n| `memos` | utilities | Create and query Memos notes — add quick notes, search by tag or content |\n| `bytestash` | utilities | Manage ByteStash code snippets — save, search, and retrieve frequently-used code |\n| `paperless-ngx` | utilities | Search and manage Paperless-ngx document archive — query by content, tag, or correspondent |\n| `radicale` | utilities | Interact with Radicale CalDAV/CardDAV — list calendars and contacts, query events |\n| `notebooklm` | research | NotebookLM CLI wrapper for deep AI research, source management, Q&A, and artifact generation |\n| `gh-address-comments` | dev-tools | Address GitHub PR review comments — fetch, triage, and resolve review feedback |\n\n## Agents\n\n### `notebooklm-specialist`\n\n**File:** `agents/notebooklm-specialist.md`\n\n**Color:** magenta\n\n**Tools:** `Bash`, `Read`, `Write`, `SendMessage`\n\n**Memory:** user (persistent across sessions)\n\nThe `notebooklm-specialist` is a research analyst agent for deep AI-powered research workflows. It is spawned by an orchestrator with a pre-created notebook ID, output directory, and research brief. The agent:\n\n1. Starts deep web research immediately (`notebooklm source add-research --mode deep --no-wait`) — this is always the first action since it takes 15–30+ minutes\n2. Adds source URLs relayed from the orchestrator as they arrive (max 50 per notebook)\n3. Waits for deep research to complete and auto-imports discovered sources\n4. Conducts an extensive Q&A session (10–20 questions across overview, comparison, technical, critical, practical, and future-directions categories)\n5. Uses `--json` flag to capture citation data with every answer\n6. Writes findings to `{output_dir}/findings/notebooklm-findings.md`\n7. Signals completion to the orchestrator via `SendMessage`\n\n**Critical constraint:** Always use `-n <notebook_id>` or `--notebook <notebook_id>`. Never use `notebooklm use <id>` — that command modifies shared state and is unsafe in parallel workflows.\n\nThe agent maintains persistent memory of effective research query patterns, timing benchmarks, and NotebookLM-specific quirks across sessions.\n\n## Marketplace Scope\n\nThe `.claude-plugin/marketplace.json` catalog covers 27 plugins total.\n\n### 1 core plugin\n\n| Plugin | Source | Description |\n|---|---|---|\n| `homelab-core` | this repo | Agents, commands, setup/health skills, and the bundled skill library |\n\n### 10 external MCP repos\n\n| Plugin | Repo | Category |\n|---|---|---|\n| `overseerr-mcp` | `jmagar/overseerr-mcp` | media |\n| `unraid-mcp` | `jmagar/unraid-mcp` | infrastructure |\n| `unifi-mcp` | `jmagar/unifi-mcp` | infrastructure |\n| `gotify-mcp` | `jmagar/gotify-mcp` | utilities |\n| `swag-mcp` | `jmagar/swag-mcp` | infrastructure |\n| `synapse-mcp` | `jmagar/synapse-mcp` | infrastructure |\n| `arcane-mcp` | `jmagar/arcane-mcp` | infrastructure |\n| `syslog-mcp` | `jmagar/syslog-mcp` | infrastructure |\n| `plugin-lab` | `jmagar/plugin-lab` | dev-tools |\n\n### 16 bundled skill-only plugins\n\n`bytestash`, `gh-address-comments`, `linkding`, `memos`, `notebooklm`, `paperless-ngx`, `plex`, `prowlarr`, `qbittorrent`, `radarr`, `radicale`, `sabnzbd`, `sonarr`, `tailscale`, `tautulli`, `zfs`\n\nThese are listed individually in the marketplace catalog so users can discover them, but they are sourced from `./skills/*` within this repo. A bundled skill graduates to its own external repo when it gains additional plugin surface area (agents, commands, hooks, MCP servers, output styles, or channels).\n\n## Symlink Architecture\n\nThe bash install path creates symlinks from this repo into `~/.claude/` so Claude Code discovers all skills, agents, and commands. The plugin path uses `~/.claude/plugins/cache/` instead and requires no symlinks.\n\n```\n~/.claude/\n├── agents/\n│   └── notebooklm-specialist.md → ~/claude-homelab/agents/notebooklm-specialist.md\n├── skills/\n│   ├── bytestash/               → ~/claude-homelab/skills/bytestash/\n│   ├── gh-address-comments/     → ~/claude-homelab/skills/gh-address-comments/\n│   ├── homelab-health/          → ~/claude-homelab/skills/homelab-health/\n│   ├── homelab-setup/           → ~/claude-homelab/skills/homelab-setup/\n│   ├── linkding/                → ~/claude-homelab/skills/linkding/\n│   ├── memos/                   → ~/claude-homelab/skills/memos/\n│   ├── notebooklm/              → ~/claude-homelab/skills/notebooklm/\n│   ├── paperless-ngx/           → ~/claude-homelab/skills/paperless-ngx/\n│   ├── plex/                    → ~/claude-homelab/skills/plex/\n│   ├── prowlarr/                → ~/claude-homelab/skills/prowlarr/\n│   ├── qbittorrent/             → ~/claude-homelab/skills/qbittorrent/\n│   ├── radarr/                  → ~/claude-homelab/skills/radarr/\n│   ├── radicale/                → ~/claude-homelab/skills/radicale/\n│   ├── sabnzbd/                 → ~/claude-homelab/skills/sabnzbd/\n│   ├── sonarr/                  → ~/claude-homelab/skills/sonarr/\n│   ├── tailscale/               → ~/claude-homelab/skills/tailscale/\n│   ├── tautulli/                → ~/claude-homelab/skills/tautulli/\n│   └── zfs/                     → ~/claude-homelab/skills/zfs/\n└── commands/\n    ├── check.md                 → ~/claude-homelab/commands/check.md\n    ├── deploy.md                → ~/claude-homelab/commands/deploy.md\n    ├── quick-push.md            → ~/claude-homelab/commands/quick-push.md\n    ├── save-to-md.md            → ~/claude-homelab/commands/save-to-md.md\n    ├── validate-plan.md         → ~/claude-homelab/commands/validate-plan.md\n    ├── homelab/                 → ~/claude-homelab/commands/homelab/\n    └── notebooklm/              → ~/claude-homelab/commands/notebooklm/\n\n~/.claude-homelab/\n├── .env                         # Credentials (chmod 600, never committed)\n└── load-env.sh                  # Copied from scripts/load-env.sh at install\n```\n\n### How Slash Commands Work\n\nSlash commands are created by placing `.md` files in `~/.claude/commands/`. Claude Code discovers them automatically.\n\n- `commands/proxy.md` → `/proxy`\n- `commands/homelab/docker-health.md` → `/homelab:docker-health`\n\nThe directory name becomes the namespace prefix. The file name becomes the command after the colon.\n\n## Configuration System\n\n### Command Files (`commands/`)\n\nEach command is a Markdown file with a YAML frontmatter block:\n\n```yaml\n---\ndescription: Short description shown in autocomplete\nargument-hint: <required> [optional]\nallowed-tools: Bash(tool:*), mcp__plugin_name__tool\n---\n\nTask instruction using $ARGUMENTS\n```\n\nKey fields:\n\n- `description` — shown in autocomplete menu\n- `argument-hint` — hint text for expected arguments\n- `allowed-tools` — pre-approved tools (no permission prompts at runtime)\n- `$ARGUMENTS` — replaced with user input after the command name\n- `` !`command` `` — dynamic context injection: runs the shell command and injects its output at load time\n\n### Prompts Sidecar System (`prompts/`)\n\nCommand prompt bodies can be extracted to `.toml` sidecar files in `prompts/`, keeping command metadata (frontmatter, description) separate from the prompt content. When populated, the directory mirrors the `commands/` structure:\n\n- `prompts/check.toml` — prompt body for `/check`\n- `prompts/homelab/docker-health.toml` — prompt body for `/homelab:docker-health`\n\nFormat:\n\n```toml\nname = \"command-name\"\ndescription = \"Short description\"\nprompt = \"\"\"\nPrompt body with instructions and dynamic context injection.\n\"\"\"\n```\n\nThe `prompts/` directory is not present by default. Create it if you extract prompts out of command `.md` files.\n\n### Output Styles (`output-styles/`)\n\nThe `output-styles/` directory is reserved for custom response format definitions. It is currently empty (`.gitkeep` placeholder). Add output style files here when commands need to enforce a specific response structure.\n\n## Development\n\n### Adding a New Service Skill\n\n1. Create the skill directory:\n   ```bash\n   mkdir -p skills/service-name/{scripts,references,examples}\n   ```\n\n2. Create `SKILL.md` with frontmatter (`name`, `description`), a mandatory invocation section, command documentation, and workflow decision trees.\n\n3. Create `README.md` for user-facing setup instructions.\n\n4. Implement scripts in `scripts/`. All scripts must:\n   - Use `source \"$REPO_ROOT/scripts/load-env.sh\"` for credentials\n   - Return JSON output\n   - Handle errors gracefully\n   - Support `--help`\n\n5. Add reference docs in `references/` (`api-endpoints.md`, `quick-reference.md`, `troubleshooting.md`).\n\n6. Create the symlink (bash path):\n   ```bash\n   ln -sf ~/claude-homelab/skills/service-name ~/.claude/skills/service-name\n   ```\n   Or re-run `./scripts/setup-symlinks.sh` to pick it up automatically.\n\n7. Add the skill to the marketplace catalog if it should be discoverable:\n   - Edit `.claude-plugin/marketplace.json`\n   - Add a `bundled` entry pointing to `./skills/service-name`\n\n8. Update this README's Skills table.\n\n### Adding a New Command\n\nSingle command (`/new-command`):\n\n```bash\ntouch commands/new-command.md\nln -sf ~/claude-homelab/commands/new-command.md ~/.claude/commands/new-command.md\n```\n\nNamespaced command (`/service:action`):\n\n```bash\nmkdir -p commands/service-name\ntouch commands/service-name/action.md\nln -sf ~/claude-homelab/commands/service-name ~/.claude/commands/service-name\n```\n\n### Credential Pattern\n\nAll scripts must source `scripts/load-env.sh` (see [Credential Model](#credential-model) above for the full pattern and variable naming conventions).\n\n## Verification\n\nRun after any structural change:\n\n```bash\n./scripts/verify.sh\n```\n\nThe verify script checks:\n\n- All required symlinks exist and point to valid targets\n- `~/.claude-homelab/.env` exists\n\nAdditional checks:\n\n```bash\n# Run all Justfile validation targets\njust validate\n\n# Spot-check section headers across key docs\nrtk rg -n \"^## \" README.md AGENTS.md CLAUDE.md\n```\n\n## Repository Layout\n\n```\nagents/                 Top-level specialist agents\ncommands/               Slash command definitions (.md files)\ncommands/homelab/       /homelab:* command definitions\ncommands/notebooklm/    /notebooklm:* command definitions\ndocs/                   Session logs and reference documentation\ndocs/references/        Shared reference docs (security-patterns.md)\nhooks/                  Reserved for future Claude Code hook definitions\noutput-styles/          Reserved for custom response format definitions\nscripts/                Install, setup, credential loading, and verification helpers\nskills/                 18 service and core skill directories\n.claude-plugin/         Claude marketplace manifest (plugin.json, marketplace.json)\n.codex-plugin/          Codex plugin manifest\ngemini-extension.json   Gemini extension manifest\nAGENTS.md               Repo-wide development instructions\nCLAUDE.md               Claude-facing project instructions\nCHANGELOG.md            Release history\n.env.example            Shared credential template (tracked, no secrets)\nJustfile                Validation and maintenance recipes\n```\n\n## Related Files\n\n- `AGENTS.md` — canonical development and repo-structure guidance\n- `CLAUDE.md` — Claude-facing project instructions including symlink architecture, command format, and skill development workflow\n- `.env.example` — shared credential template for all 16 services and 10 MCP repos\n- `.claude-plugin/marketplace.json` — marketplace source of truth (27 plugin entries)\n- `.claude-plugin/plugin.json` — `homelab-core` plugin manifest\n- `CHANGELOG.md` — release history\n- `docs/references/security-patterns.md` — reusable patterns for input sanitization, injection prevention, and API key protection\n\n## Related plugins\n\n| Plugin | Category | Description |\n|--------|----------|-------------|\n| [overseerr-mcp](https://github.com/jmagar/overseerr-mcp) | media | Search movies and TV shows, submit requests, and monitor failed requests via Overseerr. |\n| [unraid-mcp](https://github.com/jmagar/unraid-mcp) | infrastructure | Query, monitor, and manage Unraid servers: Docker, VMs, array, parity, and live telemetry. |\n| [unifi-mcp](https://github.com/jmagar/unifi-mcp) | infrastructure | Monitor and manage UniFi devices, clients, firewall rules, and network health. |\n| [gotify-mcp](https://github.com/jmagar/gotify-mcp) | utilities | Send and manage push notifications via a self-hosted Gotify server. |\n| [swag-mcp](https://github.com/jmagar/swag-mcp) | infrastructure | Create, edit, and manage SWAG nginx reverse proxy configurations. |\n| [synapse-mcp](https://github.com/jmagar/synapse-mcp) | infrastructure | Docker management (Flux) and SSH remote operations (Scout) across homelab hosts. |\n| [arcane-mcp](https://github.com/jmagar/arcane-mcp) | infrastructure | Manage Docker environments, containers, images, volumes, networks, and GitOps via Arcane. |\n| [syslog-mcp](https://github.com/jmagar/syslog-mcp) | infrastructure | Receive, index, and search syslog streams from all homelab hosts via SQLite FTS5. |\n| [plugin-lab](https://github.com/jmagar/plugin-lab) | dev-tools | Scaffold, review, align, and deploy homelab MCP plugins with agents and canonical templates. |\n\n## License\n\nMIT\n",
  "bytes": 26849,
  "sha": "3a347957c5118b47bb9c66c9a952bf436cfc61ad3db25de43837afa79dca6eb1",
  "repo_slug": "jmagar/claude-homelab",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_jmagar_claude_homelab_1230dede/readme"
}