mikrus-mcp

by paulomac1000

Not rated
GitHub

About

MCP (Model Context Protocol) server for managing VPS servers via the mikr.us API and remote Linux servers over SSH. Built in Python, runs anywhere — locally, in Docker, or as a Claude Desktop integration.

Details

Author
paulomac1000
Categories
Cloud Service, Infrastructure, Other

Setup

Install mikrus-mcp in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/paulomac1000/mikrus-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

MCP (Model Context Protocol) server for managing VPS servers via themikr.usAPIandremote Linux servers over SSH. Built in Python, runs anywhere — locally, in Docker, or as a Claude Desktop integration.

All tools follow theMCP Server Standardsfor response format, testing, and documentation.

- Requirements
-
Quick Start

- Configure environment
-
Run with Docker
-
Run locally

- Python 3.14+ (for local use) or Docker
- A
mikr.usaccount with an API keyorany SSH-accessible Linux server
- Your server identifier (e.g.your_srv) or SSH host

Edit.envwith your credentials. Three modes are supported:

MIKRUS_API_KEY=your_api_key_here MIKRUS_SERVER_NAME=your_server_name_here
MCP_SERVERS={"your_srv": {"type": "mikrus", "key": "xxx", "srv": "your_srv"}, "myssh": {"type": "ssh", "host": "srvXX.mikr.us", "port": 22, "user": "root", "password": "secret"}} MCP_DEFAULT_SERVER=your_srv

C — SSH-only (no mikr.us account needed):

MCP_SERVERS={"prod": {"type": "ssh", "host": "prod.example.com", "user": "admin", "ssh_key": "/home/user/.ssh/id_ed25519"}}

Variable name aliases (MCP_andMIKRUS_are interchangeable):

- MCP_SERVERS←→MIKRUS_SERVERS
- MCP_DEFAULT_SERVER←→MIKRUS_DEFAULT_SERVER

IMPORTANT:The.envfile contains your API key / passwords. It is gitignored and must never be committed.

Pre-built image (recommended — no local build needed)

Pulls the published image from GitHub Container Registry:

docker run --rm \ --env-file .env \ ghcr.io/paulomac1000/mikrus-mcp:latest
docker run --rm \ -e MIKRUS_API_KEY=your_key \ -e MIKRUS_SERVER_NAME=your_server \ ghcr.io/paulomac1000/mikrus-mcp:latest

Local build (use when modifying the code or for development)

# with docker compose (reads .env automatically) docker compose up mikrus-mcp # with docker compose and SSH key mount docker compose run --rm \ -v ~/.ssh/id_ed25519:/home/appuser/.ssh/id_ed25519:ro \ mikrus-mcp # or with plain docker build docker build -t mikrus-mcp . docker run --rm --env-file .env mikrus-mcp

The server communicates overstdioby default. SetMCP_PORTto enable SSE transport (seeSecurity Considerations).

Using SSH keys in Docker:Mount your private key as a read-only volume:

docker run --rm \ --env-file .env \ -v ~/.ssh/id_ed25519:/home/appuser/.ssh/id_ed25519:ro \ ghcr.io/paulomac1000/mikrus-mcp:latest

SSH keys must have permissions600or400and be readable by theappuseruser inside the container (UID 1000). If your host user has a different UID, adjust ownership withchown 1000:1000 ~/.ssh/id_ed25519or use a less restrictive mode. Certificates can be mounted the same way.

pip install -e ".[dev]" mikrus-mcp

System management tools (mikrus + SSH servers)

Docker tools (mikrus + SSH servers, requires Docker access)

Journal tools (mikrus + SSH servers, may requiresudo_password)

Note about journal tools:If the remote user is not in thesystemd-journaloradmgroup, journal commands will fail. To fix this, addsudo_passwordto the SSH server configuration. Ifsudo_passwordis omitted, the tool will still work but returns a helpful hint for the user when privileges are insufficient.

All system tools accept an optionalserverparameter to target a specific configured server (e.g.server=myssh). If omitted, the default server is used.

All 33 tools return a consistent JSON structure. Every response includes a_metaenvelope with a uniquerequest_id:

{"success": true, "data": {"server_id": "emil359", "param_ram": "1024"}, "_meta": {"request_id": "a1b2c3d4-...", "duration_ms": 42, "cached": false, "retry_safe": false}}
{"success": false, "error": "Server 'unknown' is not a mikrus server", "_meta": {"request_id": "e5f6g7h8-..."}}

Thesuccessfield is always a boolean. Successful responses contain adatakey with the tool-specific result. Error responses contain anerrorkey with a human-readable message. No tool raises unhandled exceptions — errors are always returned as structured JSON.

