Sanitized mirror from private repository - 2026-04-04 00:29:05 UTC
This commit is contained in:
293
docs/admin/mcp-server.md
Normal file
293
docs/admin/mcp-server.md
Normal file
@@ -0,0 +1,293 @@
|
||||
# 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=<key> --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
|
||||
Reference in New Issue
Block a user