Skip to main content
Glama

netscope-mcp

CI Security npm License: Apache-2.0 OpenSSF Scorecard

Give your LLM eyes on your ISP network, without giving it hands.

netscope-mcp is a strictly read-only Model Context Protocol server for ISP/WISP network operators. It lets an AI assistant (Claude, Codex, Cursor, any MCP client) inspect many MikroTik RouterOS (v6/v7) routers and switches at once, using one-call diagnosis recipes built for NOC work. VyOS and GenieACS (TR-069) support is planned for v0.2.

Status: v0.1. npm publication is pending; until then install from a release tarball or from source (see Quickstart). Not affiliated with or endorsed by MikroTik. "MikroTik" and "RouterOS" are trademarks of their owners.

netscope-mcp demo: asking an AI assistant about a router, a link and a customer, read-only

The problem

A NOC engineer at a small ISP answers the same questions all day: Is this router healthy? Why is this optical link weak? Which router is customer X on? What is plugged into this port? Each answer means logging in to several routers and running a handful of commands.

An LLM can do that legwork, but handing a model a RouterOS login with write access is a bad idea: one hallucinated /system reset-configuration or /ip firewall filter remove can take down customers. Most MikroTik MCP servers expose the whole router and rely on you to be careful.

Related MCP server: netmiko-mcp

Why read-only matters

netscope-mcp makes the safe thing the only thing:

  • Deny-by-default allowlist. Only print, monitor … once, /<menu> export hide-sensitive, ping and traceroute on a positive list of menus are ever sent. Anything else is refused before credentials are loaded or a device is contacted.

  • Secrets never reach the model. Output is redacted by key name, by pattern and by the exact credential values the server holds; script bodies are masked.

  • A read-only router account is the real boundary. The guard is one layer, not a sandbox. We show you how to create the RouterOS user so that even a bug in this project cannot change a router.

  • Auditable. 1,290+ automated tests including a security corpus (770 allowlist cases, 73 redaction cases, HTTP and property tests) run in CI, plus gitleaks, CodeQL, dependency review and OpenSSF Scorecard.

Why it is different

Typical MikroTik MCP

netscope-mcp

Goal

Manage a router through an LLM (often including writes)

Let an LLM observe a fleet safely

Write protection

Optional read-only switch, or none

Read-only is the only mode: deny-by-default allowlist of print, monitor … once, /<menu> export hide-sensitive, ping, traceroute

Secrets in output

Returned as the router sends them

Redacted by key name, by pattern and by the exact credential values the server knows; script bodies masked

Tool design

Roughly one tool per RouterOS menu

Nine tools plus diagnosis recipes (health, neighbors-map, pppoe-lookup)

Many routers

One device per call

Batch across routers in one call; one failing router does not fail the rest

"Which router has customer X?"

Query routers one by one

pppoe-lookup across all routers, or a periodic snapshot you can search in milliseconds

Features

  • Deny-by-default command guard: no abbreviations, no write verbs, no scripts, where only on non-secret columns, safe columns forced on /ppp secret, /user, /radius, /snmp.

  • Redaction on every response; exact scrubbing of known credentials in error messages.

  • Recipes that replace 5–25 raw calls with one answer.

  • Multi-router batch (up to 30 commands): parallel across routers, sequential per router over one reused session.

  • Optional snapshot store with cross-router search and explicit data age.

  • Account-lockout protection: per-device queue, session reuse, cooldown after a rejected login.

  • Output clipping, concurrency limits, timeouts, JSONL audit log (no secret values).

  • Transports: stdio (default) and Streamable HTTP with a mandatory bearer token.

  • API-SSL (port 8729) with certificate verification by default, optional fingerprint pinning, SSH (with host-key pin) for export.

60-second overview

  1. Create a read-only RouterOS user (a read policy group, API access only).

  2. Describe your routers in routers.yaml (credentials come from environment variables or a 0600 file, never plain YAML).

  3. Add the server to your MCP client and ask in plain language:

"Which router has customer alice@example.net connected, and is its uplink optical level OK?"

A full worked example is in docs/DEMO.md. The detailed steps follow.

Quickstart

Requires Node.js 20 or newer (--snapshot needs Node.js 22.5 or newer for node:sqlite).

1. Create a read-only RouterOS user

Do this first. The tool-level guard is one layer; a read-only router account is the real boundary. See docs/ROUTEROS-READONLY-USER.md.

2. Install

From a release tarball (or build one yourself with npm ci && npm run build && npm pack):

npm install -g ./netscope-mcp-0.1.0.tgz
netscope-mcp --version

From source, without installing: npm ci && npm run build, then use node dist/cli.js wherever this guide says netscope-mcp.

3. Describe your routers

Create routers.yaml (a complete example with every field is in routers.example.yaml):

settings:
  audit_log: stderr

routers:
  - id: core-1
    host: 192.0.2.10        # documentation address (RFC 5737)
    port: 8729
    family: routeros
    group: backbone
    tls_fingerprint256: "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF"   # replace with your router's SHA-256 pin (or use tls_ca_file: /path/to/ca.pem)
    credentials: { user_env: ROS_CORE1_USER, pass_env: ROS_CORE1_PASS }

Credentials are never accepted as plain values in YAML: only environment-variable names or a mode-0600 file. Full schema: docs/CONFIG.md.

4. Check the configuration, then run

export ROS_CORE1_USER=netscope-ro
export ROS_CORE1_PASS='<long random password>'
netscope-mcp --config ./routers.yaml --check     # prints "configuration OK: 1 router(s)."
netscope-mcp --config ./routers.yaml             # stdio transport

5. Connect your client

Claude Code:

claude mcp add netscope \
  --env ROS_CORE1_USER=netscope-ro --env ROS_CORE1_PASS='<password>' \
  -- netscope-mcp --config /path/to/routers.yaml

Claude Desktop / Cursor (claude_desktop_config.json, ~/.cursor/mcp.json):

{
  "mcpServers": {
    "netscope": {
      "command": "netscope-mcp",
      "args": ["--config", "/path/to/routers.yaml"],
      "env": { "ROS_CORE1_USER": "netscope-ro", "ROS_CORE1_PASS": "<password>" }
    }
  }
}

Codex CLI (~/.codex/config.toml):

[mcp_servers.netscope]
command = "netscope-mcp"
args = ["--config", "/path/to/routers.yaml"]

[mcp_servers.netscope.env]
ROS_CORE1_USER = "netscope-ro"
ROS_CORE1_PASS = "<password>"

Prefer no passwords in client configs? Use credentials: { file: /etc/netscope-mcp/core-1.cred } (mode 0600, lines user=…, password=…).

Streamable HTTP (several users, or a client that cannot spawn processes):

export NETSCOPE_MCP_TOKEN="$(openssl rand -hex 32)"
netscope-mcp --config ./routers.yaml --http 127.0.0.1:8080
# clients: POST http://127.0.0.1:8080/mcp with  Authorization: Bearer <token>

6. Try it

"List my devices, then run the health recipe on core-1 and tell me if anything looks wrong."

"Which router has customer alice@example.net connected?"

Sample output: docs/RECIPES.md.

Tools

Tool

Purpose

list_devices

List configured devices (filter, group); never credentials.

mikrotik_read

One read-only command: print (with where/proplist/count-only), monitor … once, /<menu> export hide-sensitive (SSH; full menu path only, e.g. /ip service export hide-sensitive).

mikrotik_batch

Up to 30 {device, command} items, fault-tolerant.

mikrotik_recipe

health, neighbors-map, pppoe-lookup.

ping / traceroute

From a router (or local when enabled) to a literal IP address.

snmp_get

SNMP v2c GET/walk on an allowlisted set of subtrees (max 500 rows).

switch_read

Ready-made reads for CRS switches; SwOS over SNMP.

mikrotik_snapshot

Periodic data and cross-router search, always with data age. Needs --snapshot.

Each response is concise text plus structuredContent; failures are real errors (isError: true) with a cause: policy, auth, timeout, connect, not-found, device, busy, config.

Tested on

Tested read-only against real devices on 2026-10-22 (RouterOS API with the bundled SSH runner; SNMP v2c where reachable). A check mark means every tool listed worked and no parsing problem was seen.

Device (family)

RouterOS / SwOS

API tools, recipes

export via SSH

SNMP

hEX RB750Gr3 (mmips)

6.48.6 (long-term)

yes

