NetStacksNetStacks

MCP Servers

Connect Model Context Protocol servers to extend NetStacks AI agents and chat with external tools over stdio or SSE transports.

Overview

MCP (Model Context Protocol) servers are external tool servers that extend the capabilities of NetStacks AI features. By connecting an MCP server, you give NOC agents and AI Chat access to tools that can query monitoring systems, look up assets in a CMDB, check circuit status, or perform any other operation the server chooses to expose. Each tool an MCP server advertises becomes a callable function the LLM can invoke during reasoning.

Where MCP lives

MCP server management is a Controller feature. You configure servers from the MCP Servers section under Settings → AI, where you can add a server, connect it to discover its tools, and toggle individual tools on or off. Connected, enabled tools are then available to NOC Agents and AI Chat across the deployment.

NetStacks supports two MCP transports:

  • stdio — Launches a local process on the Controller host and communicates over standard input/output. Best for MCP servers packaged as CLI tools or npm/uvx packages that run alongside the Controller.
  • SSE (HTTP endpoint) — Connects to a remote MCP server over a streamable HTTP endpoint. Best for long-running remote servers reachable by URL.
Why MCP?

The Model Context Protocol is an open standard for connecting AI systems to external tools and data sources. Instead of building a custom integration for every monitoring platform, CMDB, or ticketing system, you connect a single MCP server that exposes those capabilities as discoverable tools.

How It Works

The MCP integration follows a lifecycle of registration, connection and discovery, per-tool enablement, and invocation.

Server Registration

An operator registers an MCP server by providing a name, a transport type (stdio or sse), and connection details — a command plus arguments for stdio, or a URL for SSE. Optional authentication is configured with an auth_type and a single auth_token. If a Bearer token or API key is supplied, it is encrypted at rest by the Controller vault and never returned in API responses.

Connection & Tool Discovery

Connecting a server opens the transport and calls the MCP tools/listoperation. Each discovered tool includes a name, an optional description, and a JSON Schema input definition. Discovered tools are upserted into the registry, so the tool list stays current when you reconnect or restart a server that has added or removed capabilities. A successful connect also marks the server enabled.

Per-Tool Enablement

Operators can enable or disable individual tools from any connected server. This gives fine-grained control over which capabilities reach the AI. For example, you might enable a read-only metrics query but leave a ticket-creation tool disabled until you have tested it. Only enabled tools are exposed to NOC Agents and AI Chat, and only enabled tools can be executed directly through the API.

Connection State

The Controller tracks whether each server currently has a live connection and shows a Connected / stdio badge in the UI. This state reflects whether an active session exists in the in-memory client manager — it is not a periodic background health poll. If a server drops, reconnect it (or use Restart) to re-establish the session and re-discover tools. Use the Test action to check connectivity without changing the server's enabled state.

Tool Invocation

During a NOC Agent's reasoning loop or an AI Chat session, the LLM can select an enabled MCP tool. The Controller routes the call to the right server, passes the arguments, and returns the textual tool result to the model for further reasoning. You can also run a tool manually from the UI or API to test it.

Connecting an MCP Server

Follow these steps to register an MCP server and make its tools available to AI features. These actions require operator permissions in the Controller.

Step 1: Open MCP Servers

In the Controller admin UI, open MCP Servers. You will see the list of configured servers with a transport badge and a connection badge for each.

Step 2: Add a server

Click Add Server and enter a descriptive name (for example filesystem-tools or grafana-mcp).

