VergeOS MCP Server
Enables AI assistants to manage and monitor VergeOS virtualization platforms through natural language, including VM operations, network management, tenant administration, and cluster monitoring.
README
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
| Option | Use 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
| Tool | Description |
|---|---|
list_vms |
List all virtual machines (filter by running/name) |
get_vm |
Get detailed VM information by ID |
get_vm_status |
Get VM running status and power state |
power_on_vm |
Power on a VM |
power_off_vm |
Gracefully power off with optional wait and auto-force |
force_off_vm |
Force power off (hard shutdown) |
reset_vm |
Reset/reboot a VM |
VM Configuration
| Tool | Description |
|---|---|
modify_vm |
Change CPU cores and/or RAM (handles running VMs) |
add_drive |
Add a new disk drive to a VM |
resize_drive |
Expand an existing disk (increase only) |
get_vm_nics |
Get VM network interfaces |
get_vm_drives |
Get VM disk drives with sizes |
Network Management
| Tool | Description |
|---|---|
list_networks |
List all virtual networks |
get_network |
Get network details |
network_action |
Power on/off, reset, apply rules |
Tenant Management
| Tool | Description |
|---|---|
list_tenants |
List all tenants |
get_tenant |
Get tenant details |
tenant_action |
Power on/off, reset tenants |
Cluster & Node Management
| Tool | Description |
|---|---|
list_nodes |
List cluster nodes |
get_node_stats |
Get node statistics |
get_cluster_status |
Get cluster health status |
get_cluster_stats |
Get storage tier statistics |
Storage & Monitoring
| Tool | Description |
|---|---|
list_volumes |
List storage volumes |
get_logs |
Get system logs (filter by level/object type) |
get_alarms |
Get active alarms |
Smart Features
- Graceful shutdown with wait:
power_off_vmcan wait for VM to shut down and auto-force if timeout expires - Running VM handling:
modify_vmdetects 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)
MCP Resources
vergeos://cluster/status- Cluster status overviewvergeos://vms/list- All virtual machinesvergeos://networks/list- All virtual networksvergeos://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:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/tools |
GET | List available MCP tools |
/tools/:name |
POST | Execute an MCP tool |
/vms |
GET | List all VMs |
/vms/:id |
GET | Get VM details |
/vms/:id/:action |
POST | VM action (poweron/poweroff/reset) |
/networks |
GET | List networks |
/tenants |
GET | List tenants |
/nodes |
GET | List nodes |
/cluster/status |
GET | Cluster status |
/alarms |
GET | Active alarms |
/logs |
GET | System logs |
MCP Protocol Endpoints
| Endpoint | Method | Description |
|---|---|---|
/sse |
GET | Server-Sent Events connection |
/message |
POST | MCP 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"
VergeOS API Notes
Authentication
VergeOS uses cookie-based authentication:
- POST to
/api/sys/tokenswith Basic Auth - Response contains token in
$keyfield - 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: trueare templates, not running VMs /machine_nics?machine=<ID>may return NICs from other machines; always filter by machine ID- Use
fields=mostfor 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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
E2B
Using MCP to run code via e2b.