MCP Server Configuration Guide¶
This guide provides comprehensive instructions for configuring Model Context Protocol (MCP) servers with the AI Ops App. MCP servers extend the AI agent's capabilities by providing custom tools, context, and integrations.
Overview¶
MCP (Model Context Protocol) is an open protocol that enables AI agents to interact with external tools and services. The AI Ops App can connect to multiple MCP servers simultaneously, allowing the agent to access a wide range of capabilities.
What MCP Servers Provide¶
- Custom Tools: Execute actions like API calls, database queries, file operations
- Context Access: Retrieve information from external systems
- Integrations: Connect to third-party services (monitoring, ticketing, configuration management)
- Automation: Perform operational tasks on behalf of users
MCP Server Types¶
| Type | Description | Examples |
|---|---|---|
| Internal | Hosted within your infrastructure | Nautobot integrations, internal APIs |
| External | Third-party MCP servers | Public tools, vendor integrations |
Prerequisites¶
Before configuring MCP servers:
- At least one LLM model configured
- Network connectivity to MCP server endpoints
- Health check endpoint available on MCP servers
- Authentication credentials (if required)
Configuration Steps¶
Step 1: Deploy MCP Server¶
Choose an MCP server implementation or create your own.
Step 2: Add MCP Server in Nautobot¶
Navigate to AI Platform > Configuration > MCP Servers
Click + Add to create a new server.
Screenshot Placeholder:
[Screenshot: MCP Server List View]
Step 3: Configure Health Monitoring¶
The app automatically monitors MCP server health via the configured health check endpoint.
Step 4: Test Integration¶
Use the AI Chat Assistant to invoke tools from the MCP server.
MCP Server Configuration¶
Basic Configuration¶
Name: my-mcp-server
Status: Healthy
Protocol: HTTP
URL: http://mcp-server:8000
MCP Endpoint: /mcp
Health Check: /health
Description: Custom tools for network automation
MCP Type: Internal
Screenshot Placeholder:
[Screenshot: MCP Server Configuration Form]
Field Descriptions¶
| Field | Description | Example |
|---|---|---|
| Name | Unique identifier for the server | nautobot-tools, github-integration |
| Status | Server operational status | Healthy, Failed, Maintenance |
| Protocol | Connection type | HTTP, STDIO |
| URL | Base URL for the server | http://mcp.example.com:8000 |
| MCP Endpoint | Path to MCP protocol endpoint | /mcp, /api/mcp/v1 |
| Health Check | Health check endpoint path | /health, /api/health |
| Description | Purpose and capabilities | "GitHub API integration" |
| MCP Type | Server ownership | Internal, External |
Example MCP Server Configurations¶
Internal Nautobot Tools Server¶
Provides tools for querying and managing Nautobot data.
Name: nautobot-tools
Status: Healthy
Protocol: HTTP
URL: http://nautobot-mcp:8000
MCP Endpoint: /mcp
Health Check: /health
Description: Internal tools for Nautobot device management, IP address allocation, and configuration retrieval
MCP Type: Internal
Available Tools:
- get_device_info - Retrieve device details
- list_devices - List devices by site/role
- get_ip_addresses - Query IP address assignments
- update_device_status - Update device operational status
- get_config_context - Retrieve configuration context
Screenshot Placeholder:
[Screenshot: Nautobot Tools MCP Configuration]
Example Usage:
User: What is the status of device SW-CORE-01?
Agent: [Uses get_device_info tool]
Agent: Device SW-CORE-01 is Active, located in DC1, running IOS-XE 17.3.1
GitHub Integration Server¶
Provides tools for GitHub repository management.
Name: github-integration
Status: Healthy
Protocol: HTTP
URL: https://mcp-github.example.com
MCP Endpoint: /mcp/v1
Health Check: /api/health
Description: GitHub repository management, issue tracking, and PR automation
MCP Type: Internal
Available Tools:
- create_issue - Create GitHub issue
- list_issues - List issues with filters
- create_pull_request - Create PR
- get_repository_info - Get repo details
- search_code - Search code across repositories
Screenshot Placeholder:
[Screenshot: GitHub MCP Configuration]
Example Usage:
User: Create an issue in the automation repo for updating device configs
Agent: [Uses create_issue tool]
Agent: Created issue #42 "Update device configuration templates"
Monitoring Integration Server¶
Provides access to monitoring and alerting systems.
Name: monitoring-tools
Status: Healthy
Protocol: HTTP
URL: http://monitoring-mcp.internal:8080
MCP Endpoint: /mcp
Health Check: /health
Description: Network monitoring queries, alert management, and performance metrics
MCP Type: Internal
Available Tools:
- get_alerts - Retrieve current alerts
- acknowledge_alert - Acknowledge alert
- get_device_metrics - Get performance metrics
- check_interface_status - Check interface operational status
- get_bandwidth_usage - Query bandwidth statistics
Screenshot Placeholder:
[Screenshot: Monitoring MCP Configuration]
Example Usage:
User: Are there any critical alerts?
Agent: [Uses get_alerts tool]
Agent: Yes, 2 critical alerts:
- SW-CORE-01 Interface Gi0/1 down
- Router-01 CPU usage > 90%
Configuration Management Server¶
Provides tools for device configuration management.
Name: config-manager
Status: Healthy
Protocol: HTTP
URL: http://netbox-automation:9000
MCP Endpoint: /mcp
Health Check: /health
Description: Device configuration backup, deployment, and compliance checking
MCP Type: Internal
Available Tools:
- backup_config - Backup device configuration
- deploy_config - Deploy configuration to device
- compare_configs - Compare configurations
- check_compliance - Verify configuration compliance
- get_config_template - Retrieve configuration template
Screenshot Placeholder:
[Screenshot: Config Management MCP Configuration]
External API Integration Server¶
Connects to external third-party services.
Name: external-apis
Status: Healthy
Protocol: HTTP
URL: https://api-gateway.example.com
MCP Endpoint: /mcp/v1
Health Check: /health
Description: Third-party API integrations for IPAM, DNS, and ticketing
MCP Type: External
Available Tools:
- create_ticket - Create ServiceNow ticket
- update_dns_record - Update DNS entry
- allocate_ip_address - Allocate IP from IPAM
- query_cmdb - Query CMDB for CI information
- send_notification - Send Slack/Teams notification
Screenshot Placeholder:
[Screenshot: External APIs MCP Configuration]
Code Execution Server (Sandboxed)¶
Provides safe code execution capabilities.
Name: code-execution
Status: Healthy
Protocol: HTTP
URL: http://sandbox-mcp:8000
MCP Endpoint: /mcp
Health Check: /health
Description: Sandboxed Python code execution for data analysis and automation
MCP Type: Internal
Available Tools:
- execute_python - Execute Python code in sandbox
- validate_config - Validate device configuration
- parse_data - Parse structured data
- transform_data - Transform data formats
- generate_report - Generate custom reports
Screenshot Placeholder:
[Screenshot: Code Execution MCP Configuration]
Security Considerations: - ⚠️ Use sandboxed environment only - ⚠️ Implement resource limits (CPU, memory, time) - ⚠️ Restrict network access from sandbox - ⚠️ Validate all input before execution - ⚠️ Log all execution requests
STDIO Protocol Example¶
For local process-based MCP servers.
Name: local-file-tools
Status: Healthy
Protocol: STDIO
URL: file:///usr/local/bin/mcp-file-server
MCP Endpoint: (not used for STDIO)
Health Check: (not used for STDIO)
Description: Local file system operations
MCP Type: Internal
Use Cases: - Local file operations - Legacy tool integration - Command-line utilities - Local database access
Screenshot Placeholder:
[Screenshot: STDIO MCP Configuration]
MCP Server Implementation¶
Creating a Simple MCP Server¶
Example using Python and the MCP SDK:
# mcp_server.py
from mcp.server import Server
from mcp.types import Tool, TextContent
import httpx
app = Server("nautobot-tools")
@app.tool()
async def get_device_info(device_name: str) -> str:
"""Get device information from Nautobot.
Args:
device_name: Name of the device to query
Returns:
Device information as JSON string
"""
async with httpx.AsyncClient() as client:
response = await client.get(
f"http://nautobot/api/dcim/devices/?name={device_name}",
headers={"Authorization": "Token YOUR_TOKEN"}
)
return response.json()
@app.tool()
async def list_devices(site: str = None, role: str = None) -> str:
"""List devices with optional filters.
Args:
site: Filter by site name (optional)
role: Filter by device role (optional)
Returns:
List of devices as JSON string
"""
params = {}
if site:
params["site"] = site
if role:
params["role"] = role
async with httpx.AsyncClient() as client:
response = await client.get(
"http://nautobot/api/dcim/devices/",
params=params,
headers={"Authorization": "Token YOUR_TOKEN"}
)
return response.json()
@app.tool()
async def update_device_status(device_name: str, status: str) -> str:
"""Update device operational status.
Args:
device_name: Name of the device
status: New status (Active, Offline, Maintenance)
Returns:
Success message
"""
# Implementation
pass
# Health check endpoint
@app.health()
async def health_check():
"""Health check endpoint."""
return {"status": "healthy", "tools": len(app.tools)}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
Docker Deployment¶
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY mcp_server.py .
EXPOSE 8000
CMD ["python", "mcp_server.py"]
# docker-compose.yml
version: '3.8'
services:
nautobot-mcp:
build: .
ports:
- "8000:8000"
environment:
- NAUTOBOT_URL=http://nautobot:8080
- NAUTOBOT_TOKEN=${NAUTOBOT_TOKEN}
networks:
- nautobot-network
restart: unless-stopped
networks:
nautobot-network:
external: true
Screenshot Placeholder:
[Screenshot: MCP Server Container Logs]
Health Monitoring¶
Automatic Health Checks¶
The AI Ops App performs automatic health checks on configured MCP servers:
- Frequency: Every 5 minutes (configurable)
- Timeout: 10 seconds
- Retry Logic: 3 attempts with exponential backoff
- Status Updates: Automatic status field updates
Health Check Endpoint¶
MCP servers must implement a health check endpoint:
@app.get("/health")
async def health():
"""Health check endpoint."""
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"version": "1.0.0",
"tools_available": 5
}
Response Format:
{
"status": "healthy",
"timestamp": "2024-01-09T12:34:56.789Z",
"version": "1.0.0",
"tools_available": 5
}
Status Management¶
Healthy Status¶
- Health check passes
- All tools accessible
- Server included in agent operations
Failed Status¶
- Health check fails
- Server excluded from agent operations
- Automatic retry attempts continue
Maintenance Status¶
- Manually disabled
- Server excluded from operations
- No automatic health checks
Screenshot Placeholder:
[Screenshot: MCP Server Status Dashboard]
Security Considerations¶
Authentication¶
Implement authentication for MCP servers:
from fastapi import Header, HTTPException
@app.tool()
async def secure_tool(
param: str,
authorization: str = Header(None)
) -> str:
"""Secured tool requiring authentication."""
if not validate_token(authorization):
raise HTTPException(status_code=401, detail="Unauthorized")
# Tool logic
pass
Network Security¶
- ✓ Use HTTPS for external MCP servers
- ✓ Implement network segmentation
- ✓ Use internal DNS for internal servers
- ✓ Restrict access with firewall rules
- ✓ Use VPN for remote MCP servers
Input Validation¶
from pydantic import BaseModel, validator
class DeviceQuery(BaseModel):
device_name: str
@validator('device_name')
def validate_device_name(cls, v):
if not v.isalnum():
raise ValueError('Device name must be alphanumeric')
return v
@app.tool()
async def get_device(query: DeviceQuery) -> str:
"""Get device with validated input."""
# Tool logic with validated query.device_name
pass
Rate Limiting¶
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.tool()
@limiter.limit("10/minute")
async def rate_limited_tool(param: str) -> str:
"""Tool with rate limiting."""
pass
Troubleshooting¶
MCP Server Connection Issues¶
Symptom: Server status shows "Failed"
Check:
1. Server is running: curl http://mcp-server:8000/health
2. Network connectivity: ping mcp-server
3. Firewall rules: Check port access
4. Health endpoint accessible: Check logs
Fix:
# Restart MCP server
docker restart nautobot-mcp
# Check logs
docker logs nautobot-mcp
# Verify health endpoint
curl http://mcp-server:8000/health
Tool Discovery Issues¶
Symptom: Agent doesn't see available tools
Check: 1. MCP server status is "Healthy" 2. Tools properly registered in MCP server 3. Agent restart after MCP server changes 4. MCP endpoint URL correct
Fix:
# Restart Nautobot worker
systemctl restart nautobot-worker
# Check MCP server tools endpoint
curl http://mcp-server:8000/mcp/tools
Authentication Errors¶
Symptom: 401 Unauthorized errors
Check: 1. API tokens configured correctly 2. Token has required permissions 3. Token not expired 4. Headers sent correctly
Fix:
# Update token in environment
export MCP_AUTH_TOKEN="new-token-value"
# Restart MCP server
docker restart nautobot-mcp
Performance Issues¶
Symptom: Slow tool execution
Check: 1. MCP server resource usage 2. Network latency 3. Database query performance 4. Tool timeout settings
Optimize:
# Add caching
from functools import lru_cache
@lru_cache(maxsize=100)
@app.tool()
async def cached_tool(param: str) -> str:
"""Tool with response caching."""
# Expensive operation
pass
Best Practices¶
Development¶
- ✓ Start with HTTP protocol for easier debugging
- ✓ Implement comprehensive health checks
- ✓ Log all tool invocations
- ✓ Use async/await for I/O operations
- ✓ Implement proper error handling
Security¶
- ✓ Always use HTTPS for external servers
- ✓ Implement authentication for all tools
- ✓ Validate all inputs
- ✓ Apply rate limiting
- ✓ Use least-privilege access
Operations¶
- ✓ Monitor MCP server health
- ✓ Set up alerts for failures
- ✓ Implement automated backups
- ✓ Version control MCP server code
- ✓ Document available tools
Performance¶
- ✓ Cache expensive operations
- ✓ Use connection pooling
- ✓ Implement pagination for large results
- ✓ Set appropriate timeouts
- ✓ Monitor resource usage
Multi-MCP Server Architecture¶
Complementary Servers¶
Configure multiple servers for different domains:
1. nautobot-tools (Internal)
- Device management
- IP address allocation
- Configuration context
2. monitoring-tools (Internal)
- Alert queries
- Performance metrics
- Interface status
3. github-integration (Internal)
- Issue management
- PR automation
- Code search
4. external-apis (External)
- Ticketing system
- DNS management
- CMDB queries
Screenshot Placeholder:
[Screenshot: Multi-MCP Server Dashboard]
Load Balancing¶
For high-availability deployments:
# Multiple instances of same MCP server
nautobot-tools-1: http://mcp-1:8000
nautobot-tools-2: http://mcp-2:8000
nautobot-tools-3: http://mcp-3:8000
Use external load balancer or DNS round-robin.
Advanced Configuration¶
Custom Tool Parameters¶
from typing import Optional, List
from pydantic import BaseModel, Field
class DeviceFilter(BaseModel):
site: Optional[str] = Field(None, description="Site name")
role: Optional[str] = Field(None, description="Device role")
status: Optional[str] = Field("Active", description="Device status")
tags: Optional[List[str]] = Field(None, description="Device tags")
@app.tool()
async def search_devices(filters: DeviceFilter) -> str:
"""Advanced device search with multiple filters."""
# Complex query logic
pass
Streaming Responses¶
@app.tool()
async def stream_logs(device_name: str):
"""Stream device logs in real-time."""
async for log_line in get_device_logs(device_name):
yield log_line
Tool Composition¶
@app.tool()
async def troubleshoot_device(device_name: str) -> str:
"""Comprehensive device troubleshooting."""
# Compose multiple tools
info = await get_device_info(device_name)
alerts = await get_device_alerts(device_name)
metrics = await get_device_metrics(device_name)
return {
"device_info": info,
"alerts": alerts,
"metrics": metrics,
"recommendation": generate_recommendation(info, alerts, metrics)
}
Testing MCP Servers¶
Unit Tests¶
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_device_info():
"""Test device info retrieval."""
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post(
"/mcp/tools/get_device_info",
json={"device_name": "SW-CORE-01"}
)
assert response.status_code == 200
assert "device" in response.json()
Integration Tests¶
@pytest.mark.asyncio
async def test_mcp_integration():
"""Test full MCP integration."""
# Test health check
health = await test_client.get("/health")
assert health.status_code == 200
# Test tool discovery
tools = await test_client.get("/mcp/tools")
assert len(tools.json()) > 0
# Test tool execution
result = await test_client.post(
"/mcp/tools/get_device_info",
json={"device_name": "test-device"}
)
assert result.status_code == 200
Monitoring and Observability¶
Metrics Collection¶
from prometheus_client import Counter, Histogram
tool_calls = Counter('mcp_tool_calls_total', 'Total tool calls', ['tool_name'])
tool_duration = Histogram('mcp_tool_duration_seconds', 'Tool execution duration', ['tool_name'])
@app.tool()
async def monitored_tool(param: str) -> str:
"""Tool with metrics."""
tool_calls.labels(tool_name='monitored_tool').inc()
with tool_duration.labels(tool_name='monitored_tool').time():
# Tool logic
pass
Logging¶
import logging
logger = logging.getLogger(__name__)
@app.tool()
async def logged_tool(param: str) -> str:
"""Tool with comprehensive logging."""
logger.info(f"Tool called with param: {param}")
try:
result = await execute_logic(param)
logger.info(f"Tool succeeded: {result}")
return result
except Exception as e:
logger.error(f"Tool failed: {str(e)}", exc_info=True)
raise
Next Steps¶
After configuring MCP servers:
- Test Integration - Use tools via AI Chat Assistant
- Monitor Health - Track server health and performance
- Develop Custom Tools - Create your own MCP servers
- Security Hardening - Implement security best practices
Related Documentation¶
- Provider Configuration - LLM provider setup
- Middleware Configuration - Middleware setup
- Architecture Overview - MCP integration architecture
- External Interactions - Integration details
- Code Reference - Technical implementation details