vergeos-mcp-server

dvvincent/vergeos-mcp-server

3.2

If you are the rightful owner of vergeos-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

A Model Context Protocol (MCP) server for interacting with VergeOS virtualization platform, enabling AI assistants to manage VMs, networks, tenants, and monitor VergeOS clusters through natural language.

Tools
5
Resources
0
Prompts
0

VergeOS MCP Server

A Model Context Protocol (MCP) server for interacting with VergeOS virtualization platform. This enables AI assistants like Claude, Windsurf/Cascade, and other MCP-compatible clients to manage VMs, networks, tenants, and monitor your VergeOS cluster through natural language.

Architecture Overview

This project provides two deployment options:

┌─────────────────────────────────────────────────────────────────────────────┐
│                           DEPLOYMENT OPTIONS                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  Option 1: Local (stdio)              Option 2: Remote (HTTP + Local Proxy) │
│  ─────────────────────────            ───────────────────────────────────── │
│                                                                              │
│  ┌──────────┐    stdio    ┌─────────┐     ┌──────────┐   HTTP   ┌─────────┐│
│  │ Windsurf │◄──────────►│  MCP    │     │ Windsurf │◄────────►│  Local  ││
│  │ /Claude  │            │ Server  │     │ /Claude  │  stdio   │  Proxy  ││
│  └──────────┘            └────┬────┘     └──────────┘          └────┬────┘│
│                               │                                      │     │
│                               │ HTTPS                          HTTPS │     │
│                               ▼                                      ▼     │
│                          ┌─────────┐                          ┌──────────┐ │
│                          │VergeOS │                          │ K8s MCP  │ │
│                          │  API   │                          │ Server   │ │
│                          └─────────┘                          └────┬─────┘ │
│                                                                    │       │
│                                                               HTTPS│       │
│                                                                    ▼       │
│                                                              ┌──────────┐  │
│                                                              │ VergeOS  │  │
│                                                              │   API    │  │
│                                                              └──────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘

When to Use Each Option

OptionUse Case
Local (stdio)AI client runs on the same machine that can reach VergeOS
Remote (HTTP)AI client is remote (e.g., laptop) and VergeOS is on a private network

Features

MCP Tools

VM Power Control
ToolDescription
list_vmsList all virtual machines (filter by running/name)
get_vmGet detailed VM information by ID
get_vm_statusGet VM running status and power state
power_on_vmPower on a VM
power_off_vmGracefully power off with optional wait and auto-force
force_off_vmForce power off (hard shutdown)
reset_vmReset/reboot a VM
VM Configuration
ToolDescription
modify_vmChange CPU cores and/or RAM (handles running VMs)
add_driveAdd a new disk drive to a VM
resize_driveExpand an existing disk (increase only)
get_vm_nicsGet VM network interfaces
get_vm_drivesGet VM disk drives with sizes
Network Management
ToolDescription
list_networksList all virtual networks
get_networkGet network details
network_actionPower on/off, reset, apply rules
Tenant Management
ToolDescription
list_tenantsList all tenants
get_tenantGet tenant details
tenant_actionPower on/off, reset tenants
Cluster & Node Management
ToolDescription
list_nodesList cluster nodes
get_node_statsGet node statistics
get_cluster_statusGet cluster health status
get_cluster_statsGet storage tier statistics
Storage & Monitoring
ToolDescription
list_volumesList storage volumes
get_logsGet system logs (filter by level/object type)
get_alarmsGet active alarms
Snapshot Management
ToolDescription
list_vm_snapshotsList snapshots for a VM
create_vm_snapshotCreate a snapshot (with optional expiration and quiesce)
delete_vm_snapshotDelete a VM snapshot
restore_vm_snapshotRestore a VM from a snapshot

Smart Features

  • Graceful shutdown with wait: power_off_vm can wait for VM to shut down and auto-force if timeout expires
  • Running VM handling: modify_vm detects running VMs and can auto-shutdown to apply CPU/RAM changes
  • Log filtering: Filter logs by level (error, warning, audit) or object type (vm, node, vnet)
  • Snapshot expiration: create_vm_snapshot supports automatic expiration (default 7 days)
  • Quiesced snapshots: Option to quiesce VM before snapshot (requires guest agent)

MCP Resources

  • vergeos://cluster/status - Cluster status overview
  • vergeos://vms/list - All virtual machines
  • vergeos://networks/list - All virtual networks
  • vergeos://alarms/active - Active system alarms

Option 1: Local Installation (stdio)

Use this if your AI client runs on a machine that can directly reach your VergeOS instance.

Installation

git clone <repo-url> vergeos-mcp-server
cd vergeos-mcp-server
npm install

Configuration

Create a .env file:

VERGEOS_HOST=your-vergeos-host
VERGEOS_USER=admin
VERGEOS_PASS=your-password

