vps-ops
Provides tools for managing Docker on a remote VPS, including container operations (list, inspect, logs, stats, restart, stop, start, remove), Compose orchestration (up, restart, pull), and Swarm cluster monitoring (service and node listing), with integrated prune capabilities.
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., "@vps-opscheck the VPS disk usage and list running Docker containers"
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.
vps-ops-mcp
A stdio MCP server that operates one VPS over SSH. Cursor and Codex start the process with bun and call read-only tools (host health, Unix debug, Docker, Compose, Swarm, firewall) plus mutation tools (restart, stop, start, prune). Mutations require an explicit confirmation.
Transport is stdio. Do not start the server as a long-lived process by hand: the client (Cursor or Codex) launches it.
Contributing
See CONTRIBUTING.md (branches, pull requests, verification) and ISSUE.md (how to file an issue).
Related MCP server: Secure VPS Operations MCP Server
Requirements
Python 3 (used by the registration scripts)
OpenSSH client (
sshonPATH)A readable SSH private key with access to the remote user
On the remote host: Docker (and passwordless
sudo -nforufw,fail2ban,sshd -T,ss, anddmesgif you use those tools)
Configuration
cp .env.example .envEdit .env. The file is gitignored.
Variable | Required | Default | Purpose |
| yes | — | Absolute path to the private key. The process refuses to start if the file is missing or unreadable. |
| no |
| SSH host (placeholder; set your own host). |
| no |
| SSH user. |
| no |
| SSH port. |
| no | — | Absolute Compose directory on the VPS. Without it, Compose tools require the |
| no |
| Remote command timeout. Expiry returns |
| no |
| Cap for |
| no |
|
|
| no | — | Avoid. Prefer |
VPS_COMPOSE_DIR must be absolute and match /^[a-zA-Z0-9/_.-]+$/ (it must start with /).
Installation
bun installnpm package (requires Bun; the MCP Registry points at this artifact):
bunx @koller-nexus/vps-ops-mcpMCP Registry name: io.github.koller-nexus/vps-ops-mcp. The registry publishes metadata only after the package exists on public npm.
Register with clients
The scripts write MCP config from variables already exported in the shell. They do not load .env themselves. If you skip the export, the scripts fall back to their defaults (host, user, port, and a local key path).
Do this once at the repository root before each script:
set -a
source .env
set +aEach run backs up the destination file (*.bak.YYYYMMDDHHMMSS) and replaces only the vps-ops server. Other MCP servers stay in place.
Optional script variables:
Variable | Default | Purpose |
| this repository root | Source of the |
|
| Cursor file to update. |
|
| Codex file to update. |
VPS_COMPOSE_DIR is written into the client config only when it is set and non-empty.
Cursor
Global registration (applies in every workspace):
./scripts/register-cursor-mcp.shThe script writes ~/.cursor/mcp.json in this shape:
{
"mcpServers": {
"vps-ops": {
"command": "bun",
"args": ["/absolute/path/vps-ops-mcp/src/index.ts"],
"env": {
"VPS_HOST": "your.host",
"VPS_USER": "ubuntu",
"VPS_PORT": "22",
"VPS_SSH_KEY_PATH": "/absolute/path/to/key",
"VPS_COMMAND_TIMEOUT_MS": "30000",
"VPS_LOG_MAX_BYTES": "200000",
"VPS_ALLOW_MUTATIONS": "true"
}
}
}
}To scope it to one project, point the script at that project's mcp.json:
CURSOR_MCP_JSON="/absolute/path/to/project/.cursor/mcp.json" ./scripts/register-cursor-mcp.shThen reload the Cursor window (Command Palette → Developer: Reload Window) or restart the server under Settings → MCP. The server appears as vps-ops.
Codex
./scripts/register-codex-mcp.shThe script writes ~/.codex/config.toml:
[mcp_servers.vps-ops]
command = "bun"
args = ["/absolute/path/vps-ops-mcp/src/index.ts"]
[mcp_servers.vps-ops.env]
VPS_HOST = "your.host"
VPS_USER = "ubuntu"
VPS_PORT = "22"
VPS_SSH_KEY_PATH = "/absolute/path/to/key"
VPS_COMMAND_TIMEOUT_MS = "30000"
VPS_LOG_MAX_BYTES = "200000"
VPS_ALLOW_MUTATIONS = "true"Close and reopen the Codex session so it rereads config.toml. If the CLI is on PATH, codex mcp list should show vps-ops.
Verify
Test SSH outside MCP with the same flags the server uses:
ssh -i "$VPS_SSH_KEY_PATH" \
-o BatchMode=yes \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=accept-new \
-p "${VPS_PORT:-22}" \
"${VPS_USER}@${VPS_HOST}" \
'uname -a'In Cursor or Codex, ask the client to call vps_ping. The response is JSON:
{
"exit_code": 0,
"stdout": "...",
"stderr": "",
"duration_ms": 0,
"truncated": false
}A non-zero exit_code is an MCP error. If the process exits immediately with VPS_SSH_KEY_PATH is required or missing or unreadable, the variable never reached the client env — rerun the registration script with .env exported.
Tools
Every call returns exit_code, stdout, stderr, duration_ms, and truncated.
Read-only
Tool | Arguments | What it does |
| — |
|
| — |
|
|
|
|
| — |
|
|
|
|
|
|
|
| — |
|
| — |
|
| — |
|
|
|
|
| — |
|
| — |
|
| — | Top 30 processes by memory ( |
|
|
|
| — |
|
|
|
|
| — | Filtered |
Container, service, image, and jail names must match ^[a-zA-Z0-9][a-zA-Z0-9_.-]*$.
Mutation
These require confirm: true. With VPS_ALLOW_MUTATIONS=false, all of them are rejected.
Tool | Extra arguments | Remote command |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Security
Remote commands are fixed. There is no free-form shell tool.
Name and path arguments go through an allowlist and are quoted in the shell.
SSH uses
BatchMode=yes,IdentitiesOnly=yes, andStrictHostKeyChecking=accept-new.A mutation without
confirm: trueis rejected.docker_rmasks for the name twice. Volume prune requiresconfirm_volumes: true.For a read-only client, register with
VPS_ALLOW_MUTATIONS=false.
This server cannot be deployed
Maintenance
Related MCP Connectors
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Run commands and read/write files on your servers over Termalin's keyless tunnels (hosted MCP).
Remote shell and detached long-running jobs on your own machines — no SSH, open ports or VPN.
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Related MCP Servers
- FlicenseAqualityDmaintenanceGives AI assistants full control over a VPS via SSH, enabling command execution, file management, service control, Docker and firewall management.96-
- AlicenseAqualityCmaintenanceEnables secure, read-only inspection of a VPS over SSH through approved operations such as system health, disk usage, container logs, and service status, without giving the AI unrestricted shell access.81MIT
- AlicenseNot gradedqualityCmaintenanceEnables remote server management via SSH, including executing commands, managing persistent interactive sessions, and transferring files over SFTP.77 npmISC
- FlicenseBqualityBmaintenanceEnables safe VPS diagnostics and Docker/Docker Compose management over SSH, providing predefined read-only and mutating tools for system monitoring, container inspection, and Compose orchestration without exposing arbitrary shell execution.26-