Netmon (demo)

com.netmon由 netmon.com 發布官方發布者v1.0.1更新於 Oct 24, 2026

Public read-only demo of Netmon's network monitoring tools over a recorded snapshot.

已驗證Streamable HTTP可網頁執行安全與監控資料與分析

概覽

AI 產生的概覽

Netmon 網路監控工具的公開唯讀示範,讓助理查詢一份錄製的裝置、日誌、流量與告警快照。

可以做什麼
查詢裝置、標籤、介面與整體健康摘要,並依名稱或 IP 尋找裝置。搜尋並彙總 syslog、Windows 事件日誌與 Suricata IDS 事件,並跨所有日誌串流追蹤單一 IP。查詢 NetFlow 歷史、頻寬用量最高的工作階段與單一主機的通訊摘要。檢視告警定義、告警事件歷史與維護時段。在 Netmon 伺服器上執行即時探測:ping、traceroute、連接埠掃描、ARP 查詢、SNMP 測試與遍歷、WHOIS/GeoIP/DNS 查詢。讀取 Windows 代理程式的服務、程序與磁碟用量,以及封包擷取清單與 WAN 測速歷史。
適用情境
適合在沒有設備的情況下試用或評估 Netmon 的助理整合,或示範網路排障類問題,例如哪些裝置離線、哪台主機佔用最多頻寬、最近觸發了哪些 IDS 告警。
執行需求
遠端 streamable HTTP 端點;示範不需要帳號、權杖或安裝。README 說明示範位址與設備端點不同,後者需要 Netmon 7.0.20 或更新版本的設備、具備 API 權限的帳號,以及帶 mcp 範圍的個人存取權杖。
安裝前請注意
示範是基於虛構網路的已錄製、去識別化快照:不會寫入,也不會接觸真實網路,因此結果不是即時資料。連接真實設備時,權杖以建立者身分生效,應盡量縮小範圍;本機橋接會在首次連線時固定設備憑證,因此首次連線應在可信任網路中進行。工具結果由你的 MCP 用戶端廠商依其條款處理。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Netmon (demo),將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/com.netmon%2Fnetmon-demo/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "netmon-demo": {
      "type": "http",
      "url": "https://netmon.com/mcp-demo/mcp"
    }
  }
}

README

Netmon MCP

Connect an AI assistant to a Netmon appliance.

Netmon ships an MCP server on the appliance itself. This repository holds the client-side bridge: a small Node process that runs on your own machine, speaks stdio to Claude Desktop, and forwards every JSON-RPC message to your Netmon's /mcp endpoint over HTTPS.

Once connected, an assistant can read your devices, interfaces, logs, flow records, alerts, and Windows-agent data by calling Netmon's tools directly — with the same sign-in and permissions as any operator, and the same tag restrictions.


Try it first — no appliance needed

A public, read-only demo server answers the same 36 tools from a recorded, de-identified snapshot of a fictional 90-device network:

https://netmon.com/mcp-demo/mcp

No account, no token, no install. Point any MCP client at it:

bash
claude mcp add --transport http netmon-demo https://netmon.com/mcp-demo/mcp   # Claude Codecodex mcp add netmon-demo --url https://netmon.com/mcp-demo/mcp               # OpenAI Codexgemini mcp add --scope user --transport http netmon-demo https://netmon.com/mcp-demo/mcpopencode mcp add netmon-demo --url https://netmon.com/mcp-demo/mcpcline mcp install netmon-demo --transport http https://netmon.com/mcp-demo/mcpdevin mcp add -s user netmon-demo https://netmon.com/mcp-demo/mcp             # Windsurf / Devin Desktopcode --add-mcp '{"name":"netmon-demo","type":"http","url":"https://netmon.com/mcp-demo/mcp"}'goose session --with-streamable-http-extension "https://netmon.com/mcp-demo/mcp"

GUI clients — Claude Desktop (Settings → Connectors → Add custom connector) and ChatGPT (developer mode → Connectors) — take the URL with authentication set to None. For Cursor, Zed, Kimi Code CLI, Continue and LM Studio, drop the URL into that client's MCP config file:

json
{  "mcpServers": {    "netmon-demo": { "url": "https://netmon.com/mcp-demo/mcp" }  }}

Then ask it something real: "what's down?", "show me the Suricata alerts from last week", "which host is using the most bandwidth, and who is it talking to?"

It is a fixture, not an appliance: nothing writes, nothing reaches a real network, and every answer is the same shape a live Netmon returns — with timestamps shifted forward so the snapshot always reads as the last day or so.


Why a local bridge

Two separate walls stand between an MCP client and an appliance on your LAN, and the bridge exists for both.

Where the connection comes from. Claude Desktop's remote-connector option and ChatGPT's custom connectors both fetch the MCP URL from their vendor's cloud, not from your machine — Anthropic's docs say so outright, and their connector resolves the hostname and rejects private addresses before any request leaves their network, so your appliance's log stays empty. Most other clients (Claude Code, Codex, Gemini CLI, Cursor, VS Code, Zed, Cline, Continue, opencode, Goose, LM Studio, Kimi) connect from your own machine and are unaffected.

The certificate. This one catches nearly everyone. Most clients validate TLS against the operating system trust store and expose no skip-verify option, and an appliance ships a self-signed certificate — so the route succeeds and the handshake fails. Either install the appliance's certificate in the machine's trust store, or use the bridge, which pins it on first use.

The bridge runs as a local process and handles both. It is not a Claude-specific workaround; it is the general answer.

If your appliance is internet-facing with a publicly-trusted certificate, you can skip the bridge and point any MCP client straight at the endpoint. See Install — any MCP client below.


Requirements

  • A Netmon appliance with the MCP server enabled (Netmon 7.0.20 or newer).
  • A user account with the API permission, and a personal access token carrying the mcp:* scopes you want the assistant to have.
  • Claude Desktop for the .mcpb install. Claude Desktop supplies its own Node runtime, so nothing else is needed. Running the bridge outside Claude Desktop requires Node 18 or newer.

