# Homelab MCP Server **Last updated:** 2026-03-21 The homelab MCP (Model Context Protocol) server exposes tools that allow AI assistants (OpenCode/Claude) to interact directly with homelab infrastructure. It runs as a stdio subprocess started by OpenCode on session init. --- ## Location & Config | Item | Path | |------|------| | Server source | `scripts/homelab-mcp/server.py` | | OpenCode config | `~/.config/opencode/opencode.json` | | Runtime | Python 3, `fastmcp` library | | Transport | stdio (started per-session by OpenCode) | Changes to `server.py` take effect on the **next OpenCode session** (the server is restarted each session). --- ## Tool Categories ### 1. Portainer — Docker orchestration Manages containers and stacks across all 5 Portainer endpoints. | Tool | What it does | |------|-------------| | `check_portainer` | Health check — version and stack count | | `list_endpoints` | List all endpoints (Atlantis, Calypso, NUC, Homelab VM, RPi5) | | `list_stacks` | List all stacks, optionally filtered by endpoint | | `get_stack` | Get details of a specific stack by name or ID | | `redeploy_stack` | Trigger GitOps redeploy (pull from Git + redeploy) | | `list_containers` | List running containers on an endpoint | | `get_container_logs` | Fetch recent logs from a container | | `restart_container` | Restart a container | | `start_container` | Start a stopped container | | `stop_container` | Stop a running container | | `list_stack_containers` | List all containers belonging to a stack | **Endpoints:** `atlantis` (id=2), `calypso` (id=443397), `nuc` (id=443398), `homelab` (id=443399), `rpi5` (id=443395) --- ### 2. Gitea — Source control Interacts with the self-hosted Gitea instance at `git.vish.gg`. | Tool | What it does | |------|-------------| | `gitea_list_repos` | List all repos in the org | | `gitea_list_issues` | List open/closed issues for a repo | | `gitea_create_issue` | Create a new issue | | `gitea_list_branches` | List branches for a repo | **Default org:** `vish` — repo names can be `homelab` or `vish/homelab` --- ### 3. AdGuard — Split-horizon DNS Manages DNS rewrite rules on the Calypso AdGuard instance (`192.168.0.250:9080`). Critical context: the wildcard `*.vish.gg → 100.85.21.51` (matrix-ubuntu Tailscale IP) requires specific overrides for services that internal hosts need to reach directly (e.g. `pt.vish.gg`, `sso.vish.gg`, `git.vish.gg` all need `→ 192.168.0.154`). | Tool | What it does | |------|-------------| | `adguard_list_rewrites` | List all DNS overrides | | `adguard_add_rewrite` | Add a new domain → IP override | | `adguard_delete_rewrite` | Remove a DNS override | --- ### 4. NPM — Nginx Proxy Manager Manages reverse proxy hosts and SSL certs on matrix-ubuntu (`192.168.0.154:81`). **Critical cert rule:** Never reuse an existing `npm-N` ID. Always use the next available number when adding new certs. | Tool | What it does | |------|-------------| | `npm_list_proxy_hosts` | List all proxy hosts with domain, forward target, cert ID | | `npm_list_certs` | List all SSL certs with type and expiry | | `npm_get_proxy_host` | Get full details of a proxy host including advanced nginx config | | `npm_update_cert` | Swap the SSL cert on a proxy host | **Cert reference:** | ID | Domain | Type | |----|--------|------| | npm-1 | `*.vish.gg` + `vish.gg` | Cloudflare Origin (proxied only) | | npm-6 | `mx.vish.gg` | Let's Encrypt | | npm-7 | `livekit.mx.vish.gg` | Let's Encrypt | | npm-8 | `*.vish.gg` CF Origin | Cloudflare Origin (all proxied `*.vish.gg`) | | npm-9 | `*.thevish.io` | Let's Encrypt | | npm-10 | `*.crista.love` | Let's Encrypt | | npm-11 | `pt.vish.gg` | Let's Encrypt | | npm-12 | `sso.vish.gg` | Let's Encrypt | --- ### 5. Headscale — Tailnet management Manages nodes and pre-auth keys via SSH to Calypso → `docker exec headscale`. | Tool | What it does | |------|-------------| | `headscale_list_nodes` | List all tailnet nodes with IPs and online status | | `headscale_create_preauth_key` | Generate a new node auth key (with expiry/reusable/ephemeral options) | | `headscale_delete_node` | Remove a node from the tailnet | | `headscale_rename_node` | Rename a node's given name | **Login server:** `https://headscale.vish.gg:8443` **New node command:** `tailscale up --login-server=https://headscale.vish.gg:8443 --authkey= --accept-routes=false` --- ### 6. Authentik — SSO identity provider Manages OAuth2/OIDC apps, providers, and users at `sso.vish.gg`. | Tool | What it does | |------|-------------| | `authentik_list_applications` | List all SSO apps with slug, provider, launch URL | | `authentik_list_providers` | List all OAuth2/proxy providers with PK and type | | `authentik_list_users` | List all users with email and active status | | `authentik_update_app_launch_url` | Update the dashboard tile URL for an app | | `authentik_set_provider_cookie_domain` | Set cookie domain on a proxy provider (must be `vish.gg` to avoid redirect loops) | **Critical:** All Forward Auth proxy providers must have `cookie_domain: vish.gg` or they cause `ERR_TOO_MANY_REDIRECTS`. --- ### 7. Cloudflare — DNS management Manages DNS records for the `vish.gg` zone. | Tool | What it does | |------|-------------| | `cloudflare_list_dns_records` | List all DNS records, optionally filtered by name | | `cloudflare_create_dns_record` | Create a new A/CNAME/TXT record | | `cloudflare_delete_dns_record` | Delete a DNS record by ID | | `cloudflare_update_dns_record` | Update an existing record's content or proxied status | **Proxied (orange cloud):** Most `*.vish.gg` services **Unproxied (DNS-only):** `mx.vish.gg`, `headscale.vish.gg`, `livekit.mx.vish.gg`, `pt.vish.gg`, `sso.vish.gg`, `derp*.vish.gg` --- ### 8. Uptime Kuma — Monitoring Manages monitors and groups via SSH to Pi-5 → SQLite DB manipulation. **Always call `kuma_restart` after adding or modifying monitors** — Kuma caches config in memory. | Tool | What it does | |------|-------------| | `kuma_list_monitors` | List all monitors with type, status, URL/hostname, group | | `kuma_list_groups` | List all group monitors with IDs (for use as `parent_id`) | | `kuma_add_monitor` | Add a new http/port/ping/group monitor | | `kuma_set_parent` | Assign a monitor to a group | | `kuma_restart` | Restart Kuma container to apply DB changes | **Monitor group hierarchy:** ``` Homelab (3) → Atlantis (4), Calypso (49), Concord_NUC (44), Raspberry Pi 5 (91), Guava (73), Setillo (58), Proxmox_NUC (71), Seattle (111), Matrix-Ubuntu (115), Moon (114) ``` --- ### 9. Prometheus — Metrics queries Queries the Prometheus instance at `192.168.0.210:9090`. | Tool | What it does | |------|-------------| | `prometheus_query` | Run a PromQL instant query | | `prometheus_targets` | List all scrape targets and their health | --- ### 10. Grafana — Dashboards & alerts Inspects dashboards and alert rules at `192.168.0.210:3300`. | Tool | What it does | |------|-------------| | `grafana_list_dashboards` | List all dashboards with folder | | `grafana_list_alerts` | List all alert rules and current state | --- ### 11. Media — Sonarr / Radarr / SABnzbd Manages the media download stack on Atlantis. | Tool | What it does | |------|-------------| | `sonarr_list_series` | List TV series, optionally filtered by title | | `sonarr_queue` | Show current Sonarr download queue | | `radarr_list_movies` | List movies, optionally filtered by title | | `radarr_queue` | Show current Radarr download queue | | `sabnzbd_queue` | Show SABnzbd download queue with progress | | `sabnzbd_pause` | Pause the SABnzbd queue | | `sabnzbd_resume` | Resume the SABnzbd queue | --- ### 12. SSH — Remote command execution Runs shell commands on homelab hosts via SSH. | Tool | What it does | |------|-------------| | `ssh_exec` | Run a command on a named host | **Known hosts:** `atlantis`, `calypso`, `setillo`, `setillo-root`, `nuc`, `homelab-vm`, `rpi5`, `pi-5`, `matrix-ubuntu`, `moon`, `olares`, `guava`, `pve`, `seattle-tailscale`, `gl-mt3000` --- ### 13. Filesystem — Local file access Read/write files on the homelab-vm filesystem. | Tool | What it does | |------|-------------| | `fs_read` | Read a file (allowed: `/home/homelab`, `/tmp`) | | `fs_write` | Write a file (allowed: `/home/homelab`, `/tmp`) | | `fs_list` | List directory contents | --- ### 14. Repo — Homelab repository inspection Inspects the homelab Git repository at `/home/homelab/organized/repos/homelab`. | Tool | What it does | |------|-------------| | `list_homelab_services` | List all compose files, optionally filtered by host | | `get_compose_file` | Read a compose file by partial path or name (searches `docker-compose.yml/yaml` and standalone `*.yaml/*.yml` stacks) | --- ### 15. Notifications — ntfy push Sends push notifications via the self-hosted ntfy instance. | Tool | What it does | |------|-------------| | `send_notification` | Send a push notification to ntfy topic | **Default topic:** `homelab-alerts` **Priorities:** `urgent`, `high`, `default`, `low`, `min` --- ### 16. Health checks | Tool | What it does | |------|-------------| | `check_url` | HTTP health check against a URL with expected status code | --- ## Bug Fixes Applied (2026-03-21) | Bug | Symptom | Fix | |-----|---------|-----| | `list_homelab_services` | `AttributeError: 'str' object has no attribute 'parts'` — crashed every call | Changed `str(f).parts` → `f.parts` | | `get_compose_file` | Couldn't find standalone stack files like `homarr.yaml`, `whisparr.yaml` | Extended search to all `*.yaml/*.yml`, prefers `docker-compose.*` when both match | | `check_portainer` | Type error on `stacks.get()` — stacks is a list not a dict | Added `isinstance` guards | | `gitea_create_issue` | Type error on `data['number']` — subscript on `dict \| list` union | Added `isinstance(data, dict)` guard | --- ## Adding New Tools 1. Add helper function (e.g. `_myservice(...)`) to the helpers section 2. Add `@mcp.tool()` decorated function with a clear docstring 3. Update the `instructions=` string in `mcp = FastMCP(...)` with the new category 4. Add `pragma: allowlist secret` to any token/key constants 5. Commit and push — changes take effect next OpenCode session --- ## Related docs - `docs/admin/ai-integrations.md` — AI/LLM integrations overview - `docs/troubleshooting/matrix-ssl-authentik-incident-2026-03-19.md` — NPM cert reference - `docs/services/individual/uptime-kuma.md` — Kuma monitor group reference