Step 3: Choose a transport

  • stdio (local process) — provide a command (for example npx or uvx) and space-separated arguments.
  • SSE (HTTP endpoint) — provide the server URL (for example https://mcp-server.example.com/sse).

Step 4: Configure authentication (optional)

Set the auth type to None, Bearer Token, or API Key. For Bearer or API Key, paste the token; it is encrypted before storage. Authentication applies to SSE endpoints (the token is sent as an HTTP auth header); stdio servers typically use None and read any secrets from their own environment.

Step 5: Connect to discover tools

Save the server, then click Connect. The Controller opens the transport, runs tool discovery, persists the discovered tools, and marks the server enabled. The connection badge changes to Connected.

Test before you commit

Use Test to verify connectivity and see how many tools a server advertises without changing its enabled state or persisting tools. It runs a transient connect-and-disconnect and reports a success/failure message plus a tool count.

Step 6: Enable or disable specific tools

After discovery, review each tool's name, description, and input schema, then toggle individual tools on or off. Only enabled tools reach AI agents and AI Chat.

Review tools before enabling

Some MCP servers expose tools that modify external systems (create tickets, restart services, push configurations). Review each tool's description and input schema carefully before enabling it, and prefer read-only tools until you trust a server.

Step 7: Manage the connection

Use Disconnect to close the session and disable the server, Restart to disconnect and reconnect (re-discovering tools and re-enabling), or Delete to remove the server entirely. Deleting a server disconnects it first and cascades to its tools.

Transports & Authentication

NetStacks exposes exactly two MCP transport types. The value you store in transport_type determines which connection details are used.

transport_typeConnection fieldsUse for
stdio (default)command + argsLocal CLI / npm / uvx MCP servers on the Controller host
sseurl (streamable HTTP endpoint)Remote MCP servers reachable by URL

Authentication uses a single auth_token string interpreted according to auth_type:

auth_typeBehavior (SSE)
noneNo auth header sent
bearerSends Authorization: Bearer <token>
api-keySends the token as the auth header value verbatim
No generic 'HTTP' transport or headers map

There is no separate http transport type and no arbitrary headers object. Remote servers use the sse transport with a single auth_token. If your earlier configs used {"transport_type": "http"} or a headers map, migrate them to sse with auth_type + auth_token.

Management API

MCP servers are managed under the /api/mcp prefix. All endpoints require operator permissions and a Bearer token. The available routes are:

Method & pathPurpose
GET /api/mcp/serversList servers (with tools and live connection state)
POST /api/mcp/serversCreate a server configuration
DELETE /api/mcp/servers/:idDisconnect and delete a server (tools cascade)
POST /api/mcp/servers/:id/connectConnect, discover & persist tools, mark enabled
POST /api/mcp/servers/:id/disconnectClose the session and mark the server disabled
POST /api/mcp/servers/:id/restartDisconnect then reconnect (re-discover, re-enable)
POST /api/mcp/servers/:id/testTransient connectivity test; no state change
PUT /api/mcp/tools/:tool_id/enabledEnable or disable a single tool
POST /api/mcp/tools/:tool_id/executeRun an enabled tool with arguments
Connect performs discovery

There is no separate "discover" call. connect (and restart) opens the transport, lists tools, and upserts them. Use test when you want to check reachability and tool count without persisting tools or enabling the server.

Code Examples

Create a stdio server

Launch a local MCP server as a child process. command and args apply to stdio; server_type defaults to custom if omitted.

create-stdio-server.shbash
curl -X POST https://controller.example.net/api/mcp/servers \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "filesystem-tools",
    "transport_type": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"],
    "auth_type": "none"
  }'

Create an SSE (HTTP endpoint) server

Connect to a remote MCP server by URL. Use auth_type + auth_token for authentication (the token is encrypted at rest).

create-sse-server.shbash
curl -X POST https://controller.example.net/api/mcp/servers \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "grafana-mcp",
    "transport_type": "sse",
    "url": "https://mcp-server.example.com/sse",
    "auth_type": "bearer",
    "auth_token": "eyJhbGciOiJIUzI1NiIs..."
  }'

Connect and test

connect discovers and persists tools and enables the server. test reports reachability and a tool count without changing state.

connect-test.shbash
# Connect: discover + persist tools, mark enabled. Returns the server with tools.
curl -X POST https://controller.example.net/api/mcp/servers/<id>/connect \
  -H "Authorization: Bearer <token>"

# Test connectivity only (no enable, no persisted tools)
curl -X POST https://controller.example.net/api/mcp/servers/<id>/test \
  -H "Authorization: Bearer <token>"

# Restart: disconnect then reconnect (re-discover, re-enable)
curl -X POST https://controller.example.net/api/mcp/servers/<id>/restart \
  -H "Authorization: Bearer <token>"

# Disconnect: close the session and disable the server
curl -X POST https://controller.example.net/api/mcp/servers/<id>/disconnect \
  -H "Authorization: Bearer <token>"

Test response

The transient test returns a success flag, a message, and the tool count:

test-response.jsonjson
{
  "success": true,
  "message": "'grafana-mcp' connected — discovered 7 tools",
  "tools_discovered": 7
}

Server response shape

GET /api/mcp/servers returns servers with their tools and the live connected flag. The encrypted auth token is never included.

list-servers-response.jsonjson
[
  {
    "id": "a1b2c3d4-0000-0000-0000-000000000001",
    "name": "grafana-mcp",
    "transport_type": "sse",
    "command": "",
    "args": [],
    "url": "https://mcp-server.example.com/sse",
    "auth_type": "bearer",
    "server_type": "custom",
    "enabled": true,
    "connected": true,
    "tools": [
      {
        "id": "f0f0f0f0-0000-0000-0000-0000000000aa",
        "name": "query_range",
        "description": "Run a PromQL range query and return time-series data",
        "enabled": true,
        "input_schema": {
          "type": "object",
          "properties": {
            "query": { "type": "string", "description": "PromQL expression" },
            "range": { "type": "string", "description": "e.g. 1h, 6h, 24h" }
          },
          "required": ["query"]
        }
      }
    ]
  }
]

Enable or disable a single tool

Per-tool approval uses PUT (not PATCH) with a JSON body of {"enabled": true|false}.

set-tool-enabled.shbash
# Enable a tool by its tool_id
curl -X PUT https://controller.example.net/api/mcp/tools/<tool_id>/enabled \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'