Install — Claude Desktop

  1. Download netmon-mcp-<version>.mcpb from Releases. The same bundle ships with your appliance — Settings → System → Downloadables → Claude Desktop Extension.

  2. In Claude Desktop, open Settings → Extensions → Advanced settings → Extension Developer → Install Extension… and select the file.

  3. Fill in the two settings the extension asks for:

    SettingValue
    Netmon URLhttps://<your-netmon>/mcp — the full endpoint, including /mcp
    API Tokena personal access token (see below). The Bearer prefix is added for you if you leave it off.
  4. Restart the extension. Ask Claude something like "list the devices that are down" to confirm it is working.

Minting a token

In Netmon, go to Settings → Users, click the key icon on your user, and create a personal access token. Select only the scopes the assistant needs — the token cannot be widened later, and it can be revoked from the same screen at any time.

The account must hold the API permission. Without it, token minting and OAuth consent are both refused.


Install — any MCP client

The appliance serves Streamable HTTP at https://<your-netmon>/mcp (POST for JSON-RPC, GET for the server-to-client SSE stream, DELETE to end a session).

Clients that support OAuth 2.1 discover the authorization server on their own: the endpoint answers an unauthenticated request with 401 and a WWW-Authenticate: Bearer resource_metadata="…" challenge pointing at RFC 9728 protected-resource metadata, alongside RFC 8414 authorization-server metadata and dynamic client registration at /auth/register. You sign in through your browser on your own Netmon and approve the scopes on a consent page.

Clients without OAuth support pass a token directly:

json
{  "mcpServers": {    "netmon": {      "url": "https://netmon.example.com/mcp",      "headers": {        "Authorization": "Bearer <your-token>"      }    }  }}

Claude Code and self-signed certificates

Most appliances serve a self-signed certificate. A direct type: http entry will fail against one — the OAuth bootstrap rejects the certificate and does not consult NODE_EXTRA_CA_CERTS. Use the bridge instead, which handles the certificate itself:

json
{  "mcpServers": {    "netmon": {      "command": "node",      "args": ["/path/to/netmon-mcpd/server/index.js"],      "env": {        "NETMON_URL": "https://netmon.example.com/mcp",        "NETMON_TOKEN": "<your-token>"      }    }  }}

Tools

36 read tools, each wrapping a Netmon API endpoint and gated by an OAuth scope that is checked before the call runs.

AreaScopeExample tools
Devices & fleetmcp:devicesdevice_find, device_get, device_list, device_metric_summary, overwatch_summary, tags_list
Traffic & topologymcp:vne, mcp:devicestop_bandwidth, netflow_search, netflow_raw_search, flow_summary, get_network_entity_info, arp_table, interfaces_search
Logs & securitymcp:logssyslog_search, eventlog_search, eve_search, eve_get, log_severity_summary, syslog_facets
Alertsmcp:alertsalerts_list, alerts_history, maintenance_windows_list
Windows agentmcp:devicesagent_processes, agent_services, agent_disk_usage
Live toolsmcp:tools, mcp:devices, mcp:captureping, traceroute, arp_lookup, port_map, snmp_test, snmp_walk_run, snmp_walk_last, search_ip, speedtest_history, capture_list, capture_get
All 36 tools
ToolTitleWhat it answers
get_network_entity_infoLook Up WHOIS, GeoIP and DNSRetrieves WHOIS, GeoIP and DNS information for a public IP address or hostname.
arp_lookupARP LookupPerforms an ARP lookup to find the MAC address for a given Local IP address.
pingPing HostPing a target host from the Netmon server.
tracerouteRun TracerouteTraceroute to a target from the Netmon server.
port_mapScan Open PortsNmap port scan against a single host from the Netmon server.
search_ipSearch All Streams for an IPFind every mention of a specific IP across Netmon's log and telemetry streams: syslog, Windows eventlog, Suricata EVE, aggregated NetFlow, and ARP.
syslog_searchSearch SyslogSearch syslog messages from network devices.
eventlog_searchSearch Windows Event LogSearch Windows Event Log entries ingested from Netmon agents.
eve_searchSearch Suricata IDS EventsSearch Suricata EVE-format IDS events.
eve_getGet Suricata IDS EventFetch a single Suricata EVE event by id, decoded server-side.
log_severity_summarySummarize Log SeveritiesCount log events grouped by severity over a time window.
syslog_facetsSyslog Facet BreakdownTop-N value counts for ONE syslog field over a window — 'what are the top actions/reasons on this FortiGate in the last 2 hours' in a single call,...
netflow_searchSearch Aggregated NetFlowSearch the FULL NetFlow history: the raw flow table (the last ~15 minutes) unioned with the aggregated rollup (4 weeks of history), windowed and pr...
netflow_raw_searchSearch Raw NetFlowSearch raw NetFlow records (per-flow, not aggregated).
flow_summarySummarize NetFlow TrafficSummarize one host's network conversations: top peers, top ports, and a client-vs-service-side split, each with a residual "other" bucket plus over...
device_listList DevicesList monitored devices.
device_getGet Device DetailsFetch one device with its related state: tags, alerts, the ping / oid / interface / port / disk trackers configured on it, its SNMP walk trackers,...
device_findFind Devices by Name or IPFind devices matching a substring of label or ip_address.
overwatch_summaryOverwatch Health SummaryHigh-level network health snapshot for 'how's the network?' style questions.
snmp_testTest SNMP CredentialsProbe a device for SNMP reachability using the Netmon snmptest binary.
snmp_walk_lastGet Cached SNMP WalkFetch the most recent stored SNMP walk for a device (cached in tools_walks).
snmp_walk_runRun Fresh SNMP WalkTrigger a FRESH SNMP walk against a device.
agent_servicesList Windows ServicesList Windows services on an agent-managed device — live read via the WMI tunnel.
agent_processesList Windows ProcessesList running processes on an agent-managed device — live read via the agent tunnel.
alerts_listList Alert DefinitionsList configured alert definitions across both axes of the rule engine.
alerts_historyAlert Incident HistoryAuthoritative 'what fired and when' stream — wraps the alert_history table (one row per incident, both legacy and modern) and alert_outlet_log...
maintenance_windows_listList Maintenance WindowsLists maintenance windows — the suppression schedules that gate alert dispatch.
tags_listList TagsList tag definitions.
top_bandwidthTop Bandwidth TalkersTop NetFlow conversations over the last N minutes — the 'who's eating bandwidth right now?' question.
arp_tableGet ARP TableLists hosts observed on the local LAN(s) via the ARP table — the 'what devices have we seen recently?' question.
interfaces_searchSearch Network InterfacesCross-device interface metadata listing — answers 'what interfaces are tracked across the fleet, named like X, on device Y?'.
device_metric_summarySummarize Device MetricsDay / week / month / all-time summary stats for a single device-tracker, by metric type.
agent_disk_usageBrowse Agent Disk UsagePath-scoped folder-tree disk usage report from a Netmon agent — the 'D: drive is at 95%, what's eating it?' question.
capture_listList Packet CapturesRead-only listing of packet captures.
capture_getGet Packet Capture StatusRead-only single-capture detail.
speedtest_historySpeedtest HistoryRecent WAN speedtest results — answers 'is the internet healthy?'.

Eight scopes exist in total — the six above plus mcp:reports and mcp:system, which map to their permissions but have no tools yet.


Security model

Everything stays on your appliance. The bridge connects to the one URL you configure and nothing else. No telemetry, no vendor endpoint, no third-party service sits in the path. Netmon Services receives nothing.

Read-only. Every tool is a read. Netmon's agent write paths — killing a process, starting or stopping a Windows service, deleting a file, running PowerShell — are permanently excluded at the MCP layer, regardless of what the underlying token's permissions would otherwise allow. An assistant cannot change your monitoring configuration, acknowledge an alert, or act on a managed host.

Scoped. Each tool declares the OAuth scope it requires, and the scope is checked before the tool body runs. A token granted mcp:logs only cannot call device_list.

Yours, and no wider. A token acts as the user who minted it. Tag restrictions apply: an operator limited to the branch-offices tag gets an assistant limited to the same devices. The permission model is the one already governing the web interface and every other API client.

Revocable. Revoke a token from Settings → Users and the assistant loses access immediately. Tokens can also be scoped narrowly at mint time rather than revoked later.

Transport security

On first connection the bridge captures the appliance's TLS certificate and stores it at ~/.netmon-mcp/<hash-of-url>.pem, then verifies every later connection against that pinned certificate. This is trust-on-first-use: it protects against interception after the first connection, not during it. Make the first connection from a network you trust.

If you replace the appliance's certificate, delete the stale pin (rm ~/.netmon-mcp/*.pem) or the bridge will verify the new certificate against the old one and refuse to connect.

The bridge requires https://. Plain HTTP is rejected at startup.


Troubleshooting

The bridge writes a diagnostic log to ~/.netmon-mcp/wrapper.log.

SymptomCause
NETMON_URL must use https://The URL is http://, or the scheme is missing.
TLS probe failedThe appliance is unreachable on 443 from this machine, or the hostname does not resolve.
Connects, then fails after a certificate changeStale pin. Delete ~/.netmon-mcp/*.pem and reconnect.
Tools return an authorization errorThe token lacks the scope that tool requires, or the account lacks the API permission.
No tools appearThe URL is missing the /mcp path.

Building

bash
npm install./build.sh            # or: ./build.sh 1.0.0 to stamp a version

Output lands in build/netmon-mcp-<version>.mcpb.


Privacy Policy

Full policy: https://netmon.com/privacy-policy/

What is collected. This bridge collects no data. It holds no account, no analytics, and no callback to Netmon Services. Two files are written locally, both under ~/.netmon-mcp/: the pinned certificate of the appliance you configured, and a diagnostic log of connection events. Your Netmon URL and token are supplied by you and are held only in the extension's own configuration.

How data is used and stored. Queries and results pass between your MCP client and your appliance. The bridge forwards messages and retains none of them. All monitoring data stays in the appliance's database, under your control, in your building.

Third-party sharing. None. The bridge contacts exactly one host — the appliance URL you configure. It sends nothing to Netmon Services or any other party.

Note that your MCP client is a separate product with its own policy. When you ask an assistant a question, the tool results it receives are handled by that client's vendor under their terms. Netmon does not control that leg, which is why the scopes on a token are worth setting narrowly.

Retention. Local files persist until you delete them: remove the extension, or rm -rf ~/.netmon-mcp. Revoking the token in Settings → Users ends access immediately. Retention of the monitoring data itself is configured on your appliance, by you.

Contact. [email protected]


Support

License

Mozilla Public License 2.0 — see LICENSE.

來源:README.md,提交 484852b

工具

36

get_network_entity_info

Look Up WHOIS, GeoIP and DNS

Retrieves WHOIS, GeoIP and DNS information for a public IP address or hostname. A hostname is resolved to an IP for the GeoIP lookup (`resolved_ip`, when resolution succeeds); an IP gets a reverse DNS lookup (`hostname`, when a PTR exists). `whois` comes from whois.iana.org and nowhere else. For an address IANA returns the RIR referral record, so its `organisation` is the regional registry that administers the block (ARIN, RIPE, APNIC, LACNIC, AFRINIC) — NOT the ISP, hosting company or assignee. For a hostname it is the TLD registry, not the domain owner. Never report either as the operator; a `refer` or `whois` field only names the RIR's own whois server, which this tool does not query. `geoip` is the geolocation provider's response passed through verbatim, so the key set varies with provider tier and with whether the answer came from cache. Treat every field as optional — including `isProxy`, `asn` and `asnOrganization`, which may simply be absent. The whole `geoip` key is omitted for addresses that are not globally routable and when the lookup is unavailable. To judge hosting/datacenter versus residential or small-business ISP, reason from the evidence actually returned: - The `hostname` PTR pattern: a provider-branded label under a hosting or cloud domain reads as datacenter, whereas the address itself embedded in the name under a consumer ISP's domain reads as subscriber. A missing PTR is weak evidence in either direction. - `geoip.isProxy` when present: true points to a VPN, proxy or hosting exit. - `geoip.asnOrganization` (and `asn`) when present: a cloud, colocation or hosting provider points to a datacenter; an access or eyeball ISP points to residential. Label that classification as a heuristic and name the evidence you used for it. If no PTR came back and no ASN fields are present, say the evidence is insufficient rather than guessing.

輸入參數entity_identifier必填

arp_lookup

ARP Lookup

Performs an ARP lookup to find the MAC address for a given Local IP address. A suitable network interface is automatically selected. The list of all suitable interfaces found is also returned.

輸入參數target_ip必填

ping

Ping Host

Ping a target host from the Netmon server. Wraps POST /api/getPingInfo/{target} (permission: tools). The probe runs ON the netmon server, not on the mcpmond host — so reachability reflects what netmon can see, which is what matters for monitoring questions. Returns {address, latency (avg ms), status (true=reachable), hostname (PTR lookup; falls back to the bare address when the host has no reverse record)}. A host that does not answer is a normal result, not an error: status is false, latency is null, and two extra fields appear — reason (packet_loss = probes sent, nothing came back; unreachable = the network answered with an ICMP unreachable; unresolved = the name does not resolve) and detail (the ping line that decided it). A down host still gets its hostname resolved. status null means the probe itself failed and reachability is UNKNOWN — never read that as down. Server fixes count at 4 packets; for longer-running tests use the system tools UI. Example: ping({target: "8.8.8.8"})

輸入參數target必填

traceroute

Run Traceroute

Traceroute to a target from the Netmon server. Wraps POST /api/getTracerouteInfo/{target} (permission: tools). The probe runs ON the netmon server — hops reflect the path FROM netmon TO the target, not from wherever mcpmond is running. Server runs `traceroute --mtu -m 10 -q 2 -w 1` so you get up to 10 hops with MTU discovery; longer paths get truncated. PTR lookups happen server-side. Returns rows of {hop, address, latency (ms or null on timeout), hostname, mtu (or null)}. Example: traceroute({target: "1.1.1.1"})

輸入參數target必填

port_map

Scan Open Ports

Nmap port scan against a single host from the Netmon server. Wraps POST /api/getPortscanInfo (permission: tools). Server runs `nmap -oX - -p <ports> --open <ip>` and returns the parsed result. The probe originates from netmon, not from wherever mcpmond runs — so what's reachable here is what netmon can reach. Single targets only (single IP or hostname). The backing endpoint does not accept CIDR or ranges. If port_range is omitted, scans 1-1024. Returns the nmap host element as JSON: status, address, and ports[] with state/service/product/version. Latency: scans can take ~30-90s depending on port count and target responsiveness; client timeout is 120s. Example: port_map({target: "192.168.1.1", port_range: "22,80,443"})

輸入參數target必填port_range

search_ip

Search All Streams for an IP

Find every mention of a specific IP across Netmon's log and telemetry streams: syslog, Windows eventlog, Suricata EVE, aggregated NetFlow, and ARP. Returns one bucket per stream with {total, samples}. Streams that 4xx (e.g. 403 from tag-scope) show up in `skipped` so a partial result is still actionable. The syslog/eventlog streams match the IP via an unindexed message substring scan; on a high-volume install they can time out and land in `skipped` with guidance (narrow `hours`, or use syslog_search/eventlog_search with a device_id) rather than stalling the call. Params: - ip (required): IPv4 or IPv6 to correlate. - hours: lookback window (1-168, default 24). - per_stream: sample row cap per stream (1-100, default 10). The `total` per stream is always the full match count. - streams: narrow the fan-out to a subset — any of ['syslog','eventlog','eve','netflow','arp']. Omit for all. Permission + tag-scope checks run server-side; a tag-restricted user sees only rows for devices in their tag set. Example (narrow + short window): search_ip({ip: "10.10.1.25", hours: 1, streams: ["syslog"], per_stream: 5})

輸入參數ip必填hoursstreamsper_stream

eve_get

Get Suricata IDS Event

Fetch a single Suricata EVE event by id, decoded server-side. Wraps GET /api/eve/get/{id} (requires permission: logs). Returns an envelope: summary (signature/category/action/gid:sid:rev/severity/app_proto), endpoints, app_layer (Suricata's http/dns/tls/smb/... objects as labelled fields), flow, payload (printable text + length; the base64 bytes are omitted here), decoded (protocol-aware parse of the payload: HTTP start line/headers/body, DNS sections, TLS negotiation, SMB command detail, or a raw summary), findings (ranked high/medium/low/info: cleartext credentials, injection shapes, weak ciphers, lateral-movement pipes, ...), metadata, and the raw record. Use eve_search to locate ids.

輸入參數id必填

log_severity_summary

Summarize Log Severities

Count log events grouped by severity over a time window. One tool, three backends — pass `stream` to pick which. stream='syslog' → wraps /api/syslog/sevSum (severity 0-7, syslog scheme) stream='eventlog' → wraps /api/eventlog/sevSum (severity 0-5, Windows scheme) stream='eve' → wraps /api/eve/sevSum (severity 1-3, Suricata scheme) Use this for triage before pulling rows: 'how many criticals on host X today' returns one tight rollup instead of 1000 sample rows. Every result includes both the numeric key and a `label` so the LLM doesn't have to memorize three different scales. Window: `hours` (1-168, default 24) OR `start_time`+`end_time` (ISO-8601 UTC). Optional `device_id` narrows to one device — for eve, the controller translates this to a src_ip OR dst_ip match automatically (eve_log has no device_id column). ALL-ZERO IS NOT THE SAME AS CLEAN. A dead feed and a quiet network produce byte-identical answers here, so every response carries `meta.stream_health`: active — events landed inside your window; the counts mean what they say. stale — your window is empty, but the stream produced up to `last_event_at`, before it. The feed is alive and the empty window is real. silent — nothing in your window AND nothing in the 168h before it. Never report 'clean' from this state; `note` names the producer to check first. unknown — freshness could not be established. The zeros prove nothing. stale/silent come from re-asking the same stream over a window that strictly contains yours (one extra call, and only when every bucket is zero). No staleness threshold is guessed: `stale` means exactly 'the newest event predates the window you asked for', which on a 1-hour window is unremarkable. `checked_back_hours` and `events_before_window` say how much history the verdict rests on. Permission: logs. Tag-scoped server-side. Example: log_severity_summary({stream: 'syslog', hours: 1, device_id: 42})

輸入參數hoursstream必填end_timedevice_idstart_time

syslog_facets

Syslog Facet Breakdown

Top-N value counts for ONE syslog field over a window — 'what are the top actions/reasons on this FortiGate in the last 2 hours' in a single call, instead of pulling rows and counting them yourself. Wraps GET /api/syslog/facets (permission: logs); tag-scoped server-side. group_by takes one of two kinds of field: COLUMN (indexed, may run fleet-wide — device_id optional): facility, severity, source MESSAGE FIELD (parsed out of the message text at read time — device_id REQUIRED): action, reason, devname, type, subtype, level, logdesc, msg, service, policyid, srccountry, dstcountry, srcintf, dstintf, user, group, status, app, appcat, vpntunnel, eventtype, proto Message fields have no index and cannot get one — they are pulled out of free text — so every message pivot is a sequential scan of the window (~37x the per-row cost of a column pivot). device_id is mandatory for them and the server rejects a fleet-wide message pivot outright. `devname` and `source` are DIFFERENT keys and are deliberately not merged: `source` is the column syslog arrived with (a relay may have rewritten it to its own name), `devname` is what the device wrote about itself inside the message. Ask for the one you mean. Window: `hours` (1-168, default 24) OR `start_time`+`end_time` (ISO-8601 UTC); a window wider than 168h is refused either way. `limit` is the top-N cut (1-50, default 20). Reading the result: `facets` is the top-N; `other` is everything below the cut, so facets + other sums to `matched_rows`. `rows_without_field` counts rows in the window where the field is absent entirely — a large value is normal (a FortiGate emits many message types) and is NOT a failure. Errors are structured, and two of them are instructions: error='window_too_large' — the row pre-check refused before scanning. Lower `hours` (halve it and retry) or add/narrow device_id. `rows_in_window` and `max_rows` tell you how far over you are. Do NOT retry the same window. error='query_timeout

輸入參數hourslimitend_timegroup_by必填device_idstart_time

flow_summary

Summarize NetFlow Traffic

Summarize one host's network conversations: top peers, top ports, and a client-vs-service-side split, each with a residual "other" bucket plus overall totals. Wraps GET /api/aggnetflow/summary (permission: vne). Use this to characterize a host before pulling rows — netflow_search returns the individual conversations once a rollup here points at an interesting peer or port. Source is the windowed flow view: the raw table's live tail (the last ~15 minutes — cleanup_netflow deletes raw rows as it rolls them up) unioned with the aggregated history (agg_netflow, retained 4 weeks), so one call covers right-now through a month back with no gap at the rollup boundary. Byte totals are IN-WINDOW estimates, not lifetime totals. The window predicate is OVERLAP — a conversation crossing either edge still matches — but each matching row contributes only its bytes pro-rated to the window (uniform-rate attribution), so the totals approximate window traffic instead of bounding it from above. Still never quote a byte figure as a rate. Direction is normalized on both arms (the lower port of each conversation becomes dst_port — raw-tail rows are re-oriented the same way on read) and the rollup folds BOTH directions into one row, so sent-vs-received bytes do not exist in this data. The direction split is as_source (host was the client side) vs as_destination (host was the service side), each carrying bidirectional bytes. `conversations` counts rows, not distinct conversations — a long-lived conversation contributes one row per 15-minute roll-up tick, plus per-flow rows for its not-yet-rolled-up raw tail. Window: `hours` (default 24, max 168) OR start_time+end_time; an explicit window is held to the same 168-hour ceiling server-side — agg_netflow is BRIN-indexed on time now, but a summary still aggregates every overlapping row under a 10s statement timeout. A window too wide comes back as an error asking you to narrow it, not as partial data. `limit` is the top-N per rollup (defaul

輸入參數ip必填hourslimitend_timestart_time

device_list

List Devices

List monitored devices. Wraps GET /api/devices (permission: devices); user's tag-scope is enforced server-side. Filters (all optional, combinable): - tag: tag slug, e.g. "snmp-up" or "switches". Slug is the stable lowercase-hyphen form; tag names with spaces won't match. - status: "up" or "down" (based on latest ping). - search: substring match on label + ip_address (case-insensitive). Relation flags (all default false — opt in only what you need to keep the response small): tags, alerts, ping, oids, walks, interfaces, ports, disks. Pagination: per_page defaults to 25 (max 200), page defaults to 1. meta.pagination.has_more tells you whether more pages exist. Example: device_list({tag: "snmp-up", per_page: 10})

輸入參數tagoidspagepingtagsdisksportswalksalertssearchstatusper_page另有 1 個

device_get

Get Device Details

Fetch one device with its related state: tags, alerts, the ping / oid / interface / port / disk trackers configured on it, its SNMP walk trackers, and a netflow rollup. Wraps GET /api/device/{id} (permission: devices). **Bulk payloads are opt-in, and that is a change from how this tool used to behave.** It returned every log row every tracker collected in the window, inline: one 8-hour call on an ordinary host measured ~127 KB — 85 KB of oid log rows across 12 trackers, 35 KB for a single ping tracker's 479 samples — so pulling three hosts to "see the state" could spend 300 KB of context before any reasoning started. By default each tracker now returns its identity and latest value (which is what state questions need) plus `log_count`, the number of rows sitting in the window. include_logs:true puts the rows back. Pair it with max_log_rows (default 200 per tracker, newest kept) so one chatty tracker cannot swamp the response; a tracker that got cut carries logs_truncated:true next to the untrimmed log_count. When the question is "is this metric degrading?" rather than "what happened at 14:05?", device_metric_summary answers it from fixed-window stats and ships no rows at all. include_walk_data:true returns the stored SNMP walk payloads, omitted for the same reason: one configured walk tracker reaches ~72 KB of JSON on its own. Without the flag each walk row keeps id / oid / interval / timestamp plus walk_entries, the payload's top-level entry count. What stays unbounded: the tracker rows themselves. Both flags govern each tracker's history, never how many trackers come back — a switch with 190 monitored interfaces returns 190 interface rows in summary mode too. interfaces_search pages interface metadata across the fleet if that is the real question. Window: `hours` (1-168, default 8) or explicit start_time+end_time (ISO-8601 UTC). It scopes the netflow rollup and log_count as well as the rows themselves, so it still matters with include_logs off. The appliance

輸入參數id必填hoursend_timestart_timeinclude_logsmax_log_rowsinclude_walk_data

device_find

Find Devices by Name or IP

Find devices matching a substring of label or ip_address. Convenience wrapper for GET /api/devices?search=<q>; equivalent to device_list({search: q}). Use device_list directly when you need tag/status filters or relation includes. device_find is the one-arg shortcut for "does anything look like X?". Pagination: per_page defaults to 25 (max 200), page defaults to 1. Permission: devices. Example: device_find({q: "switch"})

輸入參數q必填pageper_page

overwatch_summary

Overwatch Health Summary

High-level network health snapshot for 'how's the network?' style questions. Wraps GET /api/devices?alerts=1&tags=1 (requires permission: devices) and aggregates in-tool: device count, active alert count (total + by severity when present on the alert row), and the top-N devices by alert count. Drill into specific devices with device_get.

輸入參數top_n

snmp_test

Test SNMP Credentials

Probe a device for SNMP reachability using the Netmon snmptest binary. Wraps POST /api/testSnmp (requires permission: write_devices). BLOCKING — can run up to 60 seconds while the server waits for the target to respond. Provide a valid snmpconfig object: for v1/v2 include snmp_version + snmp_community; for v3 include snmp_version=3 plus authuser/authpass/authprot and optionally privpass/privprot and snmp_v3_security. Returns the upstream {status, message} verbatim under `data`.

輸入參數ip必填snmpconfig必填

snmp_walk_last

Get Cached SNMP Walk

Fetch the most recent stored SNMP walk for a device (cached in tools_walks). Wraps GET /api/getLastWalk/{device} (permission: tools). Cheap single-row read. Always try this first when an SNMP walk is needed. Only fall back to snmp_walk_run if the cached row is missing or the data is too stale for the question (the controller does not stamp a freshness header — judge from the walk's own timestamps if present). Returns the raw walk row including device_id and the captured OID payload. Empty walk = device has never been walked. Example: snmp_walk_last({device_id: 42})

輸入參數device_id必填

snmp_walk_run

Run Fresh SNMP Walk

Trigger a FRESH SNMP walk against a device. Wraps POST /api/getSNMPWalkInfo/{deviceId} (permission: tools). SLOW and SIDE-EFFECTING. Server-side this shells out to walktool with a 1200s (20 minute) timeout and writes the result into the tools_walks table. Always try snmp_walk_last first; only call this when the cached walk is missing or known to be stale. MCP tool timeout is 1200s to match the server-side cap. If the device has many OIDs the call will take real wall-clock time — let it run; do not retry on timeout without first checking snmp_walk_last (the writeback may have completed even if the HTTP response stalled). Example: snmp_walk_run({device_id: 42})

輸入參數device_id必填

agent_services

List Windows Services

List Windows services on an agent-managed device — live read via the WMI tunnel. Wraps POST /api/getDeviceServices (permission: devices). Returns rows of {Name, State, DisplayName} as reported by Win32_Service. Use this to answer 'is service X running on host Y' without trawling event logs. Read-only by design — the service-control endpoints (start/stop/restart) are deliberately NOT exposed via mcpmond. Latency: server-side timeout is 60s — agents on slow links may approach that. Returns 400 if the device is offline or not agent-enrolled. Example: agent_services({device_id: 42})

輸入參數device_id必填

agent_processes

List Windows Processes

List running processes on an agent-managed device — live read via the agent tunnel. Wraps POST /api/getDeviceProcesses (permission: devices). Returns rows as reported by GETPS: (process id, name, parent, memory, etc. — exact shape depends on the agent version). Common diagnostic patterns: pair with agent_services to answer 'is the SQL Server service running but stuck?'; correlate top memory/cpu processes with eventlog_search criticals. Read-only by design — the process-kill endpoint (KILLPS) is deliberately NOT exposed via mcpmond. Server-side timeout is 60s; expect 400 if the device is offline or not enrolled. Example: agent_processes({device_id: 42})

輸入參數device_id必填

alerts_list

List Alert Definitions

List configured alert definitions across both axes of the rule engine. Modern alerts (table `alerts`, class-scoped: syslog_log / event_log / eve_log / device_down / storage) and legacy alerts (per-device tracker thresholds, surfaced via the `_hell` view) are fetched, normalized, merged, filtered, and paginated. Wraps GET /api/alerts (modern) and POST /api/getAlerts (legacy). Both endpoints return their full catalog; this tool applies the filters and pagination client-side, so the LLM doesn't need to know which axis a filter applies to. Output rows carry a `source` discriminator and a synthetic `id` string (e.g. "modern:42" / "legacy:17") so dedup is unambiguous; the original numeric id is on `raw_id`. Modern rows carry `class`, `severity`, and last-evaluated stats. Legacy rows carry `type` (tracker kind), `device_id`, and `tracker_name`. Modern rows carry NO throttle / renotify fields, on purpose: since 21.93 no modern class consults them (log-stream classes are one-fire and edge-triggered per event key; device_down and storage are stateful and diff open incidents), so they explain nothing about when a modern alert re-fires. Do not claim a modern alert is flap-damped or on a renotify timer — it isn't. Legacy trackers DO still renotify on a timer, but that config lives on the trigger and is not returned here either. `last_result_count` is NOT the same measure across classes. For syslog_log / event_log / eve_log it is the raw match count from the last evaluation BEFORE edge-trigger dedup — a steady nonzero means the pattern keeps matching, NOT that anything was notified (repeat matches of an already-seen occurrence are suppressed). For device_down it is a level: devices currently down and in scope, so nonzero means an outage is open right now. For storage it is likewise a level: volumes currently low (or held open because their reading is unreadable/stale) and in scope. Never sum or compare the two. `last_evaluated_at` is the last scheduler tick that touched the a

輸入參數pageclassscopesearchenabledper_pageseveritydevice_id

alerts_history

Alert Incident History

Authoritative 'what fired and when' stream — wraps the `alert_history` table (one row per incident, both legacy and modern) and `alert_outlet_log` (per-dispatch ledger keyed by history_id). Default mode: lists incidents newest-first. Each row is one incident with opened_at / last_event_at / resolved_at framing the lifecycle, plus aggregated outlet_types[], dispatch_count, and failed_count. `status` is computed from resolved_at: 'open' if null, 'resolved' otherwise. Drill-down mode: pass `incident_id` (the `alert_history.id`, NOT `alert_id`) to switch the call to /api/alert-history/{id}/log and return the per-outlet dispatch ledger for that one incident. Use this for 'did the email actually go' / 'what did the webhook payload look like' / 'which outlets failed' follow-ups. Filters (default mode, all client-side, AND-combined): status (open|resolved|all, default all), severity (int or array — scheme is 1-5, lower=worse), device_id, source (legacy|modern|all), hours (1-168, default 24, applied against last_event_at), search (substring on alert_label/subject). Important caps: the upstream endpoint returns at most 500 rows ordered by last_event_at DESC. We can't reach older rows than that. `meta.upstream_cap` reports this so the LLM can warn the user when results may be truncated. `severity_label` is added server-side so the LLM doesn't memorize the scale. Pagination is over the post-filter result. Tag-scope is enforced by Laravel — tag-restricted users see only incidents for devices in their slug set. Permission: alerts. Examples: alerts_history({status: 'open', severity: [1,2], hours: 1}) alerts_history({device_id: 42, hours: 24}) alerts_history({incident_id: 9182}) // dispatch ledger

輸入參數pagehourssearchsourcestatusend_timeper_pageseveritydevice_idstart_timeincident_id

maintenance_windows_list

List Maintenance Windows

Lists maintenance windows — the suppression schedules that gate alert dispatch. Use when a user asks 'why didn't this page me' or 'is this device under maintenance right now' — a quiet alert may be inside a window rather than truly silent. Two modes: - Global catalog (default): wraps GET /api/alerts/maintenance-windows. Returns every window with its schedule fields. - Per-legacy-alert: pass `alert_id` to wrap GET /api/alerts/legacy/{id}/maintenance-windows, returning only the windows attached to that legacy alert handler. Per CLAUDE.md, modern alerts (class=syslog_log/event_log/eve_log) attach windows through `alert_routing_rules`, not directly — the per-alert path is legacy-only by route constraint. If you need to inspect modern-alert suppression, look at the routing rule attached to the rule, not the alert. Each row carries: id, label, recurrence_unit (day|week|month|dawom), schedule_hour, schedule_dow (0=Sun..6=Sat), schedule_day_of_month, schedule_month, duration_minutes, plus a human-readable `description` (e.g. 'Weekly on Tue at 14:00 UTC for 60 min') so the LLM doesn't reinterpret the cron-style fields. Note: this tool does NOT compute whether a window is active *right now* — that depends on the server's local clock and the interpretation of dawom rules. The LLM should use the description + duration to reason about it. If you need a reliable yes/no, ask alertmond directly via its IPC (out of scope for mcpmond). Permission: alerts. Examples: maintenance_windows_list({}) // global catalog maintenance_windows_list({alert_id: 17}) // legacy alert 17 only

輸入參數alert_id

tags_list

List Tags

List tag definitions. The slug is the stable identifier used everywhere device-tag scoping is enforced (e.g. alert_routing_rules.tag_filters, device_list({tag: ...})). The display name is for humans. Wraps GET /api/tags. Returns every tag the caller has visibility to (Laravel does not tag-restrict the catalog itself — operators see all tags and use the slugs that match their visible devices). Tag rows are typically O(10s) per install. Optional `type` filter: 'device' tags decorate devices and are the most common (these are what device_list({tag: ...}) matches against). 'status' tags are reserved for system-derived states. 'other' is a catch-all. Default 'all' returns every type. Permission: devices. Example flow: a user says 'check our routers' → call tags_list({type: 'device', search: 'router'}) → pick a slug → call device_list({tag: 'router', status: 'down'}).

輸入參數typesearch

top_bandwidth

Top Bandwidth Talkers

Top NetFlow conversations over the last N minutes — the 'who's eating bandwidth right now?' question. Wraps GET /api/getTopBandwidth/{mins}, the same query that powers the dashboard live widget. Use this for short-window 'right now' inquiries. For longer windows (hours-to-days) or filtered top-talkers, use netflow_search instead — that tool has the rich filter set; this one is the live snapshot. Server-side cap: top 20 conversations by in-window bytes descending. We don't expose `top_n` — the upstream endpoint hardcodes the limit and there's no value in lying about that to the LLM. Each row: {src_host, src_id, src_ip, dst_host, dst_id, dst_ip, bytes, bps}. Hostnames come from the _dns view (PTR + custom overrides); src_id/dst_id are populated when the IP matches a monitored device. bytes is the conversation's in-window share (pro-rated), and bps is averaged across the window — not a live rate. Permission: vne. Examples: top_bandwidth({minutes: 5}) top_bandwidth({minutes: 60})

輸入參數minutes

arp_table

Get ARP Table

Lists hosts observed on the local LAN(s) via the ARP table — the 'what devices have we seen recently?' question. Wraps POST /api/getArpTable, which collapses arptable + _dns into one row per IP with hostname + monitored-device id resolution attached. Distinct from `arp_lookup` (single-IP MAC resolution at the current moment): this is the historical view over the last N hours. Use it for 'who's on the LAN today' / 'is there a new device' / 'where did this IP last appear' questions. Each row: {id, ip, mac, timestamp, hostname, device_id}. device_id is non-null when the IP corresponds to a monitored Netmon device; hostname comes from _dns (PTR + custom overrides). Rows are deduped by IP — only the latest seen entry per IP within the window is returned. Permission: devices. Tag-scoping is NOT applied here — ARP is subnet-level, not device-level, so it doesn't have a tag anchor. Operators see the whole LAN regardless of tag scope. Examples: arp_table({}) // last 24h, no filter arp_table({hours: 1, search: "10.0.0"}) arp_table({search: "laptop"})

輸入參數hourssearch

device_metric_summary

Summarize Device Metrics

Day / week / month / all-time summary stats for a single device-tracker, by metric type. Multi-backend: pass `metric` to pick which upstream endpoint to hit. metric='latency' → wraps POST /api/latency/stats (icmpingId). Returns: dayAvgLatency, weekAvgLatency, monthAvgLatency, allTimeAvgLatency (ms); dayAvgLoss, weekAvgLoss, monthAvgLoss, allTimeAvgLoss (%); dayPingCount/weekPingCount/etc.; dayUptime/weekUptime/etc. (% successful pings); currentLatency, currentLoss, monitoringDuration (humanized). metric='disk' → wraps POST /api/disk/stats (diskId). Returns: dayGrowthKB, weekGrowthKB, monthGrowthKB, allTimeGrowthKB (negative = filling); estimatedFillTime (humanized projection from 7-day slope); plus current available/used measurements. **This is a fixed-window summary, not time-buckets.** Comparing day vs month tells the LLM 'is this metric degrading?'. For the raw samples underneath it, call device_get({id, hours: N, include_logs: true}) — the log rows are opt-in there because they are the expensive half of that response. Discovery: `target_id` is a TRACKER id, never a device id, and device_get is the only tool that hands one out. Both sit nested in its response and both survive its default summary shape — they are tracker identity, not log rows, so no flag is needed to see them: latency → device.ping.icmping_id. `ping` is a single object, not a list: a device has at most one icmping tracker, and its key is icmping_id, not id. disk → device.disks[].id, one entry per monitored volume (agent-collected or SNMP). Most devices carry none — an empty array means there is no disk tracker to summarize, not that the lookup failed. Port-stats has no equivalent endpoint upstream and is omitted; if one lands later, add a third metric backend. Permission: devices. Tag-scoped server-side via Devices::withUserTags() before stats are computed. Examples: device_metric_summary({metric: 'latency', target_id: 17}) device_metric_summary({metric: 'disk', target_id

輸入參數metric必填target_id必填

agent_disk_usage

Browse Agent Disk Usage

Path-scoped folder-tree disk usage report from a Netmon agent — the 'D: drive is at 95%, what's eating it?' question. Wraps POST /api/getFolderUsageFromPath which RPCs into the agent's GETFOLDERUSAGEPATH command and returns the immediate-children size breakdown for the given path. Required parameters: device_id (the agent-enrolled device) and path (a Windows path on that device, e.g. "D:\\" or "C:\\Users"). Backslashes must be escaped in JSON strings — the LLM should pass "D:\\" not "D:\". Drill-down pattern: start at the drive root, identify the largest child, recurse with that child as the new path. The agent does not produce a recursive tree in one shot — that's a deliberate latency cap. Read-only by design. The agent's write paths (DELETEFILE, DELETEFOLDER, EXECUTEPS) are on the permanent deny-list at the top of tool_handler.cpp and not wrapped — even a future operator with the broadest possible PAT must not be able to drive deletions or shell exec from an LLM. Latency: BLOCKING; the upstream endpoint has a 120s timeout. Large folders may take real wall-clock time. Permission: devices. Windows-only — depends on agent enrollment (see CLAUDE.md agent enrollment section). Linux/macOS hosts have no agent-side equivalent of GETFOLDERUSAGEPATH. Example: agent_disk_usage({device_id: 42, path: "D:\\Users"})

輸入參數path必填device_id必填

capture_list

List Packet Captures

Read-only listing of packet captures. Wraps GET /api/captures. Operators see their own captures; admin (sa) sees all. The upstream endpoint returns the 200 most-recent rows ordered by id desc. Use this for 'is there a capture running on device X?' / 'do we have packet evidence for the incident?' / 'what captures finished today?' questions. Pair with capture_get to drill into one row. Each row carries: id, user_id, device_id, label, status (starting|running|stopped|expired|failed), filter (jsonb), started_at, ended_at, expires_at, packets, bytes, byte_cap. Filters (client-side, AND-combined): device_id, status, search (substring on label). Read-only is deliberate: capture creation, stop, delete, and pcapng download endpoints are NOT wrapped. PCAP bytes aren't an LLM-shaped payload anyway. Permission: capture. Examples: capture_list({}) capture_list({status: 'running'}) capture_list({device_id: 42, status: 'stopped'})

輸入參數pagesearchstatusper_pagedevice_id

capture_get

Get Packet Capture Status

Read-only single-capture detail. Wraps GET /api/captures/{id}. If the capture is still active (status=starting|running) the upstream endpoint refreshes status from netmond's IPC before responding, so packets/bytes counters are live. Returns the same row shape as capture_list rows, plus freshly-refreshed counters when applicable. Read-only is deliberate. capture_stop / capture_delete / capture_download are NOT wrapped. The chunks endpoint (GET /api/captures/{id}/chunks) is also not wrapped — pcapng bytes are an extcap-shaped payload, not an LLM-shaped one. Permission: capture. Example: capture_get({id: 17})

輸入參數id必填

speedtest_history

Speedtest History

Recent WAN speedtest results — answers 'is the internet healthy?'. Wraps GET /api/getSpeedTestHistory. Returns rows ordered by timestamp desc. Each row carries the upstream's SpeedtestLog shape — typically {id, timestamp, download_mbps, upload_mbps, latency_ms, jitter_ms, server, ...}, but any new columns added on the Laravel side flow through automatically. The tool doesn't reshape the row contents — just filters by time window and limits the return. Lower priority than ping/traceroute/netflow for general 'internet slow' investigations, but the right tool when the user specifically asks about WAN throughput trends or recent speedtest runs. Filters (client-side): hours (1-720, default 168 = 7d), limit (1-100, default 25). The upstream endpoint returns the full history with no server-side cap — narrow with hours rather than fetching unbounded. Permission: tools. Example: speedtest_history({hours: 24})

輸入參數hourslimit

版本歷史

1
  1. v1.0.1最新Sep 16, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Netmon 整合