This commit is contained in:
+61
-3
@@ -40,6 +40,22 @@ chown -R 99:100 /mnt/user/appdata/totalmcp
|
|||||||
|
|
||||||
(99:100 = `nobody:users`, the standard Unraid container ownership.)
|
(99:100 = `nobody:users`, the standard Unraid container ownership.)
|
||||||
|
|
||||||
|
### Gather your tokens
|
||||||
|
|
||||||
|
Have these in a scratch file before starting — easier than tab-switching during the GUI install.
|
||||||
|
|
||||||
|
| Token | Where to get it |
|
||||||
|
|---|---|
|
||||||
|
| **`AGENT_TOKENS`** | Generate fresh: `openssl rand -hex 32` (run 3× — one per agent: claude-code, antigravity, codex). Save them — you'll paste the same values into agent configs after install. |
|
||||||
|
| **`GITEA_TOKEN`** | `git.alwisp.com` → your avatar → **Settings** → **Applications** → **Generate New Token**. Scopes: `repo`, `issue`, `read:user`. Copy the token immediately (Gitea won't show it again). |
|
||||||
|
| **`UNRAID_API_KEY`** | On the Unraid host: `unraid-api start`, then `unraid-api key` to print the key. (Requires the unraid-api plugin from Apps.) |
|
||||||
|
| **`OPENCLAW_HOST`** | Already known: `http://10.2.0.26:18789` (NOVA). No token — LAN-only. |
|
||||||
|
| **`UNIFI_API_KEY`** | UniFi Access UI → **Settings** → **Security** → **API Tokens** → **Create**. Scopes: read all, plus the writes you want. |
|
||||||
|
| **`UNIFI_SITE_ID`** | UniFi Access UI URL contains it (`/locations/<UUID>`). Optional. |
|
||||||
|
| **`CODEX_DB_PATH`** | Container path is `/app/codex/db.sqlite` (after the volume mount). Host file: `/mnt/user/appdata/codex/db.sqlite`. |
|
||||||
|
| **`RACKMAPPER_TOKEN`** | RackMapper UI → API tokens. Optional if RackMapper has no auth. |
|
||||||
|
| **`STREAMVAULT_*`** | Skip — service not deployed yet. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Add Container — top-level fields
|
## 1. Add Container — top-level fields
|
||||||
@@ -54,7 +70,7 @@ chown -R 99:100 /mnt/user/appdata/totalmcp
|
|||||||
| **Docker Hub URL** | (leave blank — private registry) |
|
| **Docker Hub URL** | (leave blank — private registry) |
|
||||||
| **Icon URL** | (optional — set later) |
|
| **Icon URL** | (optional — set later) |
|
||||||
| **WebUI** | `http://[IP]:[PORT:8811]/health` |
|
| **WebUI** | `http://[IP]:[PORT:8811]/health` |
|
||||||
| **Extra Parameters** | `--pids-limit=2048` |
|
| **Extra Parameters** | `--pids-limit=2048 --user 0:0` (the `--user 0:0` is needed for the `docker` plugin — see §3) |
|
||||||
| **Post Arguments** | (leave blank) |
|
| **Post Arguments** | (leave blank) |
|
||||||
| **Network Type** | `Custom: br0` |
|
| **Network Type** | `Custom: br0` |
|
||||||
| **Use IPv4 only** | ☑ checked |
|
| **Use IPv4 only** | ☑ checked |
|
||||||
@@ -98,6 +114,8 @@ Click **Add Path** for each row.
|
|||||||
|
|
||||||
> Read-only is enough for `docker_list_containers`/`get_logs`/`get_stats`, but `start`/`stop`/`restart` require RW.
|
> Read-only is enough for `docker_list_containers`/`get_logs`/`get_stats`, but `start`/`stop`/`restart` require RW.
|
||||||
|
|
||||||
|
> ⚠️ **Permission gotcha:** the container runs as the unprivileged `mcp` user, but Unraid's `/var/run/docker.sock` is owned by `root:root` (mode 660). The `mcp` user has no access by default — `docker_list_containers` will return `EACCES`. The simplest fix is to add `--user 0:0` to the **Extra Parameters** field at the top of the Add Container form (run the container as root). For a LAN-only gateway behind bearer auth on a single-tenant box, this tradeoff is acceptable. See troubleshooting §7 for stricter alternatives.
|
||||||
|
|
||||||
### Required if `codex-mrp` plugin is enabled (Phase 3)
|
### Required if `codex-mrp` plugin is enabled (Phase 3)
|
||||||
|
|
||||||
| Container Path | Host Path | Access Mode | Description |
|
| Container Path | Host Path | Access Mode | Description |
|
||||||
@@ -215,6 +233,31 @@ claude mcp add --scope user --transport http totalmcp http://10.2.0.35:8811/mcp
|
|||||||
|
|
||||||
Then run `/mcp` inside Claude Code — the totalmcp tools should appear in the catalog.
|
Then run `/mcp` inside Claude Code — the totalmcp tools should appear in the catalog.
|
||||||
|
|
||||||
|
### Per-plugin smoke tests
|
||||||
|
|
||||||
|
Run these from Claude Code in order of risk (lowest first). Each row = the safest first call to confirm a plugin actually works end-to-end.
|
||||||
|
|
||||||
|
| Plugin | First call | Expected on success | Likely failure mode |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **gitea** | `gitea_list_repos` | `{ repos: [...] }` including the `totalmcp` repo | 401 → `GITEA_TOKEN` missing/wrong scopes |
|
||||||
|
| **unraid** | `unraid_host_summary` | `{ host, os, uptime, cpu, memory, array }` | GraphQL field shape mismatch — adjust queries in `src/plugins/unraid/index.ts` to match your unraid-api version |
|
||||||
|
| **docker** | `docker_list_containers` | ~35 containers from your Unraid stack | `EACCES` on `/var/run/docker.sock` — confirm `--user 0:0` is in Extra Parameters |
|
||||||
|
| **openclaw** | `openclaw_list_models` | List of models on NOVA | Connection timeout → confirm NOVA at `10.2.0.26:18789` is reachable from `10.2.0.35` |
|
||||||
|
| **unifi** | `unifi_list_sites` | List of UniFi Access locations | 404 on `/api/v1/developer/locations` — UniFi Access REST paths vary by version; adjust the plugin's endpoint paths |
|
||||||
|
| **codex-mrp** | `codex_list_work_orders` | `{ workOrders: [...] }` | `no such table: work_orders` — **expected.** Run `sqlite3 /mnt/user/appdata/codex/db.sqlite ".schema"`, then update the SQL in `src/plugins/codex-mrp/index.ts` to match real CODEX table names |
|
||||||
|
| **streamvault** | (skip) | n/a | Service not deployed — `onLoad` will warn at startup, tool calls return connection error. Disable by removing from `ENABLED_PLUGINS` until ready. |
|
||||||
|
| **rackmapper** | `rackmapper_list_racks` | `{ racks: [...] }` | 404 — RackMapper API path may differ; adjust |
|
||||||
|
|
||||||
|
### What to expect on first run
|
||||||
|
|
||||||
|
- **gitea**, **openclaw**, **docker** are highest-confidence. Built against well-documented APIs that haven't drifted.
|
||||||
|
- **unraid**, **unifi** are medium-confidence. APIs evolve between versions; field shapes may need adjustment.
|
||||||
|
- **codex-mrp** is low-confidence. Placeholder SQL by design — needs the real CODEX schema before it works.
|
||||||
|
- **streamvault** will be in failure state until the service exists. Disable for now.
|
||||||
|
- **rackmapper** depends on whether RackMapper has a JSON API; adjust if not.
|
||||||
|
|
||||||
|
Capture each plugin's failure (if any) and we'll fix the schemas/paths in a follow-up pass.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Updates
|
## 6. Updates
|
||||||
@@ -248,9 +291,22 @@ Common causes:
|
|||||||
- **`Invalid environment configuration`** — `AGENT_TOKENS` malformed or `PORT` not a number. Fix the Variable in the Unraid GUI and the container will auto-restart.
|
- **`Invalid environment configuration`** — `AGENT_TOKENS` malformed or `PORT` not a number. Fix the Variable in the Unraid GUI and the container will auto-restart.
|
||||||
- **`Cannot find module ...`** — image was built without one of the new deps (e.g., `dockerode` or `better-sqlite3`). Force-update to pull the latest image.
|
- **`Cannot find module ...`** — image was built without one of the new deps (e.g., `dockerode` or `better-sqlite3`). Force-update to pull the latest image.
|
||||||
|
|
||||||
### `docker` plugin: `docker_connect_failed`
|
### `docker` plugin: `docker_connect_failed` or `EACCES` on socket
|
||||||
|
|
||||||
Confirm the path mapping is `/var/run/docker.sock → /var/run/docker.sock` with **Read/Write** access mode.
|
Most common cause: the container is running as the unprivileged `mcp` user but `/var/run/docker.sock` is owned by `root:root` on the host.
|
||||||
|
|
||||||
|
**Quickest fix:** add `--user 0:0` to **Extra Parameters** on the container (run as root inside the container).
|
||||||
|
|
||||||
|
**Stricter alternatives** if you don't want root in the container:
|
||||||
|
1. Find the docker GID on the host: `stat -c '%g' /var/run/docker.sock` (commonly `281` on Unraid).
|
||||||
|
2. Either:
|
||||||
|
- Override the container's group with `--group-add <GID>` in Extra Parameters, **or**
|
||||||
|
- Rebuild the image with that GID baked in (modify the Dockerfile's `addgroup` step).
|
||||||
|
3. Or run a [docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) in front and point `dockerode` at the proxy URL via a `socketPath` override.
|
||||||
|
|
||||||
|
For a LAN-only gateway behind bearer auth on a single-tenant Unraid box, `--user 0:0` is the pragmatic choice.
|
||||||
|
|
||||||
|
Also confirm the path mapping is `/var/run/docker.sock → /var/run/docker.sock` with **Read/Write** access mode.
|
||||||
|
|
||||||
### `codex-mrp` plugin: `codex_mrp_connect_failed`
|
### `codex-mrp` plugin: `codex_mrp_connect_failed`
|
||||||
|
|
||||||
@@ -292,3 +348,5 @@ If you just want the gateway running with **only the Gitea plugin** to start:
|
|||||||
| Variable `GITEA_TOKEN` | *(your PAT)* |
|
| Variable `GITEA_TOKEN` | *(your PAT)* |
|
||||||
|
|
||||||
Apply, verify with `curl /health`, then expand by adding more variables and updating `ENABLED_PLUGINS` as each phase comes online.
|
Apply, verify with `curl /health`, then expand by adding more variables and updating `ENABLED_PLUGINS` as each phase comes online.
|
||||||
|
|
||||||
|
> **Note:** even the minimal install does **not** need `--user 0:0` since the `docker` plugin isn't enabled. Add `--user 0:0` only when you turn `docker` on.
|
||||||
|
|||||||
Reference in New Issue
Block a user