Or use an API token (recommended):

# Get a token
curl -sk -X POST "https://your-vergeos-host/api/sys/tokens" \
  -u "admin:password" \
  -H "Content-Type: application/json" \
  -d '{"login":"admin","password":"password"}' | jq -r '."$key"'

# Set in .env
VERGEOS_HOST=your-vergeos-host
VERGEOS_TOKEN=your-token-here

Claude Desktop Configuration

Add to ~/.config/claude/claude_desktop_config.json:

{
  "mcpServers": {
    "vergeos": {
      "command": "node",
      "args": ["/path/to/vergeos-mcp-server/src/index.js"],
      "env": {
        "VERGEOS_HOST": "your-vergeos-host",
        "VERGEOS_USER": "admin",
        "VERGEOS_PASS": "your-password"
      }
    }
  }
}

Windsurf Configuration

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "vergeos": {
      "command": "node",
      "args": ["/path/to/vergeos-mcp-server/src/index.js"],
      "env": {
        "VERGEOS_HOST": "your-vergeos-host",
        "VERGEOS_USER": "admin",
        "VERGEOS_PASS": "your-password"
      }
    }
  }
}

Option 2: Remote Installation (Kubernetes + Local Proxy)

Use this if your AI client (e.g., Windsurf on your laptop) cannot directly reach VergeOS, but you have a Kubernetes cluster that can.

Architecture

┌─────────────┐      ┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   Windsurf  │─────►│ Local Proxy │─────►│  K8s MCP    │─────►│   VergeOS   │
│  (Laptop)   │stdio │  (Laptop)   │HTTPS │  Server     │HTTPS │    API      │
└─────────────┘      └─────────────┘      └─────────────┘      └─────────────┘
                                                │
                                          ┌─────┴─────┐
                                          │  Traefik  │
                                          │  Ingress  │
                                          └───────────┘

Step 1: Deploy to Kubernetes

# Clone the repo on your K8s host
cd vergeos-mcp-server

# Edit credentials in deploy.sh or create ~/.vergeos-credentials
cat > ~/.vergeos-credentials << EOF
VERGEOS_USER=admin
VERGEOS_PASS=your-password
EOF

# Deploy
./deploy.sh

This creates:

  • Namespace: vergeos-mcp
  • Deployment running the HTTP MCP server
  • Service exposing port 3002
  • IngressRoute for external access (Traefik)

Step 2: Configure DNS

Add a DNS record pointing to your Traefik ingress:

vergeos-mcp.yourdomain.com → <traefik-ip>

Step 3: Test the Server

# Health check
curl https://vergeos-mcp.yourdomain.com/health

# List VMs
curl https://vergeos-mcp.yourdomain.com/vms

# MCP protocol test
curl -X POST https://vergeos-mcp.yourdomain.com/message \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Step 4: Install Local Proxy (on your laptop)

Since Windsurf only supports stdio-based MCP servers, you need a local proxy:

# Create directory
mkdir -p ~/.mcp/vergeos
cd ~/.mcp/vergeos

# Create package.json
cat > package.json << 'EOF'
{
  "name": "vergeos-mcp-proxy",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0",
    "node-fetch": "^3.3.2"
  }
}
EOF

# Create index.js
cat > index.js << 'EOF'
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";

const SERVER_URL = process.env.VERGEOS_MCP_URL || "https://vergeos-mcp.yourdomain.com";

async function apiCall(path, options = {}) {
  const fetch = (await import("node-fetch")).default;
  const response = await fetch(`${SERVER_URL}${path}`, {
    ...options,
    headers: { "Content-Type": "application/json", ...options.headers },
  });
  if (!response.ok) throw new Error(`API Error: ${response.status}`);
  return response.json();
}

const server = new Server({ name: "vergeos", version: "1.0.0" }, { capabilities: { tools: {} } });

const TOOLS = [
  { name: "list_vms", description: "List all VMs in VergeOS", inputSchema: { type: "object", properties: {} } },
  { name: "get_vm", description: "Get VM details by ID", inputSchema: { type: "object", properties: { id: { type: "number" } }, required: ["id"] } },
  { name: "power_on_vm", description: "Power on a VM", inputSchema: { type: "object", properties: { id: { type: "number" } }, required: ["id"] } },
  { name: "power_off_vm", description: "Power off a VM", inputSchema: { type: "object", properties: { id: { type: "number" } }, required: ["id"] } },
  { name: "reset_vm", description: "Reset a VM", inputSchema: { type: "object", properties: { id: { type: "number" } }, required: ["id"] } },
  { name: "list_networks", description: "List virtual networks", inputSchema: { type: "object", properties: {} } },
  { name: "list_tenants", description: "List tenants", inputSchema: { type: "object", properties: {} } },
  { name: "list_nodes", description: "List cluster nodes", inputSchema: { type: "object", properties: {} } },
  { name: "get_cluster_status", description: "Get cluster status", inputSchema: { type: "object", properties: {} } },
  { name: "get_alarms", description: "Get active alarms", inputSchema: { type: "object", properties: {} } },
  { name: "get_logs", description: "Get system logs", inputSchema: { type: "object", properties: { limit: { type: "number" } } } },
];