not yet tested

not reachable in the test network

RB450Gx4 (arm)

7.12.1 (stable)

yes

not yet tested

not reachable in the test network

hEX RB750Gr3 (mmips)

7.24.4 (stable)

yes

not yet tested

yes

x86 (bare metal)

7.23.8 (long-term)

yes (no /system routerboard, /system health reports only state=disabled)

yes

yes

CRS310-1G-5S-4S+ (arm)

7.23.5 (long-term)

yes (switch_read, SFP health)

yes

yes

CRS326-24S+2Q+ (mipsbe)

7.23.5 and 7.23.8 (long-term)

yes (switch_read, SFP, PSU/fan health)

yes

yes

CSS326-24G-2S+

SwOS 2.16

n/a (SNMP only)

n/a

yes (switch_read sysinfo, interfaces)

  • RouterOS 6.x: API tools work (flat /system health, oct/22/2026 dates are returned as the router writes them). export over SSH on v6 and RouterOS 6.49.x are not yet tested (no such device with SSH access was available); treat them as unverified.

  • SNMP and SSH need network reachability from the MCP host: a NAT port-forward that only exposes the API port will make SNMP/SSH time out. These failures are reported cleanly and do not affect the API tools.

  • Redaction and the allowlist behave identically on v6 and v7 in the tests above; regression fixtures for both shapes are in test/unit/compat.test.ts.

Security at a glance

  • Read-only by construction: anything not on the allowlist is refused with a policy error before a device is contacted.

  • Secrets are redacted before they reach the model.

  • redact_pii (on by default) masks the device half of customer MAC addresses and free-text columns. PPP login names are not masked by default (pppoe-lookup needs them); set redact_ppp_names: true to mask them too. See docs/CONFIG.md.

  • HTTP mode refuses to start without a token of at least 32 characters, binds to loopback by default, validates Host and Origin, accepts POST /mcp only and sends no CORS headers.

  • Plain API (port 8728) and unverified TLS work only with settings.allow_insecure: true.

  • Limits, stated honestly: the guard is a tool-level layer, not a sandbox. Always use a RouterOS account whose policy is read-only.

Details: SECURITY.md · docs/ROUTEROS-READONLY-USER.md

Documentation

Demo · Recipes · Configuration · Snapshot · FAQ · Bahasa Indonesia

Library use

The core is importable without MCP: import { NetScope, planRosCommand, redactText } from 'netscope-mcp/core'; the MCP and HTTP front-ends are in netscope-mcp/server.

Used in production

netscope-mcp was built by, and is used daily at, a small Indonesian ISP to give its NOC assistant read access to dozens of MikroTik routers (backbone, aggregation and edge). It is exercised against real fleets, not only simulators. Names and addresses are intentionally omitted here; if you run it, please open an issue or discussion and tell us your scale (anonymous is fine) so we can list adopters.

Roadmap

  • v0.1 — RouterOS v6/v7 (API, API-SSL, SSH for export), recipes, batch, snapshot, SNMP v2c, CRS/SwOS switches, stdio + HTTP.

  • v0.2 — VyOS read tools, GenieACS read-only tools, SNMPv3, RouterOS v7 REST transport.

  • v0.3 — change detection between snapshots, per-token device ACLs, MCP prompts/resources.

Contributing

Issues and pull requests are welcome, especially: RouterOS version quirks, new read-only recipes, translations of the docs, and security-test cases for the allowlist. Read CONTRIBUTING.md first (read-only is a hard requirement; fixtures use only documentation addresses). Report vulnerabilities privately as described in SECURITY.md.

License

Apache-2.0. See LICENSE and NOTICE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Provides read-only SSH access to network devices (routers, switches, firewalls) with command allow/deny policies, nt-templates output parsing, and an audit trail, enabling an AI agent to query device state securely.
    10
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely troubleshoot networks through read-only tools for device inventory, interface status, VLAN paths, BGP neighbors, route lookups, and interface error detection. Integrates with Microsoft Copilot Studio and Teams for natural-language-driven network diagnostics.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only, multi-vendor network device interaction, configuration auditing against vendor-guide rules, and safe diffing of proposed changes for AI agents to inspect and analyze network infrastructure without any commit or write capability.
    1
    Apache 2.0