nerdfunk-net/nautobot-mcp
If you are the rightful owner of nautobot-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
Nautobot MCP Server is a robust platform designed to facilitate model context protocol operations, providing seamless integration and management of network resources.
Nautobot MCP Server
A Model Context Protocol (MCP) server that provides Claude with powerful tools to interact with Nautobot using natural language queries and dynamic GraphQL filtering.
Features
- ๐ค Natural Language Queries - Use plain English to query your network infrastructure
- โก Dynamic Filtering - Filter by any property with automatic field mapping and validation
- ๐ Advanced Search - Supports lookup expressions (contains, starts with, regex, etc.)
- ๐ก๏ธ Smart Validation - Automatic field name mapping with helpful error suggestions
- ๐ Multiple Resource Types - Devices, locations, IP addresses, prefixes, device types, and more
- ๐ฏ Custom Field Support - Query custom fields with proper type handling
- ๐ MCP Prompts - Pre-configured prompt templates for common queries
- ๐ง Modular Architecture - Easy to extend with new resource types
- ๐ Comprehensive Logging - Detailed query execution and error information
Quick Start
1. Install Dependencies
pip install -r requirements.txt
2. Configuration
cp .env.example .env
# Edit .env with your Nautobot credentials
3. Test Connection
python test_server.py connection
4. Run Server
python mcp_server.py
5. Test with MCP Inspector (Recommended)
npm install -g @modelcontextprotocol/inspector
npx @modelcontextprotocol/inspector python mcp_server.py
6. Configure Claude Desktop to Use This Server
Add the following configuration to your Claude Desktop config file:
macOS/Linux: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"nautobot-mcp": {
"command": "python",
"args": ["/path/to/your/nautobot-mcp/mcp_server.py"],
"env": {
"NAUTOBOT_URL": "http://your-nautobot-instance.com",
"NAUTOBOT_TOKEN": "your-api-token"
}
}
}
}
Important Notes:
- Replace
/path/to/your/nautobot-mcp/
with the actual absolute path to your project directory - Replace
http://your-nautobot-instance.com
with your actual Nautobot URL - Replace
your-api-token
with your actual Nautobot API token - Restart Claude Desktop after making configuration changes
- Ensure Python dependencies are installed in your system Python or the Python environment Claude Desktop can access
Available Tools
๐ Dynamic Query Tools
These tools support natural language prompts and advanced filtering:
Tool | Description | Example Prompts |
---|---|---|
query_devices_dynamic | Query devices with dynamic filtering | "show device router1" , "devices with name contains core" , "devices in location datacenter1" |
query_locations_dynamic | Query locations with dynamic filtering | "show location datacenter1" , "locations with status active" , "sites in region west" |
query_ipam_dynamic | Query IP addresses with dynamic filtering | "show ip address 192.168.1.1" , "ip addresses with dns_name contains server" , "addresses with cf_environment production" |
query_prefixes_dynamic | Query network prefixes with dynamic filtering | "show prefix 10.0.0.0/8" , "prefixes within 172.16.0.0/12" , "prefixes with length 24" |
query_device_types_dynamic | Query device types with dynamic filtering | "show all device types" , "device types with vendor cisco" , "models contains c9300" |
๐ Metadata Tools
Tool | Description | Parameters |
---|---|---|
get_roles | Get available device roles | role_filter (optional) |
get_tags | Get available tags | tags_filter (optional) |
get_custom_fields | Get custom field definitions | None |
๐ฏ Legacy Query Tools
Tool | Description | Parameters |
---|---|---|
get_ip_addresses | Get IP address information (filtered) | address_filter , fields |
โจ Key Features of Dynamic Tools:
- ๐ฃ๏ธ Natural Language: Use plain English descriptions
- ๐ Field Mapping: Common aliases automatically mapped (e.g.,
hostname
โname
,site
โlocation
) - ๐ Lookup Expressions: Advanced search with
__ic
(contains),__isw
(starts with),__re
(regex), etc. - ๐ ๏ธ Custom Fields: Support for
cf_fieldname
custom field queries - โ Validation: Helpful error messages with field suggestions
Testing
Run All Tests
python test_server.py all
Interactive Testing
python test_server.py interactive
Manual JSON-RPC Testing
# List tools
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | python mcp_server.py
# Call a tool
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"devices_by_name","arguments":{"name_filter":["switch"],"match_type":"pattern"}}}' | python mcp_server.py
Configuration
Environment Variables
NAUTOBOT_URL
- Nautobot instance URL (default: http://127.0.0.1:8080)NAUTOBOT_TOKEN
- API authentication token (default: 0123456789abcdef0123456789abcdef01234567)
Example Tool Call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "devices_by_name",
"arguments": {
"name_filter": ["switch"],
"match_type": "pattern"
}
}
}
Architecture
- nautobot_client.py - API client with GraphQL/REST methods and logging
- mcp_server.py - MCP server with tool definitions and query execution
- test_server.py - Testing utilities for validation and debugging
Error Handling
- All errors are logged to console and returned in MCP responses
- Connection failures are handled gracefully
- GraphQL errors are parsed and returned with context
- Network timeouts are configured (30s default)
๐ฏ Prompt Examples
Once configured, you can use natural language to query your Nautobot instance with these example prompts:
๐ฅ๏ธ Device Queries
"Show device router1"
"Find all devices with name containing 'core'"
"Show devices in location datacenter1"
"List devices with role firewall"
"Show devices with hostname starts with 'sw-'"
"Find devices where vendor is cisco"
"Show all properties of device spine01"
"Devices with status active in location lab"
"Show devices with custom field cf_environment equal to production"
๐ Location Queries
"Show location datacenter1"
"Find locations with status active"
"Show all sites in region west-coast"
"List locations with name contains 'branch'"
"Show sites with address containing 'New York'"
"Find locations where tenant is customer1"
๐ IP Address & Network Queries
"Show ip address 192.168.1.1"
"Find IP addresses with dns_name contains 'server'"
"Show addresses with status reserved"
"List IP addresses with custom field cf_vrf production"
"Find addresses assigned to device router1"
"Show prefix 10.0.0.0/8"
"List prefixes within 172.16.0.0/12"
"Find prefixes with length 24"
"Show prefixes in location datacenter1"
๐ง Device Type & Hardware Queries
"Show all device types"
"Find device types with vendor cisco"
"Show models containing 'c9300'"
"List device types with manufacturer juniper"
"Show all catalyst models"
๐ Metadata Queries
"What device roles are available?"
"Show all tags in the system"
"List custom fields for devices"
"Show available statuses"
๐ Advanced Search Examples
"Show devices with name not equal to 'test'"
"Find devices where location ends with '-dc'"
"List IP addresses with dns_name starts with 'web-'"
"Show prefixes with description contains 'mgmt'"
"Find device types where model regex matches 'c[0-9]+'"
๐ก MCP Prompt Templates
The server also provides pre-configured prompt templates accessible through Claude:
- Device Details: "Show all properties of device {device_name}"
- Location Devices: "Show the name and IP address of all devices in location {location_name}"
- IP Lookup: "Where do I find the address {ip_address}?"
- Prefix Search: "List the prefixes that are included in {prefix_cidr}"
๐ ๏ธ Parameter Mapping & Validation
The dynamic query system includes intelligent parameter mapping and validation to make queries more intuitive and error-resistant.
๐ Automatic Field Mapping
Common field aliases are automatically mapped to their correct GraphQL field names:
Resource | Alias โ Correct Field | Example |
---|---|---|
Devices | hostname โ name | "devices with hostname router1" |
site โ location | "devices in site datacenter1" | |
vendor โ device_type__manufacturer | "devices with vendor cisco" | |
ip โ primary_ip4 | "devices with ip 192.168.1.1" | |
Locations | site โ name | "show site headquarters" |
region โ parent | "locations in region west" | |
address โ physical_address | "sites with address contains NYC" | |
IP Addresses | hostname โ dns_name | "ips with hostname web-server" |
ip โ address | "show ip 10.0.0.1" | |
Device Types | vendor โ manufacturer | "device types with vendor juniper" |
name โ model | "show device type c9300" |
โ Smart Validation
When an invalid field name is provided, the system offers helpful suggestions:
Example Error Response:
Invalid field name: 'invalid_field'.
Did you mean 'name'?
Available fields: name, location, role, status, device_type, platform, tags, tenant, rack, serial, asset_tag, primary_ip4, interfaces.
For custom fields, use 'cf_fieldname' format.
Fuzzy Matching: The system uses intelligent fuzzy matching to suggest the most likely intended field:
"loction"
โ suggests"location"
"manufacurer"
โ suggests"manufacturer"
"addres"
โ suggests"address"
๐ฏ Custom Field Support
Custom fields are automatically detected and handled with proper typing:
Standard Fields (Arrays):
$variable_value: [String]
Custom Fields (Single Values):
$variable_value: String
Usage Examples:
"devices with cf_environment production"
"ip addresses with cf_vrf management"
"locations with cf_criticality high"
๐ Validation Features
- Field Existence: Validates field names against available GraphQL fields
- Type Safety: Ensures proper parameter types (String vs Array)
- Helpful Messages: Provides specific suggestions and available options
- Logging: Logs field mappings for transparency and debugging
Example Field Mapping Log:
INFO: Mapped field 'hostname' to 'name'
INFO: Mapped field 'site' to 'location'
INFO: Mapped field 'vendor' to 'device_type__manufacturer'
๐ก Best Practices
- Use Natural Terms: The system understands common network terminology
- Custom Fields: Always prefix with
cf_
(e.g.,cf_environment
) - Case Insensitive: Field mapping is case-insensitive
- Check Logs: Review logs to understand field mappings
- Error Messages: Read validation errors for specific guidance
This intelligent mapping system makes the MCP server much more intuitive to use while maintaining the precision of GraphQL queries underneath.
Troubleshooting
Common Issues
1. "Server not found" in Claude Desktop
- Verify the absolute path to
mcp_server.py
is correct - Ensure Python is accessible from Claude Desktop's environment
- Check that all dependencies are installed:
pip install -r requirements.txt
2. "Connection failed" errors
- Verify
NAUTOBOT_URL
andNAUTOBOT_TOKEN
are correct - Test connection manually:
python test_server.py connection
- Check Nautobot instance is accessible from your machine
3. "GraphQL errors" in responses
- Verify your API token has appropriate permissions in Nautobot
- Check Nautobot logs for authentication/authorization issues
- Ensure GraphQL endpoint is enabled:
{nautobot_url}/graphql/
4. Tools not appearing in Claude Desktop
- Restart Claude Desktop after configuration changes
- Check Claude Desktop logs for MCP connection errors
- Verify JSON syntax in
claude_desktop_config.json
Debug Mode
Enable debug logging by setting environment variable:
export PYTHONPATH="$PYTHONPATH:$(pwd)"
NAUTOBOT_DEBUG=1 python mcp_server.py
๐๏ธ Architecture
Modern Dynamic Query System
The server uses a dynamic query registry that supports natural language processing and advanced filtering:
queries/
โโโ base.py # Base query classes and schemas
โโโ devices/ # Device queries
โ โโโ dynamic_device.py # Dynamic device query with field mapping
โ โโโ prompt_parser.py # Natural language prompt parser
โโโ locations/ # Location queries
โ โโโ dynamic_location.py # Dynamic location query
โ โโโ prompt_parser.py # Location prompt parser
โโโ ipam/ # IP Address Management
โ โโโ dynamic_ipam.py # Dynamic IP address query
โ โโโ filtered.py # Legacy filtered query
โ โโโ prompt_parser.py # IPAM prompt parser
โโโ prefixes/ # Network prefixes
โ โโโ dynamic_prefix.py # Dynamic prefix query
โ โโโ prompt_parser.py # Prefix prompt parser
โโโ device_types/ # Device types
โ โโโ dynamic_device_type.py # Dynamic device type query
โ โโโ prompt_parser.py # Device type prompt parser
โโโ statuses/ # Status queries
โโโ roles/ # Role queries
โโโ metadata/ # System metadata
โโโ roles.py # Device roles
โโโ tags.py # Tags
โโโ custom_fields.py # Custom field definitions
๐งฉ Core Components
1. Dynamic Query Classes
- Field Mapping: Automatic translation of common aliases (
hostname
โname
,site
โlocation
) - Validation: Smart field validation with helpful suggestions
- Custom Fields: Proper handling of
cf_*
fields with String vs Array types - Lookup Expressions: Support for advanced search operators
2. Prompt Parsers
- Natural Language: Convert English descriptions to structured queries
- Pattern Recognition: Regex-based parsing for various query patterns
- Field Enablers: Automatically enable relevant response fields based on context
3. Query Registry
- Auto-Discovery: Automatically registers all query classes
- Type Safety: Validates query schemas and parameters
- Tool Generation: Dynamically generates MCP tool definitions
๐ง Adding New Resource Types
- Create Directory Structure:
mkdir queries/your_resource
touch queries/your_resource/__init__.py
- Create Dynamic Query:
# queries/your_resource/dynamic_your_resource.py
from ..base import BaseQuery, QueryType, MatchType, ToolSchema
class DynamicYourResourceQuery(BaseQuery):
def __init__(self):
self.field_mappings = {
'alias1': 'real_field1',
'alias2': 'real_field2'
}
self.valid_fields = {'field1', 'field2', 'field3'}
self.base_query = """
query YourResources($variable_value: [String]) {
your_resources(enter_variable_name_here: $variable_value) {
field1
field2
}
}"""
super().__init__()
- Create Prompt Parser:
# queries/your_resource/prompt_parser.py
from typing import Dict, Any
def parse_your_resource_prompt(prompt: str) -> Dict[str, Any]:
# Implement parsing logic
return {"variable_name": "field1", "variable_value": ["value"]}
- Register in Main Registry:
# queries/__init__.py
from .your_resource import DynamicYourResourceQuery
# Add to query_classes list in _initialize_queries()
๐งช Development & Testing
# Test connection
python test_server.py connection
# Test all tools interactively
python test_server.py interactive
# Run server for testing
python mcp_server.py
# Test with MCP Inspector
npx @modelcontextprotocol/inspector python mcp_server.py
๐ Advanced Features
Field Mapping Examples:
'hostname' โ 'name' # Simple alias
'site' โ 'location' # Common terminology
'vendor' โ 'device_type__manufacturer' # Nested field access
'ip' โ 'primary_ip4' # Field relationship
Lookup Expression Support:
'name__ic' # Contains (case-insensitive)
'name__isw' # Starts with (case-insensitive)
'name__iew' # Ends with (case-insensitive)
'name__re' # Regular expression
'name__n' # Not equal
'name__isnull' # Is null
Custom Field Handling:
# Standard fields use [String] type
"$variable_value: [String]"
# Custom fields (cf_*) use String type
"$variable_value: String"