Tools are annotated with risk-level prefixes in their descriptions:

AI agents use these prefixes to decide whether to request user confirmation before invoking a tool. Tools are additionally gated behindENABLE_WRITE_OPERATIONS— a server-level authorization flag that must be explicitly enabled for any write, destructive, or command-execution tool to perform I/O.

You can manage multiple servers simultaneously by using theMCP_SERVERSJSON. You can mix mikrus and SSH servers, or use SSH servers exclusively (no mikr.us account required).

{ "your_srv": {"type": "mikrus", "key": "xxx", "srv": "your_srv"}, "myssh": {"type": "ssh", "host": "192.168.1.10", "port": 22, "user": "root", "password": "secret", "sudo_password": "secret"} }

All tools accept an optionalserverparameter to target a specific configured server. IfMCP_DEFAULT_SERVERis not set, thefirst serverin the JSON object is used as the default.

This MCP server grants full system access to configured servers. Treat it as aprivileged remote administration tool.

- By default, SSE listens on127.0.0.1only.
- Binding to0.0.0.0requiresMCP_UNSAFE_PUBLIC_ACCESS_CONFIRMED=1.
- Never expose SSE to the internet without authentication.Use a reverse proxy (nginx, Traefik) with TLS and basic auth if remote access is needed.

- verify_host_keydefaults tofalsefor ease of use. In production, set it totrueand provide aknown_hosts_fileto prevent MITM attacks.
- sudo_passwordis fed viaasyncssh.create_process+ stdin,nevervia shell string interpolation, so it won't appear inps aux.
- SSH private keys mounted into Docker must have permissions600or400.

- All file paths are validated against traversal (..) and forbidden paths (e.g./etc/shadow).
- Dangerous commands (rm -rf /,mkfs,dd if=) are blocked before execution.
- Shell metacharacters (;,|,$,``) in commands are rejected before any patterns are checked.
- Service names, container names, ports, and domains are validated with strict regex patterns.
- File writes outside
/home,/var/www,/opt,/tmp,/srv,/var/logtrigger a warning.

- Write, destructive, and command-execution tools are gated behindENABLE_WRITE_OPERATIONS=1(default: disabled).
- When disabled, these tools return a structured error before any I/O.
- Read-only actions (
manage_service status,manage_process list) bypass the write guard.

- API keys and passwords are loaded from environment variables or.env(gitignored).
- Never commit credentials to version control.

Add the following to yourclaude_desktop_config.json. Use absolute paths — Claude Desktop may run from a different working directory.

{ "mcpServers": { "mikrus": { "command": "docker", "args": [ "run", "--rm", "--env-file", "/absolute/path/to/mikrus-mcp/.env", "ghcr.io/paulomac1000/mikrus-mcp:latest" ] } } }

With inline credentials (Docker, no.envfile):

{ "mcpServers": { "mikrus": { "command": "docker", "args": [ "run", "--rm", "-e", "MIKRUS_API_KEY=your_key", "-e", "MIKRUS_SERVER_NAME=your_server", "ghcr.io/paulomac1000/mikrus-mcp:latest" ] } } }
{ "mcpServers": { "mikrus": { "command": "mikrus-mcp", "env": { "MIKRUS_API_KEY": "your_key", "MIKRUS_SERVER_NAME": "your_server" } } } }
{ "mcpServers": { "mikrus": { "command": "docker", "args": [ "run", "--rm", "-v", "/home/user/.ssh/id_ed25519:/home/appuser/.ssh/id_ed25519:ro", "-e", "MCP_SERVERS={\"prod\":{\"type\":\"ssh\",\"host\":\"10.0.0.5\",\"user\":\"admin\",\"ssh_key\":\"/home/appuser/.ssh/id_ed25519\"}}", "-e", "MCP_DEFAULT_SERVER=prod", "ghcr.io/paulomac1000/mikrus-mcp:latest" ] } } }

After restarting Claude Desktop, the 33 mikrus tools will be available for use.

# Unit tests (fast, no credentials needed) — 310 tests pytest tests/unit/ -q --cov=mikrus_mcp --cov-report=term # Smoke tests — API connectivity and response format pytest tests/smoke/ -q # Integration tests — real mikr.us API pytest tests/integration/ -q # E2E tests — full pipeline workflows pytest tests/e2e/ -q

All tests userespx(HTTP mocking) orunittest.mock(SSH mocking). No real network calls are made in unit or e2e tests. Smoke and integration tests require a validMIKRUS_API_KEYand skip gracefully otherwise.

