Skip to content

MCP server

Yagra can expose an opt-in MCP tool surface so an AI client — Claude Code, Claude Desktop, or another MCP-capable assistant — can query live monitoring state in natural language: “which nodes are down?”, “summarize the active alerts”, “show CPU on edge-router-1 for the last hour”, “run anomaly detection and tell me what looks wrong”.

The server exposes 34 tools: 31 read, 3 write. The read tools see the same data the WebUI does, and the Troubleshoot trio runs the same on-demand analyses the WebUI runs — they only read stored history and return findings. The three write tools act on the monitoring system, never on the network itself: there are no tools that configure or change network devices, by design.

The guiding rule is read parity: whatever the WebUI can see, an MCP client can see. A new read endpoint ships with its tool, or with a written reason it has none. That rule deliberately does not extend to writes — the write surface stays frozen at the three below.

Tool What it does Minimum role
get_fleet_summary Fleet health summary: node counts per state, active alert count Viewer
list_nodes List nodes with rolled-up state, with search Viewer
get_node_status Full status for one node: summary, active alerts, interfaces Viewer
list_node_groups The folder tree, with map coordinates and optional per-folder health tallies Viewer
get_active_alerts Active alerts, newest first, filterable by node and severity Viewer
get_alert_history Recent alert fires and clears, with paging Viewer
alert_trends How alerting behaves over time: chronic offenders, recent transitions, or a weekday×hour heat map Viewer
list_suppressions Maintenance windows and mutes — what is currently silencing alerts Viewer
query_metrics A node’s metric time series — latest value, a range, or a rate Viewer
get_interface_series One interface’s traffic and error history, aligned on a shared time axis Viewer
top_metrics Rank nodes fleet-wide by any metric Viewer
top_interfaces Rank interfaces fleet-wide by throughput, errors, discards or biggest change Viewer
fleet_throughput Aggregate fleet traffic over a window Viewer
get_neighbors What a node is cabled to (CDP/LLDP), current and as a change log Viewer
get_topology kind= the dependency graph with root-cause attribution, the derived connectivity links, the operator overrides on them, or the shadow comparison Viewer
list_discovered_endpoints Hosts seen on the network that nothing is monitoring, from router ARP caches Viewer
top_flows Top flows for one node or the whole fleet: talkers, conversations, ports, protocols, AS Viewer
flow_fanout Per-source fan-out — distinct destinations and ports (a scan/worm signal) Viewer
search_events Search passive events: syslog, traps, webhooks Viewer
event_stats Passive-event triage stats: noisiest nodes, severity mix, unmatched signatures Viewer
run_analysis Run an on-demand Troubleshoot analysis and wait for findings Operator
get_analysis_findings Fetch an analysis run and its findings by id Viewer
list_analyses List recent analysis runs, or the recurring schedules Viewer
search_analysis_findings Search Troubleshoot findings across every run, by node, folder, severity or time Viewer
get_system_health section= Yagra’s own state: the poller fleet, poll-loop counters, which poller holds which nodes, recent core↔poller outages, per-store reachability, host resources, forwarding delivery, whether stored credentials still decrypt, the running version, and which optional tiers are on Viewer¹
get_report_runs Recent report runs and their outcomes Viewer
get_audit Who changed or acknowledged what View-audit
get_config kind= Yagra’s own configuration, over 28 reads: thresholds, event rules and sources, notification channels and routing rules, profiles and collection templates, a node’s collected metrics, classification rules, the MIB catalog, a node’s URL/DNS check, discovery candidates and scans, Meraki orgs/networks/polling, forwarding destinations, report definitions and schedules, and the retention / adjacency / LLM / roles / OIDC / LDAP settings Varies²
fleet_state_history How the fleet’s state mix moved over a window Viewer
get_dns_chain The resolution chain behind a DNS monitor Viewer
run_rca An LLM explanation of one incident — the same one the WebUI’s “Explain this incident” produces Operator
ack_alert Write. Acknowledge (or clear the ack on) an active alert Operator
open_maintenance Write. Open a maintenance window for one node Operator
poll_now Write. Trigger an immediate out-of-schedule poll of one node Admin

Every write — and every launched analysis — is recorded in the audit log, attributed to the token that made it.

¹ get_system_health sections require different permissions, matching the WebUI exactly: most need view, forwarding status needs manage-config, and credential health needs manage-credentials. Read-only does not mean readable-by-anyone. Report runs and the state timeline refuse a group-scoped token rather than showing it the whole fleet, exactly as the REST endpoints do.

² get_config works the same way, per kind — each one demands the permission its REST counterpart demands, so a Viewer is served the role matrix and refused the threshold ruleset from the same tool: manage-users for OIDC and LDAP, manage-config for fourteen of them, and view for the rest. No stored secret is returned — a node’s URL check reports whether a credential is bound (has_credential), never which one.

Off by default. Set YAGRA_ENABLE_MCP=true for core (uncomment it in docker-compose.yml, or add it to your .env for the deploy compose) and restart. The endpoint is then served on the API port at:

https://<yagra-host>/mcp # through the WebUI's TLS edge (preferred)
http://<yagra-host>:8080/mcp # core's API port directly, plaintext

