NanoKVM MCP Server
Provides remote management capabilities for RISC-V based NanoKVM hardware, including power control, HID input (keyboard/mouse), and real-time display monitoring.
Enables remote operating system installation and management by allowing AI assistants to mount and unmount Ubuntu ISO images on the remote machine.
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., "@NanoKVM MCP Server take a screenshot of the server console"
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.
NanoKVM MCP Server
An MCP (Model Context Protocol) server for controlling Sipeed NanoKVM devices. This enables AI assistants like Claude to remotely control hardware via keyboard, mouse, power buttons, and screen capture.
What is NanoKVM?
NanoKVM is an open-source, affordable IP-KVM device based on RISC-V. It allows remote access to computers at the BIOS level—perfect for managing servers, embedded systems, or any headless machine.
Related MCP server: jetkvm-mcp
What is MCP?
Model Context Protocol is an open standard for connecting AI assistants to external tools and data sources. This server exposes NanoKVM functionality as MCP tools that Claude and other AI assistants can use.
Features
Category | Capabilities |
Power Control | Power on/off, reset, force shutdown via ATX header |
Keyboard | Type text, send key combinations (Ctrl+C, Alt+F4, etc.) |
Mouse/Touch | Click, move, scroll, tap at absolute screen coordinates |
Screenshots | Capture display as JPEG from MJPEG video stream |
ISO Mounting | Mount/unmount ISO images for remote OS installation |
Monitoring | Power LED status, HDD activity, HDMI state, resolution |
Installation
From Source
git clone https://github.com/scgreenhalgh/nanokvm-mcp.git
cd nanokvm-mcp
pip install -e .Dependencies
Python 3.10+
mcp- Model Context Protocol SDKhttpx- Async HTTP clientwebsockets- WebSocket client for real-time HIDpycryptodome- AES encryption for authenticationpillow- Image processing for screenshots
Configuration
Environment Variables
Variable | Required | Default | Description |
| Yes | - | NanoKVM IP address or hostname |
| No |
| Web UI username |
| No |
| Web UI password |
| No |
| Target screen width in pixels |
| No |
| Target screen height in pixels |
| No |
| Use HTTPS instead of HTTP |
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"nanokvm": {
"command": "python",
"args": ["-m", "nanokvm_mcp.server"],
"env": {
"NANOKVM_HOST": "192.168.1.100",
"NANOKVM_USER": "admin",
"NANOKVM_PASS": "admin",
"NANOKVM_SCREEN_WIDTH": "1920",
"NANOKVM_SCREEN_HEIGHT": "1080"
}
}
}
}Claude Code
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"nanokvm": {
"command": "python",
"args": ["-m", "nanokvm_mcp.server"],
"env": {
"NANOKVM_HOST": "192.168.1.100"
}
}
}
}Available MCP Tools
Power Control
Tool | Parameters | Description |
|
| Control power button or reset |
| - | Get power and HDD LED states |
Actions:
power- Short press (800ms) - normal power on/offpower_long- Long press (5000ms) - force power offreset- Press reset button
Display
Tool | Parameters | Description |
| - | Get HDMI connection state and resolution |
| - | Reset HDMI connection |
| - | Capture display as base64 JPEG |
Keyboard Input
Tool | Parameters | Description |
|
| Type text (max 1024 chars) |
|
| Send single key with modifiers |
Supported Keys:
Letters:
a-zNumbers:
0-9Function keys:
f1-f12Navigation:
up,down,left,right,home,end,pageup,pagedownControl:
enter,escape,tab,backspace,delete,insert,space
Mouse/Touch Input
Tool | Parameters | Description |
|
| Tap at screen coordinates |
|
| Click button, optionally at position |
|
| Move cursor to position |
|
| Scroll wheel (positive=down) |
Coordinate System:
Origin (0, 0) is top-left corner
Coordinates are in screen pixels based on
SCREEN_WIDTHandSCREEN_HEIGHTInternally mapped to NanoKVM's 1-32767 absolute coordinate range
Storage
Tool | Parameters | Description |
| - | List available ISO images |
|
| Mount ISO image |
| - | Unmount current ISO |
| - | Get mounted image info |
System
Tool | Parameters | Description |
| - | Reset keyboard/mouse devices |
| - | Get NanoKVM device info |
| - | Get hardware information |
Usage Examples
Once configured, ask Claude to:
Request | Tool Used |
"Is the server powered on?" |
|
"Power on the machine" |
|
"Reset the server" |
|
"Force shutdown" |
|
"Type 'root' and press enter" |
|
"Press Ctrl+Alt+Delete" |
|
"Take a screenshot" |
|
"Click at position 500, 300" |
|
"Mount the Ubuntu ISO" |
|
Programmatic Usage
You can also use the client library directly:
import asyncio
from nanokvm_mcp import NanoKVMClient
async def main():
# Initialize client
client = NanoKVMClient(
host="192.168.1.100",
username="admin",
password="admin",
screen_width=1920,
screen_height=1080,
)
try:
# Check power status
status = await client.get_led_status()
print(f"Power LED: {status['pwr']}, HDD LED: {status['hdd']}")
# Get HDMI info
hdmi = await client.get_hdmi_status()
print(f"Resolution: {hdmi['width']}x{hdmi['height']}")
# Type some text
await client.paste_text("Hello, World!")
# Send Enter key
await client.send_key("enter")
# Take a screenshot
screenshot = await client.screenshot()
with open("screenshot.jpg", "wb") as f:
f.write(screenshot)
# Click at coordinates
await client.tap(500, 300)
# Power cycle
await client.reset()
finally:
await client.close()
asyncio.run(main())API Reference
See API_REFERENCE.md for complete documentation of the NanoKVM REST API and WebSocket protocol, including:
Authentication (AES-256-CBC encryption)
All REST endpoints with request/response formats
WebSocket HID protocol for keyboard and mouse
USB HID keycodes reference
Direct SSH HID access via
/dev/hidg*
How It Works
Architecture
┌─────────────────┐ HTTP/WS ┌─────────────────┐
│ MCP Client │◄────────────────►│ NanoKVM │
│ (Claude, etc.) │ │ │
└────────┬────────┘ │ ┌───────────┐ │
│ │ │ REST API │ │
MCP Protocol │ └───────────┘ │
│ │ ┌───────────┐ │
┌────────▼────────┐ │ │ WebSocket │ │
│ nanokvm-mcp │ │ │ /api/ws │ │
│ Server │ │ └───────────┘ │
│ │ │ ┌───────────┐ │
│ • Power control │ │ │ MJPEG │ │
│ • HID input │ │ │ Stream │ │
│ • Screenshots │ │ └───────────┘ │
└─────────────────┘ └─────────────────┘Communication Methods
Feature | Method | Endpoint |
Authentication | REST |
|
Power control | REST |
|
Text input | REST |
|
Key/Mouse events | WebSocket |
|
Screenshots | REST |
|
ISO mounting | REST |
|
Development
Setup
# Clone repository
git clone https://github.com/scgreenhalgh/nanokvm-mcp.git
cd nanokvm-mcp
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytestProject Structure
nanokvm-mcp/
├── nanokvm_mcp/
│ ├── __init__.py # Package exports
│ ├── server.py # FastMCP server with tool definitions
│ ├── client.py # NanoKVM API client (REST + WebSocket)
│ ├── auth.py # AES password encryption
│ └── hid.py # USB HID keycodes and helpers
├── pyproject.toml # Package configuration
├── README.md # This file
└── API_REFERENCE.md # Complete API documentationTroubleshooting
Connection Refused
Verify NanoKVM is reachable:
ping <NANOKVM_HOST>Check web UI is accessible:
http://<NANOKVM_HOST>Verify credentials are correct
Authentication Failed
Default credentials are
admin/adminCheck if password was changed in NanoKVM web UI
Authentication can be disabled in
/etc/kvm/server.yaml
HID Input Not Working
Try
nanokvm_reset_hidtoolCheck "Reset HID" in NanoKVM web UI
Verify USB cable connection to target machine
Check
/dev/hidg*devices exist on NanoKVM via SSH
Screenshot Timeout
Ensure HDMI is connected and signal detected
Check
nanokvm_hdmi_statusfor connection stateTry
nanokvm_hdmi_resetto reinitialize
License
MIT
Related Projects
Sipeed NanoKVM - The hardware this server controls
Model Context Protocol - The protocol specification
FastMCP - Python MCP framework
Available Tools
19 toolsnanokvm_clickB
Click a mouse button, optionally at a specific position.
Args:
button: Mouse button - "left", "right", or "middle"
x: Optional X coordinate to move to before clicking
y: Optional Y coordinate to move to before clicking
Inputs: button, x, y. Returns: result
nanokvm_hardwareB
Get NanoKVM hardware information.
Returns:
Dictionary with hardware details
Inputs: no named parameters.
nanokvm_hdmi_resetA
Reset the HDMI connection. Useful if video is not displaying correctly.
Inputs: no named parameters. Returns: result
nanokvm_hdmi_statusA
Get HDMI connection status and resolution.
Returns:
Dictionary with HDMI state including:
- connected: Whether HDMI signal is detected
- width: Video width in pixels
- height: Video height in pixels
Inputs: no named parameters.
nanokvm_infoB
Get NanoKVM device information.
Returns:
Dictionary with device info including IP, firmware version, etc.
Inputs: no named parameters.
nanokvm_led_statusA
Get the power and HDD LED status of the target machine.
Returns:
Dictionary with 'pwr' and 'hdd' boolean values indicating LED states.
- pwr: True if power LED is on (machine is powered)
- hdd: True if HDD LED is on (disk activity)
Inputs: no named parameters.
nanokvm_list_imagesA
List available ISO images on the NanoKVM device.
Returns:
List of available images with file paths and metadata
Inputs: no named parameters. Returns: result
nanokvm_mounted_imageA
Get information about the currently mounted ISO image.
Returns:
Dictionary with mounted image info, or None if nothing mounted
Inputs: no named parameters. Returns: result
nanokvm_mount_isoA
Mount an ISO image for the target machine.
The target machine will see this as an attached CD-ROM or USB disk.
Args:
file: Path to ISO file on the NanoKVM device
as_cdrom: Mount as CD-ROM (True) or USB disk (False)
Inputs: file (required), as_cdrom. Returns: result
nanokvm_moveA
Move mouse cursor to absolute screen position.
Args:
x: X coordinate (0 = left edge)
y: Y coordinate (0 = top edge)
Inputs: x (required), y (required). Returns: result
nanokvm_powerA
Control the target machine's power.
Args:
action: Power action to perform
- "power": Short press power button (800ms) - normal on/off
- "power_long": Long press power button (5000ms) - force off
- "reset": Press reset button (DEPRECATED for Pi 5 - use power_cycle)
Note: Raspberry Pi 5 has NO hardware reset button. The "reset" action
will not work on Pi 5. Use nanokvm_power_cycle() instead.
Inputs: action. Returns: result
nanokvm_power_cycleA
Power cycle the target machine (force off, wait, power on).
This is the recommended way to "reset" a Raspberry Pi 5 since
it has no hardware reset button. The sequence is:
1. Force power off (5 second button hold)
2. Wait for specified duration
3. Power on (short button press)
Args:
off_duration_ms: Time to wait after power off before powering on (ms).
Default 3000ms (3 seconds) ensures clean power cycle.
Use longer values (5000+) if you have slow storage.
Returns:
Status message indicating power cycle completion
Inputs: off_duration_ms. Returns: result
nanokvm_reset_hidA
Reset the HID (keyboard/mouse) devices.
Use this if keyboard or mouse input stops working.
Inputs: no named parameters. Returns: result
nanokvm_screenshotA
Capture a screenshot from the target machine's display.
Returns the screenshot as a JPEG image that can be displayed or analyzed.
By default, 4K images are resized to 1080p to keep the response size
manageable.
Args:
max_width: Maximum width in pixels (default 1920, use 0 for no limit)
max_height: Maximum height in pixels (default 1080, use 0 for no limit)
quality: JPEG quality 1-100 (default 80)
Returns:
JPEG image of the current display
Inputs: max_width, max_height, quality.
nanokvm_scrollB
Scroll the mouse wheel.
Args:
amount: Scroll amount. Positive = scroll down, negative = scroll up.
Inputs: amount (required). Returns: result
nanokvm_send_keyA
Send a single key press to the target machine.
Args:
key: Key to press. Can be:
- Named keys: enter, escape, tab, backspace, delete, space
- Function keys: f1, f2, ..., f12
- Arrow keys: up, down, left, right
- Navigation: home, end, pageup, pagedown, insert
- Single characters: a, b, 1, 2, etc.
ctrl: Hold Ctrl modifier
shift: Hold Shift modifier
alt: Hold Alt modifier
meta: Hold Meta/Windows/Command modifier
Inputs: key (required), ctrl, shift, alt, +1 more. Returns: result
nanokvm_send_textA
Type text on the target machine via keyboard emulation.
Uses the NanoKVM paste API which is faster than individual key presses.
Maximum 1024 characters per call.
Args:
text: The text to type (max 1024 characters)
language: Keyboard layout - "" for US QWERTY, "de" for German
Inputs: text (required), language. Returns: result
nanokvm_tapA
Tap at a specific screen position (touchscreen/mouse emulation).
Coordinates are in screen pixels based on NANOKVM_SCREEN_WIDTH and
NANOKVM_SCREEN_HEIGHT environment variables.
Args:
x: X coordinate (0 = left edge, screen_width = right edge)
y: Y coordinate (0 = top edge, screen_height = bottom edge)
Inputs: x (required), y (required). Returns: result
nanokvm_unmount_isoB
Unmount the currently mounted ISO image.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 19 tools
Each tool has a distinct purpose with clear boundaries. For example, nanokvm_click, nanokvm_move, and nanokvm_tap handle different mouse/touch actions, while nanokvm_power and nanokvm_power_cycle manage power operations with specific use cases. No tools appear to overlap or cause confusion in selection.
All tools follow a consistent snake_case naming convention with a 'nanokvm_' prefix and descriptive verb_noun combinations, such as nanokvm_click, nanokvm_hardware, and nanokvm_mount_iso. This uniformity makes the tool set predictable and easy to navigate.
With 19 tools, the server provides comprehensive coverage for NanoKVM device management, including input emulation, power control, media handling, and status monitoring. The count is well-scoped for the domain, offering necessary functionality without being excessive.
The tool set covers all essential aspects of NanoKVM operations: hardware and status queries (e.g., nanokvm_info, nanokvm_hdmi_status), input control (e.g., nanokvm_click, nanokvm_send_text), power management (e.g., nanokvm_power, nanokvm_power_cycle), and ISO image handling (e.g., nanokvm_mount_iso, nanokvm_unmount_iso). No obvious gaps exist for the server's purpose.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
- DNS-DATA RemoteDeprecatedcom.dns-data
Connect AI assistants to authorized Windows and macOS devices for files, commands, and management.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Connect AI assistants to your approved computer for files, commands, browser and desktop tasks.
Related MCP Servers
- FlicenseAqualityCmaintenanceEnables AI assistants to monitor and control server hardware (power, thermal, storage, firmware, event logs) via Redfish BMC API on Dell iDRAC, HPE iLO, Lenovo XCC, Supermicro BMC, and others.174-
- AlicenseNot gradedqualityCmaintenanceMCP server that enables AI to see and control a physical computer via a JetKVM device for screen viewing, mouse/keyboard input, media mounting, and power management.21MIT
- FlicenseNot gradedqualityDmaintenanceA safety-first Model Context Protocol server for controlling a single PiKVM device, enabling keyboard, mouse, and power operations with strong security and audit.1-
- FlicenseAqualityDmaintenanceMCP server for controlling Sipeed NanoKVM devices, enabling remote hardware control via keyboard, mouse, power, and screenshots. It allows AI assistants like Claude to manage headless machines at the BIOS level.20-