olvm-mcp
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., "@olvm-mcpwhich VMs are currently running, and on which hosts?"
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.
olvm-mcp
An MCP server for Oracle Linux Virtualization Manager (OLVM) and oVirt. It lets AI assistants such as Claude read your virtualization inventory through the engine's REST API.
Tested against OLVM 4.5.5. This is Phase 1: read-only.
Tools
Tool | What it returns |
| VMs with status, cluster, host, CPUs, memory, OS |
| One VM in detail, including disks and network interfaces |
| KVM hosts with status, cluster, CPU, memory, running VMs, OS and VDSM version |
search accepts the engine's search syntax, for example status=up, name=web* or cluster=Default and status=down.
Every tool is marked read-only (readOnlyHint), and results are capped at 200 items.
Related MCP server: Proxmox MCP Server
How it works
Logs in through the engine's SSO token endpoint (
/ovirt-engine/sso/oauth/token, scopeovirt-app-api). The official oVirt SDK uses the same flow, so Keycloak and older logins both work.Calls the REST API v4 in JSON over HTTPS with httpx. The official
ovirt-engine-sdk-pythonisn't used because it has no Windows build.Verifies TLS with the engine's CA certificate.
Refreshes the token automatically when it expires.
Requirements
Python 3.12+ and uv
Network access to the engine on port 443 (directly, or through an SSH tunnel)
An engine user with a read-only role. Don't use
admin.
Setup
1. Create a read-only engine user
For Keycloak installs (the default on OLVM 4.5):
In the Keycloak admin console (
https://<engine>/ovirt-engine-auth/admin/, realm ovirt-internal), add a user namedmcp-reader@ovirt. Set a password with Temporary turned off.In the Administration Portal, go to Administration → Users → Add and add the user (provider
internalkeycloak-authz).Go to Administration → Configure → System Permissions → Add and assign ReadOnlyAdmin.
The API username is then mcp-reader@ovirt@internalsso.
2. Get the engine's CA certificate
curl -k -o olvm-ca.pem "https://<engine-fqdn>/ovirt-engine/services/pki-resource?resource=ca-certificate&format=X509-PEM-CA"3. Install and test
uv sync
uv run pytestThen run the smoke test against your engine. It prompts for the password:
# PowerShell
$env:OLVM_URL = "https://<engine-fqdn>/ovirt-engine"
$env:OLVM_USERNAME = "mcp-reader@ovirt@internalsso"
$env:OLVM_CA_FILE = "C:\path\to\olvm-ca.pem"
uv run python scripts/smoke_test.py vm-testConfiguration
Variable | Required | Description |
| yes | Engine base URL, e.g. |
| yes | e.g. |
| one of | File containing only the password (recommended) |
| one of | The password itself |
| recommended | Engine CA certificate (PEM). Without it, the system trust store is used |
| no | Seconds per request (default 30) |
| no |
|
See .env.example.
Connect an MCP client
Claude Desktop
Edit %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"olvm": {
"command": "uv",
"args": ["--directory", "C:\\path\\to\\olvm-mcp-server-repo", "run", "olvm-mcp"],
"env": {
"OLVM_URL": "https://<engine-fqdn>/ovirt-engine",
"OLVM_USERNAME": "mcp-reader@ovirt@internalsso",
"OLVM_PASSWORD_FILE": "C:\\path\\to\\mcp-reader.pw",
"OLVM_CA_FILE": "C:\\path\\to\\olvm-ca.pem"
}
}
}
}Restart Claude Desktop, then ask, for example: "Which VMs are running, and on which hosts?"
Claude Code
claude mcp add olvm -e OLVM_URL=https://<engine-fqdn>/ovirt-engine -e OLVM_USERNAME=mcp-reader@ovirt@internalsso -e OLVM_PASSWORD_FILE=/path/to/mcp-reader.pw -e OLVM_CA_FILE=/path/to/olvm-ca.pem -- uv --directory /path/to/olvm-mcp-server-repo run olvm-mcpEngine reachable only through SSH
Tunnel port 443 and map the engine's FQDN to 127.0.0.1 in your hosts file. The engine's login only works with the FQDN given to engine-setup:
ssh -i <key> -L 443:localhost:443 opc@<engine-public-ip>Troubleshooting
Error | Cause |
| Wrong username format or password, or the password is still marked Temporary in Keycloak |
| The user has no role in OLVM. Assign ReadOnlyAdmin (system-wide) |
| Set |
| Network, tunnel or hosts-file problem. Check |
Development
src/olvm_mcp/
config.py settings from environment variables
client.py REST client: SSO login, token refresh, errors
formatting.py compact summaries of engine JSON
server.py MCP server and tools
tests/ unit tests against a mocked engine (respx)
scripts/ smoke test against a real engineLogs go to stderr, because stdout carries the MCP protocol.
Roadmap
Phase 2: operator actions (start/stop, snapshots, migration, host maintenance) with dry-run, confirmation and an audit log
Phase 3: Streamable HTTP transport with authentication, for remote clients
Phase 4: agents built on top (triage, capacity reports, provisioning)
License
Available Tools
3 toolsget_vmARead-onlyIdempotent
Get details of one virtual machine, including its disks and network interfaces.
Args:
name_or_id: The VM's exact name, or its UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| name_or_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds only what the payload contains (disks, NICs), not error behavior for a missing name/UUID or lookup semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded single-line purpose followed by a short Args block; both sentences earn their place. The Args heading is minor formatting noise but the content is substantive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A single required parameter with a clear description, plus an output schema that handles return values. Nothing critical is missing for correct invocation, though error behavior on an unresolved name/UUID is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the schema offers only a bare 'Name Or Id' title, so the description carries the burden and does so usefully by specifying 'exact name, or its UUID'. It doesn't clarify case sensitivity or ambiguity handling, but it clearly adds meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get details of one virtual machine') and enumerates the notable return content (disks, network interfaces). The word 'one' implicitly separates it from list_vms, but it never names the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the agent can infer this is the single-VM lookup versus the list_vms sibling. There is no explicit when-to-use, no exclusion, and no mention of alternatives or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_hostsARead-onlyIdempotent
List KVM hosts with their status, cluster, CPU, memory and running VM count.
Args:
search: Optional oVirt search query, for example `status=up`,
`cluster=Default`, or `name=kvm*`. Leave empty to list all hosts.
max_results: Maximum number of hosts to return (1-200, default 50).
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered by structured data. The description adds nothing behavioral beyond that (no auth requirements, no pagination/truncation behavior when more hosts match), so it merely matches the annotation baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line summary followed by a scoped Args list; no filler sentences. The format is slightly verbose in listing parameters that are also present in the schema, but each line adds meaning the schema lacks.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be re-explained, and both parameters are covered. Annotations handle the safety profile. Only minor gaps remain, such as what happens when results exceed max_results or exceed the 200 ceiling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full load and does so reasonably well: it gives the search query syntax with three examples, states that an empty value lists everything, and documents the 1-200 range and default 50 for max_results. Only missing detail is the exact search field grammar beyond the examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('KVM hosts') and even enumerates the fields returned (status, cluster, CPU, memory, running VM count). Siblings list_vms and get_vm operate on a clearly different resource, so the agent can route without ambiguity, though the description never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The Args block explains how to use `search` (with three concrete query examples and 'leave empty to list all hosts'), which is real usage guidance for the parameter. However, there is no when-to-use/when-not guidance relative to list_vms or any other tool, so context is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_vmsARead-onlyIdempotent
List virtual machines with their status, cluster, host, CPUs and memory.
Args:
search: Optional oVirt search query, for example `status=up`,
`name=web*`, `cluster=Default and status=down`, or `host=kvm01`.
Leave empty to list all VMs.
max_results: Maximum number of VMs to return (1-200, default 50).
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior, so the bar is lower. The description still adds real value beyond them by disclosing the result bound (1-200) and default (50), which the schema does not express as a range constraint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in a single sentence, with parameters organized under a clear 'Args:' block. The four search examples are slightly more than needed, but each demonstrates a distinct query form so they largely earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read-only listing tool with an output schema covering return values, the description is nearly complete: purpose, both parameters, and result limits are all addressed. Only error handling and ordering conventions are left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full load and does so well: it defines the search parameter's syntax with multiple domain-specific examples and gives the max_results range and default. It stops short of describing invalid-query behavior or result ordering.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List virtual machines') and enumerates the returned attributes (status, cluster, host, CPUs, memory). The plural list framing clearly separates it from the singular get_vm sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use guidance through four example search queries and explicitly states 'Leave empty to list all VMs.' It does not, however, name alternatives such as get_vm for single-VM lookups or explain when listing is preferable to a targeted fetch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_vm - First observed
list_hosts - First observed
list_vms
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: list_vms and list_hosts enumerate different resources, and get_vm provides single-VM detail. There is no overlap or ambiguity between them.
All three tools follow a consistent verb_noun pattern (list_vms, get_vm, list_hosts), with plural nouns for list operations and singular for the detail operation, which is idiomatic and predictable.
Three tools is borderline thin for an oVirt virtualization server; it covers only basic VM and host inventory, leaving little room for the broader management surface the domain implies. A read-only inventory intent could justify this, but it feels underpowered.
The surface only supports listing VMs, getting one VM, and listing hosts. It lacks VM lifecycle actions (start/stop/reboot), host detail or operations, cluster and storage domain queries, and create/update/delete operations, which are significant gaps for an oVirt management server.
Maintenance
Related MCP Connectors
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Discover Frontier inference capabilities and read sanitized usage through read-only tools.
- HAVNOAuthapp.havnre
Read-only AI access to HAVN properties, leads, tasks, files, media, and analytics.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to manage HPE OneView infrastructure through the REST API, including server hardware operations, power control, profile management, and network/storage configuration.-
- AlicenseAqualityDmaintenanceEnables read-only interaction with Proxmox homelab VMs and containers, allowing LLM agents to list VMs, monitor status and performance metrics, view snapshots, and check cluster health through natural language queries.8MIT
- AlicenseNot gradedqualityDmaintenanceProvides AI assistants with direct access to Red Hat OpenShift AI observability data, enabling querying of Prometheus metrics, Alertmanager alerts, Loki logs, Grafana dashboards, and Kubernetes cluster state to troubleshoot vLLM inference workloads.5MIT
- FlicenseNot gradedqualityCmaintenanceEnables management of oVirt / Red Hat Virtualization environments via AI assistants, supporting VM lifecycle, power operations, snapshots, and infrastructure queries.-