Skip to main content
Glama

NanoKVM MCP Server

Python 3.10+ License: MIT

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 SDK

  • httpx - Async HTTP client

  • websockets - WebSocket client for real-time HID

  • pycryptodome - AES encryption for authentication

  • pillow - Image processing for screenshots

Configuration

Environment Variables

Variable

Required

Default

Description

NANOKVM_HOST

Yes

-

NanoKVM IP address or hostname

NANOKVM_USER

No

admin

Web UI username

NANOKVM_PASS

No

admin

Web UI password

NANOKVM_SCREEN_WIDTH

No

1920

Target screen width in pixels

NANOKVM_SCREEN_HEIGHT

No

1080

Target screen height in pixels

NANOKVM_HTTPS

No

false

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

nanokvm_power

action: power, power_long, reset

Control power button or reset

nanokvm_led_status

-

Get power and HDD LED states

Actions:

  • power - Short press (800ms) - normal power on/off

  • power_long - Long press (5000ms) - force power off

  • reset - Press reset button

Display

Tool

Parameters

Description

nanokvm_hdmi_status

-

Get HDMI connection state and resolution

nanokvm_hdmi_reset

-

Reset HDMI connection

nanokvm_screenshot

-

Capture display as base64 JPEG

Keyboard Input

Tool

Parameters

Description

nanokvm_send_text

text, language

Type text (max 1024 chars)

nanokvm_send_key

key, ctrl, shift, alt, meta

Send single key with modifiers

Supported Keys:

  • Letters: a-z

  • Numbers: 0-9

  • Function keys: f1-f12

  • Navigation: up, down, left, right, home, end, pageup, pagedown

  • Control: enter, escape, tab, backspace, delete, insert, space

Mouse/Touch Input

Tool

Parameters

Description

nanokvm_tap

x, y

Tap at screen coordinates

nanokvm_click

button, x, y

Click button, optionally at position

nanokvm_move

x, y

Move cursor to position

nanokvm_scroll

amount

Scroll wheel (positive=down)

Coordinate System:

  • Origin (0, 0) is top-left corner

  • Coordinates are in screen pixels based on SCREEN_WIDTH and SCREEN_HEIGHT

  • Internally mapped to NanoKVM's 1-32767 absolute coordinate range

Storage

Tool

Parameters

Description

nanokvm_list_images

-

List available ISO images

nanokvm_mount_iso

file, as_cdrom

Mount ISO image

nanokvm_unmount_iso

-

Unmount current ISO

nanokvm_mounted_image

-

Get mounted image info

System

Tool

Parameters

Description

nanokvm_reset_hid

-

Reset keyboard/mouse devices

nanokvm_info

-

Get NanoKVM device info

nanokvm_hardware

-

Get hardware information

Usage Examples

Once configured, ask Claude to:

Request

Tool Used

"Is the server powered on?"

nanokvm_led_status

"Power on the machine"

nanokvm_power

"Reset the server"

nanokvm_power with action="reset"

"Force shutdown"

nanokvm_power with action="power_long"

"Type 'root' and press enter"

nanokvm_send_text + nanokvm_send_key

"Press Ctrl+Alt+Delete"

nanokvm_send_key with modifiers

"Take a screenshot"

nanokvm_screenshot

"Click at position 500, 300"

nanokvm_click

"Mount the Ubuntu ISO"

nanokvm_mount_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

POST /api/auth/login

Power control

REST

POST /api/vm/gpio

Text input

REST

POST /api/hid/paste

Key/Mouse events

WebSocket

/api/ws

Screenshots

REST

GET /api/stream/mjpeg (parsed)

ISO mounting

REST

POST /api/storage/image/mount

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
pytest

Project 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 documentation

Troubleshooting

Connection Refused

  1. Verify NanoKVM is reachable: ping <NANOKVM_HOST>

  2. Check web UI is accessible: http://<NANOKVM_HOST>

  3. Verify credentials are correct

Authentication Failed

  1. Default credentials are admin/admin

  2. Check if password was changed in NanoKVM web UI

  3. Authentication can be disabled in /etc/kvm/server.yaml

HID Input Not Working

  1. Try nanokvm_reset_hid tool

  2. Check "Reset HID" in NanoKVM web UI

  3. Verify USB cable connection to target machine

  4. Check /dev/hidg* devices exist on NanoKVM via SSH

Screenshot Timeout

  1. Ensure HDMI is connected and signal detected

  2. Check nanokvm_hdmi_status for connection state

  3. Try nanokvm_hdmi_reset to reinitialize

License

MIT

Available Tools

19 tools
nanokvm_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

    A4/5.0

    Scored across 19 tools

    Disambiguation5/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    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.

    Completeness5/5

    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

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      C
      maintenance
      Enables 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.
      17
      4
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP 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.
      21
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      A safety-first Model Context Protocol server for controlling a single PiKVM device, enabling keyboard, mouse, and power operations with strong security and audit.
      1
      -
    • F
      license
      A
      quality
      D
      maintenance
      MCP 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
      -