vlp-mcp-agent
by ATE-Labs
README.md
# vlp-mcp-agent
MCP server for VLP lab VM automation. Runs on the manager VM of an EPC HOL SKU vPOD alongside the existing `vlp-tools-agent`. Exposes VM capabilities as first-class MCP tools so Cursor, Claude Code, and other AI agents can automate lab tasks without manual SSH sessions.
## What it does
Wraps the co-located [`vlp-tools-agent`](https://github.com/ATE-Labs/vlp-tools-agent) REST API at `localhost:8787` and adds general VM tooling on top. The existing agent's WebSocket connection to the VLP Hub is untouched.
```
Developer Machine
└── SSH tunnel :8789 → Manager VM :5480
├── vlp-mcp-agent (this project) :8789
│ └── calls localhost:8787
└── vlp-tools-agent (Spring Boot) :8787
└── outbound WSS → VLP Hub
```
## Tools available to the AI agent
### VLP-specific
| Tool | What it does |
|---|---|
| `trigger_vlp_operation` | Trigger a VLP platform operation (e.g. `killApp`) via the vlp-tools-agent |
| `execute_script` | Execute a sh/PowerShell/Python script — via agent API or direct subprocess fallback |
| `get_vm_info` | Return VM identity and network info (requestId, tenant, vmName, etc.) |
### General VM tools
| Tool | What it does |
|---|---|
| `run_command` | Run a shell command on this VM |
| `read_file` | Read a text file from this VM |
| `write_file` | Write a text file to this VM |
| `list_directory` | List a directory on this VM |
| `upload_file` | Push a binary file to this VM (base64) |
| `download_file` | Pull a binary file from this VM (base64) |
| `http_request` | Make an HTTP request from this VM's network perspective |
---
## Remote side — install once (manager VM)
```bash
git clone git@benhtodd-bc:ATE-Labs/vlp-mcp-agent.git
cd vlp-mcp-agent
./install.sh
```
Installs to `/opt/vlp-mcp-agent/`. Service is installed but **not started**.
---
## Local side — connect when needed
### Start / stop
```bash
# Connect (starts service on manager VM + opens SSH tunnel)
./connect-manager.sh holuser@<manager-ip>
# Disconnect (closes tunnel + stops service)
# Press Ctrl-C in the connect-manager.sh terminal — it handles cleanup automatically.
# Or manually:
./disconnect-manager.sh holuser@<manager-ip>
```
Environment variable overrides:
```bash
VLP_SSH_PORT=5480 # SSH port for the manager VM (default: 5480)
VLP_MCP_PORT=8789 # MCP port to tunnel (default: 8789)
```
### On-demand via SSH (no tunnel, no persistent service)
For one-off use, Cursor can launch the server as a subprocess over SSH — no tunnel needed:
```json
{
"mcpServers": {
"vlp-manager": {
"command": "ssh",
"args": ["-p", "5480", "holuser@<manager-ip>",
"/opt/vlp-mcp-agent/venv/bin/python",
"/opt/vlp-mcp-agent/vlp_mcp_agent/server.py",
"--stdio"]
}
}
}
```
---
## Agent config — connect via SSH tunnel
After `connect-manager.sh` is running:
### Cursor
Edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project):
```json
{
"mcpServers": {
"vlp-manager": {
"url": "http://localhost:8789/sse"
}
}
}
```
### Claude Code
Edit `~/.claude/settings.json`:
```json
{
"mcpServers": {
"vlp-manager": {
"url": "http://localhost:8789/sse"
}
}
}
```
---
## Development / local testing
```bash
# Install deps
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]" # or: pip install -r requirements.txt
# Run locally (no vlp-tools-agent required — tools that need it will report gracefully)
python vlp_mcp_agent/server.py --port 8789
# Run tests
pytest
```
---
## Relationship to vlp-tools-agent
This project is a **companion**, not a replacement. The `vlp-tools-agent` continues to:
- Maintain the WebSocket connection to the VLP Hub
- Handle `executeVmScript` messages from VLP
- Manage reconnection, heartbeats, and pending message queues
This agent adds the MCP interface layer on top, enabling AI-driven automation. When the vlp-tools-agent owners add a `POST /api/script/execute` endpoint, `execute_script` will automatically use it; until then it falls back to direct subprocess execution.
---
## Security
- Binds to `127.0.0.1` only — not reachable without SSH access to the manager VM
- SSH (port 5480) is the authentication layer — no separate token needed
- Configurable command timeouts and blocked path prefixes in `config.yaml`
- `Restart=no` in systemd unit — never auto-starts, must be started manually
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues