keenetic-mcp
Manages Keenetic routers, providing tools to list devices, manage static DHCP leases, rename devices, check WAN status, and reboot.
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., "@keenetic-mcpShow me the list of connected devices."
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.
keenetic-mcp
An MCP server that lets an AI assistant (Claude, or any MCP client) manage your Keenetic router in plain language — list connected devices, pin static DHCP leases, rename devices, check WAN status, and reboot.
It talks to the router's built-in RCI JSON API over HTTP, so there's no cloud, no third-party service, and nothing leaves your network. You run it yourself against your own router.
Tested against a Keenetic Hopper DSL (KN-3610). The RCI API is shared across the Keenetic line (Giga, Viva, Hopper, Ultra, …), so other models should work too. If you confirm one, please open an issue/PR to grow the list.
Why
Keenetic's RCI API is powerful but poorly documented, and its auth is a fiddly two-step MD5-challenge + SHA256 dance that trips people up for hours. This wraps the common device/lease/WAN operations behind clean MCP tools so you can just say "pin the Raspberry Pi to a static IP" and it happens.
Related MCP server: vyos-mcp
Tools
Tool | Type | What it does |
| read | Active DHCP lease table (ip / mac / name / remaining time) |
| read | Static reservations ( |
| read | Suggest a free IP for a new static reservation |
| read | WAN/internet status, WAN IP, uptime, CPU/memory |
| read | Port-forward / static NAT rules ( |
| write | Assign a fixed IP to a MAC (low-level — you supply the MAC) |
| write | ⭐ Find a device by IP/MAC/name and pin its current (or a given) IP in one step. Conflict-guarded. |
| write | ⭐ Set a device's persistent display name (the name shown in the web UI) |
| write | Remove a reservation |
| write | Reboot the router (only with |
Safety: write tools are off by default
Read tools always work. Write tools are disabled until you set KEENETIC_ENABLE_WRITES=1 in the server environment. This means a fresh install can look but not touch — no accidental reboots or lease changes while you explore. Even once enabled, write tools are guarded:
pin_devicerefuses if the target IP is already active on, or statically reserved to, a different device.Address-like identifiers (
"66") never fuzzy-match a device name (e.g.Room-66-Cam).Every write reads the RCI response back and reports
status:errorinstead of silently "succeeding".rebootrequires an explicitconfirm=True.
Install
Requires Python 3.10+.
The easy way — no clone, no venv. With uv installed, run it straight from GitHub; your MCP client launches it on demand (see Connecting an MCP client). To install it as a command instead:
uv tool install "git+https://github.com/karyaboyraz/keenetic-mcp"
# or: pipx install "git+https://github.com/karyaboyraz/keenetic-mcp"Then set your router password in the environment (KEENETIC_PASS) and run keenetic-router-mcp. By default it speaks stdio — the transport desktop MCP clients expect.
The installed command is
keenetic-router-mcp. The GitHub repo iskeenetic-mcp.
From source (for development or the systemd service):
git clone https://github.com/karyaboyraz/keenetic-mcp.git
cd keenetic-mcp
python3 -m venv .venv
.venv/bin/pip install .
cp .env.example .env
# edit .env: set KEENETIC_PASS (and KEENETIC_ENABLE_WRITES=1 if you want write tools)
.venv/bin/keenetic-router-mcpConfiguration
All configuration is via environment variables (see .env.example):
Variable | Default | Notes |
|
| Your router's web-admin address |
|
| Admin username |
| — | Required. Admin password |
|
| Set to |
|
|
|
|
| Bind address for |
|
| Bind port for |
Connecting an MCP client
stdio — the client launches the server (recommended)
Most clients (Claude Desktop, Claude Code, Cursor, …) start the server themselves and talk over stdio. With uv installed, no prior install step is needed — uvx fetches from GitHub and runs it. Add to your client's MCP config (claude_desktop_config.json, ~/.mcp.json, etc.):
{
"mcpServers": {
"keenetic": {
"command": "uvx",
"args": ["--from", "git+https://github.com/karyaboyraz/keenetic-mcp", "keenetic-router-mcp"],
"env": {
"KEENETIC_URL": "http://192.168.1.1",
"KEENETIC_PASS": "your-router-admin-password",
"KEENETIC_ENABLE_WRITES": "0"
}
}
}
}If you installed it as a command (uv tool install / pipx), use "command": "keenetic-router-mcp" with no args. Restart the client (MCP config isn't hot-reloaded), then ask: "list my router's devices".
http — connect to a running network service
If you run it as a long-lived service (KEENETIC_TRANSPORT=http, see Running as a service), point the client at the URL instead:
{
"mcpServers": {
"keenetic": {
"type": "http",
"url": "http://127.0.0.1:8905/mcp"
}
}
}Running as a service (Linux)
A keenetic-mcp.service systemd unit is included — it runs the server over HTTP (KEENETIC_TRANSPORT=http) so clients connect to it by URL. Put the repo at /opt/keenetic-mcp, create the venv there (python3 -m venv .venv && .venv/bin/pip install .), fill in .env, then:
sudo cp keenetic-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now keenetic-mcpHow the auth works
For anyone reusing the RCI API directly, this is the part that's hard to find. Keenetic uses a two-step challenge:
GET /auth→ returns401withX-NDM-RealmandX-NDM-Challengeheaders.Compute
md5 = MD5("<user>:<realm>:<pass>"), thensha = SHA256(challenge + md5).POST /authwith{"login": user, "password": sha}→ sets a session cookie.POST /rci/with alist[dict]command tree, using that cookie.
Write commands must be followed by [{"system":{"configuration":{"save":{}}}}] or they're lost on reboot. See server.py for the full, working implementation.
Security notes
The server has full admin control of your router. Bind it to
127.0.0.1(or a trusted LAN only) — never expose port 8905 to the internet.Your password lives only in
.env(gitignored). Nothing is sent anywhere except your own router.This is not affiliated with or endorsed by Keenetic. Use at your own risk.
License
MIT — see LICENSE.
Available Tools
10 toolsfind_free_ipARead-onlyIdempotent
Suggest up to 5 unused IPs on the LAN for a new static reservation (read-only; changes nothing). Use before set_static_lease or pin_device(ip=...) to avoid conflicts. Excludes active leases, existing static reservations, the gateway and broadcast. start/end are last octets (e.g. 100 and 149 → 192.168.1.100-149); pick a range outside the router's dynamic DHCP pool. start > end is accepted and swapped.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last last-octet to scan (2-254). | |
| start | No | First last-octet to scan (2-254). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive, and the description reinforces 'read-only; changes nothing.' It adds valuable behavior beyond annotations: exclusions (active leases, static reservations, gateway, broadcast) and the accepted/auto-swapped behavior for start > end.
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 three tight sentences, with the core purpose and safety property first, followed by usage guidance and parameter clarification. Every clause carries information; there is no filler or duplication of the schema.
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 low-complexity read-only scan tool with two optional params, an output schema, and safety annotations, the description covers purpose, preconditions, exclusions, and parameter semantics. There is no missing information an agent would need to invoke it appropriately.
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?
Although the schema already describes the last-octet range with defaults, the description adds the crucial domain meaning: start/end are last octets, with a concrete example, the recommendation to avoid the DHCP pool, and the swap behavior for reversed bounds. This moves well beyond the schema's bare integer descriptions.
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 opens with a specific verb ('Suggest'), a concrete deliverable ('up to 5 unused IPs on the LAN'), and the intended purpose ('for a new static reservation'). It also notes the read-only nature and differentiates this suggestion/scan tool from sibling mutation tools like set_static_lease and pin_device.
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?
It explicitly says to use this before set_static_lease or pin_device(ip=...) to avoid conflicts, and it tells the caller to pick a range outside the router's dynamic DHCP pool. It also states what the scan excludes, so the agent knows what results mean and when the tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesARead-onlyIdempotent
List devices currently holding a DHCP lease: ip, mac, name, remaining lease time (live, read-only). Use this to find a device's IP/MAC before pin_device or rename_device. For fixed reservations (including offline devices) use list_static_leases instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds value beyond annotations by noting the data is 'live, read-only' and that it shows current DHCP lease state, including remaining lease time. No contradictions or hidden behavioral surprises.
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?
Three short sentences, each earning its place: the first states the core purpose and fields, the second gives a concrete call-to-action, and the third routes to the correct alternative. The most important scoping constraint is front-loaded.
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 parameterless, read-only list operation with an output schema and strong annotations, the description covers what the tool returns, when to use it, and which sibling to use instead. Nothing an agent needs to invoke it correctly is missing.
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, so the description need not explain parameter semantics. The baseline of 4 applies because there is nothing for the description to compensate for, and the 100% schema coverage is trivially satisfied by the empty schema.
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 states a specific verb ('List') and a precise resource ('devices currently holding a DHCP lease'), and enumerates the returned fields: ip, mac, name, remaining lease time. It also distinguishes itself from list_static_leases by explicitly scoping to live DHCP leases, so an agent can choose correctly without opening the schema.
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?
It gives explicit when-to-use guidance: use this before pin_device or rename_device to find a device's IP/MAC. It also gives an explicit when-not-to-use condition, directing agents to list_static_leases for fixed reservations and offline devices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_port_forwardsARead-onlyIdempotent
List port-forwarding / static NAT rules as raw 'ip static' lines from the running-config (read-only). Use to see which ports are exposed to the internet and to which LAN host. This server cannot add or remove port forwards; change them in the router's web UI.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds that it reads the running-config and returns raw line output, and it discloses the server's inability to mutate port forwards. No contradiction with annotations.
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?
Three sentences with no filler: purpose and format, usage context, and a limitation. Each sentence earns its place and is front-loaded with the most important information.
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 zero-parameter read-only list tool with an output schema, the description covers purpose, usage, safety, and the key operational limitation. Nothing an agent needs to invoke it correctly is missing.
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, so the schema entirely covers parameter semantics. The description doesn't need to add parameter-level detail; baseline 4 for a no-parameter tool.
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?
States a specific verb and resource ('List port-forwarding / static NAT rules') with a precise format ('raw ip static lines from the running-config'). Clearly distinguishable from sibling tools about leases and devices.
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?
Gives an explicit use case ('see which ports are exposed to the internet and to which LAN host') and a clear limitation ('cannot add or remove port forwards; change them in the router's web UI'). It does not name an alternative because no modifying sibling exists, but the when-to-use guidance is explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_static_leasesARead-onlyIdempotent
List static DHCP reservations (MAC → fixed IP) from the router's running-config (read-only). Use this to check which IPs are already reserved before set_static_lease/pin_device, or to find the MAC to pass to remove_static_lease. Includes offline devices; for currently connected devices use list_devices.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/destructive behavior, and the description adds useful context: it reads from the router's running-config and includes offline devices, which affects how results should be interpreted. This goes beyond the annotations without contradicting them.
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 compact: the core operation is front-loaded, and each sentence earns its place by adding use-case or alternative tool guidance. There is no filler or 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?
For a simple, zero-parameter read-only list operation with an output schema and strong annotations, the description covers source, scope, and use cases. Nothing needed to invoke or route correctly is missing.
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, so there is no parameter semantics burden on the description. The input schema is empty and fully covered, and the description adds all needed operational context.
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 names a specific verb and resource: 'List static DHCP reservations (MAC → fixed IP)'. It further distinguishes itself from list_devices by noting it covers offline devices, so an agent can tell these tools apart immediately.
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 explicitly states when to use this tool: before set_static_lease/pin_device to check reserved IPs, and to find the MAC for remove_static_lease. It also names the alternative list_devices for currently connected devices, giving clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pin_deviceAIdempotent
Turn a connected device's current IP into a static reservation in one step (no need to know the MAC), then save the config. Preferred way to give a device a fixed IP; use set_static_lease only for devices that are offline (not in list_devices). A name fragment must match exactly one device; an address-like identifier must be the full IP or MAC and never matches names ("66" won't hit "Room-66-Cam"). Passing ip moves the device there at its next lease renewal — get a candidate from find_free_ip. Refuses (changes nothing) if the target IP is active on or reserved to another device. Examples: pin_device("192.168.1.66") · pin_device("PS5", "192.168.1.154")
| Name | Required | Description | Default |
|---|---|---|---|
| ip | No | Optional IPv4 to pin to instead of the device's current IP. Empty = keep current IP. | |
| identifier | Yes | Device IP (e.g. 192.168.1.66), MAC, or a fragment of its name, looked up in the active DHCP lease table. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses meaningful behavior: it saves the config, moves the device at next lease renewal, and refuses without changes if the target IP is active or reserved. It also explains identifier-matching quirks that could otherwise cause failures.
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 dense but every clause earns its place: scope, alternative routing, matching rules, side effects, conflict behavior, and examples. It is front-loaded with the core purpose and keeps examples compact.
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 output schema and annotations, the description covers the prerequisites, alternatives, edge cases, parameter semantics, and failure behavior. An agent has enough information to select and invoke the tool correctly without additional inference.
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 coverage is 100%, so the baseline is 3. The description adds valuable semantic detail beyond the schema: name fragments must match exactly one device, address-like identifiers never match names, and the ip parameter means 'move to this address at next renewal' with candidates from find_free_ip.
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 and resource ('Turn a connected device's current IP into a static reservation') and explicitly contrasts the tool with set_static_lease. It is immediately clear what the tool does and how it differs from siblings.
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 gives explicit when-to-use guidance: pin_device is the preferred way for connected devices, set_static_lease is only for offline devices, and find_free_ip should supply candidate IPs. Examples further reinforce correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rebootADestructive
Reboot the router. All devices lose internet for ~1-2 minutes and this MCP server cannot reach the router until it is back. Use only as a last resort (e.g. WAN stuck down per wan_status); config and lease changes are already saved and never need a reboot. Call once with confirm=false to preview, then confirm=true to run.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to actually reboot; false returns a cancellation notice. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already mark this as destructive, but the description goes further by disclosing real-world impact: all devices lose internet for ~1-2 minutes and the MCP server cannot reach the router until it is back. It also explains the preview/cancel behavior, which is not fully captured by the annotations alone.
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 compact and front-loaded: the first sentence names the action, the second gives impact, the third gives usage boundaries, and the fourth gives the invocation sequence. Every sentence adds necessary information with no filler.
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 single-boolean, destructive tool with an output schema and annotations, the description is complete. It covers what happens, when to use and not use, and the exact call sequence. There is no missing information an agent would need to invoke it correctly.
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 input schema already describes the confirm boolean with 100% coverage, so the baseline is 3. The description adds meaningful workflow semantics beyond the schema by specifying the exact two-call pattern: confirm=false to preview, then confirm=true to execute. This elevates it slightly above baseline.
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 states a specific verb and resource: 'Reboot the router.' It also distinguishes itself from sibling tools by framing itself as a last-resort operation (e.g., WAN stuck down per wan_status), making it clear this is not a routine config or lease change tool.
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 explicitly says to use only as a last resort and gives a concrete example with wan_status. It also tells the agent when not to reboot ('config and lease changes are already saved and never need a reboot') and provides the confirm=false preview then confirm=true invocation workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_static_leaseADestructive
Delete the static DHCP reservation for a MAC and save the router config. Irreversible (re-create it with set_static_lease). The device stays online but may get a different dynamic IP at its next lease renewal. Use list_static_leases to find the exact MAC first. To move a device to another IP, call set_static_lease/pin_device directly instead of removing first.
| Name | Required | Description | Default |
|---|---|---|---|
| mac | Yes | Device MAC address, e.g. aa:bb:cc:dd:ee:ff (case-insensitive). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses effects beyond annotations: irreversibility, config save, device staying online, possibly receiving a different dynamic IP. DestructiveHint=true is confirmed and expanded with the exact consequences and recovery path.
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?
Every sentence is functional: action, irreversibility, network consequence, prerequisite, and routing to alternatives. Front-loaded primary action, no filler.
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 one-parameter destructive command, description covers prerequisites, consequences, alternatives, and recovery. Output schema exists, so return-format documentation is not required. Nothing an agent needs to call this safely is missing.
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?
Input schema already fully documents the MAC parameter (100% coverage) with format and case-insensitivity, so description adds little about semantics. The instruction to find the exact MAC through list_static_leases adds value but baseline 3 applies because schema covers the parameter definition.
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?
States the action precisely: 'Delete the static DHCP reservation for a MAC and save the router config.' Names the resource (static DHCP reservation) and differentiates from siblings by referencing set_static_lease and list_static_leases. An agent knows exactly what operation this performs.
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?
Explicitly instructs to 'Use list_static_leases to find the exact MAC first' and warns 'To move a device to another IP, call set_static_lease/pin_device directly instead of removing first.' This gives clear when-to-use, prerequisites, and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_deviceAIdempotent
Give a device a persistent DISPLAY name on the router (Keenetic 'known host' entry = the device name in the web UI). identifier: the device's IP, MAC, or current name fragment (looked up in the active lease table). name: the new display name (spaces allowed; double quotes and non-printable characters are stripped). NOTE: set_static_lease / pin_device do NOT change the DISPLAY name — the display name is set ONLY by this tool. Examples: rename_device("192.168.1.66", "Pi5 Media") · rename_device("PS5", "PlayStation 5 Living Room")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | New display name; spaces allowed, double quotes and control characters are stripped. | |
| identifier | Yes | Device IP (e.g. 192.168.1.66), MAC, or a fragment of its name, looked up in the active DHCP lease table. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses persistence of the name, the stripping of double quotes and non-printable characters, and the fact that the identifier is looked up in the active lease table. These are behavioral details not present in the annotations, and there is no contradiction with the annotation hints (idempotentHint, destructiveHint false).
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 tightly structured: purpose first, then parameter semantics, a critical sibling note, and examples. Every sentence earns its place—no filler or repetition of schema content. The format is readable and front-loads the most important information.
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 simplicity (2 params, output schema present, annotations provided), the description covers all necessary context: what it does, how to identify the device, the new name constraints, and how it relates to sibling tools. Nothing an agent needs to call it correctly is missing.
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 input schema already has 100% coverage for both parameters, so the baseline is 3. The description adds extra meaning by explaining that identifier can be an IP, MAC, or name fragment and is resolved via the active lease table, and by giving concrete examples of valid invocations. This goes beyond the schema's terse descriptions.
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 states a specific verb and resource: 'Give a device a persistent DISPLAY name on the router'. It also differentiates from siblings by explicitly noting that set_static_lease and pin_device do NOT change the display name, making it unmistakable what this tool uniquely does.
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?
It gives explicit when-to-use guidance by stating that the display name is set ONLY by this tool and that sibling tools do not affect it. Examples further clarify correct invocation patterns, leaving no ambiguity about when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_static_leaseAIdempotent
Reserve a fixed IP for a MAC address (static DHCP lease) and save the router config. Use when you already know the MAC (e.g. a device that is offline); for a connected device prefer pin_device, which looks up the MAC for you and checks for IP conflicts. This tool does NOT check conflicts — call find_free_ip or list_static_leases first. Re-running with the same values is harmless. The optional name is only the dhcp-host label; to change the display name in the web UI use rename_device. Takes effect when the device next renews its lease (reconnect it to apply immediately).
| Name | Required | Description | Default |
|---|---|---|---|
| ip | Yes | IPv4 address to reserve, inside the LAN subnet (e.g. 192.168.1.120). | |
| mac | Yes | Device MAC address, e.g. aa:bb:cc:dd:ee:ff (case-insensitive). | |
| name | No | Optional internal label for the dhcp-host entry (not the web-UI display name). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses that the tool does NOT check IP conflicts, saves the router config, is safe to re-run with the same values, and takes effect only on next DHCP lease renewal. These are meaningful behavioral traits that the structured annotations do not convey.
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 dense but well-structured: definition, usage condition, alternative, conflict caveat, idempotency, parameter nuance, and effect timing each earn their place. It is front-loaded with the action and scope and contains no filler.
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 description covers prerequisites, conflict-checking guidance, side effects, persistence, timing, and parameter semantics. With an output schema present, nothing needed for correct invocation is missing.
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 coverage is 100%, so the baseline is 3. The description adds extra parameter meaning by clarifying that the optional name is only the dhcp-host label and by pointing to rename_device for changing the web-UI display name, which goes slightly beyond what the schema alone provides.
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 opens with a specific verb and resource: 'Reserve a fixed IP for a MAC address (static DHCP lease) and save the router config.' It also names and distinguishes sibling tools like pin_device and rename_device, so an agent can clearly identify what set_static_lease does and what it does not do.
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?
It gives an explicit when-to-use condition ('Use when you already know the MAC'), names the preferred alternative for connected devices (pin_device), and instructs calling find_free_ip or list_static_leases first because this tool does not check conflicts. This leaves no ambiguity about tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wan_statusARead-onlyIdempotent
Report internet (WAN) connectivity and router health: per-uplink connected/link state and WAN IP, plus router uptime, CPU load and memory. Read-only; queries the router live on every call (no caching). Use to diagnose "is the internet down?" or check the public IP; not for LAN devices (use list_devices).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the read-only nature is covered. The description adds the important behavioral detail that it queries the router live on every call with no caching, which is not in annotations and affects expected latency and freshness. It also lists the specific metrics reported. No contradiction with annotations.
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?
Two sentences with zero waste. The first sentence states the core function and output; the second adds usage context and the sibling distinction. Every clause carries information, and the most important info (what it does) is front-loaded. Perfectly 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?
Given there are no parameters and the output schema exists (per context signals), the description sufficiently covers what the tool does, when to use it, and what to expect. It also notes the live-query behavior, which is important for agents deciding between this and cached tools. Nothing an agent needs to call it correctly is missing.
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, so the schema is empty and there is nothing to describe. Per instructions, baseline for 0 params is 4. The description adds value by enumerating the output fields (per-uplink state, WAN IP, uptime, CPU, memory), which implicitly tells the agent what the call returns. It doesn't need to explain any input 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?
Description states a specific verb (Report) and resource (WAN connectivity and router health), enumerating concrete data points (uplink state, WAN IP, uptime, CPU, memory). It explicitly names the sibling tool list_devices and the condition that selects it, distinguishing the tool without ambiguity.
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?
Provides explicit when-to-use guidance: 'diagnose is the internet down?' or check the public IP. Clearly states what it is not for (LAN devices) and names the alternative (list_devices). This is exactly what the dimension asks for – both positive and negative use cases.
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.
10 tool updates
- First observed
find_free_ip - First observed
list_devices - First observed
list_port_forwards - First observed
list_static_leases - First observed
pin_device - First observed
reboot - First observed
remove_static_lease - First observed
rename_device - First observed
set_static_lease - First observed
wan_status
TDQS
Scored across 10 tools
Most tools have clearly distinct purposes, and the descriptions cross-reference each other well. The main overlap is between pin_device and set_static_lease, but the descriptions clearly separate them by online/offline usage and conflict checking, so an agent should be able to choose correctly.
Tool names mostly follow a consistent snake_case verb_noun pattern (list_devices, set_static_lease, remove_static_lease, rename_device). Minor deviations are reboot as a bare verb and wan_status as a noun phrase rather than a verb_noun name, but these do not create real confusion.
Ten tools is well-scoped for a router-management server. Each tool covers a meaningful operation or read-only query, and the set is neither bloated nor too thin for the apparent domain.
The DHCP lease lifecycle is well covered: active leases, static leases, create via set_static_lease or pin_device, delete, rename, and free-IP lookup. The main gap is that port forwarding is read-only only, and the server explicitly cannot add or remove port-forward rules, which limits full network configuration coverage but does not break the core DHCP/status workflows.
Maintenance
Related MCP Connectors
MCP server for Gainium — manage trading bots, deals, and balances via AI assistants
MCP server for AI dialogue using various LLM models via AceDataCloud
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP server that connects AI assistants to the ZONT heating system via the official REST API. It enables users to monitor device states, control heating modes, and perform diagnostics using natural language.MIT
- AlicenseAqualityDmaintenanceMCP server for managing VyOS routers via the VyOS HTTP API, allowing AI assistants to read config, set interfaces, firewall rules, VPNs, and more.172MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives AI assistants real-time access to your homelab infrastructure. It enables querying node status, managing Docker containers, controlling Proxmox VMs, and inspecting OPNsense firewall state through natural conversation.2MIT
- AlicenseNot gradedqualityAmaintenanceEnables MCP agents to control Keenetic routers via plain language, providing network monitoring, device management, and safe configuration changes with backup and read-only options.105 npm24MIT