# Probe MCP documentation --- --- > On-premises network probe (single-file Go container + cloudflared tunnel) with a Cloudflare Worker engine and MCP server exposing LAN telemetry to Claude. --- --- # What is Probe MCP? Source: https://docs.neuralconfig.com/probe-mcp/ Probe MCP gives Claude eyes on a customer's **live local network** — the protocols that only exist on the LAN and never reach a cloud management plane: syslog, SNMP, sFlow, NetFlow, packet capture, and SSH. Cloud-only tools can't see any of it. A small on-prem probe collects the ground truth, and a Cloudflare engine exposes it to Claude in plain language. ## The two halves - **The probe** — a single hardened Go container (with a bundled `cloudflared` tunnel) that you run on one Linux host on the customer LAN. It receives syslog and SNMP traps, polls SNMP, collects sFlow/NetFlow, discovers devices, and can capture packets or open SSH sessions on demand. It stores the raw data locally and dials home over an **outbound-only** tunnel — no inbound ports. - **The engine** — a Cloudflare Worker that ingests the probe's aggregates, stores them, and serves an **MCP server** to Claude. You add one URL to Claude as a custom connector and ask your network questions. ## The idea: one tool, a whole LAN Like the sibling `r1-mcp` server, Probe MCP's `tools/list` returns exactly **one** MCP tool, `code_mode`. Inside it, Claude writes small JavaScript programs against a `probe` object that can list your probes, query stored rollups, and reach live into the LAN — SNMP, syslog search, topology, PoE, live packet connections, SSH. See [How code mode works](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/). ## What you can ask for - *"What's flooding the syslog on the Charleston probe in the last hour?"* - *"Which switch ports are erroring or flapping right now?"* - *"Walk the LLDP neighbors and draw me the L2 topology."* - *"Which access points are drawing the most PoE?"* - *"Run an assessment on this site and give me a scorecard PDF."* The [workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/) in Claude's **+** menu package the bigger ones as guided flows. ## Standalone, or a RUCKUS companion Probe MCP stands alone for any network. It is also a **companion** to the RUCKUS MCP servers: [link it to R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/) and R1-MCP's Claude can reach the same on-LAN ground truth — local inventory, ICX/AP CLI, and config restore — that a cloud controller can't see. ## Getting started 1. [Sign in and enroll a probe](https://docs.neuralconfig.com/probe-mcp/setup/getting-started/) 2. [Deploy the probe container](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/) on a LAN host 3. [Point your devices at it](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/) 4. [Connect it to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/) ## Where your data lives Raw telemetry stays on the probe by default; only aggregates leave the LAN, and live raw data is fetched on demand over the tunnel. See the [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/). ## Explore the docs ### Set up - [Getting started](https://docs.neuralconfig.com/probe-mcp/setup/getting-started/): The four steps to a working setup — sign in, enroll a probe, deploy it, connect Claude. - [Deploying the probe](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/): Run the probe container on a LAN host — host requirements, the run command, and verifying the tunnel. - [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/): Configure switches, APs, and firewalls to send syslog, SNMP, and flow data to the probe. - [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/): Add Probe MCP as a custom connector — the MCP URL and the OAuth consent. - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): The probe's YAML config file — every collector section and its real default. - [API connections and the vault](https://docs.neuralconfig.com/probe-mcp/setup/connections/): Register upstream APIs Claude can call with a secret injected server-side, never exposed to the model. ### How it works - [How code mode works](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/): One MCP tool running small JavaScript programs against the probe, instead of dozens of wire tools. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): Running an AI agent on your LAN — data residency, the outbound-only tunnel, and what leaves the network. ### Reference - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): Every probe.* function Claude can call inside code mode, with arguments and return shapes. - [Workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/): The two guided workflows in Claude's + menu — an assessment scorecard and probe exploration. - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): The run budget, timeouts, row and size caps, retention windows, and the services that ship disabled. ### More - [Linking with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/): Let R1-MCP's Claude reach your probe, and see which read-only subset it gets. - [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/): Activation failures, a probe that won't stay connected, and collectors returning nothing. --- # Getting started Source: https://docs.neuralconfig.com/probe-mcp/setup/getting-started/ Getting to a working setup is four steps: sign in, enroll a probe, deploy it on the customer LAN, and connect Claude. ## 1. Sign in Go to the [Probe MCP dashboard](https://probe-mcp.lanpulse.com) and **Sign in with Google**. Signing in creates your workspace. There is nothing to install to use the dashboard — the probe container comes later, and only runs on-site. Straight after Google hands you back, you get a one-page acceptance screen: tick the box and click **Agree and continue**. It covers NeuralConfig LLC's Terms of Service and Privacy Policy plus the two probe-mcp addenda, which are where packet capture, device CLI access, and SSH session recording are disclosed. You can't reach the dashboard, a probe, or any tool call before it. It reappears if any of those documents is republished. ## 2. Enroll a probe On the dashboard, click **Enroll a probe**, give the site a name (and an optional timezone, pre-filled from your browser), and click **Provision probe**. You get back a one-line **Docker command** containing a **single-use activation code that expires** — mint it when you're ready to run it. If it expires or you need a new one, use the **New activation command** button on the probes list. ## 3. Deploy the probe and point your network at it Run that Docker command on a Linux host on the customer LAN that has Docker and outbound internet. The container activates itself, opens its outbound tunnel, and appears as **Online** in the dashboard with its **LAN IP**. Then configure your network devices to send telemetry to that LAN IP — syslog, SNMP traps, and sFlow. Full detail: - [Deploying the probe](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/) - [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/) ## 4. Connect Claude Copy your MCP URL — `https://probe-mcp.lanpulse.com/mcp` — from the dashboard and add it to Claude as a custom connector. Claude walks you through a Google consent once, then `code_mode` appears in its tools. - [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/) ## Verify it works Ask Claude: > Using Probe MCP, list my probes and show the last hour of syslog volume. If the probe is Online and receiving events, you'll get real data back. If not, see [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/). :::tip Want the fastest payoff? Run the [`assessment_scorecard` prompt](https://docs.neuralconfig.com/probe-mcp/reference/prompts/) once the probe is Online — it scans syslog, SNMP, and sFlow and produces a co-branded findings PDF. ::: ## Next steps - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): Turn on the collectors that ship disabled — sFlow and NetFlow, packet capture, SSH. - [How code mode works](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/): Why there's only one tool, and which questions still work when the probe is offline. - [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/): Activation failures, a probe that won't come Online, and telemetry that never arrives. --- # Deploying the probe Source: https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/ The probe is a single container you run on one host inside the customer LAN. It collects telemetry locally and dials home over an outbound tunnel — there are no inbound ports to open. ## Host requirements - A **Linux host on the LAN** — ideally on the same broadcast domain (or a SPAN destination) as the gear you want to watch. - **Docker** installed. - **Outbound internet** access so the bundled `cloudflared` tunnel can connect. Nothing inbound needs to be reachable. The image is a small Alpine-based container that bundles the probe binary and `cloudflared`, built for `linux/amd64`, `linux/arm64`, and `linux/arm`. ## Run the container [Enroll a probe](https://docs.neuralconfig.com/probe-mcp/setup/getting-started/) in the dashboard to get a ready-to-paste `docker run` command. Run it on the host: ```bash # Example shape — copy the real one-liner (with your activation code) from the dashboard. docker run -d --name probe-mcp \ --network host \ -v probe-data:/var/lib/probe-mcp \ -e ACTIVATION_CODE=act_xxxxxxxx \ ``` Two things to know about that command: - **`--network host`** — the probe binds its listeners (syslog, SNMP traps, sFlow) directly on the host's network so LAN devices can reach them. This is why you don't publish individual ports. - **`ACTIVATION_CODE`** — a **single-use code that expires**. The probe uses it exactly once, on first start, to fetch its identity, tunnel token, and shared secret from the engine; after that it never needs the code again. ## The data volume The probe stores everything under **`/var/lib/probe-mcp`** — its SQLite databases, the offline upload buffer, and its persisted credentials. Mount a named volume there (as the one-liner does) so the probe keeps its identity and buffered data across restarts and image upgrades. :::caution If you don't persist `/var/lib/probe-mcp`, a container recreate throws away the probe's saved credentials and it will try to re-activate — which fails, because the activation code was single-use. Always keep the volume. ::: ## Verify it's Online Within a minute the probe should show as **Online** in the dashboard, with its **LAN IP** and last heartbeat. Once it's Online: 1. [Point your devices at it](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/) using that LAN IP. 2. [Connect Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/) and ask it to list your probes. ## Re-activating a probe If a probe is stuck in a **pending** state, or you need to redeploy on a fresh host, use **New activation command** on the probes list to mint a new single-use Docker command. ## What the probe does and doesn't reach out to The probe makes only **outbound** connections: the `cloudflared` tunnel to the engine, plus outbound SNMP polls and (if enabled) SSH to your devices. Its local HTTP API is bound to `127.0.0.1:8080` and is reachable only through the tunnel, never exposed on the LAN. See the [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/) for the full network picture. The probe heartbeats every 60 seconds. If those stop, it's flagged **offline** after 180 seconds of silence, by a sweep that runs every 5 minutes — so the dashboard can lag a failure by a few minutes. See [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/#online-in-the-dashboard-but-calls-still-fail). ## Next steps - [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/): The collector ports, and which ones are listening by default. - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): The YAML config, its real defaults, and the env-var overrides. - [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/): Add the MCP URL as a custom connector and authorize it. --- # Pointing your network at the probe Source: https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/ Once the probe is [Online](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/), point your network devices at its **LAN IP** (shown on the probes list). The probe listens on the standard collector ports; you send to those. ## Collector ports Configure each device to export to the probe's LAN IP on these ports: | Telemetry | Send to (on the probe's LAN IP) | On by default? | |---|---|---| | **Syslog** (RFC 3164 + RFC 5424) | UDP **514** and TCP **514** | Yes | | **SNMP traps** (v1 / v2c) | UDP **162** | Yes | | **sFlow** | UDP **6343** | **No — must be enabled** | | **NetFlow** (v5 / v9) | UDP **2055** | **No — must be enabled** | :::caution **sFlow and NetFlow are off by default.** The flow collector (`flow_collector`) ships disabled. Turn it on in the probe config before pointing exporters at 6343/2055, or the flow data is dropped. See [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/). ::: ## SNMP polling (the probe reaches out) SNMP is different — the probe **polls your devices outbound** on UDP **161**; you don't point anything at the probe for this. SNMP polling is **on by default** with community `public` and SNMP **v2c**, and the probe auto-discovers devices it learns about from syslog, sFlow, and discovery. To poll a device the probe must have the right **community string** (or v3 credentials) and the device must permit SNMP from the probe's IP. Set the communities and version in the probe config — see [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/). ## Device discovery Discovery is on by default: the probe reads the ARP table and listens for mDNS/Bonjour, SSDP/UPnP, and LLDP to build a device inventory. Active ICMP sweeps (`ping_sweep`) are **off** by default; enable them in config if you want the probe to actively probe the subnet. ## Verify data is arriving After you've pointed a device at the probe, ask Claude: > Using Probe MCP, show me the syslog volume for the last 15 minutes, and search > the live syslog for anything from that switch's IP. Stored rollups (like syslog volume) confirm ingest is working; a live search confirms the probe is receiving and indexing messages right now. If nothing shows up, check the port, the device's export config, and that the collector is enabled — see [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/). ## How long the probe keeps it Retention is enforced on the probe, so a query can only reach back as far as the data still on disk: syslog and trap events for **7 days** or **1 GiB**, whichever comes first; flow aggregates for **24 hours**; individual flow records for **6 hours**. The aggregates shipped to the engine outlive all of that, which is why "what did syslog volume look like last week?" still answers when a raw search can't. Full table in [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/#how-long-data-is-kept). ## Next steps - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): Enable the flow collector, set SNMP communities, and tune the collectors. - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): What Claude can ask of the telemetry once it's arriving. - [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/): The checklist when telemetry isn't showing up — wrong target, collector off, wrong port. --- # Connecting to Claude Source: https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/ The engine serves a **remote** MCP server. There's nothing to install in Claude — you add one URL as a custom connector and authorize it. (The probe itself still runs on the LAN; see [Deploying the probe](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/).) ## Add the connector 1. Copy your MCP URL from the [Probe MCP dashboard](https://probe-mcp.lanpulse.com) — `https://probe-mcp.lanpulse.com/mcp`. 2. In Claude, go to **Settings → Connectors → Add custom connector**. 3. Paste the URL and add it. 4. Claude opens a consent page. Approve it. 5. The connector shows as connected, and `code_mode` appears in Claude's tools. ## What the consent flow is doing Probe MCP uses **OAuth 2.1 with Dynamic Client Registration and PKCE** (S256): 1. Claude registers itself as an OAuth client automatically — there's no client ID to paste. 2. You're sent to Probe MCP to authorize, which requires your **Google session**. If you aren't signed in, you'll be asked to sign in first — and if you haven't accepted the current [terms](#accepting-the-terms), that screen comes before the consent page rather than after it. 3. Probe MCP issues Claude an access token bound to your account, scoped to `probe:call`. That token is what makes the single shared MCP URL personal: every request Claude makes carries it, and the engine resolves it to your account and your probes. Tokens are stored **hashed** — the engine never keeps a raw copy of a token it issued. Access tokens last 30 days and refresh automatically. ## Accepting the terms The first time you sign in — and again whenever the documents are republished — Probe MCP shows a one-page acceptance screen before it will do anything else: tick the box, click **Agree and continue**. The box covers NeuralConfig LLC's Terms of Service and Privacy Policy plus the probe-mcp terms and privacy addenda, which are the documents that cover packet capture, device CLI access, and SSH session recording. It guards **both** entry points, so an MCP client hits it too: adding the connector while your acceptance is out of date shows the acceptance screen first, then the OAuth consent page. Each acceptance is logged with the exact document versions you agreed to. ## Where it works Any Claude surface that supports custom connectors — Claude Desktop, Claude on the web, and Claude Code. The [workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/) appear in the **+** menu on surfaces that support MCP prompts. ## Verify it's working Ask Claude: > Using Probe MCP, list my probes. If the connector is live but not authorized, Claude will say it can't authenticate rather than returning an empty list — a useful distinction when debugging. ## When authorization fails - **Redirect loop / "too many redirects"** — usually a browser cookie problem during the Google hop. Try a normal (non-private) window, allow cookies for `probe-mcp.lanpulse.com`, and re-add the connector. - **"Not authenticated" on every call** — the token was revoked, or the connector was added before you finished signing in. Remove the connector and add it again. - **Connected, but calls say a probe is offline** — the MCP side is fine; the *probe* isn't reachable. Check the probe is Online in the dashboard. See [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/). ## Revoke access Remove the connector in Claude, or revoke the token from the dashboard. Revoking is immediate — the next request Claude makes fails the bearer check. Removing the connector does **not** delete your probes or their data. ## Next steps - [Workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/): Run the assessment scorecard from Claude's + menu for a co-branded findings PDF. - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): Everything Claude can call once the connector is live. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): How the OAuth tokens are scoped, hashed, and rotated. --- # Configuring the probe Source: https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/ Most deployments run on defaults. When you need to tune what the probe collects — turn on sFlow, enable packet capture, change SNMP communities — you edit its YAML config. ## Where the config lives The container reads its config from **`/etc/probe-mcp/probe.yaml`**. Mount your file there (read-only) when you run the container. Settings are resolved in this order, later winning: 1. Compiled-in **defaults** 2. The **YAML file** 3. **Environment variables** So you can override a single knob with an env var without editing the file. Only `cloud_url` and `data_dir` are strictly required, and both have defaults. A fourth source exists that you don't edit: the engine can send the probe a **config downlink**, which the probe stores and applies on top of the above. That is how a linked R1-MCP provisions LBS venue credentials. The probe validates a downlink **per block** — if one block is bad it keeps its previous values for that block, applies the rest of the document, and reports a `config_rejected` fault on every heartbeat until a valid document replaces it. You'll see that in `probe_status`; see [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/#ask-the-probe-whats-wrong-with-it-first). ## Global settings | Key | Default | |---|---| | `cloud_url` | `https://probe-mcp.lanpulse.com` | | `data_dir` | `/var/lib/probe-mcp` | | `log_level` | `info` (`debug`, `info`, `warn`, `error`) | `probe_id`, `probe_secret`, and `activation_code` are normally set by [activation](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/), not by hand. ## Collector sections and defaults | Section | Key defaults | Enabled by default? | |---|---|---| | `syslog` | `udp_port: 514`, `tcp_port: 514`, `max_msg_len: 8192` | **Yes** | | `snmp` | `version: "2c"`, `communities: ["public"]`, `poll_interval: 60`, `auto_discover: true` | **Yes** (outbound poll to UDP 161) | | `snmp_trap` | `udp_port: 162` (inherits `snmp.communities` if empty) | **Yes** | | `flow_collector` | `sflow_port: 6343`, `netflow_port: 2055`, `aggregation_sec: 300`, `top_n: 10` | **No** | | `discovery` | `interval_sec: 300`, `arp_watch: true`, `mdns/ssdp/lldp: true`, `ping_sweep: false` | **Yes** (ping sweep off) | | `pcap` | `interfaces: []` (all up), `bpf: ""`, `ring_bytes: 1 GiB`, `snap_len: 1600` | **No** | | `ssh` | `max_sessions: 5`, `idle_timeout_sec: 600` | **No** | | `tftp` | `port: 69`, `ttl_sec: 300`, `max_kb: 1024` | **No** | | `liveness` | `interval_sec: 60`, `timeout_sec: 600` | **No** | | `reach_through` | `allowed_hosts: []`, `max_bytes: 8 MiB`, `timeout_sec: 8` | **No** | | `vault` | `max_entries: 128` | **Yes** | | `lbs` | `port: 8883`, `local_port: 1883`, `report_interval_sec: 6`, `duration_min: 60`, `bands: [1, 2]`, `include_randomized: false` | **No** | | `api` | `listen_addr: "127.0.0.1:8080"` | **Yes** | | `tunnel` | `health_check_sec: 30`, `metrics_addr: "127.0.0.1:20241"` | **Yes** | | `rollup` | `interval_sec: 60` | **Yes** | | `buffer` | `max_size_mb: 256`, `flush_on_drain: true` | (always on) | | `retention` | `max_age_hours: 168` (7 days), `max_size_mb: 1024` | (always on) | ## Enabling optional services The most common changes: - **sFlow / NetFlow** — set `flow_collector.enabled: true`, then point exporters at UDP 6343 / 2055. See [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/). - **Packet capture** — set `pcap.enabled: true` and (optionally) `pcap.interfaces` / `pcap.bpf`. Capture is Linux-only and needs the **`CAP_NET_RAW`** capability. - **SSH device CLI** — set `ssh.enabled: true` to allow on-demand SSH sessions to devices. - **Active discovery** — set `discovery.ping_sweep: true` to ICMP-sweep the subnet in addition to passive discovery. - **Reach-through** — set `reach_through.enabled: true` to let `https_forward` call a private on-prem controller through the probe. Leave `allowed_hosts` empty to permit any private host, or list exact hosts to narrow it further. - **Config-restore TFTP** — set `tftp.enabled: true` for the `serve_tftp` pair used by [R1-MCP's Test Bed Manager](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#config-restore-over-tftp--what-it-needs). The `lbs` block is the exception to all of this: **you don't set `lbs.enabled` yourself.** It is switched on when R1-MCP registers an LBS source against the probe and off when the last one is removed, and the venue credentials under `lbs.venues` arrive the same way. The rest of the block — port, bands, reporting interval — is yours, and a downlink carries your values through untouched. See [Telemetry forwarding to R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#telemetry-forwarding-to-r1-mcp). Each of these fails with a distinct error while it's off — `pcap disabled`, `ssh proxy disabled`, `reach_through disabled`, `tftp disabled`, `flow collector not enabled` — so a failing call tells you which key to set. :::caution Some features need Linux capabilities the base container doesn't grant on its own: packet capture and LLDP discovery need `CAP_NET_RAW`. Grant them explicitly when you run the container. See the [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/) for the privileges the probe uses. ::: ## Command-line flags The `probe` binary accepts: | Flag | Default | Purpose | |---|---|---| | `-config` | `""` | Path to the config file. | | `-log-level` | `""` | Override the log level (`debug`/`info`/`warn`/`error`). | | `-version` | `false` | Print version and exit. | ## Environment-variable overrides Handy for one-off overrides without touching the file: | Env var | Overrides | |---|---| | `ACTIVATION_CODE` | The one-time activation code (first start only). | | `PROBE_CLOUD_URL` | `cloud_url` | | `PROBE_DATA_DIR` | `data_dir` | | `PROBE_LOG_LEVEL` | `log_level` | | `PROBE_API_LISTEN` | `api.listen_addr` | | `PROBE_PCAP_ENABLED` | `pcap.enabled` (`1`/`true`) | | `PROBE_PCAP_INTERFACES` | `pcap.interfaces` (comma-separated) | | `PROBE_PCAP_BPF` | `pcap.bpf` | `PROBE_ID`, `PROBE_SECRET`, and `PROBE_TUNNEL_METRICS_ADDR` are also honored but are normally managed by activation. ## Next steps - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): What each of these settings caps at, and the retention windows they control. - [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/): The collector ports to configure on switches, APs, and firewalls. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): The container privileges each optional service needs. --- # API connections and the vault Source: https://docs.neuralconfig.com/probe-mcp/setup/connections/ A **connection** is an upstream HTTPS API that Claude can call **with a secret it never sees** — the engine or the probe injects the credential at call time. You register connections from the dashboard's **Connections** page (the browser counterpart of the `store_connection` / `connection_egress` [tools](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/)). ## What a connection holds - A **label** and a **system** (`r1`, `sz`, `cp`, or `generic`). - An **endpoint** host and port. - An **auth-injection kind** — `bearer`, `basic`, `header`, or `query`. - An optional flag to **tolerate a self-signed TLS cert** (for on-prem controllers). - A **storage mode** for the secret (below). ## Storage modes Where the secret lives decides what the connection can reach and how it survives a probe outage: | Mode | Where the secret lives | Reaches | Survives probe offline? | |---|---|---|---| | `cloud` | AES-256-GCM-encrypted in the cloud | Public endpoints only | Yes | | `probe_vault` | Sealed end-to-end to the probe, on the probe only | LAN endpoints too | No | | `probe_vault_fallback` | Probe vault **plus** a standing encrypted cloud copy | LAN + public | Yes | Use `probe_vault` when the credential must never leave the LAN and the target is a private/on-prem controller. Use `cloud` for public SaaS APIs. Use the fallback mode when you want LAN reach but also want egress to keep working if the probe drops. ## The post-quantum probe vault When you provision a `probe_vault` secret, your **browser** fetches the probe's hybrid recipient keys (**P-256 ECDH + ML-KEM-768**), seals the secret locally, and posts **only ciphertext**. The cloud relays the sealed envelope to the probe and never sees the plaintext. On the probe, vault secrets are held encrypted with AES-256-GCM. ```mermaid sequenceDiagram participant B as Your browser participant E as Cloud engine participant P as Probe (on LAN) B->>E: Request the probe's recipient keys E-->>B: P-256 ECDH + ML-KEM-768 public keys Note over B: Seal the secret locally → ciphertext B->>E: Post ciphertext only E->>P: Relay the sealed envelope (plaintext never seen by the cloud) P->>P: Store the vault secret, encrypted AES-256-GCM ``` ## Break glass — temporary cloud access A pure `probe_vault` connection stops working when the probe is offline, because the secret only exists on the probe. **Break glass** pushes an **explicit, time-boxed encrypted cloud copy** so `connection_egress` keeps working during an outage. - You trigger it from the dashboard with a **TTL** — 15, 30, or 60 minutes (60 is the max). - The copy is treated as gone the moment it expires, and a background sweep purges expired copies. - Break glass is a **dashboard-only** action (session-authenticated browser → engine). It is deliberately **not** an MCP tool, so secrets never pass through the model channel. :::note Break glass requires the engine to reach the upstream API directly (the cloud can't reach the LAN), so it only helps for connections whose endpoint is publicly reachable. ::: ## Calling a connection `connection_egress` makes the call. The secret is injected on the probe for the vault modes and in the cloud for `cloud` mode; either way it never enters the program Claude wrote. Responses are capped at **8 MiB** and the upstream timeout is caller-set but capped at **9 seconds**. If a `probe_vault` connection is called while the probe is offline and no break-glass copy exists, the call returns **`no_cloud_secret`** — that error means "there is nowhere left to get the credential", not that the connection is misconfigured. The vault holds up to **128** entries per probe. ## Next steps - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): The connection and vault functions, and what each one returns. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): How secrets are encrypted at rest and sealed in transit. - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): Egress timeouts, response caps, and the vault entry limit. --- # How code mode works Source: https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/ Probe MCP's `tools/list` returns exactly one tool: **`code_mode`**. Understanding what happens inside it explains most of the server's behavior. ## The approach `code_mode` accepts a small program — the **body of an async JavaScript function** (plain JavaScript only; TypeScript syntax is a parse error). Inside it, a `probe` object provides functions that list your probes, read stored rollups, and reach live into the LAN. Claude writes the program, the engine runs it in a sandboxed V8 isolate on Cloudflare, and only the *result* comes back into the conversation. The payoff: Claude can loop, filter, and join across many probe calls in one round trip, and only the answer — not thousands of intermediate rows — enters the context window. See the [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/) for the full `probe.*` catalog. ## Stored vs. on-demand — the important split Every `probe.*` function is one of two kinds, and the difference is what breaks when a probe goes offline: - **Stored** functions read aggregates the engine already ingested — they work even if the probe is currently offline. These include `list_probes`, `probe_status`, `list_devices`, `syslog_rollups`, `snmp_metrics`, `top_talkers`, and `forward_status`. - **On-demand** functions reach *live* into the probe over its tunnel — SNMP gets/walks, live syslog search, topology, PoE, live packet connections, SSH, and so on. These require the **probe to be Online**; if it isn't, they return a `probe_offline` result rather than data. So "what did syslog look like yesterday?" works any time, but "walk this switch's SNMP right now" needs the probe up. ## The run budget Each `code_mode` run has a **30-second** wall-clock budget, and each on-demand tunnel call within it has its own timeout of **10 seconds**. If the run exceeds the budget it returns `{ error: 'timeout' }`. The budget is per-run and starts fresh on every invocation, so a follow-up question isn't penalized by the last one. A very broad request may come back in stages; asking for a narrower scope is usually faster than asking for everything at once. The two timeouts compose: three slow on-demand calls in a row can spend the whole budget by themselves. See [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/) for every cap a broad request can hit. ## Errors don't throw `probe.*` calls return structured results instead of throwing — a call that fails comes back with an error field (for example `probe_offline` or `timeout`) so the program can inspect it and adapt. If Claude reports a specific failure back to you, that's why. ## Your credentials never leave the server The program runs on Cloudflare, not in Claude. When it reaches the probe, the engine applies your identity and the probe's shared secret server-side. Claude sees the results; it never sees the probe's secret. See the [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/). ## Next steps - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): Every probe.* function, grouped by stored versus on-demand. - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): The run budget, tunnel timeout, row caps, and the services that ship disabled. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): Where the program runs, what it can reach, and what never leaves the LAN. --- # Security model Source: https://docs.neuralconfig.com/probe-mcp/concepts/security/ Running an AI agent's eyes on a live LAN is a trust decision, so here is exactly what the probe and engine do with your network and your secrets. ## Data residency — raw stays on the LAN The probe stores raw telemetry **locally**, in SQLite databases under `/var/lib/probe-mcp`. Only **aggregates** (rollups, top-N, health summaries) are shipped to the engine. Raw, live data — a syslog search, an SNMP walk, a packet slice — is fetched **on demand** over the tunnel when Claude asks for it, and only the result of a query leaves the LAN. ## Network exposure — outbound only - The probe opens **no inbound public ports**. It connects out through a bundled `cloudflared` tunnel; the engine reaches the probe only back down that tunnel. - The probe's local HTTP API binds to **`127.0.0.1:8080`** and is reachable only through the tunnel, never exposed on the LAN. - On the LAN, the probe *listens* only for the telemetry you point at it (syslog, SNMP traps, sFlow) and makes *outbound* SNMP polls and — if enabled — SSH to your devices. The whole picture: raw telemetry stays inside the LAN, the probe dials out to the engine over a single `cloudflared` tunnel (the engine's own requests ride back down that same tunnel), and Claude reaches the engine — never the probe directly. ```mermaid flowchart LR claude["Claude"] subgraph cloud["NeuralConfig cloud"] engine["Engine"] end subgraph lan["Customer LAN — raw telemetry stays here"] probe["Probe container
local API bound to 127.0.0.1:8080"] devices["Switches · APs · firewalls"] devices -->|"syslog 514 · SNMP traps 162 · sFlow 6343"| probe probe -->|"SNMP poll 161 · SSH (outbound)"| devices end claude -->|"OAuth 2.1"| engine probe ==>|"outbound cloudflared tunnel · no inbound ports"| engine engine -. "requests ride back down the same tunnel" .-> probe ``` ## Telemetry authentication — HMAC both ways - The probe signs every uplink to the engine with **HMAC-SHA256** over a shared secret, with a **5-minute timestamp window** and a signature-nonce cache to reject replays, plus sequence-gap detection. - Requests the engine sends *down* to the probe are HMAC-signed the same way, with their own replay cache. ## MCP authentication — OAuth 2.1 Claude connects with **OAuth 2.1 (Dynamic Client Registration + PKCE-S256)**. Access tokens are scoped to `probe:call`, stored as **SHA-256 hashes** (the engine never keeps a raw copy of a token it issued), and refresh tokens **rotate with reuse detection** — replaying a rotated token revokes the whole token family. See [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/). ## Secrets at rest - Persisted probe credentials (tunnel token, shared secret) are written mode `0600` in a `0700` data directory. - The connection **vault** encrypts secrets with **AES-256-GCM**. Provisioning a probe-vault secret is **end-to-end**: your browser seals it to the probe's hybrid **post-quantum** recipient keys (P-256 ECDH + ML-KEM-768) and the cloud only ever relays ciphertext. See [API connections and the vault](https://docs.neuralconfig.com/probe-mcp/setup/connections/). ## Companion link security When you [link with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/), the calling system proves its identity with a **signed assertion**, and each system's key is resolved separately — **R1-MCP, the one live caller, signs with its own dedicated key**, so compromising R1-MCP yields nothing that can forge an assertion for another system. The registered-but-dormant systems (`sz-mcp`, `cp-mcp`, the coordinator) share a default key until they wire up and get their own. Two more properties matter for a security review: - **Rotation is never a hard cutover.** Each key accepts a previous value during a rotation window, so the key can be replaced without a moment where valid callers are rejected. - **Short keys fail closed.** A signing key shorter than 32 characters is treated as unset rather than accepted as weak, so a misconfigured secret refuses callers instead of admitting them. Beyond the signature, the link is scoped: a linked system may call only the tools on **its own allowlist** — see [what the link grants](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#what-the-link-grants) — host validation rejects private/loopback/link-local targets, and every link, owner-move, and revoke is written to an audit trail. ## Container privileges — what the probe needs Be precise with a security team about the container's footprint today: - It runs with **host networking** (`--network host`) so LAN devices can reach its collector ports. - Binding the privileged trap/syslog ports (162, 514) requires **root** or `CAP_NET_BIND_SERVICE`, and the shipped container runs with those privileges. - **Packet capture and LLDP discovery need `CAP_NET_RAW`** — grant it only when you enable those features. :::note The probe binary is a pure-Go static build (`CGO_ENABLED=0`) using an embedded SQLite, shipped in a small Alpine-based image alongside `cloudflared`. If your review needs the exact base image and capability set for a given release, ask [support](https://support.neuralconfig.com/probe-mcp?from=docs). ::: ## The privileged capabilities are opt-in The three things a security review usually asks about — capturing packets, opening SSH sessions to devices, and terminating TLS to a private controller — are **all disabled by default** and stay disabled until someone edits the probe's config on the host. So is the config-restore TFTP server, which serves bytes over cleartext UDP. A probe deployed and left alone collects telemetry and polls SNMP; it does none of those things. The full list, with the error each one returns while it's off, is in [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/#services-that-ship-disabled). ## Next steps - [API connections and the vault](https://docs.neuralconfig.com/probe-mcp/setup/connections/): How a secret is sealed to the probe end-to-end, and what break glass exposes. - [Linking with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/): Exactly which functions a linked companion system may call against your probe. - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): The keys that turn the privileged capabilities on, and their defaults. --- # Probe tools reference Source: https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/ Inside [`code_mode`](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/), Claude calls functions on a `probe` object. They fall into the groups below. Remember the split: **stored** functions work even when the probe is offline; **on-demand** functions reach live into the LAN and need the probe **Online**. **Some of these need a service turned on first:** Packet capture, SSH, reach-through, TFTP, flow collection, and the RUCKUS One LBS receiver ship **disabled** on the probe. The functions that depend on them are always callable in code mode and fail with a specific error until you enable them in the [config](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/) — they're marked below, and listed together in [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/#services-that-ship-disabled). ## Reference | Function | What it does | |---|---| | `get_reference` | Fetch bundled guides and playbooks (no argument lists available docs; a `doc`/`section` fetches a section). | ## Stored (offline-OK) Aggregates the engine already ingested — read even when the probe is offline. | Function | What it does | |---|---| | `list_probes` | List your probes with site, status, last heartbeat, and LAN IP. | | `probe_status` | One probe's latest status, heartbeat, and version. | | `list_devices` | Discovered device inventory (SNMP + discovery) with taxonomy. | | `syslog_rollups` | Syslog volume summary (average / peak events-per-minute) over a window. | | `snmp_metrics` | SNMP health rollup (CPU, memory, bandwidth) per device. A device that never answered the CPU or memory OID returns **`null`**, not `0` — see below. | | `top_talkers` | Top **20** source IPs by bytes, from sFlow. Empty unless the flow collector is enabled. | | `forward_status` | Whether this probe's telemetry is reaching a linked system, one entry per link. Reads cloud state, so it answers even when the probe is offline. | ## On-demand (probe must be Online) These proxy live to the probe over its tunnel. | Function | What it does | |---|---| | `query_syslog` | Live syslog query by severity / host / program / time (SNMP traps included). | | `search_syslog` | Full-text (FTS5) search of live syslog. Has its own small query syntax — see below. | | `snmp_get` | Live SNMP GET of specific OIDs. | | `snmp_walk` | Live SNMP WALK of a subtree. | | `poe_status` | Live PoE diagnostics (POWER-ETHERNET-MIB + RUCKUS ICX). | | `port_diag` | Live per-port health (IF-MIB) — status, speed, error counters. | | `query_flows` | Live individual sFlow records. **Needs `flow_collector.enabled`.** | | `topology` | Live L2 topology graph (LLDP + wireless associations). | | `inventory` | Live ground-truth LAN inventory with RUCKUS fingerprints. | | `reconcile_inventory` | Join a controller's cloud inventory against probe ground truth. | | `top_conns` | Top live packet-capture connections by bytes (Zeek-style). **Needs `pcap.enabled`.** | | `search_conns` | Free-text search of the live pcap connection table. **Needs `pcap.enabled`.** | | `pcap_query` | Slice the pcap ring buffer to a downloadable `.pcap`. **Needs `pcap.enabled`.** | | `auth_sessions` | Correlated 802.1X/EAPOL + RADIUS + DHCP access timeline. | | `https_forward` | Reach a private on-prem controller over HTTP (RFC1918 targets only). **Needs `reach_through.enabled`.** | | `serve_tftp` | Serve one config file over TFTP for a switch restore (lab/bench). **Needs `tftp.enabled`.** | | `stop_tftp` | Tear down the active TFTP serve. **Needs `tftp.enabled`.** | ### What `search_syslog` accepts Words and phrases are **literal**. A hyphen, colon, or quote inside a term is searched for, not parsed as syntax, so a program name like `snmp-trap-assoc` finds what you expect. On top of the literal text you can use: | Syntax | Meaning | |---|---| | `AND` · `OR` · `NOT` | Boolean operators. They must be **upper case** | | `( )` | Grouping | | `term*` | Prefix match | | `"exact phrase"` | Phrase match | Column filters (`program:foo`) and `NEAR` are deliberately **not** available — `query_syslog` already filters by program and hostname as arguments. A search containing nothing searchable (only punctuation) comes back with `search query has no searchable terms`. ### Why `snmp_metrics` can return `null` A `null` `avg_cpu_pct` or `avg_mem_pct` means **the device was asked and never answered** — most RUCKUS APs don't implement those OIDs. It does not mean zero load, and it must not be read as one. Each row also carries `cpu_unknown` and `mem_unknown`: the number of samples in the window where the value was missing. When only some samples are missing, the average is rescaled over the ones that were actually measured rather than diluted by the gaps. :::note Rows written before this behaviour shipped carry no such flag and read as measured, so a device can keep showing `0` until the older samples age out of the window. That is self-correcting, not a stuck value. ::: ## RUCKUS One LBS receiver The probe can run an embedded MQTT broker that RUCKUS One's Location Based Service reports into, which is the only source of **measured** client signal on the LAN. The receiver ships **off** and is switched on for you when R1-MCP registers an LBS source — see [Linking with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#telemetry-forwarding-to-r1-mcp). All three are on-demand and return `{ error: 'lbs_disabled' }` until it is wired. | Function | What it does | |---|---| | `lbs_status` | Receiver health: the broker, one entry per venue, and the frame counters. If the probe can't be reached, the last document it uplinked (at most 5 minutes old) comes back with `stale: true`. | | `lbs_clients` | Clients currently heard by RUCKUS APs, with per-chain RSSI, SNR, and PHY. Readings are kept for **5 minutes** only. | | `lbs_airtime` | Measured channel airtime per AP per band — average and peak busy percentage. Minute rollups are kept for **24 hours**. | **Three things these results are not:** **A row is an observation, not a client.** One client heard by three APs on two bands is up to six `lbs_clients` rows, so a row count is not a client count — take the distinct set of `client_mac` instead. The same applies to `lbs_airtime`'s `clients_avg`, which must never be summed across rows. **LBS is 2.4 and 5 GHz only.** There is no 6 GHz, so every client count from this source is a floor, not a total, and a quiet result is not a quiet radio environment. **`broker.healthy: true` does not mean data is arriving.** Read the counters: a venue is genuinely receiving only when its `state` is `receiving` *and* `totals.last_accepted_at` is recent. ## Forward links (R1-MCP only) These configure telemetry forwarding to a linked RUCKUS One deployment. R1-MCP calls them during source provisioning — they aren't functions you drive by hand, and they are on **R1-MCP's allowlist alone**, not the other companion systems'. | Function | What it does | |---|---| | `r1_forward_configure` | Register the complete source list for a link and provision the matching LBS credentials on the probe's broker. **Writes the probe's config**, and the list is whole-link: a source you omit stops being forwarded. | | `r1_forward_remove` | Stop forwarding one source, or tear down a whole link. Removing the last LBS source turns the receiver off entirely. | Both are idempotent, and the probe picks the change up on its next heartbeat — within **60 seconds**. ## API connections and vault Register upstream APIs Claude can call with a server-injected secret. See [API connections and the vault](https://docs.neuralconfig.com/probe-mcp/setup/connections/). | Function | What it does | |---|---| | `store_connection` | Register an upstream API connection (cloud / probe-vault / fallback secret modes). | | `list_connections` | List registered connections (never the secrets). | | `delete_connection` | Delete a connection and its probe-side vault secret. | | `vault_pubkey` | Fetch a probe's hybrid post-quantum vault recipient keys (P-256 + ML-KEM-768). | | `provision_vault_secret` | Deliver a secret to the probe vault as an end-to-end sealed envelope. | | `connection_egress` | Make an authenticated call to an upstream API, secret injected server/probe-side. | ## Device CLI (SSH over the tunnel) All of these except `store_device_credential` **need `ssh.enabled`** on the probe, which is off by default. | Function | What it does | |---|---| | `store_device_credential` | Store an SSH credential (AES-256-GCM at rest). | | `device_cli` | Open a persistent SSH session to a device; returns a `session_id`. Five concurrent sessions, reaped after 600 s idle. | | `ssh_send` | Send input to an open SSH session. | | `ssh_read` | Read accumulated output from an SSH session. | | `ssh_close` | Close an SSH session and finalize its recording. | | `run_device_cli` | RUCKUS-aware batch CLI to an ICX switch or AP — up to 8 commands, 256 KB of output. | ## Report | Function | What it does | |---|---| | `generate_scorecard` | Render a co-branded assessment/scorecard PDF from findings; returns a shareable URL. | :::note You don't call these by name in chat — you ask Claude for an outcome and it picks the functions. The [workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/) package the common flows. ::: ## Next steps - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): Row caps, size caps, and timeouts for each of these functions, plus the services that ship disabled. - [How code mode works](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/): What happens inside code_mode, and why stored functions survive a probe outage. - [Workflow prompts](https://docs.neuralconfig.com/probe-mcp/reference/prompts/): The two guided flows that call these functions for you from Claude's + menu. --- # Workflow prompts Source: https://docs.neuralconfig.com/probe-mcp/reference/prompts/ Probe MCP serves a small set of **MCP prompts** — guided workflows that appear in Claude's **+** menu on surfaces that support them. Each fills in the right `code_mode` calls for you; you just supply a few arguments. ## `assessment_scorecard` — Network Assessment Scorecard (PDF) Scans a probe's syslog, SNMP, and sFlow, ranks findings **red / yellow / green**, and renders a **co-branded PDF** you can hand to a customer. This is the flagship deliverable — the demo, the assessment artifact, and the install-acceptance report in one. All arguments are optional: | Argument | Purpose | |---|---| | `probe` | Which probe to assess (defaults to your probe if you have one). | | `window` | Time window to assess over. | | `company` | Your company name, for co-branding. | | `prepared_for` | The customer / recipient name on the report. | | `email` | Where to send or associate the report. | The report renders server-side and comes back as a shareable URL. ## `explore_probe` — Explore what my probe can see A **read-only** orientation: Claude tours what the probe is collecting — syslog volume, discovered devices, SNMP health, top talkers, topology — without writing anything or generating a report. Good for a first look at a new site. Arguments (optional): | Argument | Purpose | |---|---| | `probe` | Which probe to explore. | | `goal` | A focus for the tour (e.g. "find noisy devices"). | ## If the prompts don't appear MCP prompts only show on Claude surfaces that support them. If you don't see the **+** menu entries, confirm the [connector is authorized](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/) and that you're on a surface that supports MCP prompts. You can always ask for the same outcomes in plain language instead. Both prompts are **on demand** — you run them when you want them. Neither can be scheduled, and neither sends anything on its own. ## Next steps - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): The probe.* functions these prompts call on your behalf. - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): Caps that apply to a scorecard run, including the 50-finding limit per report. - [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/): Getting the connector authorized so the + menu entries appear. --- # Limits and budgets Source: https://docs.neuralconfig.com/probe-mcp/reference/limits/ Every limit that can end a Probe MCP request, in one place. Most only bite when you ask Claude for something broad — "search every log message this week", "walk every switch" — which is exactly the case worth knowing about in advance. If a call came back empty or with an error and you want to know *why*, start with [services that ship disabled](#services-that-ship-disabled): a function that exists but was never enabled on the probe is the most common surprise. ## The `code_mode` run | Limit | Value | What happens when you hit it | |---|---|---| | Wall-clock budget | **30 seconds** | The run returns `{ error: 'timeout' }`. Work already done is lost | | Tunnel round-trip | **10 seconds** per on-demand call | That one call resolves with an error; the rest of the program keeps running | Each `code_mode` invocation gets a **fresh** 30-second budget — the limit is per-run, not per-conversation, so a follow-up question starts over. The two timeouts compose badly on purpose: three slow on-demand calls in sequence can spend the whole 30-second budget by themselves. Stored functions (`list_probes`, `syslog_rollups`, `snmp_metrics`, `top_talkers`, `list_devices`, `probe_status`) don't cross the tunnel and are far cheaper — see [stored vs. on-demand](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/#stored-vs-on-demand--the-important-split). :::tip Ask for one scope at a time — one probe, one switch, one hour. Claude will happily write a program that walks every device on the LAN, and that program is the one that times out. ::: ## Services that ship disabled Several `probe.*` functions depend on a probe service that is **off by default**. The function is always present in code mode; it fails at the probe with a specific error until you enable it in [`/etc/probe-mcp/probe.yaml`](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/). | Functions | Needs | Default | Error until enabled | |---|---|---|---| | `top_conns`, `search_conns`, `pcap_query` | `pcap.enabled` (plus `CAP_NET_RAW`) | **Off** | `pcap disabled` | | `device_cli`, `ssh_send`, `ssh_read`, `ssh_close`, `run_device_cli` | `ssh.enabled` | **Off** | `ssh proxy disabled` | | `https_forward` | `reach_through.enabled` | **Off** | `reach_through disabled` | | `serve_tftp`, `stop_tftp` | `tftp.enabled` | **Off** | `tftp disabled` | | `query_flows` | `flow_collector.enabled` | **Off** | `flow collector not enabled` | | `lbs_status`, `lbs_clients`, `lbs_airtime` | `lbs.enabled` | **Off** | `lbs_disabled` | Syslog, SNMP polling, SNMP traps, discovery, the vault, and the rollup engine are all **on** by default and need no configuration. The LBS receiver is the one row you don't set by hand: it is switched on for you when R1-MCP registers an LBS source against the probe, and off again when the last one is removed. See [Linking with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#telemetry-forwarding-to-r1-mcp). `top_talkers` is the exception to the pattern above. It's a **stored** function reading aggregates the engine already holds, so with the flow collector off it returns an empty list rather than an error — there was never any sFlow to aggregate. An empty `top_talkers` and a failing `query_flows` have the same cause. ## Per-function caps ### Row limits Every list-shaped function accepts a `limit`, and each has its own ceiling. Ask for more and the argument is rejected rather than silently truncated. | Function | Default rows | Maximum | |---|---|---| | `query_syslog`, `search_syslog`, `query_flows` | 100 | **1,000** | | `list_devices`, `search_conns`, `auth_sessions` | 100 | **500** | | `top_conns` | 50 | **500** | | `inventory` | all | **2,000** | | `reconcile_inventory` | — | **5,000** devices in the controller list you pass it | | `generate_scorecard` | — | **50** findings per report | | `top_talkers` | **20** — fixed | not adjustable | | `lbs_clients` | 500 | **5,000** | ### Windows and sizes | Function | Limit | Value | |---|---|---| | `topology` | Wireless association look-back (`withinHours`) | default 24 h, max **720 h** (30 days) | | `inventory`, `reconcile_inventory` | "Seen alive within" (`aliveWithinSecs`) | default 300 s, max **86,400 s** | | `pcap_query` | Packets per slice | default and max **50,000**, capped at **64 MiB** | | `pcap_query` | Time window | defaults to the **last 5 minutes** | | `https_forward`, `connection_egress` | Upstream timeout (`timeoutMs`) | caller-set, capped at **9 s** | | `https_forward` | Response body | probe-side cap of **8 MiB** (`reach_through.max_bytes`) | | `connection_egress` | Response body | **8 MiB** | | `serve_tftp` | Serve window (`ttlSec`) | **clamped to the probe's `tftp.ttl_sec`** — 300 s by default; `ttlSec` above 900 is rejected outright | | `serve_tftp` | Config file size | **1,024 KB** (`tftp.max_kb`) | | `device_cli` | Terminal geometry | up to **500** columns × **300** rows | | `ssh_read` | Wait for new output (`waitMs`) | default 1,000 ms, max **8,000 ms** | | `run_device_cli` | Commands per batch | **8** | | `run_device_cli` | Output captured | **256 KB** | | `lbs_clients` | Look-back (`withinSecs`) | default 30 s, max **300 s** | | `lbs_airtime` | Window (`windowMin`) | default 60 min, max **1,440 min** (24 h) | The 9-second upstream cap and the 10-second tunnel round-trip are deliberately close: a reach-through call that needs longer than 9 seconds would outlive the tunnel call carrying it. ## Concurrency and storage on the probe | Resource | Limit | Config key | |---|---|---| | Concurrent SSH sessions | **5** | `ssh.max_sessions` | | SSH idle timeout | **600 s**, then the session is reaped | `ssh.idle_timeout_sec` | | TFTP serves | **one file, one client** at a time — a second `serve_tftp` returns `serve_failed` until you `stop_tftp` | — | | TFTP serve window | default and ceiling are the **same key** — asking for longer than `tftp.ttl_sec` silently gets you `tftp.ttl_sec` | `tftp.ttl_sec` | | Vault entries | **128** | `vault.max_entries` | | Packet-capture ring buffer | **1 GiB**, oldest packets overwritten | `pcap.ring_bytes` | | Offline upload buffer | **256 MB** | `buffer.max_size_mb` | An SSH session that goes idle for ten minutes is closed underneath you — a later `ssh_send` returns `session_not_found`. Open a new session rather than treating it as an error. ## How long data is kept Retention is enforced **on the probe**, not in the cloud. Once a window has aged out, no query can recover it. | Data | Kept for | Also capped at | |---|---|---| | Syslog and SNMP-trap events | **168 hours** (7 days) | **1 GiB** | | Flow aggregates | **24 hours** | — | | Individual flow records | **6 hours** | **500 MB** | | Packet capture | until the ring buffer wraps | **1 GiB** | | LBS client readings | **5 minutes** | — | | LBS airtime rollups (per minute) | **24 hours** | — | :::caution The LBS windows are much shorter than everything above them. `lbs_clients` answers "where is this client **now**", not "where was it this morning" — a reading five minutes old is already gone, and there is no history to fall back on. ::: Whichever limit is reached first wins — a chatty network hits the 1 GiB event cap well before seven days. Aggregates shipped to the engine (syslog rollups, SNMP health, top talkers) are the part that survives, which is why those queries still answer questions about last week when a raw search can't. ## How fast a dead probe is noticed A probe showing **Online** in the dashboard is not proof it is reachable *right now*, and the gap is large enough to confuse a live call. | Event | Timing | |---|---| | Probe heartbeat | every **60 seconds** | | Silence before a probe counts as offline | **180 seconds** (three missed heartbeats) | | Sweep that flips the status | every **5 minutes** | `lbs_status` is the one function that still answers from cache when the probe is unreachable: the last document the probe uplinked is served for up to **5 minutes**, marked `stale: true` with an `age_s`. Read a stale body as history — a stale `state: 'receiving'` says the venue *was* receiving when the probe last spoke, which is necessarily before it went quiet. With nothing cached you get `probe_offline` like everything else. So a probe that dies can keep showing **Online** for up to roughly eight minutes. During that window an on-demand call doesn't return `probe_offline` — it returns **`probe_unreachable`**, which means the tunnel has no healthy origin. Both mean the same thing for you: the probe isn't answering. See [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/#error-vocabulary). ## Next steps - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): Every probe.* function, which ones are stored versus on-demand, and which need a service enabled. - [Configuring the probe](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/): Turn on the services that ship disabled — flow collection, packet capture, SSH, reach-through, and TFTP. - [Troubleshooting](https://docs.neuralconfig.com/probe-mcp/troubleshooting/): What each error code means, including the ones a disabled service returns. --- # Linking with R1-MCP Source: https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/ Probe MCP is a **companion** to the RUCKUS MCP servers. Linking your Probe MCP account to [R1-MCP](https://docs.neuralconfig.com/r1-mcp/) lets R1-MCP's Claude reach the on-LAN ground truth a cloud controller can't see — local inventory, live device CLI, and switch config restore — using your probe. ## The link is started from the R1-MCP side This is the part people get backwards: **you begin in R1-MCP, not here.** The consent link carries R1-MCP's signed identity assertion, so it can only be minted on the R1-MCP side. Your Probe MCP probes list shows a note saying the same thing; it is informational, and there is no button here that starts a link. 1. Open your **[R1-MCP dashboard](https://r1-mcp.lanpulse.com)** and enable the **Test Bed Manager** feature. 2. In the **Probe (config restore)** card, click **Connect probe-mcp**. 3. You land on Probe MCP's link page. If you aren't signed in, sign in with **Google**. 4. Review the two identities shown — your R1-MCP account and your Probe MCP account — and click **Connect accounts**. That's it. The link is **one-time** and **revocable**. ## Why two identities are shown The link is gated by two independent facts: a **signature** proving a trusted sibling (R1-MCP) vouched for that external identity, and your **live Probe MCP session** proving you own the Probe MCP account. Both must line up, so the consent page shows you both sides before you approve. ## What the link grants Once linked, R1-MCP's Claude — acting for your linked identity — can call **36 of the 43** [probe functions](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/) against your probe. The allowlist is deny-by-default: everything that mutates your account or produces a shareable artifact is held back. **Included**, and worth knowing about before you approve: - All the **stored** and **on-demand read** functions — inventory, syslog, SNMP, flows, topology, PoE, pcap, and access sessions. - **`https_forward`** and **`connection_egress`**, so R1-MCP's Claude can reach a private on-prem controller through your probe and make authenticated upstream calls with a secret it never sees. - **The SSH device CLI** — `device_cli`, `ssh_send`, `ssh_read`, `ssh_close`, and `run_device_cli`. This is not read-only: the grant permits a linked R1-MCP session to run commands on switches and APs using credentials you already stored. It still needs `ssh.enabled` on the probe, which is [off by default](https://docs.neuralconfig.com/probe-mcp/reference/limits/#services-that-ship-disabled). Read this as a **permission**, not as today's behaviour: R1-MCP currently exposes only 15 read-only tools of the 36 to its model, and the CLI is not among them. Widening that needs no change here, though — which is why the allowlist, not R1-MCP's current surface, is what you are approving. - **`serve_tftp` / `stop_tftp`** for config restore — granted to R1-MCP **only**, not to the other companion systems. - **The forward-link pair, `r1_forward_configure` and `r1_forward_remove`** — also R1-MCP only. These are the one part of the grant that **writes**: they rewrite the `lbs` block of your probe's config to add or remove venue credentials, and switch the LBS receiver on and off with them. Everything else a linked system can reach either reads, or acts on a device with a credential you stored — this changes the probe's own configuration. **Held back**, first-party to your own Probe MCP session: `generate_scorecard`, `get_reference`, `store_connection`, `delete_connection`, `vault_pubkey`, `provision_vault_secret`, and `store_device_credential`. A linked system can *use* a stored credential or connection; it cannot create, replace, or delete one. ## Config restore over TFTP — what it needs The reason the TFTP pair exists: once RUCKUS One ages out a switch backup, there is no cloud API left to re-inject it. A Worker can't help — it speaks HTTPS to a hostname, not UDP to a LAN address — so the probe serves the saved config on the switch's own LAN and the switch pulls it with `copy tftp startup-config`. Linking the accounts is necessary but **not sufficient**. The restore also needs: - **`tftp.enabled: true`** in the probe's [config](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/). It is **off by default**, and `serve_tftp` returns `tftp disabled` until you turn it on. - **The probe on the same LAN as the switch**, since the switch is given the probe's LAN IP to fetch from. What the probe serves is deliberately narrow: **one file, one client, read requests only**, held **in memory and never written to disk**, size-capped at 1,024 KB, its SHA-256 verified before the first byte goes out, and torn down automatically when the window expires. That window is **`tftp.ttl_sec`, which is both the default and the ceiling** — 300 seconds out of the box. Asking `serve_tftp` for a longer window doesn't extend it; you get `tftp.ttl_sec` regardless. Raise the config key if a restore genuinely needs longer. :::caution **TFTP is cleartext and unauthenticated.** For the length of the serve window, anything on that LAN can request the file, and a switch config carries secret material. This is built for a lab or bench test bed — call `stop_tftp` as soon as the copy finishes rather than waiting for the TTL. ::: ## Telemetry forwarding to R1-MCP The link has a second half that isn't a tool call at all. Once R1-MCP registers **sources** against your probe, matching telemetry is forwarded to it as it arrives, with no round trip through Claude. Three source kinds exist — `lbs`, `syslog`, and `snmp` — and R1-MCP handles the LBS ones today. Registering an LBS source is what switches the probe's **LBS receiver** on: the call provisions that venue's credentials on the probe's embedded MQTT broker and sets `lbs.enabled`. Removing the last one turns it off again. The probe applies either change on its next heartbeat, within **60 seconds**. You don't edit the `lbs` block yourself — your own settings in it (port, bands, reporting interval) are carried through untouched. ### Checking the forward is alive `forward_status` reports one verdict per link. **Read the verdict, not the timestamp:** | Verdict | Means | |---|---| | `ok` | Forwarding, and the last attempt was accepted | | `faulted` | The last forward was refused. `lastError` says whether the whole link is being rejected or only some sources | | `silent` | Something was forwarding and stopped | | `never_forwarded` | Nothing has ever been sent. Not the same as `silent` — nothing was configured, versus something that was and quit | | `disabled` | Turned off deliberately | `silent` is the one no other signal can see. Every other health check on either side needs a message to *arrive* before it can report anything, so a probe that simply stops forwarding trips none of them. A link counts as silent after **600 seconds** without a successful forward. :::note Every verdict here is about what **this** system sent, never about what arrived. R1-MCP answers the receiving half separately, using the same words for different claims. `ok` here with nothing showing there points at the network or the URL between them — not at the probe, and not at the ingest. ::: ## Moving a link between accounts If the R1-MCP identity is already linked to a **different** Probe MCP account, the link is refused unless you explicitly confirm the move (a checkbox that warns the other account loses access). Re-linking the same pair just shows "already connected." ## Revoke a link From the Probe MCP dashboard, view your links and delete the one you want to revoke. Every link, owner-move, and revoke is recorded in an audit trail. :::note `sz-mcp`, `cp-mcp`, and the coordinator are registered as potential companions, but only **R1-MCP** is a live caller today. The other three get a smaller allowlist — **31 functions**, the shared read and egress surface — without the TFTP pair, the forward-link pair, or `forward_status`. Serving a switch config on your LAN is deliberately R1-MCP's Test Bed Manager alone, and the forward links are R1-MCP's own relationship with your probe. ::: ## Next steps - [Probe tools reference](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/): The full catalog of probe.* functions, so you can see exactly what the allowlist covers. - [Security model](https://docs.neuralconfig.com/probe-mcp/concepts/security/): How the link is authenticated — per-system signing keys, rotation, and the audit trail. - [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/): The TFTP serve window and size cap, and the services a linked caller still needs enabled. --- # Troubleshooting Source: https://docs.neuralconfig.com/probe-mcp/troubleshooting/ ## Activation fails on first start The probe activates once, on first start, using the single-use code. Common exact errors and what they mean: | Error in the probe logs | Cause / fix | |---|---| | `not activated and no activation code provided (set ACTIVATION_CODE)` | The container started with no code and no saved credentials. Use the dashboard's [Docker command](https://docs.neuralconfig.com/probe-mcp/setup/deploying-the-probe/), which sets `ACTIVATION_CODE`. | | `activation failed: HTTP ` | The code was wrong, already used, or expired. Mint a **New activation command** from the probes list. | | `activation request: ` | The probe can't reach the engine. Check outbound internet from the host. | | `activation response missing required fields` | The engine returned incomplete credentials — retry with a fresh code; contact [support](https://support.neuralconfig.com/probe-mcp?from=docs) if it persists. | | `create data dir` / `write shared-secret` / `persist activation state` | The data directory isn't writable. Ensure the `/var/lib/probe-mcp` volume is mounted and writable. | :::caution The activation code is **single-use**. If you recreate the container without persisting the `/var/lib/probe-mcp` volume, its saved credentials are gone and re-activation fails. Always keep the volume; if it's lost, re-activate with a new code. ::: ## The probe never shows Online - Confirm the container is running (`docker ps`) and check its logs (`docker logs probe-mcp`). - The tunnel is outbound — confirm the host has outbound internet. - A probe stuck **pending** in the dashboard usually never finished activation — mint a new activation command and redeploy. A probe moves through three states. It starts **pending** at enrollment, becomes **online** when it activates and sends its first heartbeat, and is flipped back to **offline** by a scheduled sweep once it has gone silent — heartbeats are sent every 60 seconds, three missed ones (180 seconds) count as silent, and the sweep runs every 5 minutes. A probe that recovers goes straight back to **online** on its next heartbeat, with no re-activation. ```mermaid stateDiagram-v2 [*] --> pending: Enroll a probe in the dashboard pending --> online: Activation succeeds, first heartbeat pending --> pending: Activation fails (mint a new code) online --> online: Heartbeat every 60s online --> offline: Silent 180s, caught by the 5-minute sweep offline --> online: Heartbeat resumes ``` ## Online in the dashboard, but calls still fail The status you see can lag reality by several minutes: silence has to last 180 seconds, and only the next 5-minute sweep writes the change. During that gap the dashboard still says **Online** while nothing is answering. You can tell the two cases apart by the error Claude reports: - **`probe_offline`** — the engine already knows the probe is down and refuses to proxy the call at all. - **`probe_unreachable`** — the engine believed the probe was up, tried the tunnel, and found no healthy origin behind it. This is the lag window. Both mean the same thing in practice. Check the container on the LAN host rather than trusting the dashboard's status. ## Ask the probe what's wrong with it first Before you go hunting, check `probe_status`. The probe reports faults about itself on every heartbeat, and the engine turns them into a `findings` list: > Using Probe MCP, run probe_status on my probe and tell me what findings it > reports. `status: 'online'` only means the probe is talking to us. A service inside it can be running and discarding every packet it receives, which is exactly what `findings` catches: | Finding | What it means | |---|---| | `config_rejected` | The probe **refused part of the config it was sent** and is still running its previous values for the named blocks. It repeats this every heartbeat until a valid document replaces it, so it is current, not historical | | `snmp_traps_discarded` | The trap listener is receiving traps and accepting **none**. An empty trap history is the listener, not a quiet network — the community doesn't match | | `snmp_traps_partially_discarded` | Traps are being accepted, but **some senders are rejected** on community. Those devices' events are missing from an otherwise healthy-looking history. The finding names the senders; read the community off those devices and add it to `snmp_trap.communities` | | `wal_backlog` | Upload segments are queued and not draining. Steady state is 0; a figure that doesn't fall across heartbeats means the tunnel is down or the drainer is wedged | :::caution An empty `findings` list is not a clean bill of health if `reported_health` is `null`. That means **this probe build doesn't report any of it** — "does not say", never "is fine". Upgrade the container to get the signal. ::: ## No telemetry is arriving - **Wrong target** — devices must send to the probe's **LAN IP** (shown on the probes list), not to a controller. - **Collector off** — syslog and SNMP traps are on by default, but **sFlow and NetFlow are not**. Enable `flow_collector` in the [config](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/) before pointing exporters at 6343/2055. - **Wrong port** — syslog is 514 (UDP and TCP), SNMP traps 162/UDP, sFlow 6343/UDP, NetFlow 2055/UDP. See [Pointing your network at the probe](https://docs.neuralconfig.com/probe-mcp/setup/sending-telemetry/). - **SNMP polling** — the probe polls devices outbound on 161; the device must allow SNMP from the probe's IP and the community/version must match. ## The connector won't authorize in Claude - **Redirect loop** — a cookie problem on the Google hop. Use a normal (non- private) window and allow cookies for `probe-mcp.lanpulse.com`, then re-add the connector. - **"Not authenticated" on every call** — the token was revoked or the connector was added before sign-in finished. Remove and re-add it. See [Connecting to Claude](https://docs.neuralconfig.com/probe-mcp/setup/connecting-claude/). ## `code_mode` times out or says a probe is offline - **`{ error: 'timeout' }`** — the run hit its 30-second budget. Ask for a narrower scope (one device, a shorter window) rather than everything at once. - **`probe_offline`** — you asked for **on-demand** live data (SNMP, live syslog, topology, pcap, SSH) but the probe isn't reachable. Stored rollups still work; the live queries need the probe [Online](https://docs.neuralconfig.com/probe-mcp/concepts/how-code-mode-works/). Bring the probe back up and retry. See [Limits and budgets](https://docs.neuralconfig.com/probe-mcp/reference/limits/) for the full set of timeouts, row caps, and size caps a broad request can run into. ## A function exists but says it's disabled Several probe services ship **off** and are enabled in the probe's [config](https://docs.neuralconfig.com/probe-mcp/setup/configuring-the-probe/). The function is always callable in code mode; it's the probe that refuses. Set the key, restart the container, and retry. | Error | Enable | Affects | |---|---|---| | `pcap disabled` | `pcap.enabled: true` (plus the `CAP_NET_RAW` capability) | `top_conns`, `search_conns`, `pcap_query` | | `ssh proxy disabled` | `ssh.enabled: true` | `device_cli`, `ssh_send`, `ssh_read`, `ssh_close`, `run_device_cli` | | `reach_through disabled` | `reach_through.enabled: true` | `https_forward` | | `tftp disabled` | `tftp.enabled: true` | `serve_tftp`, `stop_tftp` | | `flow collector not enabled` | `flow_collector.enabled: true` | `query_flows` | | `lbs_disabled` | Registered by R1-MCP, not set by hand — see [Linking with R1-MCP](https://docs.neuralconfig.com/probe-mcp/linking-with-r1-mcp/#telemetry-forwarding-to-r1-mcp) | `lbs_status`, `lbs_clients`, `lbs_airtime` | | `discovery disabled` | `discovery.enabled: true` (on by default) | `inventory`, `topology` | ## Error vocabulary Every `probe.*` call returns a structured result rather than throwing, so a failure arrives as an `error` field your question comes back quoting. The ones worth recognizing: | Error | Means | |---|---| | `probe_offline` | The engine knows the probe is down and didn't attempt the call | | `probe_unreachable` | The tunnel has no healthy origin — the probe died and the status hasn't caught up | | `probe_not_found` | No probe with that id on your account. Re-check with `list_probes` | | `probe_error` | The probe answered, but with a failure it didn't classify | | `lbs_disabled` | The RUCKUS One LBS receiver isn't wired on this probe | | `search query has no searchable terms` | A `search_syslog` term was all punctuation. See [what the search accepts](https://docs.neuralconfig.com/probe-mcp/reference/probe-tools-reference/#what-search_syslog-accepts) | | `timeout` | The 30-second `code_mode` budget ran out | | `metrics_unavailable` | The stored-aggregate query failed. Affects `snmp_metrics`, `top_talkers`, `syslog_rollups` | | `host_forbidden` / `endpoint_forbidden` | The target isn't a private LAN address, or isn't on the reach-through allowlist | | `connection_not_found` / `connection_inactive` | The connection id is wrong, or the connection has been deactivated | | `not_a_vault_connection` | A vault operation was aimed at a `cloud`-mode connection | | `no_cloud_secret` | A `probe_vault` connection was called while the probe was down, with no break-glass copy in place. See [break glass](https://docs.neuralconfig.com/probe-mcp/setup/connections/#break-glass--temporary-cloud-access) | | `credential_not_found` / `credential_required` | No SSH credential is stored for that device | | `session_not_found` | The SSH session was closed, or was reaped after 600 seconds idle. Open a new one | | `serve_failed` | A TFTP serve is already active. Call `stop_tftp` first | | `render_failed` / `storage_failed` | The scorecard PDF couldn't be rendered or stored | ## Still stuck? Contact [support](https://support.neuralconfig.com/probe-mcp?from=docs) with your probe's site name and the exact error text from `docker logs probe-mcp`.