Skip to main content

REGENT

License: MIT Latest Release Last Commit Stars

MCP server that lets an AI configure your OpenWrt router. You say what the network should do — "give everyone on the cable and Wi-Fi internet" — and it works out which uci and ubus commands that takes, in which order, and which service has to be reloaded before any of it takes effect

[!IMPORTANT]

Nothing changes by default. Until OPENWRT_ENABLE_WRITE=1 is set, every tool that writes is refused and only reading works. Rebooting, flashing, and resetting ask for more than that: each of those calls has to carry its own confirmation. The server opens no network ports — the MCP client starts it and talks to it over stdin and stdout

[!CAUTION]

Disclaimer: This project is provided under the MIT License and hands an AI root access to a live router. A model can misread an instruction, and the safeguards here — the write gate, the confirmations, the rollback timer — reduce that risk without removing it. A bad change can cut your connection, take the network down, or leave a device that needs a physical reset or a reflash to recover. Take a backup first, keep physical access to the router, and never point this at something you cannot afford to lose. The author disclaims all liability for any damage, downtime, or data loss. By using this software you take full responsibility for what it does to your equipment


🔍 Example

The router this was built against stopped passing traffic, and nothing in the web interface looked wrong. Four separate faults were causing it, none of them visible on the page where it was configured. One call to routerTopology names all four and says what each one breaks:

UPLINK   wwan via phy1-sta0, 192.168.1.4/24, gateway 192.168.1.1
SERVES   lan  192.168.1.1/24   DHCP OFF
AP       HomeNet  2.4 GHz  →  wwan2

WARNINGS 4
  ! lan (192.168.1.0/24) is on the same subnet as the uplink — the default
    gateway resolves to this router itself and nothing routes out
  ! access point HomeNet is attached to 'wwan2', which is not up —
    clients will associate and get no address
  ! dhcp is not serving lan — clients there must be configured by hand
  ! the uplink sits in zone lan, which does not masquerade — replies to
    clients have nowhere to return to
  • Any one of the four is enough to stop traffic - together they took an afternoon to find by hand, because a router in this state reports itself as healthy
  • routerShareUplink repairs all four in one call - it puts the changes in an order that keeps the router reachable while they are applied, gives a reason for each one, and arms a rollback timer first, in case the repair cuts the connection it is travelling over

🚀 Key Features

  • 🩺 A Diagnosis, Not a Dump - routerTopology reads the whole configuration in one pass and reports what is broken and why that stops traffic, rather than handing back a listing for you to interpret
  • 🧠 Whole Recipes, Not Single Commands - "share the uplink with clients" is six changes across three config files, and the wrong order locks you out partway through. That recipe lives in the server, so the model does not have to reassemble it correctly every time
  • ⏱️ Insurance Against Lockout - You reach the router through the network the router provides, so a bad change can take away the means of undoing it. Before a risky change the config files are copied aside and a restore is scheduled on the device itself. If the router still answers afterwards the restore is canceled; if it does not, the restore runs and the old settings come back
  • 🔒 Three Levels of Access - Reading always works. Changing anything needs the write gate open. Rebooting, flashing, and resetting need the gate and a separate confirmation on each individual call
  • 🔑 Secrets Stay In - The router returns Wi-Fi passwords, VPN keys, and subscription links in clear text. They are stripped before anything is sent back to the model, and before anything is written to the command log or read out of the system log
  • 📡 Routed Client Mode - Built for the case where the OpenWrt box has no wire of its own: it joins somebody else's router over Wi-Fi as a client, then serves its own LAN and Wi-Fi behind NAT, adding the VPN and ad-blocking that the upstream cannot provide
  • 🧪 Testable Without Hardware - Command building and output parsing are pure functions, so all 457 tests run against a fake SSH transport. The fixtures they run on are output copied verbatim from a live router, including while it was broken

🛠️ Using