# Disable a tool (removes it from the AI-available set)
curl -X PUT https://controller.example.net/api/mcp/tools/<tool_id>/enabled \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Execute a tool

Run an enabled tool directly. The request wraps arguments under arguments; the response returns text content and an error flag.

execute-tool.shbash
curl -X POST https://controller.example.net/api/mcp/tools/<tool_id>/execute \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "arguments": {
      "query": "rate(ifInOctets[5m])",
      "range": "1h"
    }
  }'

# Response:
# {
#   "content": "timestamp,value\n2026-06-15T12:00:00Z,1421.4\n...",
#   "is_error": false
# }
Disabled tools cannot be executed

execute only matches tools that are currently enabled, so it rejects a disabled (or unknown) tool with 404 Not Found. Enable the tool first with the PUT .../enabled call above.

Questions & Answers

Q: What is MCP (Model Context Protocol)?
A: MCP is an open standard for connecting AI systems to external tools and data sources. It defines how an AI host (like NetStacks) discovers tools, invokes them, and receives results. This lets NetStacks integrate with any MCP-compatible server without writing a custom connector for each external system.
Q: What MCP transports does NetStacks support?
A: Two. stdio launches a local process on the Controller host and talks over standard input/output (provide command and args). SSE connects to a remote server over a streamable HTTP endpoint (provide a url). There is no separate generic "HTTP" transport type — remote servers use sse.
Q: How do I authenticate to a remote MCP server?
A: Set auth_type to bearer or api-key and provide a single auth_token. For bearer, NetStacks sends Authorization: Bearer <token>; for api-key it sends the token as the auth header value. The token is encrypted at rest and never returned by the API. There is no free-form headers map.
Q: How do I discover what tools a server provides?
A: Discovery happens on connect (and restart). The Controller calls the MCP tools/list operation and upserts the results, each with a name, description, and JSON Schema input. Reconnect or restart a server to pick up tools it has added or removed. Use Test to see the tool count without persisting anything.
Q: Can I disable specific tools from a server?
A: Yes. After discovery, each tool can be enabled or disabled individually via PUT /api/mcp/tools/:tool_id/enabled. Disabled tools are not exposed to NOC Agents or AI Chat and cannot be executed (a direct execute returns 404). This is ideal for restricting AI to read-only tools.
Q: Does NetStacks continuously health-check MCP servers?
A: The connected flag reflects whether a live session currently exists in the Controller's in-memory client manager — it is not a periodic background poll, and there is no automatic reconnect loop. If a server drops, use Connect or Restart to re-establish the session, or Test to check reachability without changing state.
Q: Can NOC Agents use MCP tools?
A: Yes. Enabled MCP tools become part of the tool set agents can call during their reasoning loops. A triage agent could call a metrics tool to pull interface utilization, a CMDB tool to find the affected device's provider, and a circuit tool to check for a provider-side outage — all without custom integration code.
Q: Do MCP servers get access to my network devices or NetStacks credentials?
A: No. MCP servers do not connect to your devices directly and do not receive NetStacks credentials. They only reach whatever external systems they are themselves configured to access. The Controller invokes their tools on the AI's behalf and returns the text result to the model.

Troubleshooting

Connection failing

A failed connect returns an error response carrying the underlying transport failure (a failed test instead returns success: false with the error in its message). Check by transport:

  • stdio — Verify the command exists on the Controller host and is executable, and that any required packages are installed. A bad command surfaces as a process-spawn error in the Controller logs.
  • SSE — Verify the url is reachable from the Controller host. Check firewall rules, DNS, and TLS validity, and confirm the auth_type/auth_token are correct and unexpired.

No tools discovered

If a server connects but lists no tools, it may not implement tools/listcorrectly, or it may expose tools conditionally. Check the MCP server's own logs, then Restart the server to re-run discovery.

Tool execution failing

  • Confirm the tool is enabled — executing a disabled tool returns 404 Not Found.
  • Check the tool's input_schema and ensure the arguments object matches it (correct field names and required fields).
  • Verify the MCP server itself has the permissions it needs on the downstream system (for example, a read-scoped API key), and review the server's logs.

Server shows disconnected after a drop

Because there is no automatic reconnect loop, a server that loses its session stays disconnected until you act. Click Connect to re-establish it, or Restart to force a clean disconnect-then-reconnect that also re-discovers tools.

Verbose MCP logging

Increase Controller log verbosity (for example RUST_LOG=debug) to see MCP connect, discovery, and tool-call activity, including how many tools each server advertised.

Learn how MCP servers fit into the rest of the NetStacks AI stack:

  • NOC Agents — Autonomous agents that call enabled MCP tools during their reasoning loops
  • AI Chat — Interactive sessions that can invoke MCP tools for real-time answers
  • LLM Configuration — Choose the provider and model that drive tool selection and invocation
  • Knowledge Base — Ground AI answers in your own documents alongside MCP tool output
  • Quick Calls — One-click API call templates that complement MCP tool capabilities
  • System Settings — Global configuration for AI features