mirror of
https://github.com/jmagar/unraid-mcp.git
synced 2026-03-23 12:39:24 -07:00
Resolves review threads: - PRRT_kwDOO6Hdxs50T0Wp (test-destructive.sh: add key cleanup on failure path) - PRRT_kwDOO6Hdxs50T0Ws (test-destructive.sh: pick last notification match by title) - PRRT_kwDOO6Hdxs50T0Wt (README.md: correct test-actions.sh coverage description) - PRRT_kwDOO6Hdxs50T0Wv (CLAUDE.md: add info.update_ssh to destructive actions list) - PRRT_kwDOO6Hdxs50T0Wy (http_layer test: inp["config"] -> inp["parameters"]) - PRRT_kwDOO6Hdxs50T0Wz (DESTRUCTIVE_ACTIONS.md: key ID extraction key.id not top-level) - PRRT_kwDOO6Hdxs50T0W2 (DESTRUCTIVE_ACTIONS.md: delete_archived — add archive step) - PRRT_kwDOO6Hdxs50T0W3 (DESTRUCTIVE_ACTIONS.md: rclone params provider_type/config_data/name) - PRRT_kwDOO6Hdxs50T0W4 (DESTRUCTIVE_ACTIONS.md: notification delete list+match pattern) - PRRT_kwDOO6Hdxs50T0W5 (DESTRUCTIVE_ACTIONS.md: create_folder uses folder_name param) - PRRT_kwDOO6Hdxs50T0W7 (README.md: cleanup note — test-tools.sh may write tmp log file) Changes: - test-destructive.sh keys test: attempt key delete cleanup when delete step fails - test-destructive.sh notifications test: reverse list to pick most-recent title match - tests/mcporter/README.md: accurate coverage claim; accurate cleanup section - CLAUDE.md: info.update_ssh added to destructive actions list - tests/http_layer/test_request_construction.py: assert parameters not config field - docs/DESTRUCTIVE_ACTIONS.md: all 5 example code blocks corrected with right parameter names, correct ID extraction paths, and proper sequencing Co-authored-by: Claude <noreply@anthropic.com>
152 lines
6.5 KiB
Markdown
152 lines
6.5 KiB
Markdown
# mcporter Integration Tests
|
|
|
|
Live integration smoke-tests for the unraid-mcp server, exercising real API calls via [mcporter](https://github.com/mcporter/mcporter).
|
|
|
|
---
|
|
|
|
## Two Scripts, Two Transports
|
|
|
|
| | `test-tools.sh` | `test-actions.sh` |
|
|
|-|-----------------|-------------------|
|
|
| **Transport** | stdio | HTTP |
|
|
| **Server required** | No — launched ad-hoc per call | Yes — must be running at `$MCP_URL` |
|
|
| **Flags** | `--timeout-ms N`, `--parallel`, `--verbose` | positional `[MCP_URL]` |
|
|
| **Coverage** | 10 tools (read-only actions only) | 11 tools (all non-destructive actions) |
|
|
| **Use case** | CI / offline local check | Live server smoke-test |
|
|
|
|
### `test-tools.sh` — stdio, no running server needed
|
|
|
|
```bash
|
|
./tests/mcporter/test-tools.sh # sequential, 25s timeout
|
|
./tests/mcporter/test-tools.sh --parallel # parallel suites
|
|
./tests/mcporter/test-tools.sh --timeout-ms 10000 # tighter timeout
|
|
./tests/mcporter/test-tools.sh --verbose # print raw responses
|
|
```
|
|
|
|
Launches `uv run unraid-mcp-server` in stdio mode for each tool call. Requires `mcporter`, `uv`, and `python3` in `PATH`. Good for CI pipelines — no persistent server process needed.
|
|
|
|
### `test-actions.sh` — HTTP, requires a live server
|
|
|
|
```bash
|
|
./tests/mcporter/test-actions.sh # default: http://localhost:6970/mcp
|
|
./tests/mcporter/test-actions.sh http://10.1.0.2:6970/mcp # explicit URL
|
|
UNRAID_MCP_URL=http://10.1.0.2:6970/mcp ./tests/mcporter/test-actions.sh
|
|
```
|
|
|
|
Connects to an already-running streamable-http server. Covers all read-only actions across 10 tools (`unraid_settings` is all-mutations and skipped; all destructive mutations are explicitly skipped).
|
|
|
|
---
|
|
|
|
## What `test-actions.sh` Tests
|
|
|
|
### Phase 1 — Param-free reads
|
|
|
|
All actions requiring no arguments beyond `action` itself.
|
|
|
|
| Tool | Actions tested |
|
|
|------|----------------|
|
|
| `unraid_info` | `overview`, `array`, `network`, `registration`, `connect`, `variables`, `metrics`, `services`, `display`, `config`, `online`, `owner`, `settings`, `server`, `servers`, `flash`, `ups_devices`, `ups_device`, `ups_config` |
|
|
| `unraid_array` | `parity_status` |
|
|
| `unraid_storage` | `disks`, `shares`, `unassigned`, `log_files` |
|
|
| `unraid_docker` | `list`, `networks`, `port_conflicts`, `check_updates`, `sync_templates`, `refresh_digests` |
|
|
| `unraid_vm` | `list` |
|
|
| `unraid_notifications` | `overview`, `list`, `warnings`, `recalculate` |
|
|
| `unraid_rclone` | `list_remotes`, `config_form` |
|
|
| `unraid_users` | `me` |
|
|
| `unraid_keys` | `list` |
|
|
| `unraid_health` | `check`, `test_connection`, `diagnose` |
|
|
| `unraid_settings` | *(all 9 actions skipped — mutations only)* |
|
|
|
|
### Phase 2 — ID-discovered reads
|
|
|
|
IDs are extracted from Phase 1 responses and used for actions requiring a specific resource. Each is skipped if Phase 1 returned no matching resources.
|
|
|
|
| Action | Source of ID |
|
|
|--------|--------------|
|
|
| `docker: details` | first container from `docker: list` |
|
|
| `docker: logs` | first container from `docker: list` |
|
|
| `docker: network_details` | first network from `docker: networks` |
|
|
| `storage: disk_details` | first disk from `storage: disks` |
|
|
| `storage: logs` | first path from `storage: log_files` |
|
|
| `vm: details` | first VM from `vm: list` |
|
|
| `keys: get` | first key from `keys: list` |
|
|
|
|
### Skipped actions (and why)
|
|
|
|
| Label | Meaning |
|
|
|-------|---------|
|
|
| `destructive (confirm=True required)` | Permanently modifies or deletes data |
|
|
| `mutation — state-changing` | Modifies live system state (container/VM lifecycle, settings) |
|
|
| `mutation — creates …` | Creates a new resource |
|
|
|
|
**Full skip list:**
|
|
- `unraid_info`: `update_server`, `update_ssh`
|
|
- `unraid_array`: `parity_start`, `parity_pause`, `parity_resume`, `parity_cancel`
|
|
- `unraid_storage`: `flash_backup`
|
|
- `unraid_docker`: `start`, `stop`, `restart`, `pause`, `unpause`, `update`, `remove`, `update_all`, `create_folder`, `set_folder_children`, `delete_entries`, `move_to_folder`, `move_to_position`, `rename_folder`, `create_folder_with_items`, `update_view_prefs`, `reset_template_mappings`
|
|
- `unraid_vm`: `start`, `stop`, `pause`, `resume`, `reboot`, `force_stop`, `reset`
|
|
- `unraid_notifications`: `create`, `create_unique`, `archive`, `unread`, `archive_all`, `archive_many`, `unarchive_many`, `unarchive_all`, `delete`, `delete_archived`
|
|
- `unraid_rclone`: `create_remote`, `delete_remote`
|
|
- `unraid_keys`: `create`, `update`, `delete`
|
|
- `unraid_settings`: all 9 actions
|
|
|
|
### Output format
|
|
|
|
```
|
|
<action label> PASS
|
|
<action label> FAIL
|
|
<first 3 lines of error detail>
|
|
<action label> SKIP (reason)
|
|
|
|
Results: 42 passed 0 failed 37 skipped (79 total)
|
|
```
|
|
|
|
Exit code `0` when all executed tests pass, `1` if any fail.
|
|
|
|
---
|
|
|
|
## Destructive Actions
|
|
|
|
Neither script executes destructive actions. They are explicitly `skip_test`-ed with reason `"destructive (confirm=True required)"`.
|
|
|
|
All destructive actions require `confirm=True` at the call site. There is no environment variable gate — `confirm` is the sole guard.
|
|
|
|
### Safe Testing Strategy
|
|
|
|
| Strategy | When to use |
|
|
|----------|-------------|
|
|
| **Create → destroy** | Action has a create counterpart (keys, notifications, rclone remotes, docker folders) |
|
|
| **No-op apply** | Action mutates config but can be re-applied with current values unchanged (`update_ssh`) |
|
|
| **Dedicated test remote** | Action requires a remote target (`flash_backup`) |
|
|
| **Test VM** | Action requires a live VM (`force_stop`, `reset`) |
|
|
| **Mock/safety audit only** | Global blast radius, no safe isolation (`update_all`, `reset_template_mappings`, `setup_remote_access`, `configure_ups`) |
|
|
| **Secondary server only** | Run on `shart` (10.1.0.3), never `tootie` (10.1.0.2) |
|
|
|
|
For exact per-action mcporter commands, see [`docs/DESTRUCTIVE_ACTIONS.md`](../../docs/DESTRUCTIVE_ACTIONS.md).
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
```bash
|
|
# mcporter CLI
|
|
npm install -g mcporter
|
|
|
|
# uv (for test-tools.sh stdio mode)
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
|
|
# python3 — used for inline JSON extraction
|
|
python3 --version # 3.12+
|
|
|
|
# Running server (for test-actions.sh only)
|
|
docker compose up -d
|
|
# or
|
|
uv run unraid-mcp-server
|
|
```
|
|
|
|
---
|
|
|
|
## Cleanup
|
|
|
|
`test-actions.sh` connects to an existing server and leaves it running; it creates no temporary files. `test-tools.sh` spawns stdio server subprocesses per call — they exit when mcporter finishes each invocation — and may write a timestamped log file under `${TMPDIR:-/tmp}`. Neither script leaves background processes.
|