You never launch the server yourself. The MCP client spawns it, talks to it over stdin and stdout, and shuts it down on exit, so it only has to be registered once. Nothing needs installing first — uvx fetches the package on the first run. After that you describe what you want in ordinary words

  • Register with the client - add this to wherever that client keeps its MCP configuration

    {
      "mcpServers": {
        "regent": {
          "command": "uvx",
          "args": ["regent-mcp"]
        }
      }
    }
    
  • Point it at the router - create a .env in the configuration directory for your system

    Windows %APPDATA%\regent\.env
    Linux, macOS ~/.config/regent/.env
    OPENWRT_HOST=192.168.1.1
    

    That address is the only required line, since every other setting already holds what a stock OpenWrt answers on

    Setting Default
    OPENWRT_HOST required — the router's address
    OPENWRT_USER root
    OPENWRT_PORT 22
    OPENWRT_KEY the file named key beside this .env
    OPENWRT_ENABLE_WRITE unset, so nothing can be changed
    OPENWRT_TIMEOUT 30 seconds per command
    OPENWRT_ROLLBACK_DELAY 90 seconds before an unconfirmed change reverts
  • Give it a key of its own - generate it next to that .env, never reusing a personal one

    ssh-keygen -t ed25519 -f key -N "" -C "regent"
    
  • Authorize the key on the router - this sends the public half over and appends it in one go. A stock OpenWrt still accepts a password, which is what gets you in the first time

    ssh root@192.168.1.1 "mkdir -p /etc/dropbear; cat >> /etc/dropbear/authorized_keys; chmod 600 /etc/dropbear/authorized_keys" < key.pub
    

Settings are read once when the server starts, so restart the client after editing .env

What is available depends on what you have allowed:

  • Read only - Works immediately, nothing to configure
  • Change settings - Add OPENWRT_ENABLE_WRITE=1 to .env
  • Reboot, flash, reset, restore a backup - Needs explicit confirmation on the call as well

🧰 Tools

Area Tools
Orientation routerTopology — what the router does and what is wrong with it
Changes routerApplyUci — any change under the watchdog, with a dry run
Backups routerBackups, routerBackupCreate, routerBackupInspect, routerBackupRestore
System routerSystemInfo, routerExec, routerReboot, routerFactoryReset, routerFirmwareUpgrade
Network routerInterfaces, routerDhcpLeases, routerClients
Wi-Fi routerWireless, routerWirelessClients
Firewall routerFirewallZones, routerFirewallRuleset
Services routerServices, routerServiceControl
Packages routerPackages, routerFindPackage, routerInstallPackage, routerRemovePackage
Diagnostics routerLog, routerPing, routerResolve
Ads and Trackers routerAdblockStatus, routerAdblockSources, routerAdblockConfigure, routerAdblockStorage, routerAdblockUseStorage
VPN routerVpnStatus, routerVpnProbeNode
Intents routerJoinUpstreamWifi, routerPlanShareUplink, routerShareUplink

These cover what gets asked for most, but they do not have to cover everything. routerExec runs an arbitrary command on the router, so a request nobody anticipated still has a way through — it just gives up the guardrails the dedicated tools provide

[!TIP]

Leave OPENWRT_ROLLBACK_DELAY alone unless you know why you are changing it. It is how many seconds the router waits before undoing a change nobody confirmed, 90 by default, and it is your safety net for when the AI reconfigures the very interface you are connected through

[!WARNING]

Confirmed on one device so far — a TP-Link Archer C59 running OpenWrt 23.05.4. Every parser was checked against what that router prints, including while it was broken. That proves they match its output, not that the output is universal. Package handling will not work on OpenWrt 24.10, where opkg became apk


🔨 Develop

🔧 Requirements

  • Python 3.10+
  • Essential packages
    fastmcp asyncssh python-dotenv typing-extensions pytest pytest-asyncio
    

⚡️ Quick Setup Guide

  • Clone & Open Project
    git clone https://github.com/m-o-z-z-i-x/REGENT.git
    cd REGENT
    code .
    
  • Set Up Virtual Environment
    • In VS Code
      • Open terminal (Ctrl+~)
      • Run
        python -m venv .venv
        
    • Restart the terminal so .venv activates itself
  • Install Dependencies
    pip install -e ".[dev]"
    
  • Generate an SSH Key (one per router — never reuse a personal key)
    ssh-keygen -t ed25519 -f keys/key -N "" -C "regent"
    
  • Run the Tests (no router needed)
    pytest -q
    
  • Try It Against a Real Router - copy .env.example to .env, fill in the address, then point a client at the checkout instead of at uvx, so every edit is live without rebuilding
    {
      "mcpServers": {
        "regent": {
          "command": "<project>/.venv/Scripts/python.exe",
          "args": ["-m", "regent.server"]
        }
      }
    }
    

