Configured in my lab. Works well for sysadmin tasks and reporting functions! Thanks for making available. I also included a summary table where the Agent used API versus MCP if it’s useful.
MCP reporting POC
SKILL
TrueNAS lab health (RGY) — all four MCP servers:
truenas-core, truenas-scale, truenas-offsite1, truenas-offsite2.
Read-only. No dismiss/write unless I explicitly authorize.
Per host (MCP): system_info, system_health, list_alerts (dismissed=false), query_pools.
Also (tn-ws.py — MCP has no these APIs):
Core: pool.snapshottask.query
Scale: replication.query
(Offsites are receive-only; expect no local snap/repl tasks.)
RGY (active alerts only; dismissed ignored; INFO success does not grade):
G = reachable, p0 ONLINE/healthy, no active WARNING/CRITICAL, snap/repl not ERROR
Y = reachable + pool OK, but active WARNING (or degraded-but-online)
R = unreachable, pool not ONLINE/unhealthy, CRITICAL/ERROR alert, or task state ERROR
Lab overall = worst host (R > Y > G).
Deliverable:
1. Update canvases/truenas-lab-health.canvas.tsx
- Stats: overall + host G/Y/R (or snap/repl OK counts)
- Callout: lab status
- Host table: RGY | MCP | Host / IP | Version | Uptime | Pool | Active alerts | Snap / repl | Notes
- Snapshot table (Core): ID | Dataset | Schedule | Retain | Enabled | State | Last run
- Replication table (Scale): RGY | Name | Dir | Path | Schedule | Retain | Enc | State | Notes
- RGY pills + matching rowTone; caption with source + timestamp
2. Short chat summary with the same host table
Always mask host IPs as 10.40.0.** (never print last octets).
Clean slate each run — grade only current live state.
MCP vs API (feedback for TrueNAS Labs MCP)
| Needed for this workflow |
MCP |
API (tn-ws.py) |
system_info, system_health, list_alerts(dismissed=false), query_pools |
Yes |
Yes |
| Periodic snapshot tasks (config + state) |
Missing (query_snapshots only) |
pool.snapshottask.query |
| Replication tasks (config + state) |
Missing |
replication.query |
| Grade active alerts only |
Partial — system_health still includes dismissed in alerts[]/alert_count |
Prefer alert.list filtered; or use MCP list_alerts(dismissed=false) |
MCP Build POC
Using the truenas mcp for our truenas-* hosts, build the solution in the workflow diagram in the agent-lab.
Guidelines:
Use the existing repluser as you see fit. Just use default time schedules.
Source pools are the p0/dsMusic, p0/dsHomes, and p0/dsBackups datasets.
Ask few questions and just do it unless creds changes and you need my approval.
Keep track of the MCP versus API functions so we can feed back to the TrueNAS Labs MCP developers.
graph TD
subgraph A[Production Server]
P["1. Take Snapshot (zfs)"] -->|Snapshot Data| B;
end
subgraph B[Backup Orchestrator Server]
B_Job(["2. Native Replication Job"]) -->|Stream Snapshot| O1;
B_Job -->|Stream Snapshot| O2;
end
subgraph Offsite_Storage[Offsite1 & Offsite2 Physical Servers]
direction LR
O1["Offsite1 Pool (p0/Archives)"]
O2["Offsite2 Pool (p0/Archives)"]
style O1 fill:#ffcccc,stroke:#cc0000,stroke-width:2px
style O2 fill:#ffcccc,stroke:#cc0000,stroke-width:2px
end
subgraph Security[🔒 Security & Recovery Protocol]
direction TB
E_Barrier(Dataset Encrypted at Rest)
U_Step(["Manual Unlock"])
end
%% Connections and Flow Logic
%% Replication Flow
B -->|3. Write Data| O1;
B -->|3. Write Data| O2;
%% Offsite State and Recovery
O1 --> E_Barrier;
O2 --> E_Barrier;
E_Barrier -- Requires Key --> U_Step;
U_Step --> |4. Data Available| R[Restore/Browse Data];
%% The full cycle
A --> B;
B --> O1;
B --> O2;
%% Notes and Legend
style B_Job fill:#e6f7ff, stroke:#007bff
style E_Barrier fill:#fff2cc, stroke:#ff9900, stroke-width:2px
subgraph Legend
L1[✅ Key Benefit: Data is unreadable if the physical box is stolen.]
L2[⚙️ Operational Benefit: No scripts needed; uses native TrueNAS GUI.]
end
Workflow is live end-to-end on the lab.
Built
| Step |
Host |
What |
| Snapshots |
truenas-core |
Periodic tasks on p0/dsBackups, p0/dsHomes, p0/dsMusic — every 15m (:00/:15/:30/:45), keep 4h |
| PULL |
truenas-scale |
pull-from-prod-* → p0/Archives/<leaf> via repluser / prod-ssh — :05/:20/:35/:50, keep 8h |
| PUSH + encrypt |
truenas-scale → offsite1/2 |
push-to-offsite{1,2}-* → encrypted p0/Archives/<leaf> — :10/:25/:40/:55, keep 8h |
MCP vs API (feedback for TrueNAS Labs MCP)
| Needed for this workflow |
MCP |
API (tn-ws.py) |
system_info, query_pools, query_datasets, query_snapshots, query_jobs, list_alerts |
Yes |
Yes |
create_dataset (incl. encryption options) |
Yes |
Yes |
Users / repluser / SSH pubkey |
Missing |
user.query/create/update |
| SSH service enable/start |
Missing |
service.* |
| Keychain + host-key scan |
Missing |
keychaincredential.* |
| Periodic snapshot tasks |
Missing |
CORE: pool.snapshottask.*; prove snap: zfs.snapshot.create (CORE has no pool.snapshot.*) |
Replication CRUD + replication.run |
Missing |
replication.query/create/update/run |
| Dataset lock/unlock |
Missing |
pool.dataset.lock/unlock |
zfs allow |
Missing |
SSH as root (SCALE truenas_admin cannot) |
Highest-value MCP adds: replication task CRUD/run, keychain SSH creds, snapshottask CRUD, and CORE-aware snapshot create (zfs.snapshot.create).
Ops notes
- SCALE auth rate-limits rapid
tn-ws.py reconnects — space calls or keep a session.
- PUSH must use
readonly=IGNORE for repluser (cannot set readonly).
- Consider rotating
TN_SCALE_API_KEY — a rate-limit error briefly echoed the key in a local terminal log.