Skip to main content
Glama
by kcsoukup
README.md20.7 kB
# ASUS Merlin Router MCP Server Model Context Protocol (MCP) server for managing ASUS routers running Asuswrt-Merlin firmware via SSH/SCP. ![Docker Pulls](https://img.shields.io/docker/pulls/kcsoukup/asus-merlin-mcp) ![Docker Image Version](https://img.shields.io/docker/v/kcsoukup/asus-merlin-mcp?sort=semver) ![Docker Image Size](https://img.shields.io/docker/image-size/kcsoukup/asus-merlin-mcp) --- ## 🚨 BREAKING CHANGE - v3.x Security Update **Docker containers now run as rootless (non-root user `mcpuser`) for enhanced security.** **If upgrading from v1.0.0 to v3.x, you MUST update your MCP configuration with TWO changes:** | Component | v1.0.0 (Deprecated) | v3.x (Current) | |-----------|---------------------|----------------| | Container User | `root` | `mcpuser` (UID 1000) | | Volume Mount | `~/.ssh:/root/.ssh:ro` | `~/.ssh:/home/mcpuser/.ssh:ro` | | SSH Key Path | `/root/.ssh/id_rsa` | `/home/mcpuser/.ssh/id_rsa` | **Required Changes:** 1. **Update Volume Mount** in Docker args: ```json "-v", "~/.ssh:/home/mcpuser/.ssh:ro" // Changed from /root/.ssh ``` 2. **Update Environment Variable**: ```json "ROUTER_KEY_FILE": "/home/mcpuser/.ssh/id_rsa" // Changed from /root/.ssh/id_rsa ``` **Complete MCP Configuration Example:** ```json { "mcpServers": { "asus-router": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/home/yourusername/.ssh:/home/mcpuser/.ssh:ro", "-e", "ROUTER_HOST=192.168.1.1", "-e", "ROUTER_USER=admin", "-e", "ROUTER_KEY_FILE=/home/mcpuser/.ssh/id_rsa", "kcsoukup/asus-merlin-mcp:latest" ] } } } ``` **Security Benefits:** - ✅ Follows Docker security best practices (rootless containers) - ✅ Reduces attack surface by running as non-privileged user - ✅ Prevents privilege escalation vulnerabilities --- ## Features This MCP server provides **47 tools** across 8 categories for comprehensive router management: - **System Information** (14 tools): Router info, device lists, WiFi status, services, NVRAM, file operations, processes - **Firewall Management** (2 tools): Configure firewall settings and VPN passthrough - **URL/Keyword Filtering** (9 tools): Global URL/keyword content filtering - **Network Service Filtering** (6 tools): Block/allow services by IP/port/protocol with scheduling (NEW in v3.0) - **MAC Filtering** (3 tools): Add/remove/list WiFi access control rules - **DHCP Management** (3 tools): Add/remove/list static IP reservations - **Internet Access Control** (2 tools): Block/unblock devices (parental controls) - **VPN Routing Policy** (3 tools): Route devices through VPN clients (Asuswrt-Merlin only) - **VPN Server Monitoring** (2 tools): Monitor VPN server status and users For detailed example prompts for each tool, see **[TOOLS_PROMPTS.md](TOOLS_PROMPTS.md)** ## Prerequisites ### Router Setup 1. Enable SSH on your router: - Login to router web interface - Go to **Administration > System** - Set **Enable SSH** to **LAN only** (or LAN & WAN if needed) - Click **Apply** 2. (Recommended) Set up SSH key authentication: ```bash # On your Debian workstation ssh-keygen -t rsa -b 4096 # Copy your public key to router ssh-copy-id admin@192.168.1.1 # Or manually via web interface: # Administration > System > SSH Authentication Key ``` ### Debian Workstation Setup ```bash # Install Python 3.11+ if not already installed sudo apt update sudo apt install python3 python3-pip python3-venv # Optional: Install Docker for containerized deployment sudo apt install docker.io docker-compose ``` ## Installation ### Option 1: Local Installation (Recommended for Development) 1. **Clone or create project directory:** ```bash mkdir asus-merlin-mcp cd asus-merlin-mcp ``` 2. **Save the MCP server code as `asus_merlin_mcp.py`** 3. **Create virtual environment and install dependencies:** ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` 4. **Configure router connection:** ```bash cp .env.example .env nano .env # Edit with your router details ``` 5. **Test the connection:** ```bash # Export environment variables export $(cat .env | xargs) # Run the server (it will connect via stdio) python asus_merlin_mcp.py ``` ### Option 2: Docker Installation #### Quick Start - Pull from Docker Hub: ```bash # Pull the pre-built image (use :latest for current version or specific version tag) docker pull kcsoukup/asus-merlin-mcp:latest ``` **Available versions:** `v1.0.0`, `v3.0`, `latest` #### Build from Source (Alternative): 1. **Build the Docker image:** ```bash docker build -t asus-merlin-mcp . ``` 2. **Edit docker-compose.yml with your router credentials** ```bash # Optional -- The credentials are passed to the container via the MCP configurations in Claude or other chatbots. ``` 3. **Run with Docker Compose:** ```bash docker-compose up -d ``` ## Claude Configuration The configuration location depends on which Claude installation you're using: ### Claude Code (Native Installation) MCP servers are automatically configured in `~/.claude.json` under your project path: **Config file:** `~/.claude.json` #### For Local Installation: ```json { "installMethod": "native", "projects": { "/path/to/asus-merlin-mcp": { "mcpServers": { "asus-router": { "command": "/path/to/asus-merlin-mcp/venv/bin/python", "args": ["/path/to/asus-merlin-mcp/asus_merlin_mcp.py"], "env": { "ROUTER_HOST": "192.168.1.1", "ROUTER_PORT": "22", "ROUTER_USER": "admin", "ROUTER_KEY_FILE": "/home/yourusername/.ssh/id_rsa" } } } } } } ``` #### For Docker Installation: ```json { "installMethod": "native", "projects": { "/path/to/asus-merlin-mcp": { "mcpServers": { "asus-router": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/home/yourusername/.ssh:/home/mcpuser/.ssh:ro", "-e", "ROUTER_HOST=192.168.1.1", "-e", "ROUTER_PORT=22", "-e", "ROUTER_USER=admin", "-e", "ROUTER_KEY_FILE=/home/mcpuser/.ssh/id_rsa", "kcsoukup/asus-merlin-mcp:latest" ] } } } } } ``` --- ### Claude Code (NPM Installation) **Config file:** `~/.claude/settings.json` #### For Local Installation: ```json { "mcpServers": { "asus-router": { "command": "/path/to/asus-merlin-mcp/venv/bin/python", "args": ["/path/to/asus-merlin-mcp/asus_merlin_mcp.py"], "env": { "ROUTER_HOST": "192.168.1.1", "ROUTER_PORT": "22", "ROUTER_USER": "admin", "ROUTER_KEY_FILE": "/home/yourusername/.ssh/id_rsa" } } } } ``` #### For Docker Installation: ```json { "mcpServers": { "asus-router": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/home/yourusername/.ssh:/home/mcpuser/.ssh:ro", "-e", "ROUTER_HOST=192.168.1.1", "-e", "ROUTER_PORT=22", "-e", "ROUTER_USER=admin", "-e", "ROUTER_KEY_FILE=/home/mcpuser/.ssh/id_rsa", "kcsoukup/asus-merlin-mcp:latest" ] } } } ``` --- ### Claude Desktop **Config file locations:** - **Linux:** `~/.config/Claude/claude_desktop_config.json` - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` #### For Local Installation: ```json { "mcpServers": { "asus-router": { "command": "/path/to/asus-merlin-mcp/venv/bin/python", "args": ["/path/to/asus-merlin-mcp/asus_merlin_mcp.py"], "env": { "ROUTER_HOST": "192.168.1.1", "ROUTER_PORT": "22", "ROUTER_USER": "admin", "ROUTER_KEY_FILE": "/home/yourusername/.ssh/id_rsa" } } } } ``` #### For Docker Installation: ```json { "mcpServers": { "asus-router": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/home/yourusername/.ssh:/home/mcpuser/.ssh:ro", "-e", "ROUTER_HOST=192.168.1.1", "-e", "ROUTER_PORT=22", "-e", "ROUTER_USER=admin", "-e", "ROUTER_KEY_FILE=/home/mcpuser/.ssh/id_rsa", "kcsoukup/asus-merlin-mcp:latest" ] } } } ``` **Important Notes:** - Replace `/home/yourusername` with your actual home directory path (e.g., `/home/triskull`) - Do NOT use `${HOME}` or `~` in JSON configuration files - they will not expand - After updating the configuration file, restart Claude Code or Claude Desktop for the changes to take effect ## Usage Examples Once configured in Claude Desktop, you can interact with your router: **Example prompts:** - "What's the current status of my router?" - "List all connected devices" - "Restart the wireless service" - "Show me the WiFi configuration" - "Get the value of wan_ipaddr from NVRAM" - "Upload this backup script to /jffs/scripts/" - "Check if VPN is running" - "Show me the router's system log" ## Available Tools For detailed example prompts, see **[TOOLS_PROMPTS.md](TOOLS_PROMPTS.md)** ### System Information Tools (14) | Tool | Description | |------|-------------| | `get_router_info` | System info (uptime, memory, firmware) | | `get_connected_devices` | List DHCP clients | | `get_all_network_devices` | Comprehensive device list (DHCP + static + ARP) | | `get_wifi_status` | WiFi status for all radios | | `restart_service` | Restart specific service | | `reboot_router` | Reboot router (requires confirmation) | | `get_vpn_status` | Check VPN client/server status | | `list_processes` | Show running processes | | `get_nvram_variable` | Read NVRAM variable | | `set_nvram_variable` | Write NVRAM variable | | `execute_command` | Run custom SSH command | | `read_file` | Read file from router | | `upload_file` | Upload file (MD5 verified) | | `download_file` | Download file (MD5 verified) | ### MAC Filtering Tools (3) | Tool | Description | |------|-------------| | `add_mac_filter` | Add device to MAC filter (whitelist/blacklist) | | `remove_mac_filter` | Remove device from MAC filter | | `list_mac_filters` | Show current MAC filters | ### DHCP Management Tools (3) | Tool | Description | |------|-------------| | `add_dhcp_reservation` | Reserve IP for MAC address (static lease) | | `remove_dhcp_reservation` | Remove DHCP reservation | | `list_dhcp_reservations` | Show all DHCP reservations | ### Internet Access Control Tools (2) | Tool | Description | |------|-------------| | `block_device_internet` | Block/unblock device internet (parental controls) | | `list_blocked_devices` | Show blocked devices | ### VPN Routing Policy Tools (3) | Tool | Description | |------|-------------| | `add_vpn_routing_policy` | Route device through VPN client | | `remove_vpn_routing_policy` | Remove device from VPN routing | | `list_vpn_policies` | Show all VPN routing policies | ### VPN Server Monitoring Tools (2) | Tool | Description | |------|-------------| | `get_vpn_server_status` | VPN server status and connected clients | | `get_vpn_server_users` | List authorized VPN server users | ## Common Services to Restart - `wireless` - WiFi services - `wan` - WAN connection - `httpd` - Web interface - `vpnclient1` - VPN client 1 - `vpnclient2` - VPN client 2 - `dnsmasq` - DNS/DHCP server ## Security Notes 1. **Use SSH keys instead of passwords** for better security 2. **Enable SSH on LAN only** unless you need WAN access 3. **Be careful with NVRAM operations** - incorrect values can break your router 4. **Test commands manually first** before automating 5. **Keep backups** of your router configuration ## Troubleshooting ### Connection Issues ```bash # Test SSH connection manually ssh admin@192.168.1.1 # Check if SSH is enabled on router # Via web interface: Administration > System > Enable SSH ``` ### Permission Denied ```bash # Ensure SSH keys are readable chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub # Verify key is added to router ssh admin@192.168.1.1 "cat /tmp/home/root/.ssh/authorized_keys" ``` ### Import Errors ```bash # Ensure virtual environment is activated source venv/bin/activate # Reinstall dependencies pip install -r requirements.txt --force-reinstall ``` ### Volume Mount Errors (Docker) If you see an error like: ``` Error: error creating named volume "${HOME}/.keys": error running volume create option: names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*: invalid argument ``` **Cause:** JSON configuration files do not expand shell variables like `${HOME}` or `~`. **Solution:** Replace `${HOME}` with your actual home directory path in the configuration: ```json // Wrong - will not work: "-v", "${HOME}/.ssh:/home/mcpuser/.ssh:ro" // Correct - use absolute path: "-v", "/home/triskull/.ssh:/home/mcpuser/.ssh:ro" ``` To find your home directory: ```bash echo $HOME # Output: /home/triskull ``` ## How-To Guide: Common Administrative Tasks This section provides practical examples for common router administration tasks using the MCP tools. ### Managing the Hosts File The router's custom hosts file (`/jffs/configs/hosts.add`) allows you to add static DNS entries that persist across reboots. #### View Current Hosts File **Via Claude:** ``` "Show me the contents of /jffs/configs/hosts.add" ``` **MCP Tool Used:** `read_file` #### Add a New Host Entry **Option 1: Download, Edit, Upload (Recommended)** 1. Download the file: ``` "Download /jffs/configs/hosts.add from the router to ./hosts.add" ``` *Uses: `download_file` tool* *Note: Downloads are MD5 checksum verified for integrity* 2. Edit the file locally with your text editor: ```bash nano hosts.add # Add line like: # 192.168.0.100 newserver.damage.inc newserver ``` 3. Upload back to router: ``` "Upload ./hosts.add to /jffs/configs/hosts.add on the router" ``` *Uses: `upload_file` tool* *Note: Uploads are MD5 checksum verified to ensure file integrity* 4. Apply changes: ``` "Restart the dnsmasq service" ``` *Uses: `restart_service` with `service_name: dnsmasq`* **⚠️ WARNING:** Do NOT use `execute_command` with echo/heredoc for file operations. Always use the download → edit → upload workflow shown above for file safety and MD5 verification. #### Update an Existing Host Entry 1. Download the hosts file 2. Edit locally to change the desired line 3. Upload back to router 4. Restart dnsmasq #### Remove a Host Entry Via Claude: ``` "Execute this command: sed -i '/hostname-to-remove/d' /jffs/configs/hosts.add" "Restart the dnsmasq service" ``` *Replace `hostname-to-remove` with the actual hostname or IP* ### Managing NVRAM Variables NVRAM stores persistent router configuration. **Warning:** Incorrect values can break your router! #### Get a Single NVRAM Variable ``` "Get the NVRAM variable wan_ipaddr" ``` *Uses: `get_nvram_variable`* #### Set an NVRAM Variable (Without Commit) ``` "Set NVRAM variable custom_setting to value123 but don't commit" ``` *Uses: `set_nvram_variable` with `commit: false`* This sets the variable in RAM but won't persist across reboots. #### Set and Commit NVRAM Variable ``` "Set NVRAM variable custom_setting to value123 and commit it" ``` *Uses: `set_nvram_variable` with `commit: true`* **⚠️ Warning:** Committed changes persist across reboots. Double-check values before committing! #### Backup NVRAM to File ``` "Execute this command: nvram show > /jffs/nvram_backup_$(date +%Y%m%d).txt" "Download /jffs/nvram_backup_20250101.txt to ./nvram_backup.txt" ``` ### Managing Custom Scripts Scripts in `/jffs/scripts/` persist across reboots and can run at various router events. #### Common Script Hooks - `init-start` - First script run during boot - `services-start` - Runs after router services start - `wan-start` - Runs when WAN interface comes up - `firewall-start` - Runs when firewall starts #### Upload a Custom Script ``` "Upload ./my-custom-script.sh to /jffs/scripts/services-start on the router" ``` *MD5 checksum automatically verified to ensure script integrity* Then make it executable: ``` "Execute this command: chmod +x /jffs/scripts/services-start" ``` #### View Existing Scripts ``` "Execute this command: ls -la /jffs/scripts/" ``` #### Read a Script's Contents ``` "Read the file /jffs/scripts/firewall-start" ``` ### Monitoring and Diagnostics #### Check System Resources ``` "What's my router's current status?" ``` *Uses: `get_router_info` - Shows uptime, memory, firmware* #### List All Connected Devices ``` "List all connected devices on my network" ``` *Uses: `get_connected_devices` - Shows DHCP leases* #### Find a Specific Device ``` "Show connected devices and look for hostname 'rpiserver'" "Execute this command: cat /var/lib/misc/dnsmasq.leases | grep rpiserver" ``` #### Check WiFi Status ``` "What's my WiFi status?" ``` *Uses: `get_wifi_status` - Shows radio status and SSIDs* #### View System Logs ``` "Read the file /jffs/syslog.log with max 50 lines" ``` *Uses: `read_file` with `max_lines: 50`* #### Monitor Running Processes ``` "List all running processes" "List processes filtered by 'vpn'" ``` *Uses: `list_processes` with optional filter* ### VPN Management #### Check VPN Status ``` "What's my VPN status?" ``` *Uses: `get_vpn_status` - Shows client/server states* #### View VPN Configuration ``` "Execute this command: nvram show | grep vpn_client1" ``` #### Restart VPN Client ``` "Restart the vpnclient1 service" ``` *Uses: `restart_service` with `service_name: vpnclient1`* ### Service Management #### Restart Wireless Service ``` "Restart the wireless service" ``` *Useful after changing WiFi settings* #### Restart WAN Connection ``` "Restart the wan service" ``` *Forces WAN reconnection* #### Restart Web Interface ``` "Restart the httpd service" ``` *Restarts the router's web UI* ### File Management **Note:** All file uploads and downloads are cryptographically verified using MD5 checksums to ensure data integrity. This is especially important for binary files, scripts, and executables. #### Download Router Files ``` "Download /jffs/configs/dnsmasq.conf.add to ./dnsmasq.conf.add" ``` *Checksum verified for integrity* #### Upload Configuration Files ``` "Upload ./firewall-rules.txt to /jffs/scripts/firewall-start" ``` *Checksum verified to prevent corruption* #### Check File Permissions ``` "Execute this command: ls -la /jffs/scripts/" ``` #### Make Script Executable ``` "Execute this command: chmod +x /jffs/scripts/script-name" ``` ### Advanced Router Operations #### Backup Entire JFFS Partition ``` "Execute this command: tar -czf /tmp/jffs_backup_$(date +%Y%m%d).tar.gz /jffs/" "Download /tmp/jffs_backup_20250101.tar.gz to ./router_backup.tar.gz" ``` #### View Network Connections ``` "Execute this command: netstat -an | grep ESTABLISHED" ``` #### Check Router Temperature (if supported) ``` "Execute this command: wl -i eth1 phy_tempsense" ``` #### Reboot Router ``` "Reboot the router" ``` *Requires confirmation - **⚠️ This will disconnect all clients!*** ### Tips and Best Practices 1. **Always test commands manually first** before automating them 2. **Keep backups** of configuration files before making changes 3. **Use descriptive hostnames** in hosts.add for easier management 4. **Document your custom scripts** with comments 5. **Restart services after configuration changes** to apply them 6. **Use SSH keys** instead of passwords for better security 7. **Be cautious with NVRAM commits** - test without commit first 8. **Monitor logs** after making changes to catch issues early ## Advanced Usage ### Backup Router Configuration ```bash # Via Claude: "Download the router's NVRAM backup" # This will use the download_file tool to get /jffs/nvram/nvram.txt ``` ### Upload Custom Scripts ```bash # Upload a script to run on router boot # Files in /jffs/scripts/ persist across reboots ``` ### Monitor Router Health ```bash # Set up periodic checks via cron jobs on the router # Use the execute_command tool to create cron entries ``` ## Contributing Feel free to extend this MCP server with additional tools for: - Traffic monitoring - Firewall rule management - Bandwidth statistics - Port forwarding configuration - Guest network management ## Resources - [Asuswrt-Merlin Wiki](https://github.com/RMerl/asuswrt-merlin.ng/wiki) - [MCP Documentation](https://modelcontextprotocol.io/) - [Paramiko Documentation](https://www.paramiko.org/) ## License MIT License - Use at your own risk. Always maintain backups of your router configuration.

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/kcsoukup/asus-merlin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server