A checkout keeps .env, keys/ and logs/ beside the code and prefers them over the configuration directory, so working on the project never reads or writes an installed copy's settings

[!TIP]

Settings are read once at startup, so the MCP client has to be restarted after editing .env or the code. .env carries everything needed to reach the router — address, user, port, key. The two tunables that do not vary between routers, the command timeout and the rollback delay, sit in regent/config.py, where an environment variable can still override either of them


🌟 Future Roadmap

Done

  • Core over SSH - One reused session, with command building and parsing kept apart from it
  • Risk Tiers - Read, write, and destructive, each with its own explicit permission
  • Watchdog Rollback - Survives the SSH session dying, because that is what it insures against
  • Reading the State - Network, Wi-Fi, firewall, packages, diagnostics
  • Topology Analysis - With the common faults named, rather than a plain dump
  • Safe Arbitrary Changes - Snapshot, rollback, and a reload of whichever service owns the config
  • Ad Blocking - Weighed against the router's free memory before it is applied
  • VPN - PassWall status and the four faults that make it look like it is working
  • Composite Intents - Joining an upstream network and sharing it with clients
  • Backups - Create, inspect, and restore the configuration

Planned improvements

  • apk Support - Package handling on OpenWrt 24.10 and newer
  • Other Devices - Only the Archer C59 is confirmed so far
  • Guest Network - A separate isolated Wi-Fi in one call

Suggestions? Open an Issue to discuss new features!


🤝 Contribution

Contributions are welcome! Here's how to help improve the project

  • Fork the repository
  • Create a feature branch
    git checkout -b feature/your-feature-name
    
  • Commit your changes
    git commit -m "Add: your feature description"
    
  • Push to your fork
    git push origin feature/your-feature-name
    
  • Open a Pull Request to the main branch of this repository

🔗 Acknowledgments

This project would not be possible without these amazing open-source contributions

  • OpenWrt - the firmware, and the UCI/ubus interfaces this server drives
  • FastMCP by Prefect — the MCP server framework
  • AsyncSSH by Ron Frederick — pure-Python asyncio SSH

📈 Repo Activity

Repobeats analytics image

🙏 Support

⭐ Love this project? Give it a star!

If you find this tool helpful and want to support its development — consider buying me a coffee!

YooMoney Boosty

TON:

UQBZVRZFeZI4CepVq_OF5_KiQ_oo62SzmWlGvppfGuyRqUSE

Bitcoin:

bc1qunr4lkes5xdanln8j5l0gm6e7x0kfw2e6z4yve

Monero:

89vPf9GUBdFXmpEhFiBSiQMQbAeWZYCGDZBfr6e45zpNVUQ8cMnYFc8ct5FH3TJvftSbKTgkHzkiPB9QoYKhNhBdLeWvesC

USDT (TRC20):

TCKL4YBLAFEHFesUuGBiB85aywNE38zVSQ


📬 Contacts

All my contact links are available here


📝 License

This project is licensed under the MIT License

Metadata

Release files for regent-mcp 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for regent-mcp 1.0.0
File Size Uploaded
regent_mcp-1.0.0.tar.gz 74.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for regent-mcp 1.0.0
File Interpreter ABI Platform
regent_mcp-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 131.1 kB

Release files / regent_mcp-1.0.0.tar.gz

Download URL regent_mcp-1.0.0.tar.gz
Size 74.0 kB
Tags Source
SHA-256 checksum
How to use checksums
e9eefaa39e7014b24986e7bfb80eff32407787732bd646b2d8b5f437da4e6e41
BLAKE2b-256 checksum
How to use checksums
ff447dd30b89c0681a1d24a0a6222d1396b7d3b729c1112f1f01b19b5505cc29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Release files / regent_mcp-1.0.0-py3-none-any.whl

Download URL regent_mcp-1.0.0-py3-none-any.whl
Size 57.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3b121ff39c220a32e3e2e2d4ed0254adf550d76e9d3087380fd70fdf13d77737
BLAKE2b-256 checksum
How to use checksums
39cf2fa3ab509017d8226d8f481aa3c8f2722e77d5af710a5a44ce0e54439dd8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page