Secure VPS Operations MCP Server
Enables inspection of Docker containers, including listing containers and reading their logs.
Provides visibility into Grafana container health and logs through the container inspection tools.
Allows users to check the syntax and validity of Nginx configuration files on the VPS.
Provides visibility into OpenSearch container health and logs through the container inspection tools.
Provides visibility into Prometheus container health and logs through the container inspection tools.
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., "@Secure VPS Operations MCP ServerCheck the system health and disk usage on my VPS"
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.
Secure VPS Operations MCP Server
A secure, read-only Model Context Protocol (MCP) server for inspecting a VPS over SSH without giving an AI assistant unrestricted shell access.
The core idea is simple: the AI selects approved operations; it never constructs or executes arbitrary shell commands.
What This Project Does
This project exposes a small set of MCP tools for safe VPS inspection:
get_system_healthget_disk_usagelist_containersget_container_logsget_service_statuscheck_nginx_configurationcheck_ssl_expirycheck_database_health
Each MCP tool validates input locally, checks configured allowlists, then calls a fixed SSH gateway command on the VPS. The gateway maps operation names to root-owned scripts under /usr/local/lib/mcp/scripts.
There is intentionally no generic execute_shell tool.
Related MCP server: mcp-vps-monitor
Architecture
AI Client
|
v
MCP Client
|
v
Local Python MCP Server
|
v
SSH key authentication
|
v
Dedicated VPS user
|
v
/usr/local/bin/mcp-command-gateway
|
v
Root-owned allowlisted scriptsWhy Python
This first version uses Python 3.11+ because the official MCP Python SDK, asyncssh, and Pydantic make a small control-plane server straightforward to build and audit.
Java would also be viable, especially inside an existing Spring-based internal platform, but Python keeps this MCP adapter smaller and simpler for the first release.
Security Model
The security boundary is based on constraints rather than prompting:
No unrestricted shell tool
Dedicated SSH user, not root
SSH key authentication only
Host-key verification through
known_hostsFixed gateway command on the VPS
Operation allowlist in the gateway
Resource allowlists for containers, services, domains, and databases
Root-owned scripts that the SSH user cannot edit
Narrow sudo rules only where required
Output sanitisation before returning data to the model
Append-only JSONL audit logs
Local Setup
Create a virtual environment:
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e '.[test]'Create local configuration:
cp .env.example .envEdit .env:
SSH_HOST=your-vps-host-or-ip
SSH_PORT=22
SSH_USERNAME=mcp-operator
SSH_PRIVATE_KEY_FILE=/path/to/private/key
SSH_KNOWN_HOSTS_FILE=/path/to/known_hosts
ALLOWED_CONTAINERS=grafana,prometheus,opensearch
ALLOWED_SERVICES=app.service,docker.service,nginx.service
ALLOWED_DOMAINS=api-dev.example.com,api-staging.example.com
ALLOWED_DATABASES=appdbPin the VPS host key:
ssh-keyscan -H your-vps-host-or-ip >> ~/.ssh/known_hostsRun tests:
python -m pytestRun the MCP server locally:
contabo-ops-mcpFor stdio MCP usage, the server will appear to wait for input. That is expected. An MCP client starts the process and communicates with it over stdin/stdout.
VPS Setup
Create a dedicated user on the VPS:
sudo useradd --create-home --shell /bin/bash mcp-operator
sudo mkdir -p /home/mcp-operator/.ssh
sudo chmod 700 /home/mcp-operator/.ssh
sudo chown -R mcp-operator:mcp-operator /home/mcp-operatorCreate an SSH key locally:
ssh-keygen -t ed25519 -f ~/.ssh/vps_mcp -C "vps-operations-mcp"Add the public key to the VPS:
sudo tee /home/mcp-operator/.ssh/authorized_keys > /dev/null <<'EOF'
PASTE_PUBLIC_KEY_HERE
EOF
sudo chown -R mcp-operator:mcp-operator /home/mcp-operator/.ssh
sudo chmod 700 /home/mcp-operator/.ssh
sudo chmod 600 /home/mcp-operator/.ssh/authorized_keys
sudo chmod 755 /home/mcp-operatorTest SSH from your local machine:
ssh -i ~/.ssh/vps_mcp mcp-operator@your-vps-host-or-ipGateway Installation
Copy the gateway to the VPS:
scp -i ~/.ssh/vps_mcp vps/mcp-command-gateway mcp-operator@your-vps-host-or-ip:/tmp/mcp-command-gatewayInstall it on the VPS:
sudo install -o root -g root -m 755 /tmp/mcp-command-gateway /usr/local/bin/mcp-command-gateway
sudo mkdir -p /usr/local/lib/mcp/scripts
sudo chown -R root:root /usr/local/lib/mcp
sudo chmod -R 755 /usr/local/lib/mcpThe gateway accepts structured JSON like this:
{
"operation": "system.health",
"arguments": {}
}It rejects unknown operations and never accepts raw shell commands.
Example Script
Create /usr/local/lib/mcp/scripts/system-health on the VPS:
sudo tee /usr/local/lib/mcp/scripts/system-health > /dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
load_average="$(cut -d ' ' -f1-3 /proc/loadavg)"
uptime_seconds="$(cut -d. -f1 /proc/uptime)"
hostname="$(hostname)"
printf '{"success":true,"hostname":"%s","uptimeSeconds":%s,"loadAverage":"%s"}\n' \
"$hostname" \
"$uptime_seconds" \
"$load_average"
EOF
sudo chown root:root /usr/local/lib/mcp/scripts/system-health
sudo chmod 755 /usr/local/lib/mcp/scripts/system-healthTest directly on the VPS:
printf '{"operation":"system.health","arguments":{}}' | /usr/local/bin/mcp-command-gatewayTest from your local machine over SSH:
ssh -i ~/.ssh/vps_mcp mcp-operator@your-vps-host-or-ip \
'printf '\''{"operation":"system.health","arguments":{}}'\'' | /usr/local/bin/mcp-command-gateway'MCP Client Configuration
For an MCP client that supports local stdio servers, configure the command as:
{
"mcp": {
"vps-ops": {
"type": "local",
"command": [
"/absolute/path/to/project/.venv/bin/python",
"/absolute/path/to/project/src/contabo_mcp/main.py"
],
"enabled": true,
"env": {
"PYTHONPATH": "/absolute/path/to/project/src"
}
}
}
}Restart the MCP client after changing its config.
Example prompts:
"Check system health on the VPS."
"Show disk usage on the VPS."
"Show the last 20 logs for the Grafana container."
"Check SSL expiry for
api-dev.example.com.""Check status of
nginx.service."
Development
Run tests:
source .venv/bin/activate
python -m pytestCheck config loading:
python -c "from contabo_mcp.config import get_settings; print(get_settings().ssh_host)"Check the SSH gateway from Python:
python - <<'PY'
import asyncio
from contabo_mcp.config import get_settings
from contabo_mcp.ssh_gateway import SshGateway
async def main():
gateway = SshGateway(get_settings())
result = await gateway.execute("system.health", {})
print(result.exit_code)
print(result.stdout)
print(result.stderr)
asyncio.run(main())
PYCurrent Scope
This repository is intentionally read-only for the first release.
Write operations such as service restarts, Nginx reloads, certificate renewal, backups, deployments, and rollbacks should be added only after implementing:
Explicit approval handling
Risk classification
Narrow sudo rules
Idempotency checks
Post-action health verification
Stronger audit records
Failure and rollback behavior
License
This project is licensed under the MIT License. See LICENSE for details.
Available Tools
8 toolscheck_database_healthA
Return health information for an allowlisted PostgreSQL database.
| Name | Required | Description | Default |
|---|---|---|---|
| database | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states 'return health information' which implies a read-only operation, but it does not disclose potential side effects, authentication requirements, or behavior when the database is not allowlisted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that immediately conveys the action and resource. Every word is meaningful and there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only one parameter and an output schema exists, but the description lacks usage guidance and behavioral transparency. It is minimally viable but leaves gaps in understanding what happens in edge cases or how to choose this over siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% parameter coverage. The description adds the 'allowlisted' constraint and indicates the parameter is a database name, but does not provide format details or further semantic meaning beyond the schema's basic string type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'return' and identifies the resource as 'health information' for an 'allowlisted PostgreSQL database', which clearly distinguishes it from sibling tools like get_system_health or get_service_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context that this tool is for PostgreSQL database health, implying when it should be used. However, it does not explicitly mention alternatives or when not to use it, but the scope is clear enough for a simple health check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_nginx_configurationB
Run nginx configuration validation on the VPS.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. It merely says 'run validation' without explaining whether the tool is read-only, what it validates specifically, what the output format is, or how to interpret success/failure. This is insufficient for an agent to anticipate side effects or return values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no fluff. It is concise but may be under-specified; however, for a zero-parameter tool, this length is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with no parameters, and an output schema exists, so returning details are covered. However, the description gives no context on when to run this validation or what the output represents, leaving the agent without enough information to decide when to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so schema coverage is trivially 100%. Per the rubric, a baseline of 4 applies when no parameters exist. The description adds no parameter-related detail, but none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Run nginx configuration validation') and locates it ('on the VPS'). This verb+resource+scope construction distinguishes it from sibling tools like system health or SSL expiry checks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives. It does not mention typical use cases (e.g., after nginx config edits) or when other diagnostic tools would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_ssl_expiryB
Return certificate expiry details for an allowlisted domain.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It mentions the 'allowlisted' constraint, which hints at possible domain restrictions, but doesn't disclose what happens for non-allowlisted domains, whether the check is a live network lookup, or any side effects or rate limits. It's too sparse to be transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler. It front-loads the verb and object, making it immediately parsable. The brevity is appropriate for a simple tool, though it sacrifices depth.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with a single parameter and an output schema exists, so return values are presumably documented. However, the description omits critical usage context such as the allowlist enforcement behavior, possible error conditions, and when to choose this over the sibling tools. It's minimally complete but leaves clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. The only hint is 'allowlisted domain' which suggests that the domain parameter must be pre-approved, but it doesn't explain the format, any constraints (e.g., FQDN vs URL), or what values are acceptable. The parameter name 'domain' is self-explanatory but the description adds little beyond that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the verb 'Return' and clearly specifies the resource ('certificate expiry details') and scope ('allowlisted domain'). It clearly distinguishes from sibling tools which target system health, containers, logs, and database status—none of which relate to SSL certificate details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention any exclusions or prerequisites other than the implied 'allowlisted domain' constraint, which isn't elaborated as a usage condition. There are no explicit 'when to use' or 'instead of' statements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_container_logsC
Return recent logs for an allowlisted Docker container.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | ||
| container | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It does not explain what 'recent' means, what happens with a non-allowlisted container, whether logs are streamed or returned in a batch, or any limiting behavior. The single sentence provides minimal behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no fluff, front-loaded with the verb and resource. It is appropriately concise and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema, return value details are covered, but the lack of annotations, 0% schema parameter coverage, and a one-line description mean important execution context is missing. For a simple read operation, the description still leaves gaps around parameter semantics, error behavior, and usage prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it does not. Neither the 'container' parameter nor the 'lines' parameter is explained. The description only mentions 'recent logs', which does not clarify that 'lines' controls the number of lines returned, nor how the container identifier should be specified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and clearly identifies the resource ('recent logs for an allowlisted Docker container'). This distinguishes it from sibling tools like get_system_health or list_containers, and the 'allowlisted' qualifier adds useful scoping.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, when not to use it, or any prerequisites beyond the implicit 'allowlisted' status. There is no mention of using list_containers first to find a container name or of error conditions for non-allowlisted containers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_disk_usageA
Return filesystem usage for the VPS.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It does not explicitly state that the operation is read-only, nor does it mention potential side effects, permissions, or return format. The verb 'Return' implies a safe query, but important behavioral details are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that directly states the tool's purpose with no unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple no-parameter query with an output schema present. The description sufficiently communicates what the tool does, and the output schema covers return value details. Nothing more is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, so the schema has no parameter details to explain. The baseline for 0-param tools is 4, and the description does not need to add parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Return') and the resource ('filesystem usage for the VPS'). It effectively distinguishes this tool from siblings like get_system_health or check_database_health by focusing specifically on disk usage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives. The description only states what the tool does without any context, exclusions, or mention of sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_service_statusA
Return systemd status for an allowlisted service.
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the allowlist constraint, implying the tool will fail for non-allowlisted services, but it does not specify required permissions, rate limits, or the exact return behavior beyond the output schema. The read-only nature is implicit in 'status' but not explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of seven words, front-loaded with the verb and resource. It contains no filler or redundant information, earning a perfect score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with an output schema, the description is largely complete: it identifies the resource, the constraint, and implicitly the parameter. It does not detail the allowlist mechanism or possible errors, but the output schema covers return values, so this is acceptable. Slight deduction for not fully explaining the allowlist behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no description for the 'service' parameter, and schema description coverage is 0%. The description adds meaning by clarifying that the parameter is the name of an allowlisted service, which is a key constraint not evident from the schema alone. It does not provide format examples but compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns systemd status for a service, with a specific constraint (allowlisted). The verb 'Return' and resource 'systemd status' are unambiguous, and the 'allowlisted' scoping distinguishes it from sibling tools like get_system_health or list_containers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for checking systemd service status, but it does not explicitly state when to use it versus alternatives or mention any exclusions. It provides context by naming the resource and constraint, but lacks explicit guidance on alternative selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_system_healthA
Return CPU, memory, load, disk, and service health summary from the VPS.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It accurately states the tool returns a summary, strongly implying a read-only operation, but it does not explicitly confirm non-destructiveness, mention any required permissions, or describe what 'health' means in terms of thresholds. The lack of disclaimers or caveats leaves some ambiguity, but the description is not misleading.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that efficiently lists all key information. No wasted words, and the structure is immediately understandable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simple purpose, zero parameters, and the presence of an output schema (as indicated by context signals), the description provides sufficient context. It clearly enumerates the subsystems covered, though it could have added a note about its relationship to more specific sibling tools for enhanced completeness. That gap prevents a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema is an empty object (100% schema coverage). Per the rubric, a baseline score of 4 applies when there are no parameters, as there is nothing further the description needs to explain about arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with the specific verb 'Return' and names the exact resource: a 'health summary' covering CPU, memory, load, disk, and service health. This clearly differentiates it from siblings like get_disk_usage (disk only) and get_service_status (services only).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool's role as a high-level overview is implied by listing multiple subsystems, but the description does not explicitly say when to use this instead of more specific siblings, nor does it mention any exclusions or prerequisites. Usage context is implied but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_containersA
List allowlisted Docker containers and their status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It indicates a read-only operation ('List') and adds that it only returns 'allowlisted' containers with status, which is useful context. However, it does not explain what 'allowlisted' means or any potential failure conditions, leaving some ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that clearly states the tool's purpose. No unnecessary words or fluff, making it highly scannable and appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (no parameters) and an output schema exists, so the description doesn't need to explain return values. The only notable gap is the undefined term 'allowlisted', which may require additional context to fully understand the tool's scope. Otherwise, it is complete for a basic listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters and the schema has 100% coverage (empty object), so the description has no parameter details to add. According to the rubric, 0 parameters sets a baseline score of 4, and the description does not interfere with that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' with the resource 'Docker containers' and scope 'allowlisted', making it clear what the tool does. It also includes 'status', which distinguishes it from sibling tools like get_container_logs (which retrieves logs) and get_service_status (which checks services).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage scenario (when you need to see allowlisted containers and their status) but does not explicitly state when to use it over alternatives. There are no exclusions or mentions of other tools like get_container_logs, so it is not fully differentiated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
check_database_health - First observed
check_nginx_configuration - First observed
check_ssl_expiry - First observed
get_container_logs - First observed
get_disk_usage - First observed
get_service_status - First observed
get_system_health - First observed
list_containers
TDQS
Scored across 8 tools
Most tools have clearly distinct purposes (system health, disk usage, containers, logs, services, nginx, SSL, database). There's minor overlap between get_system_health and get_disk_usage/get_service_status, but descriptions clarify the scope.
All tool names follow a consistent verb_noun pattern (get_*, list_*, check_*) with snake_case throughout. The verbs are predictable and appropriate for the actions.
8 tools is well-scoped for a VPS operations/monitoring server. Each tool addresses a distinct monitoring need without redundancy or bloat.
The server covers core VPS health checks (system, disk, containers, services, nginx, SSL, database) well. Minor gaps exist (e.g., no network health or process-level details), but the surface is sufficient for typical operational monitoring.
Maintenance
Related MCP Connectors
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Run verified read-only code tools: quant diagnostics + agent-ops preflight, no source exposure.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceProvides read-only server monitoring and diagnostic tools for AI assistants to manage Linux and Unraid systems via SSH. It enables natural language interactions for container management, storage health checks, and system log analysis while keeping credentials secure.17ISC
- AlicenseAqualityBmaintenanceProvides system monitoring tools for VPS including CPU, memory, disk, network ping, top processes, and Docker status, with read-only architecture and security features.4MIT
- AlicenseAqualityCmaintenanceProvides read-only access to host system metrics (CPU, memory, disk), Docker container health/logs, and sandboxed log file analysis via MCP tools, enabling AI agents to monitor enterprise infrastructure safely.3MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to safely explore and diagnose remote servers by providing a read-only sandbox with controlled access to files, logs, Docker, and databases. It exposes MCP tools that allow natural-language investigation and direct command execution without write permissions.3-