SetMCP_REST_PORTto expose an HTTP bridge that turns tool calls into REST endpoints:

MCP_PORT=8300 MCP_REST_PORT=8301 mikrus-mcp # GET http://127.0.0.1:8301/health # GET http://127.0.0.1:8301/tools # POST http://127.0.0.1:8301/tools/get_server_info {"params": {}}

This is a development utility for smoke testing and debugging. It is separate from the MCP SSE transport and runs on its own port. All endpoints have/api/prefixed mirrors (GET /api/health,GET /api/tools,POST /api/tools/{name}). Tool manifest endpoints are also available atGET /tools/{name}/manifestandGET /api/tools/{name}/manifest.

ruff check src/ tests/ ruff format --check src/ tests/ mypy src/ bandit -r src/
src/mikrus_mcp/ ├── __init__.py # Package version ├── __main__.py # python -m mikrus_mcp entry point ├── config.py # Environment variable loader (dotenv) — single-server, multi-server, SSH-only ├── constants.py # Backward-compat re-export for tools/constants.py ├── validators.py # Centralized input validation (path, port, service, container, domain) ├── sanitizer.py # Log sanitization (redacts API keys, IPs, passwords, MACs) ├── client.py # Async HTTP client (httpx) + SSH client (asyncssh) ├── server.py # MCP server with 33 tools, stdio + SSE transport, partial startup ├── rest_bridge.py # Optional REST bridge for smoke/e2e testing (on MCP_REST_PORT) └── tools/ ├── __init__.py ├── constants.py # SSOT defaults, tool manifests, validation limits, write guard ├── response.py # _success_response / _error_response helpers ├── capabilities.py # describe_mikrus_capabilities introspection tool (L3+) ├── mikrus_api.py # 12 mikr.us API tools + internal functions + registration ├── system.py # 14 system management tools (exec, file, service, disk, etc.) ├── container_journal.py # 6 Docker + journalctl tools + registration └── discovery.py # Server listing tool + registration tests/ ├── conftest.py # Root: environment loading ├── fixtures.py # Mock data constants ├── _env_loader.py # Shared .env loader for conftest files │ ├── unit/ # Unit tests — zero I/O, fully mocked │ ├── conftest.py │ ├── test_client.py │ ├── test_config.py │ ├── test_server_tools.py │ ├── test_ssh_client.py │ ├── test_multi_server.py │ ├── test_rest_bridge.py │ ├── test_sanitizer.py │ ├── test_tool_registration.py │ ├── test_capabilities.py │ └── test_validators.py │ ├── smoke/ # Smoke tests — direct API calls (skipif no creds) │ ├── conftest.py │ ├── test_connectivity.py │ ├── test_critical_tools.py │ └── test_response_format.py │ ├── integration/ # Integration tests — real API calls │ ├── conftest.py │ ├── mcp_wrapper.py │ └── test_real_tools.py │ └── e2e/ # E2E tests — full pipeline workflows ├── conftest.py └── test_server_api.py

- 33 tools total:2 discovery + 12 mikr.us API + 19 system management tools.
- All tools return
{"success": True/False, ...}JSON format for consistent error handling.
- All write operationsare protected by input validation — no shell injection possible.
- Errors are logged to
stderr, in compliance with the MCP specification.
- The mikr.us
/execendpoint has a 65-second client timeout (API limit is 60s).
-
/stats,/info,/serwery,/db, and/porty`have a 60-second API-side cache.
- Tool descriptions are optimized for LLM agents — each explainswhenandwhyto use the tool.

-

DevOps MCP — Secure MCP Server for Linux Server Automation

A three-tier access control MCP server that allows AI assistants (Claude Code, Cursor, Windsurf) to safely scan, plan, and operate Linux servers via SSH without full write access. Includes an out-of-band human consent token gate, automated port-conflict scanning, and a completely read-only default safe mode to eliminate accidental destructive commands on production environments.

The official Impreza Host connector for offshore server management

A local MCP server that securely connects to remote servers over SSH, acting as a proxy for MCP commands.

An MCP server that provides SSH-based remote management tools, acting as proxy

Core AWS MCP server providing prompt understanding and server management capabilities.

An MCP server for 1Panel, a modern Linux server operation and maintenance panel.

A comprehensive MCP server for configuring and managing Cisco ACI (Application Centric Infrastructure) fabrics through the APIC REST API.

Official Cisco MCP server for connecting AI agents to Meraki's cloud-managed networking solutions.

An MCP server for Cisco NSO (Network Services Orchestrator) that exposes NSO data and operations as MCP primitives.

Access Cisco Support APIs for bug searches and other support-related tasks.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.