omv-mcp
Provides tools to manage Docker containers: list containers, view logs, and restart containers.
Allows managing an OpenMediaVault NAS, including system info, disk usage, block devices, filesystems, disks, SMART status, shared folders, SMB shares, users, groups, and direct omv-rpc calls.
Provides tools to manage Portainer stacks: list stacks, get stack compose files, and update stacks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@omv-mcp show disk usage"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
omv-mcp — MCP server for the OpenMediaVault NAS
Manage and inspect an OpenMediaVault NAS from any MCP-capable AI harness (Claude Code, Claude Desktop, Copilot, Cursor, Codex, …): 48 tools across system, storage/SMART health, Docker, and Portainer stacks, plus resources, prompts, and completions.
Install (one command)
Install uv if you don't have it, then run setup:
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
uvx omv-mcp setup# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
uvx omv-mcp setupSetup asks for your NAS address and SSH login, then does everything else:
Passwordless SSH — if key login isn't set up yet, it installs your public key using your OMV password once (never stored; an ed25519 key is generated if you don't have one).
Live verification — runs real
omv-rpcanddocker pson the NAS and shows the results.Portainer (optional) — paste an API key to enable the compose-stack tools (Portainer → user icon → Access tokens); blank to skip.
Registration — registers with Claude Code automatically and prints paste-ready config blocks for Claude Desktop, VS Code, and Cursor.
Requirements: root SSH login on the NAS (OMV's default) and any address that reaches it — a LAN IP like
192.168.x.xis what v1 is tested on. Tailscale IPs usually work as-is; official Tailscale support lands in v2.
Related MCP server: linux-ssh-mcp-server
Two modes, one package
Mode B — run anywhere (default). The server runs on your machine and executes every command on the NAS over one persistent SSH connection (~25 ms per call after the handshake). Nothing is installed on the NAS.
your machine NAS (OMV, Debian)
┌────────────────────────────┐ ┌──────────────────────┐
│ MCP client ──▶ omv-mcp │ ═ ssh (1) ══▶ │ omv-rpc / docker / … │
│ (uvx omv-mcp) │ ─ tunnel ───▶ │ Portainer :9000 │
└────────────────────────────┘ └──────────────────────┘Mode A — run on the NAS (advanced). Choose A during setup: it installs
uv on the NAS and registers the client to launch the server there over
stdio-on-SSH. Commands are then local subprocess calls on the NAS.
your machine NAS (OMV, Debian)
┌─────────────┐ ┌────────────────────────────────┐
│ MCP client ─┼── ssh … uvx omv-mcp ▶ omv-mcp ─▶ omv-rpc / docker / …│
└─────────────┘ └────────────────────────────────┘The selector is one config key: OMV_HOST set → Mode B; unset → Mode A.
Configuration
omv-mcp setup writes this for you. File location:
%APPDATA%\omv-mcp\config.env (Windows) or ~/.config/omv-mcp/config.env
(macOS/Linux/NAS). Real environment variables override the file.
Key | Default | Meaning |
| (empty) | NAS address. Set = Mode B (remote); empty = Mode A (on-NAS). |
|
| SSH user (v1 requires root). |
|
| SSH port. |
| (empty) | Explicit private key path; default is ssh-agent, then |
| (auto) | Explicit Portainer API URL. Auto = |
| (empty) | Enables the stack tools. |
|
| Portainer endpoint id. |
Host keys are trust-on-first-use, pinned in <config dir>/known_hosts; a
changed host key fails loudly. Dropped SSH connections reconnect once,
transparently. In Mode B, Portainer traffic rides an SSH tunnel — the API key
never crosses your network in cleartext, and no port besides SSH needs to be
reachable.
Register a client manually
Setup prints these for you; for reference (Mode B):
{ "mcpServers": { "omv": { "command": "uvx", "args": ["omv-mcp"] } } }claude mcp add omv -- uvx omv-mcpVS Code (.vscode/mcp.json) uses "servers" with "type": "stdio", same
command. For Mode A, setup prints the equivalent ssh …@nas -T -- uvx omv-mcp
form.
Updating: uvx caches the package; refresh with uvx omv-mcp@latest --version
(or uv cache clean omv-mcp).
⚠️ Safety
This server executes as root on the NAS and is meant for a single trusted
user. There is no deny-list — run_command and omv_rpc are unrestricted
root. The destructive named tools (reboot, shutdown, apply_updates,
docker_prune, stop_container, stop_stack, restart_stack,
update_stack, run_smart_test) require confirm=True. Your Portainer API
key is stored in the per-user config file on whichever machine runs the
server. Do not expose this server to untrusted clients.
Tools
Group | Tools |
System |
|
Storage / health |
|
Users/groups |
|
Docker |
|
Portainer stacks |
|
⚠️ = unrestricted root or requires confirm=True.
Resources
Read-only NAS context any client can pull without a tool call:
URI | Content |
| live host/OMV info (JSON) |
| per-mount usage for OS + data disks (JSON) |
| composite: SMART overall + disk/CPU temps + df (JSON) |
| Portainer stacks (JSON) |
| last 100 log lines (template) |
| compose YAML (template) |
Prompts & completions
Canned diagnostic workflows — diagnose_storage_health, triage_containers,
whats_using_space, audit_shares_and_permissions — plus argument
autocompletion for container names, stack ids, and share names.
apply_updates, docker_prune, stop_stack, restart_stack, and
update_stack are async and emit MCP log/progress notifications while they run.
Development
git clone https://github.com/vnaveenb/openmediavault-mcp-ssh.git
cd openmediavault-mcp-ssh
uv sync # venv with Python 3.12 + deps
uv run pytest # unit tests (no NAS needed)
uv run python tests/smoke_client.py # live smoke test (uses your config.env)
uv run omv-mcp setup --dev # register THIS checkout instead of PyPIPRs welcome! See CONTRIBUTING.md for the workflow (GitHub Flow, conventional commits, squash-merge).
⚠️ This server runs as root on the NAS. Review every change with that in mind — never merge a PR you haven't read and understood.
License
MIT © 2026 Naveen Busiraju.
Available Tools
48 toolsapply_updatesADestructive
Install pending APT upgrades (apt-get -y upgrade, noninteractive).
Requires confirm=True. Run available_updates first to see what changes.
Returns {exit_code, output}.
Inputs: confirm.
available_updatesA
APT packages with pending upgrades (name/versions only). {count, packages}.
Inputs: no named parameters.
container_inspectA
Full docker inspect for one container (config, mounts, network, state).
Inputs: name (required).
container_logsA
Last tail lines of a container's logs.
Inputs: name (required), tail. Returns: result
container_statsA
Live per-container CPU%, memory, net/block I/O (docker stats --no-stream).
Inputs: no named parameters.
cpu_tempB
CPU temperature in °C (OMV CpuTemp plugin).
Inputs: no named parameters.
disk_temperaturesA
Current temperature (°C) of every physical disk (smartctl -A per disk).
Inputs: no named parameters.
disk_usageA
Human-readable filesystem usage (df -h).
Inputs: no named parameters. Returns: result
docker_execADestructive
Run a shell command inside a container as its user. UNRESTRICTED -- no allow/deny-list. Returns {stdout, stderr, exit_code}.
Inputs: cmd (required), name (required), timeout.
docker_pruneADestructive
Reclaim space by removing stopped containers, dangling images, unused
networks and build cache (docker system prune -f). Set volumes=True to
also drop anonymous volumes (DELETES their data). Requires confirm=True.
Inputs: confirm, volumes.
docker_system_dfA
Disk usage + reclaimable space by images/containers/volumes/build cache
(docker system df).
Inputs: no named parameters.
get_stack_composeC
The full compose file for a Portainer stack.
Inputs: stack_id (required). Returns: result
get_system_infoA
OMV/host info: hostname, OMV version, kernel, CPU, memory, uptime, load.
Inputs: no named parameters.
list_block_devicesA
Block devices with size/model/serial/fs/mountpoint/uuid (lsblk -J).
Inputs: no named parameters.
list_containersA
Docker containers with names/status/image (docker ps; include_all adds stopped).
Inputs: include_all.
list_disksB
Physical disk devices known to OMV.
Inputs: no named parameters.
list_filesystemsA
All filesystems OMV knows about (mounted or not).
Inputs: no named parameters.
list_groupsC
Non-system OMV groups.
Inputs: no named parameters.
list_imagesB
Docker images (repo, tag, id, size).
Inputs: no named parameters.
list_networksC
Docker networks (id, name, driver, scope).
Inputs: no named parameters.
list_stacksA
Portainer stacks (id, name, status).
Inputs: no named parameters.
list_usersC
Non-system OMV users.
Inputs: no named parameters.
list_volumesB
Docker volumes (name, driver, mountpoint).
Inputs: no named parameters.
memory_infoB
RAM and swap usage in bytes (free -b).
Inputs: no named parameters.
network_infoA
Network interfaces with addresses (ip -j addr); virtual docker/veth
interfaces are filtered out for signal.
Inputs: no named parameters.
omv_rpcADestructive
Generic OMV RPC passthrough: omv-rpc -u admin <service> <method> <params>.
UNRESTRICTED -- can call mutating methods too. Discover methods by
grepping /usr/share/openmediavault/engined/rpc/*.inc on the host.
Inputs: method (required), service (required), params.
rebootADestructive
Reboot the NAS. Requires confirm=True.
Inputs: confirm.
restart_containerADestructive
Restart a single container (seconds of downtime).
Inputs: name (required).
restart_stackADestructive
Stop then start a stack (downtime during the cycle). Requires confirm=True.
Inputs: stack_id (required), confirm.
run_commandADestructive
Run an arbitrary shell command on the NAS as root. UNRESTRICTED and UNGUARDED -- there is no allow/deny-list. Prefer the specific tools (omv_rpc, docker, stacks) over hand-editing config. Returns {stdout, stderr, exit_code}.
Inputs: cmd (required), timeout.
run_smart_testA
Start a SMART self-test on a device. kind is 'short', 'long', or
'conveyance'. The test runs in the background (adds drive load); poll
results later with smart_selftest_log. Requires confirm=True.
Inputs: device (required), kind, confirm.
sensors_readoutA
All lm-sensors readings as structured JSON (sensors -j).
Inputs: no named parameters.
service_logsA
Last lines journal entries for a systemd unit (journalctl -u).
Inputs: unit (required), lines. Returns: result
service_statusB
systemd active/enabled state per unit (systemctl, fast). Defaults to
a common NAS set if none given.
Inputs: units.
shutdownADestructive
Power off the NAS. Requires confirm=True.
Inputs: confirm.
smart_attributesA
Full SMART attribute table for one device (smartctl -A), plus current
temperature and power-on hours. device is 'sda' or '/dev/sda'.
Inputs: device (required).
smart_healthA
SMART overall-health self-assessment for one device (PASSED/FAILED).
device is 'sda' or '/dev/sda'.
Inputs: device (required).
smart_selftest_logB
SMART self-test history for one device (smartctl -l selftest).
Inputs: device (required).
smart_statusB
S.M.A.R.T. overview per device (overall health status, from OMV).
Inputs: no named parameters.
start_containerB
Start a stopped container.
Inputs: name (required).
start_stackA
Start a stopped stack (brings its containers up).
Inputs: stack_id (required).
stop_containerADestructive
Stop a running container (downtime until restarted). Requires confirm=True.
Inputs: name (required), confirm.
stop_stackADestructive
Stop a running stack (takes all its containers down). Requires confirm=True.
Inputs: stack_id (required), confirm.
storage_summaryA
Per-mount usage for the OS + data disks (df): device, mount, fstype,
total/used/avail bytes, and percent. Skips tmpfs/overlay/virtual mounts.
Inputs: no named parameters.
top_processesA
Top processes by cpu or mem (ps, fast). sort_by is 'cpu' or 'mem'.
Inputs: limit, sort_by.
update_stackADestructive
Redeploy a stack with the given compose YAML. DESTRUCTIVE: recreates containers (brief downtime). Requires confirm=True. Existing Env is preserved automatically.
Inputs: compose (required), stack_id (required), confirm.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 48 tools
Most tools have clearly distinct purposes, but smart_status vs smart_health and disk_usage vs storage_summary overlap enough to cause confusion. Overall, an agent can usually tell tools apart with careful reading.
Naming follows a loose pattern: list_* for enumeration and verb_object for actions, but there are outliers like docker_system_df, omv_rpc, cpu_temp, and container_stats. Mixed conventions are still readable but not consistently applied.
48 tools is far beyond the typical 3-15 range and the 25+ threshold. The high granularity (e.g., six SMART-specific tools) feels excessive, especially since generic run_command and omv_rpc already exist for arbitrary operations.
The tool set covers monitoring and lifecycle operations for Docker/stacks and system info, but lacks CRUD for OMV shared folders, users, groups, and SMB shares. The unrestricted omv_rpc and run_command fill gaps but bypass the safer specific tools.
Maintenance
Related MCP Connectors
Linux server administration over OAuth MCP: shell, Docker, systemd, files and monitoring.
Manage CloudPepper servers, Odoo instances, backups, and deployments over MCP.
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Remote MCP for JSON repair, hashing, formatting, IDs, dates, units, and other small tools.
Related MCP Servers
- FlicenseBqualityCmaintenanceEnables AI assistants to monitor and manage OpenMediaVault NAS systems by providing access to storage, network shares, user accounts, and system services. It supports OMV 5 and 6 via the JSON-RPC API for comprehensive hardware and configuration oversight through natural language.393-
- AlicenseNot gradedqualityCmaintenanceRemote Linux operations via SSH, exposed as an MCP server, with tools for filesystem, systemd, Docker, network, and more, using per-user AD authentication and optional sudo elevation.1MIT
- AlicenseAqualityCmaintenanceAn MCP server that lets AI assistants manage an OpenMediaVault NAS over SSH using OMV's own RPC interface, covering disks, filesystems, shares, users, S.M.A.R.T. health, services, and configuration changes. It exposes a small set of generic tools to discover and call RPC methods, plus optional shell access.6MIT
- AlicenseAqualityCmaintenanceExposes a Raspberry Pi homelab's systemd service health, disk usage, CPU temperature, and LAN game-server status as read-only MCP tools, letting MCP clients answer questions like "how's the homelab doing?" without SSHing in manually.4MIT