ROS-MCP
Provides tools for managing MikroTik RouterOS devices via SSH, including listing devices and executing CLI commands.
Click on "Install 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., "@ROS-MCPshow interfaces on main router"
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.
ROS-MCP
ROS-MCP is a small MCP gateway for managing multiple MikroTik RouterOS devices over SSH. It exposes exactly two tools and keeps device credentials, SSH session reuse, retries, timeouts, and output limits behind the gateway.
Despite the project name, ROS means MikroTik RouterOS, not Robot Operating
System.
MCP tools
device_list
Returns the configured, non-sensitive device inventory. It performs no network I/O and never returns passwords, private keys, environment-variable names, or host-key fingerprints.
command_execute
command_execute(device: string, command: string, dry_run: boolean = true)deviceis always required. There is no implicit default-device fallback.commandis one RouterOS CLI line, limited to 8 KiB.dry_run=truevalidates locally and does not open an SSH connection.A result with
status=unknownmeans the command may have executed and must not be retried automatically.
The gateway does not implement RouterOS Safe Mode and does not claim that a dry run validates RouterOS syntax or effects.
Related MCP server: MikroTik MCP Server
Configuration
Choose exactly one device-registry source:
ROS_DEVICES_JSON, containing the JSON object directly; orros-mcp --config PATH, wherePATHis a UTF-8 JSON file.
The two sources use the same schema. Do not set ROS_DEVICES_JSON when using
--config; the server rejects ambiguous configuration sources. Each device
defines its SSH authentication method.
{
"main": {
"display_name": "Main Router",
"description": "Internet edge",
"host": "192.168.88.1",
"port": 22,
"username": "ai-mgmt",
"enabled": true,
"tags": ["production", "edge"],
"connect_timeout_seconds": 15,
"command_timeout_seconds": 25,
"keepalive_seconds": 30,
"idle_ttl_seconds": 300,
"output_limit_bytes": 1048576,
"auth": {
"type": "password",
"password": "REPLACE_WITH_ROUTEROS_SSH_PASSWORD"
},
"host_key": {
"fingerprint_sha256": "SHA256:REPLACE_WITH_43_BASE64_CHARACTERS"
}
},
"office": {
"display_name": "Office Router",
"host": "10.0.0.1",
"port": 22,
"username": "ai-mgmt",
"auth": {
"type": "private_key",
"private_key_env": "ROS_OFFICE_PRIVATE_KEY",
"passphrase_env": "ROS_OFFICE_KEY_PASSPHRASE"
},
"host_key": {
"fingerprint_sha256": "SHA256:REPLACE_WITH_43_BASE64_CHARACTERS"
}
}
}devices.example.json contains the same sanitized configuration as a starting
point. Keep actual device inventories outside version control.
For password authentication, set exactly one of these fields:
password: the RouterOS SSH password directly in the configuration; no credential environment variable is required.password_env: the name of an environment variable containing the password.
The legacy password_env form remains supported. Private-key authentication
continues to use private_key_env and optional passphrase_env references:
ROS_MAIN_PASSWORD=<main RouterOS SSH password>
ROS_OFFICE_PRIVATE_KEY=<complete PEM/OpenSSH private-key text>
ROS_OFFICE_KEY_PASSPHRASE=<optional key passphrase>An inline password is plaintext in the configuration file. Treat that file as
a secret: do not commit it, and mount it read-only in containers. For a local
process, restrict it to the deployment user (for example, chmod 600 devices.json). The default devices.json name is excluded from Git and Docker
build contexts.
Device IDs must match ^[a-z][a-z0-9_-]{0,63}$. Configuration is validated and
resolved once at startup, so restart the server after changing a configuration
file. Missing secrets, unknown fields, duplicate JSON keys, invalid IDs, and
malformed SHA-256 fingerprints prevent startup.
The host-key fingerprint is mandatory. Unknown keys are never accepted through
TOFU or Paramiko's AutoAddPolicy.
Run locally
Python 3.11 or newer and uv are required for local development.
uv sync --all-groups
export ROS_DEVICES_JSON='{"main":{"host":"192.168.88.1","username":"ai-mgmt","auth":{"type":"password","password_env":"ROS_MAIN_PASSWORD"},"host_key":{"fingerprint_sha256":"SHA256:REPLACE_WITH_43_BASE64_CHARACTERS"}}}'
export ROS_MAIN_PASSWORD='replace-me'
uv run ros-mcpTo deploy from a file instead, put the JSON object above in a UTF-8 file and pass its path. The inline password in the file requires no credential environment variable.
chmod 600 /absolute/path/to/devices.json
uv run ros-mcp --config /absolute/path/to/devices.jsonThe process speaks MCP over stdio. Application code does not write ordinary messages to stdout because stdout belongs to the protocol.
Run with uvx
Use uvx to run a released version without cloning this repository. Pin the
Git tag (or a full commit SHA) so deployments do not move with a branch:
uvx --from 'git+https://github.com/asharca/ros-mcp.git@v0.1.0' \
ros-mcp --config /absolute/path/to/devices.jsonThe final ros-mcp selects this project's console command. This requires uv
and Git. Do not use uvx ros-mcp: that PyPI name belongs to a different
project. This repository is installed from its Git source instead.
Docker
Published images are available from GHCR:
docker pull ghcr.io/asharca/ros-mcp:latestmain publishes latest, main, and sha-<commit> tags. Git tags such as
v1.2.3 additionally publish 1.2.3 and 1.2.
To build locally:
docker build -t ros-mcp:local .
docker run --rm -i \
--read-only \
--tmpfs /tmp:rw,size=16m \
-e ROS_DEVICES_JSON \
-e ROS_MAIN_PASSWORD \
ros-mcp:localThe image runs as a non-root user, exposes no port, and starts the stdio MCP server directly. Its root filesystem is safe to run read-only.
Docker with a configuration file
Mount the configuration file read-only and pass the container path to
--config after the image name. A file with an inline password needs no
credential environment variable.
docker run --rm -i \
--read-only \
--tmpfs /tmp:rw,size=16m \
--mount type=bind,src="/absolute/path/to/devices.json",dst=/config/devices.json,readonly \
ghcr.io/asharca/ros-mcp:latest \
--config /config/devices.jsonUse an absolute source path that is visible to the Docker daemon. With Docker
Desktop, share the source directory; with a remote daemon, use a file or secret
mount managed on that daemon rather than a path from the MCP client's machine.
The mounted file must be readable by the image's UID/GID 10001. Do not use
-t or -d: the MCP transport needs attached stdin and stdout. Do not disable
networking because the gateway needs outbound SSH access to RouterOS devices.
Use a managed secret mount or set an owner/ACL that permits UID/GID 10001 to
read the file without making it world-readable. If the file uses password_env,
private_key_env, or passphrase_env, forward each referenced variable with
Docker's -e option.
Deploy as an MCP server
ROS-MCP uses the stdio transport. Configure your MCP client to start one process
per server instance and keep its stdin and stdout connected to the client.
Client configuration formats differ; clients that use an mcpServers object can
use either of the following shapes.
uvx
{
"mcpServers": {
"ros-mcp": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/asharca/ros-mcp.git@v0.1.0",
"ros-mcp",
"--config",
"/absolute/path/to/devices.json"
]
}
}
}Docker
{
"mcpServers": {
"ros-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--read-only",
"--tmpfs",
"/tmp:rw,size=16m",
"--mount",
"type=bind,src=/absolute/path/to/devices.json,dst=/config/devices.json,readonly",
"ghcr.io/asharca/ros-mcp:latest",
"--config",
"/config/devices.json"
]
}
}
}For a file that uses environment-variable credential references instead, add the
client's environment entries and matching Docker -e arguments. Verify host-key
fingerprints through a trusted out-of-band channel, use a least-privileged
RouterOS account, and keep manual approval enabled for command_execute in the
MCP client.
ToolPlane
Publish the image to a registry reachable by ToolPlane's Docker daemon.
In a workspace, choose
MCP > Add custom MCP > Docker.For environment configuration, enter the image reference and leave Start Command empty. Add
ROS_DEVICES_JSONand all referenced secret variables on the deployment's Variables page, then restart it.For file configuration, use ToolPlane's file or secret-mount facility to place the file at (for example)
/config/devices.json, then set Start Command to--config /config/devices.json. Add deployment variables only when the file uses environment-variable credential references, then restart it.Leave
Disconnect from networkdisabled so the container can reach RouterOS SSH addresses.
ToolPlane currently has a 30-second call timeout. Configure
command_timeout_seconds to about 25 seconds there, or raise ToolPlane's timeout
above the gateway's command timeout.
Execution behavior
One reusable SSH session is maintained per device.
Commands for the same device are serialized in a bounded FIFO.
Different devices can execute concurrently.
A stale session may reconnect once before command dispatch.
A command is never replayed after dispatch.
stdout and stderr are drained concurrently and retained up to the configured per-stream byte limit.
All SSH clients are explicitly closed during MCP server shutdown.
Logging
ROS-MCP has no audit-log Module, log-query tool, command history, or persistent request/output storage. Expected operational failures are returned as structured tool results. The MCP runtime is configured to emit only error-level diagnostics to stderr.
Development
uv run pytest
uv run ruff check src tests
uv run ruff format --check src testsThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceEnables AI assistants to interact with MikroTik RouterOS devices through API and SSH connections, supporting network monitoring, configuration management, and diagnostics across multiple routers with automatic connection fallback.3MIT
- Alicense-qualityDmaintenanceEnables management of MikroTik routers running RouterOS 6 and 7 via SSH, Telnet, or API with automatic command adaptation. Provides over 46 MCP tools for device management, firewall, DHCP, VPN, configuration profiles, and more.3MIT
- Alicense-qualityDmaintenanceEnables management of network devices via SSH using Netmiko, supporting command execution, configuration management, and concurrent operations across multiple vendors.4MIT
Related MCP Connectors
Tailscale device, route, DNS, key, user, and ACL management over MCP and CLI.
Offline methodology engine for authorized penetration testing, CTF, and security research.
55 tools, 7 Resources, Sigma rules, email SPF/DMARC, MITRE, CVE/KEV, risk_score. No key.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/asharca/ros-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server