Mcp Server Qnap Qvs — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Server Qnap Qvs (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
MCP server for QNAP Virtualization Station (QVS) — manage virtual machines, snapshots, disks, and more on your QNAP NAS via the QVS REST API.
Note: This is not an official QNAP product. The QVS REST API is undocumented — this project is based on reverse-engineering the web UI and the qnap-qvs-sdk-for-go project.
Before you start, you need:
If you want the server to report VM IP addresses (via get_vm_ips and get_overview), install the QEMU guest agent inside each VM:
# For Ubuntu/Debian VMs:
sudo apt install qemu-guest-agent
sudo systemctl enable --now qemu-guest-agentWithout the guest agent, IP-related tools will return a helpful message explaining what's needed. Everything else works without it.
| Component | Tested | Expected |
|---|---|---|
| QTS | — | 5.1.0+ |
| QuTS hero | h5.2.8 | h5.1.0+ |
| Virtualization Station | 4.1.x | 3.x+ |
| NAS hardware | x86 (AMD Ryzen) | x86 with VT-x/AMD-V |
39 tools across 7 categories:
confirm=true# Via uvx (recommended)
uvx mcp-server-qnap-qvs
# Or via pip
pip install mcp-server-qnap-qvs
# Or via Docker (for remote/NAS deployment)
docker pull ghcr.io/arnstarn/mcp-server-qnap-qvs:latestThere are two separate authentication layers:
The server authenticates to your QNAP's Virtualization Station API using your NAS admin credentials. This happens automatically — you just provide the credentials via environment variables:
| Variable | Description | Required |
|---|---|---|
QNAP_HOST | NAS hostname or IP address | Yes |
QNAP_PORT | HTTPS port (default: 443) | No |
QNAP_USERNAME | QTS admin username | Yes |
QNAP_PASSWORD | QTS admin password | Yes |
QNAP_VERIFY_SSL | Verify TLS certificate (default: false) | No |
Most QNAP devices use self-signed certificates, so QNAP_VERIFY_SSL=false is typical. Set it to true if you've installed a valid certificate.
When running in SSE mode (remote/Docker), the server requires a Bearer token so only authorized MCP clients can connect:
| Variable | Description | Required |
|---|---|---|
MCP_AUTH_TOKEN | A secret string you choose (like a password) | No |
The server runs on your machine. Claude Code spawns it as a subprocess — no network, no token needed.
Claude Code (~/.claude.json):
{
"mcpServers": {
"qnap-qvs": {
"command": "uvx",
"args": ["mcp-server-qnap-qvs"],
"env": {
"QNAP_HOST": "your-nas.local",
"QNAP_USERNAME": "admin",
"QNAP_PASSWORD": "your-password",
"QNAP_VERIFY_SSL": "false"
}
}
}
}Claude Desktop (claude_desktop_config.json): same format as above.
The server runs on the NAS (or any Docker host) and MCP clients connect over the network.
Start the server:
# Via Docker (recommended for NAS deployment)
docker run -d \
-p 8445:8445 \
-e QNAP_HOST=localhost \
-e QNAP_USERNAME=admin \
-e QNAP_PASSWORD=your-password \
-e QNAP_VERIFY_SSL=false \
-e MCP_AUTH_TOKEN=your-secret-token \
ghcr.io/arnstarn/mcp-server-qnap-qvs:latest
# Or via Docker Compose
cp .env.example .env # Edit .env with your credentials
docker-compose up -d
# Or directly with env vars
MCP_TRANSPORT=sse MCP_AUTH_TOKEN=your-secret-token mcp-server-qnap-qvsWhen running on the NAS itself, set QNAP_HOST=localhost since the server and the API are on the same machine.
Connect your MCP client:
{
"mcpServers": {
"qnap-qvs": {
"url": "http://your-nas.local:8445/sse",
"headers": {
"Authorization": "Bearer your-secret-token"
},
"transportType": "sse"
}
}
}ghcr.io/arnstarn/mcp-server-qnap-qvs:latest or import the docker-compose.ymlQNAP_HOST=localhost, QNAP_USERNAME, QNAP_PASSWORD, MCP_AUTH_TOKEN)Install the QPKG directly on your QNAP NAS. It runs as a Docker container via Container Station.
Step 1: Add the repository
https://raw.githubusercontent.com/arnstarn/mcp-server-qnap-qvs/main/qpkg/repo.xmlStep 2: Install
Step 3: Configure credentials
The QPKG creates a .env file with placeholder values. You need to edit it with your actual QNAP credentials.
SSH into your NAS and edit the .env file:
ssh [email protected]
# Find the install path
QPKG_DIR=$(getcfg mcp-server-qnap-qvs Install_Path -f /etc/config/qpkg.conf)
# Edit the .env file (use vi, nano, or echo)
cat > "$QPKG_DIR/.env" << 'EOF'
QNAP_HOST=localhost
QNAP_PORT=443
QNAP_USERNAME=your-admin-username
QNAP_PASSWORD=your-admin-password
QNAP_VERIFY_SSL=false
MCP_AUTH_TOKEN=pick-any-secret-string-here
EOF
# Restart the service to pick up the new config
/etc/init.d/mcp-server-qnap-qvs.sh restartReplace your-admin-username and your-admin-password with the credentials you use to log into the QNAP web UI. The MCP_AUTH_TOKEN is any secret string you choose — you'll use it as the Bearer token in your MCP client config.
Step 4: Connect your MCP client
{
"mcpServers": {
"qnap-qvs": {
"url": "http://your-nas.local:8445/sse",
"headers": {
"Authorization": "Bearer pick-any-secret-string-here"
},
"transportType": "sse"
}
}
}Use the same MCP_AUTH_TOKEN value you set in Step 3.
Updating: When a new version is released, the App Center will show an update. Or pull the latest Docker image manually:
ssh [email protected]
CS_DIR=$(getcfg container-station Install_Path -f /etc/config/qpkg.conf)
${CS_DIR}/bin/docker pull ghcr.io/arnstarn/mcp-server-qnap-qvs:latest
/etc/init.d/mcp-server-qnap-qvs.sh restart| Variable | Description | Default | Used In |
|---|---|---|---|
QNAP_HOST | NAS hostname or IP | — | Both modes |
QNAP_PORT | NAS HTTPS port | 443 | Both modes |
QNAP_USERNAME | QTS admin username | — | Both modes |
QNAP_PASSWORD | QTS admin password | — | Both modes |
QNAP_VERIFY_SSL | Verify TLS cert | false | Both modes |
MCP_TRANSPORT | Transport mode: stdio or sse | stdio | — |
MCP_HOST | SSE listen address | 0.0.0.0 | SSE only |
MCP_PORT | SSE listen port | 8445 | SSE only |
MCP_AUTH_TOKEN | Bearer token for SSE auth | (auto-generated) | SSE only |
| Tool | Description |
|---|---|
list_vms | List all VMs with full details |
get_vm | Get detailed info for a single VM |
get_vm_states | Lightweight status overview of all VMs |
get_vm_ips | Get VM IP addresses (requires QEMU guest agent in the VM) |
list_vm_disks | List disks attached to a VM |
get_vm_adapters | Network interfaces — MAC, model, bridge |
get_vm_graphics | VNC console info — port, password status |
get_vm_cdroms | CD-ROM drives and mounted ISOs |
get_vm_usbs | USB passthrough devices |
list_images | Available ISO images on the NAS |
get_qvs_logs | QVS audit/event logs (paginated) |
get_overview | Dashboard — VM count, host resources, utilization %, per-VM summary with networking |
get_stopping_progress | Monitor bulk shutdown operations |
| Tool | Description | Confirm? |
|---|---|---|
start_vm | Start a stopped VM | No |
shutdown_vm | Graceful ACPI shutdown | Yes |
force_shutdown_vm | Immediate force stop | Yes |
reset_vm | Hard restart | Yes |
suspend_vm | Suspend to memory | No |
resume_vm | Resume suspended VM | No |
| Tool | Description | Confirm? |
|---|---|---|
create_vm | Create a new VM with CPU, memory, disk, OS type | Yes |
update_vm | Change name, CPU, memory, auto-start, description | Yes |
delete_vm | Permanently destroy a VM and its disks | Yes |
clone_vm | Clone a VM with a new name | Yes |
export_vm | Export a VM to a NAS path | Yes |
import_vm_file | Import a VM from an OVA/OVF file on the NAS | Yes |
| Tool | Description | Confirm? |
|---|---|---|
resize_disk | Expand a virtual disk | Yes |
delete_disk | Remove and delete a disk | Yes |
mount_iso | Mount an ISO to a VM's CD-ROM | Yes |
unmount_iso | Eject an ISO from a VM's CD-ROM | Yes |
check_iso | Scan a shared folder for available ISO files | — |
download_iso | Download an ISO from a URL to the NAS | Yes |
| Tool | Description | Confirm? |
|---|---|---|
list_snapshots | List snapshots for a VM | — |
create_snapshot | Create a VM snapshot | Yes |
revert_snapshot | Revert VM to a snapshot | Yes |
delete_snapshot | Delete a snapshot | Yes |
All destructive operations require confirm=true. Without it, the tool returns a preview of what it would do — no changes are made. This prevents accidental VM deletions, shutdowns, or snapshot reverts.
The get_vm_ips tool and the IP section of get_overview require the QEMU guest agent running inside the VM. Install it:
# Ubuntu/Debian
sudo apt install qemu-guest-agent && sudo systemctl enable --now qemu-guest-agent
# CentOS/RHEL
sudo yum install qemu-guest-agent && sudo systemctl enable --now qemu-guest-agentAll other tools work without the guest agent.
IP addresses can only be retrieved from running VMs. Start the VM first with start_vm.
curl -k https://your-nas.local:443QNAP_PORT accordinglygit clone https://github.com/arnstarn/mcp-server-qnap-qvs.git
cd mcp-server-qnap-qvs
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/ tests/
# Build QPKG (requires Docker)
docker build -t qpkg-builder -f qpkg/Dockerfile.builder .
docker run --rm -v "$(pwd)/qpkg:/work" qpkg-builderThe QVS REST API is not officially documented. This project's API knowledge comes from:
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.