server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  try {
    const result = await apiCall(`/tools/${name}`, { method: "POST", body: JSON.stringify(args || {}) });
    return { content: [{ type: "text", text: JSON.stringify(result.result, null, 2) }] };
  } catch (error) {
    return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
EOF

# Install dependencies
npm install

Step 5: Configure Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "vergeos": {
      "command": "node",
      "args": ["/Users/yourusername/.mcp/vergeos/index.js"],
      "env": {
        "VERGEOS_MCP_URL": "https://vergeos-mcp.yourdomain.com"
      }
    }
  }
}

Restart Windsurf to load the new MCP server.


REST API Reference

The HTTP server also exposes a REST API for direct access:

EndpointMethodDescription
/healthGETHealth check
/toolsGETList available MCP tools
/tools/:namePOSTExecute an MCP tool
/vmsGETList all VMs
/vms/:idGETGet VM details
/vms/:id/:actionPOSTVM action (poweron/poweroff/reset)
/networksGETList networks
/tenantsGETList tenants
/nodesGETList nodes
/cluster/statusGETCluster status
/alarmsGETActive alarms
/logsGETSystem logs

MCP Protocol Endpoints

EndpointMethodDescription
/sseGETServer-Sent Events connection
/messagePOSTMCP JSON-RPC messages

Example Interactions

Once connected, you can ask your AI assistant:

  • "List all VMs in VergeOS"
  • "Power off the VM named 'test-vm'"
  • "Show me the cluster status"
  • "What alarms are active?"
  • "List all virtual networks"
  • "Get details for VM ID 34"
  • "How many nodes are in the cluster?"
  • "Show me the last 20 log entries"
  • "Create a snapshot of VM 34 called 'before-upgrade'"
  • "List all snapshots for the web-server VM"
  • "Restore VM 34 from snapshot ID 123"
  • "Add 2GB RAM to the database VM"
  • "Add a 50GB data disk to VM 34"

VergeOS API Notes

Authentication

VergeOS uses cookie-based authentication:

  1. POST to /api/sys/tokens with Basic Auth
  2. Response contains token in $key field
  3. Use token as cookie: Cookie: token=<value>
# Get token
TOKEN=$(curl -sk -X POST "https://vergeos/api/sys/tokens" \
  -u "admin:password" \
  -H "Content-Type: application/json" \
  -d '{"login":"admin","password":"password"}' | jq -r '."$key"')

# Use token
curl -sk "https://vergeos/api/v4/vms" -b "token=$TOKEN"

API Quirks

  • VMs with is_snapshot: true are templates, not running VMs
  • /machine_nics?machine=<ID> may return NICs from other machines; always filter by machine ID
  • Use fields=most for detailed responses, but be aware of large payloads

Security Considerations

  • SSL verification is disabled for self-signed certificates (common in homelabs)
  • Store credentials in environment variables or Kubernetes secrets
  • Use API tokens instead of username/password when possible
  • The HTTP server should be behind TLS (handled by Traefik/Ingress)
  • Consider network policies to restrict access to the MCP server

Troubleshooting

Connection Issues

# Test VergeOS API directly
curl -sk https://your-vergeos-host/api/v4/vms -b "token=YOUR_TOKEN"

# Test MCP server
curl https://vergeos-mcp.yourdomain.com/health

Token Expiration

Tokens may expire. The server automatically fetches new tokens using username/password if configured.

# Manually refresh token
curl -sk -X POST "https://your-vergeos-host/api/sys/tokens" \
  -u "admin:password" \
  -H "Content-Type: application/json" \
  -d '{"login":"admin","password":"password"}'

Kubernetes Logs

kubectl logs -n vergeos-mcp deployment/vergeos-mcp
kubectl get pods -n vergeos-mcp

Local Proxy Issues

# Test proxy directly
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node ~/.mcp/vergeos/index.js

File Structure

vergeos-mcp-server/
├── src/
│   ├── index.js           # Stdio MCP server (local use)
│   ├── http-server.js     # HTTP server (legacy)
│   ├── mcp-http-server.js # HTTP+MCP server (K8s deployment)
│   └── stdio-proxy.js     # Stdio proxy for remote server
├── local-proxy/
│   ├── package.json       # Local proxy dependencies
│   └── index.js           # Local proxy for Windsurf
├── deploy.sh              # Kubernetes deployment script
├── k8s-deployment.yaml    # Kubernetes manifests
├── package.json
├── .env.example
└── README.md

License

MIT