Both work, and both speak the Streamable HTTP transport. Prefer the first — the WebUI container proxies /mcp to core, so the connection is encrypted. While a deployment is still on its self-signed bootstrap certificate, a client that cannot be told to trust it has to fall back to core’s plaintext port; importing a real certificate at Settings ▸ TLS is what makes the TLS URL usable everywhere. When MCP is disabled the path is not mounted (404), byte-identical to before. MCP always requires authentication, even if the public-dashboard option is on.

Authentication is the gate, so the server accepts any Host header by default. To additionally pin the hostnames clients may use, set YAGRA_MCP_ALLOWED_HOSTS to a comma-separated list.

The server’s own activity shows up in core’s Prometheus metrics: tool calls are counted per tool and outcome, and authentication failures separately — so an assistant hammering the endpoint, or a revoked token still being tried, is visible the same way everything else in Yagra is.

Sign in to the WebUI as an admin → Settings ▸ API tokens ▸ New token → choose a role → copy the yat_… value shown once. This is the bearer token the AI client sends.

  • Viewer — a read-only assistant: every read tool works, except run_analysis. Running a Troubleshoot analysis is an Operator action (the same permission that acknowledges alerts), so a Viewer token can browse past runs and findings but cannot launch new ones.
  • Operator — everything above, plus launching analyses, acknowledging alerts (ack_alert), and opening maintenance windows (open_maintenance).
  • Admin — everything, including poll_now, which takes the same permission as any other change to what and when Yagra polls.

A token can also be limited to node groups, and every tool honours it: lists and searches come back narrowed, rankings and histories are filtered, and a tool asked about a node outside the scope answers exactly what it answers for an id that does not exist. One view is deliberately omitted rather than narrowed — event_stats’ unmatched-signature ranking is aggregated across nodes and keeps no attribution to filter by, so a scoped token gets it back empty with a note saying why. Roles, permissions and scoping are described in Users & SSO.

A regular login session token from the REST API works too, but it expires; an API token is meant for an unattended client and is revocable from the same page.

Claude Code (CLI or VS Code extension) — use --scope user so the server is available in every project and directory:

Terminal window
claude mcp add --scope user --transport http yagra http://<yagra-host>:8080/mcp \
--header "Authorization: Bearer yat_your_token"

Without --scope user, claude mcp add defaults to local scope — the CLI sees it, but the VS Code extension does not load local-scope servers (it reads user-scope and project .mcp.json servers only), so /mcp in the extension won’t show it. MCP servers are also loaded at session start, so reload the window / start a new session after adding. Then /mcp should list yagra as connected; ask it to list nodes or summarize alerts.

Claude Desktop — Desktop bridges to a remote HTTP server via the mcp-remote helper. Add this to claude_desktop_config.json (Settings ▸ Developer ▸ Edit config), then restart Desktop:

{
"mcpServers": {
"yagra": {
"command": "npx",
"args": [
"-y", "mcp-remote", "http://<yagra-host>:8080/mcp",
"--header", "Authorization: Bearer yat_your_token"
]
}
}
}

Gemini CLI — add the server to ~/.gemini/settings.json (or a project-local .gemini/settings.json). The httpUrl key selects the Streamable HTTP transport:

{
"mcpServers": {
"yagra": {
"httpUrl": "http://<yagra-host>:8080/mcp",
"headers": { "Authorization": "Bearer yat_your_token" }
}
}
}

Restart gemini, then /mcp lists the Yagra tools. Gemini Code Assist (VS Code) reads the same settings.json.

claude.ai (web) / Team / Enterprise — add Yagra as a Custom Connector (Settings ▸ Connectors). This requires the /mcp endpoint to be reachable from Anthropic’s servers, i.e. a public HTTPS URL (e.g. front it with a reverse proxy or a Cloudflare Tunnel) — a LAN/VPN-only address won’t work here. The same public-HTTPS requirement applies to the Gemini web app / Vertex AI agent connectors.

Any MCP client / quick check with curl — the transport is plain JSON-RPC over HTTP, so you can smoke-test without a client:

Terminal window
curl -sN http://<yagra-host>:8080/mcp \
-H "Authorization: Bearer yat_your_token" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The AI client makes the HTTP call from your machine, not from the model provider’s cloud — a desktop or CLI assistant only needs network access to <yagra-host>:8080, over the same LAN or a VPN. No public inbound exposure is required unless you want a hosted connector (the claude.ai web app, or the Gemini web app / Vertex AI agents), which must reach /mcp over public HTTPS as noted above.

  • Tool results become conversation context. The AI reads live monitoring data — node names, addresses, alerts — and for a cloud-hosted assistant that data is sent to the model provider you connected. Treat tool output as you would any data leaving your boundary.
  • Device credentials are never included in any tool result. SNMP communities, SNMPv3 credentials, and poll-target API keys stay encrypted at rest and are excluded from every response shape.
  • Keep the token least-privileged. A Viewer token is the right default for an assistant that only answers questions; grant Operator only when you want it acting on alerts, maintenance, and analyses.
  • Revoke when done. Delete the token from Settings ▸ API tokens when a client no longer needs it; it stops working immediately.
  • Every write is audited. ack_alert, open_maintenance, and poll_now each record an audit entry attributing the action to the token that made it — the same trail the WebUI’s own actions leave.