mcp-incus-vm
Provides control of QEMU virtual machines via SSH, including mouse and keyboard input, screenshots, command execution, and file transfer, with lifecycle operations managed through external libvirt/virsh.
Click on "Install 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., "@mcp-incus-vmList my VMs and give me a summary of each."
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.
MCP QEMU VM Control
MCP Incus/QEMU VM Control
Let Claude (or any MCP-compatible LLM) see your screen, move the mouse, type on the keyboard, and run commands — all inside an isolated Incus (or QEMU) virtual machine. Perfect for AI-driven automation, testing, and computer-use experiments without risking your host system.
A Model Context Protocol (MCP) server for controlling Incus or QEMU virtual machines via SSH + hypervisor adapters. The SSH control plane (mouse/keyboard/screenshots) is hypervisor-agnostic; lifecycle operations (launch/stop/exec/delete/list/info) are routed through a pluggable adapter that auto-detects Incus vs QEMU.
Table of Contents
Related MCP server: QEMU Screenshot MCP Server
Features
Mouse Control - Move cursor and click buttons
Keyboard Input - Type text and send key combinations
Action Batching - Execute sequences of UI actions in one call
Screenshots - Capture and retrieve VM screenshots
SSH Command Execution - Run shell commands on the VM
File Transfer - Upload and download files via SFTP
VM Lifecycle -
vm_launch,vm_stop,vm_delete,vm_exec,vm_list,vm_info(Incus adapter)Hypervisor-agnostic - Same MCP tools work against Incus or QEMU VMs
Project Management - Organize outputs into project folders with logs, results, and advice
Advice System - Save and retrieve tips for future LLM sessions
Hypervisor support
Adapter | Lifecycle tools | SSH control plane |
Incus (default if | full: launch/stop/exec/delete/list/info | yes |
QEMU (auto fallback) | stub — lifecycle managed externally via | yes |
Select via HYPERVISOR env var: auto (default), incus, or qemu. The adapter is created once at server startup and injected into every tool via AppContext.
Prerequisites
Host System
Python 3.12+
uv(recommended) orpipQEMU/KVM with libvirt
virt-manager (optional, for GUI management)
VM Requirements
Linux with X11 desktop environment
SSH server enabled
Required packages:
openssh,xdotool,scrot,xrandr,xinput
Incus Setup
If you have the incus CLI installed and a local Incus server reachable, the MCP server will auto-detect it and enable the full lifecycle adapter (vm_launch/vm_stop/vm_exec/vm_list/vm_info/vm_delete).
1. Install Incus
# NixOS (add to configuration.nix)
environment.systemPackages = [ pkgs.incus pkgs.incus-cli ];
# Arch/Manjaro
sudo pacman -S incus incus-cli
# Debian/Ubuntu (via upstream repo)
sudo apt install incus2. Initialize and start the Incus server
sudo incus admin init # one-time: storage backend, network, etc.
incus version # confirm CLI + server reachable3. Launch a VM
incus launch images:debian/12 my-vmThen point VM_HOST at the VM's IP (or its Incus bridge address) and run the MCP server — lifecycle tools just work.
4. Force a specific adapter
If incus is on PATH but you want QEMU behavior (e.g. you manage VMs externally), set HYPERVISOR=qemu in .env.
QEMU/libvirt Setup
1. Install virtualization packages
Arch/Manjaro:
sudo pacman -S qemu-full libvirt virt-manager dnsmasq iptables-nftDebian/Ubuntu:
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virt-manager bridge-utilsFedora:
sudo dnf install @virtualization2. Configure libvirt
# Enable and start libvirtd
sudo systemctl enable --now libvirtd
# Add your user to libvirt group
sudo usermod -aG libvirt $USER
# Log out and back in, then verify
groups # should show 'libvirt'3. Set up the default network
libvirt provides a default NAT network (192.168.122.0/24) that VMs use to communicate with the host:
# Check network status
virsh -c qemu:///system net-list --all
# If 'default' is not active, start it
virsh -c qemu:///system net-start default
# Enable autostart
virsh -c qemu:///system net-autostart defaultThe default network configuration:
Bridge:
virbr0Host IP:
192.168.122.1DHCP range:
192.168.122.2-192.168.122.254Mode: NAT (VMs can access internet, host can access VMs)
4. Create a VM with virt-manager
Launch virt-manager
Create a new VM (File → New Virtual Machine)
Select installation media (ISO)
Allocate resources:
Memory: 4096 MB recommended
CPUs: 2+ recommended
Important: Under "Network selection", choose "Virtual network 'default': NAT"
Complete installation
5. Configure the VM
After installing the guest OS:
# Inside the VM - Install required packages
# Arch/Manjaro
sudo pacman -S --needed openssh xdotool scrot xorg-xrandr xorg-xinput
# Debian/Ubuntu
sudo apt install openssh-server xdotool scrot x11-xserver-utils xinput
# Enable SSH
sudo systemctl enable --now sshd6. Create the automation user
On the VM:
# Create vmrobot user
sudo useradd -m -s /bin/bash vmrobot
sudo passwd vmrobot
# Set up SSH key authentication
sudo -u vmrobot mkdir -p /home/vmrobot/.ssh
sudo -u vmrobot chmod 700 /home/vmrobot/.sshOn the host:
# Copy your public key to the VM
ssh-copy-id vmrobot@192.168.122.XX
# Or manually add to /home/vmrobot/.ssh/authorized_keys on VM7. Grant X11 access to vmrobot
The vmrobot user needs permission to access the X display. On the VM, as the user who owns the desktop session:
# Quick fix (run once per session)
xhost +local:vmrobot
# Permanent fix - add to ~/.xprofile or ~/.xinitrc
echo "xhost +local:" >> ~/.xprofile8. Choose SSH user strategy
There are two approaches for the SSH user:
Option A: Dedicated vmrobot user (default)
Safer — limited permissions, can't accidentally break desktop config
Requires
xhost +local:vmrobotfor X11 access (step 7)Set
VM_DESKTOP_USERif you need commands that require the desktop user's context (clipboard, password manager, dbus):# On the VM, allow vmrobot to run commands as your desktop user echo 'vmrobot ALL=(sergey) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/vmrobot-desktop sudo chmod 440 /etc/sudoers.d/vmrobot-desktopThen set
VM_DESKTOP_USER=sergeyin your config. Usessh_execute("xclip -selection clipboard -o", as_desktop_user=True).
Option B: SSH directly as the desktop user
Simpler — full desktop access out of the box, no xhost or sudo needed
Set
VM_USERto your desktop username (e.g.,sergey)All commands run with full desktop permissions
Best for personal/development VMs where isolation isn't a concern
9. Find your VM's IP address
# From the host
virsh -c qemu:///system domifaddr manjaro
# Or from inside the VM
ip addr show | grep "inet 192.168.122"10. Test the connection
# Test SSH
ssh vmrobot@192.168.122.XX
# Test X11 automation
ssh vmrobot@192.168.122.XX 'DISPLAY=:0 xdotool getmouselocation'
# Test screenshot
ssh vmrobot@192.168.122.XX 'DISPLAY=:0 scrot /tmp/test.png && echo Success'Installation
1. Clone the repository
git clone https://github.com/Neanderthal/mcp-qemu-vm.git
cd mcp-qemu-vm2. Install dependencies
Using uv (recommended):
uv venv && source .venv/bin/activate
uv pip install -r requirements.txtUsing pip:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtConfiguration
Set environment variables or create a .env file:
Variable | Default | Description |
|
| VM IP address |
|
| SSH username |
|
| SSH port |
|
| X11 display |
| (empty) | SSH private key path (optional) |
| (empty) | Desktop session owner, if different from |
|
| UTF-8 locale forced for |
| (none) | SSH known_hosts file path (optional) |
|
| SSH connection timeout in seconds |
See .env.example for a documented template.
Using with Hermes Agent
The MCP server integrates cleanly with Hermes Agent. Tools become available to the agent as soon as the server is reachable — assuming a VM is running on VM_HOST (the lifespan opens the SSH connection at startup).
1. Install the server (editable mode)
# Creates a dedicated venv + installs the `mcp-incus-vm` console script
mkdir -p ~/.local/venvs/mcp-incus-vm
uv venv --python 3.12 ~/.local/venvs/mcp-incus-vm
VIRTUAL_ENV=~/.local/venvs/mcp-incus-vm \
uv pip install -e /path/to/mcp-incus-vmVerify the binary works:
~/.local/venvs/mcp-incus-vm/bin/mcp-incus-vm --help2. Register in ~/.hermes/config.yaml
Add a new entry under mcp_servers:
mcp_servers:
# ...existing entries...
incus-vm:
command: /home/rocha/.local/venvs/mcp-incus-vm/bin/mcp-incus-vm
enabled: true
env:
HYPERVISOR: auto # auto | incus | qemu
VM_HOST: 192.168.122.79 # SSH endpoint of the VM
VM_USER: vmrobot
VM_PORT: "22"
VM_DISPLAY: ":0"3. Verify
hermes mcp list
# Name Transport Tools Status
# incus-vm /home/rocha/.local/venvs/... all enabled ✓ enabledIf the row shows ✓ enabled, the MCP is registered. Tools appear in hermes tools list filtered by incus-vm.
4. Available tools to the agent
Once a VM is reachable:
Lifecycle (always available when Incus is detected):
vm_list,vm_info,vm_launch,vm_stop,vm_delete,vm_execControl plane (needs
VM_HOSTreachable):move_mouse,click,type_text,press_keys,take_screenshot,ssh_execute,ssh_upload,ssh_download, etc.
Caveat: lifespan opens SSH at startup
The server's lifespan opens an SSH connection to VM_HOST immediately when Hermes starts the MCP. If no VM is running at that address, the MCP handshake will hang and the tools won't appear. This is intentional — the control plane (mouse/keyboard/screenshots) only makes sense against a running VM. The Incus lifecycle tools (vm_launch etc.) work independently of VM_HOST because they invoke incus locally.
If you only want lifecycle tools (no control plane), set VM_HOST to a non-routable address so the SSH connect fails fast:
env:
VM_HOST: 127.0.0.1
VM_PORT: "65535" # closed port — connect fails in <100msUsage
MCP Client Configuration
Add to your MCP client config (e.g., Claude Desktop claude_desktop_config.json):
{
"qemu-vm-control": {
"command": "python3",
"args": ["/path/to/mcp-qemu-vm/server.py"],
"env": {
"VM_HOST": "192.168.122.79",
"VM_USER": "vmrobot",
"VM_PORT": "22",
"VM_DISPLAY": ":0"
}
}
}Config file locations:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Development with MCP Inspector
uv run mcp dev server.py
# With custom environment
VM_HOST=192.168.122.79 VM_USER=vmrobot uv run mcp dev server.pyRunning Standalone
python server.pyTools Reference
Project Management
Projects organize all outputs (screenshots, logs, results, advice) into timestamped folders under data/projects/.
Tool | Description |
| Create a new project (required before screenshots) |
| Load an existing project |
| List all projects |
| Get current project statistics |
| Add a log entry |
| Read project logs |
| Save a result file |
| Save tips for future sessions |
| Read all saved advice |
Mouse & Keyboard
Tool | Description |
| Move cursor (mode: "absolute" or "relative") |
| Click a button; optional |
| Click at coords relative to the active window's client area |
| Active window id, title, position & geometry |
| Mouse-wheel scroll (up/down/left/right) at cursor |
| Press at start, drag to end, release (select/slider/DnD) |
| Type text (newlines → Return, UTF-8 safe); |
| Press key combo, e.g., |
| Hold / release a key or modifier (e.g. Shift-click) |
| Load the VM clipboard (fast insert for big ASCII) |
| Set clipboard (if |
| Focus & raise a window by title or id |
| Pause execution |
| Execute a sequence of actions in one call |
Batch Actions Example
[
{"action": "press_keys", "keys": ["Ctrl", "Shift", "p"]},
{"action": "wait", "seconds": 0.5},
{"action": "type_text", "text": "Terminal: Focus Terminal"},
{"action": "press_keys", "keys": ["Return"]}
]Object Location (OCR)
Locate on-screen elements by their visible text — exact pixel coordinates, no coordinate guessing. The host OCRs the full-resolution screenshot (tesseract) and maps the match straight into the click path. Works on any visible text, including nested Citrix/web where accessibility APIs can't reach; does not find unlabeled icons.
Tool | Description |
| OCR the screen; return every match's center & box |
| Find text and click its center (precise) |
click_text("Submit") # finds "Submit" and clicks its exact center
find_text("File") # lists all matches with coordinates
click_text("OK", index=1) # click the 2nd "OK" if several matchZoom (magnify a region, then click it precisely)
When detail is too small/low-contrast to resolve in the full screenshot, magnify a region and click within it. The server keeps the crop mapping, so a point you pick in the zoomed image maps back to the exact full-screen pixel — no coordinate math.
Tool | Description |
| Crop around (x, y) and magnify; returns a viewable image + mapping |
| Click a point given in the last zoom's image coords |
zoom(800, 600, width=400, height=300, scale=4) # view a 4× magnified crop
click_zoomed(610, 250) # click that spot → exact full-screen pixelSet-of-Mark (pick by number)
For dense or ambiguous screens, overlay numbered marks on every detected text element and pick one by its number — a discrete choice that's far more reliable than estimating coordinates.
Tool | Description |
| Annotate the screen with numbered boxes; returns the image + a legend |
| Click the element labeled |
mark_screen() # view the annotated screenshot + legend (0 -> "File", 1 -> "Edit", …)
click_mark(1) # click element #1 at its exact centerHost requirements: tesseract (the binary) plus pillow and pytesseract
in the server's Python env. These are optional — the rest of the server runs
without them; only the OCR (find_text/click_text) and zoom (zoom) tools
need them (zoom needs only pillow):
# Arch/Manjaro host
sudo pacman -S tesseract tesseract-data-eng
uv pip install pillow pytesseractSSH Operations
Tool | Description |
| Run a shell command on the VM |
| Upload file to VM |
| Download file from VM |
| Get connection status |
Screenshots
Tool | Description |
| Capture screenshot (requires active project) |
Screenshots are saved to the project's screenshots/ folder and exposed as MCP resources at vm://screenshot/{id}.
Display Calibration
Tool | Description |
| Show the xdotool↔screenshot scale factors; |
Scale factors are auto-detected at startup (HiDPI/scaling mismatches); coordinate tools apply them transparently.
Typical Workflow
1. project_init("my-task", "Description")
2. take_screenshot()
3. ... perform VM operations ...
4. project_read_logs()
5. project_save_result("output.txt", data)
6. project_save_advice("Title", "Lessons learned...")For continuing work:
1. project_list()
2. project_load("data/projects/...") # Shows any saved advice
3. ... continue work ...Best Practices for LLM Automation
These lessons were learned from real-world usage and help avoid common pitfalls.
1. Always Screenshot Before Actions
Before ANY interaction:
take_screenshot()Analyze the image
Identify current focus (which window/field is active)
Only then proceed with actions
Never skip screenshots to "save time" - blind actions lead to errors.
2. Don't Trust Mouse Clicks for Focus
Clicking on a window/terminal does NOT reliably switch focus, especially in:
Nested environments (Citrix, remote desktop)
High-latency connections
Applications with multiple panels (VS Code, IDEs)
Use keyboard shortcuts instead:
[
{"action": "press_keys", "keys": ["Ctrl", "Shift", "p"]},
{"action": "wait", "seconds": 0.5},
{"action": "type_text", "text": "Terminal: Focus Terminal"},
{"action": "wait", "seconds": 0.3},
{"action": "press_keys", "keys": ["Return"]},
{"action": "wait", "seconds": 0.5}
]Then take_screenshot() to verify before typing.
3. Required Wait Times
After This Action | Wait Time |
Opening Command Palette | 0.5s |
Typing search text | 0.3s |
Pressing Enter/Return | 0.5-1.0s |
Command execution | 1.0-2.0s |
Window/focus switch | 0.5s |
Never rapid-fire actions - they may arrive out of order.
4. Use Batch Actions
Use run_actions() instead of separate tool calls to reduce latency and ensure ordering:
# Instead of 5 separate calls:
run_actions([
{"action": "press_keys", "keys": ["Ctrl", "Shift", "p"]},
{"action": "wait", "seconds": 0.5},
{"action": "type_text", "text": "command"},
{"action": "wait", "seconds": 0.3},
{"action": "press_keys", "keys": ["Return"]}
])5. SSH Scope Limitation
ssh_execute only reaches the first VM layer. For nested environments (VM → Citrix → Windows), use UI automation to type commands in the visible terminal.
6. Recovery Commands
Problem | Solution |
Typed in wrong window (few chars) |
|
Multiple lines in wrong place |
|
File corrupted |
|
VS Code revert |
|
7. Common Mistakes to Avoid
Typing immediately after clicking terminal (focus may not have switched)
Skipping screenshots to "save time"
Using
ssh_executefor nested environment commandsNot waiting between actions
Assuming focus switched without verification
Architecture
┌─────────────┐ SSH ┌──────────────┐
│ │ ◄──────────────────► │ │
│ MCP Server │ │ QEMU VM │
│ (Host) │ │ (Linux) │
│ │ │ │
└──────┬──────┘ └──────────────┘
│ │
│ MCP Protocol │
│ (stdio) │
│ │
▼ ▼
┌─────────────┐ xdotool, scrot
│ LLM Client │ X11 automation
│ (Claude) │
└─────────────┘Network topology:
┌────────────────────────────────────────────────────┐
│ Host (192.168.122.1) │
│ ┌──────────┐ │
│ │ virbr0 │◄── NAT bridge │
│ └────┬─────┘ │
│ │ │
│ ┌────┴─────┐ │
│ │ QEMU VM │ 192.168.122.79 │
│ │ (manjaro)│ │
│ └──────────┘ │
└────────────────────────────────────────────────────┘UI Action Dispatch
All xdotool interactions are built from a small set of pure command builders
(_type_cmd, _keys_cmd, _click_cmd, _move_cmd) so the shell command for an
action is constructed in exactly one place. Each builder takes an already
shlex.quote()d display string and returns the command to run on the VM; the
builders also own input validation (key-name pattern, button map, click-count
clamp) and the UTF-8 locale prefix for typing.
Two paths consume these builders:
Standalone tools (
move_mouse,click,type_text,press_keys,wait) — individually exposed MCP tools with typed signatures and rich docstrings.run_actions— the batch path. It dispatches throughACTION_HANDLERS, a{name: async handler}registry that is the single source of truth for which actions a batch supports. Each handler shares the signatureasync (app_ctx, display, action_dict) -> summary. Unknown action names raise and stop the batch (consistent with its "stops on first error" contract).
run_actions(actions)
│ for each action
▼
ACTION_HANDLERS[name] ──► _act_*(app, display, action)
│ uses
▼
_type_cmd / _keys_cmd / _click_cmd / _move_cmd
│
▼
run_vm_cmd(ssh, …) ──► xdotool over SSHAdding a new batch action: write a _act_<name>(app, display, action) handler
(reusing or adding a _*_cmd builder) and add one entry to ACTION_HANDLERS. No
changes to the dispatch loop are needed.
Project Structure
mcp-qemu-vm/
├── server.py # Main MCP server (single file)
├── pyproject.toml # Project metadata, ruff & pytest config
├── requirements.txt # Python dependencies
├── .env.example # Documented env var template
├── test_ssh_tools.py # Unit tests (no-VM) + manual SSH smoke check
├── LICENSE # MIT
├── data/
│ └── projects/ # Project folders
│ └── YYYYMMDD-HHMMSS_name/
│ ├── screenshots/
│ ├── logs/
│ ├── results/
│ └── advice/
└── README.mdKnown Issues & Limitations
Issues confirmed in real nested-environment use (host → Citrix → Windows → Outlook). Each lists the symptom, the root cause, and the current workaround.
#1 and #2 are fixed in server.py. #3–#6 are inherent limitations of the nested
environment (Citrix/RDP session policy) or the architecture (SSH lands on the first VM
layer only) — they can't be fixed in this server, so the workarounds remain the
recommended approach.
1. type_text fails on Cyrillic / non-ASCII text — FIXED
Symptom:
type_text(and anyxdotool typewith non-ASCII) errors out with exit status 1. Direct run reveals:Invalid multi-byte sequence encountered / xdo_enter_text_window reported an error. ASCII text types fine.Root cause:
xdotool typedecodes multi-byte input using the current locale, but thevmrobot/ desktop-user SSH environment has no UTF-8 locale (LANGempty, keyboard layout bareus). Without a UTF-8LC_CTYPE, multi-byte UTF-8 (Cyrillic, etc.) cannot be decoded.Fix (applied):
type_textand therun_actionstype step now prefix the xdotool invocation withLC_ALL=$VM_LOCALE(defaultC.UTF-8), so non-ASCII text works out of the box. Override with theVM_LOCALEenv var if the VM lacksC.UTF-8(e.g. setVM_LOCALE=ru_RU.utf8; check available locales withlocale -a).
2. Embedded newlines in typed text become literal glyphs, not Enter — FIXED
Symptom: Typing multi-line text (e.g.
xdotool typewith\n, ortype --file -) into a rich editor like Outlook produces one run-on paragraph with stray box/control-character glyphs where the line breaks should be — paragraph breaks are lost.Root cause: In this nested Citrix → Windows path, the
\n(LF) is delivered as a literal control character to the editor instead of being interpreted as a Return keypress.Fix (applied):
type_text(and therun_actionstype step) now split text on newlines, type each line via stdin, and send line breaks as explicitReturnkey presses instead of a literal LF.\r\nand\rare normalised first. This works in both terminals and rich editors — no caller-side splitting needed.
3. Clipboard redirection may be disabled in the guest session
Symptom: Setting the host/X clipboard (
xclip -selection clipboard) and pasting withCtrl+Vdoes not transfer text into the Windows/Citrix layer.Root cause: Clipboard redirection is turned off in the Citrix/RDP session policy, so the inner session has its own isolated clipboard.
Workaround: do not rely on copy/paste to inject text across the nesting boundary; fall back to typing (see issues #1 and #2).
4. Focus is silently stolen after long operations
Symptom: A long type/automation sequence succeeds, but subsequent keystrokes (e.g.
BackSpaceto correct text) have no effect — verified by a zero pixel-diff between before/after screenshots.Root cause: A desktop/mail notification toast (e.g. new-mail popup) grabs focus partway through, so later keys go to the wrong window.
Workaround: re-assert focus by clicking the target window/field immediately before each keyboard burst, and verify the result with a screenshot (crop the region and diff) rather than trusting the tool's exit code. Keep keyboard bursts short so a focus steal corrupts less.
5. Mouse clicks are unreliable for window/focus switching
See Best Practices §2. In nested environments a
click often raises a different background window than intended; there is no reliable
Alt+Tab (it leaks to the host WM). Prefer the in-app taskbar / window controls and
verify every switch with a screenshot.
6. ssh_execute only reaches the first VM layer
ssh_execute lands on the host/first VM only. Commands do not reach inner Citrix /
Windows layers — use UI automation (type_text, press_keys, run_actions) for those.
See Best Practices §5.
Troubleshooting
Cannot connect to VM
Check VM is running:
virsh -c qemu:///system listCheck network is active:
virsh -c qemu:///system net-list # If default is inactive: virsh -c qemu:///system net-start defaultCheck VM has IP:
virsh -c qemu:///system domifaddr <vm-name>Test SSH connectivity:
ssh vmrobot@192.168.122.XX
Mouse/keyboard not working
Verify
xdotoolis installed on VM:which xdotoolCheck X11 display:
echo $DISPLAY(should be:0)Test manually:
DISPLAY=:0 xdotool getmouselocationNon-ASCII text failing with exit 1 / "Invalid multi-byte sequence"? Missing UTF-8 locale — see Known Issues #1.
Line breaks not working / run-on text? See Known Issues #2.
Screenshots failing / X11 Authorization Error
If you see Authorization required, but no authorization protocol specified:
Quick fix (run as X session owner on VM):
xhost +local:vmrobotPermanent fix - Add to ~/.xprofile:
xhost +local:Verify access:
# Check current xhost settings
DISPLAY=:0 xhost
# Should show:
# access control enabled, only authorized clients can connect
# LOCAL:VM network issues
# Restart the default network
virsh -c qemu:///system net-destroy default
virsh -c qemu:///system net-start default
# Check virbr0 bridge exists
ip addr show virbr0License
Released under the MIT License — © 2026 Sergey Istomin.
Related
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceEnables AI assistants to interact with Ubuntu VMs via SSH, including executing commands, simulating keyboard/mouse input, capturing screenshots, and controlling GUI applications remotely.Last updated1
- FlicenseAqualityDmaintenanceEnables AI agents to capture high-quality screenshots from running QEMU virtual machines using the QEMU Machine Protocol (QMP), automatically discovering VMs and returning screenshots as PNG images.Last updated1
- Alicense-qualityDmaintenanceEmpowers AI agents to see, reason, and control computers via VNC, providing advanced vision features like OCR and image search, human-like input control, and optional SSH remote command execution.Last updated1MIT
- Alicense-qualityCmaintenanceEnables AI assistants to manage remote servers via SSH with agentless command execution, file operations, and service management.Last updatedMIT
Related MCP Connectors
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Operate your Linux servers from your LLM. Every action runs through an auditable allowlist.
Build, validate, and deploy multi-agent AI solutions from any AI environment.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/RAGton/mcp-incus-vm'
If you have feedback or need assistance with the MCP directory API, please join our Discord server