README.mdā¢10.6 kB
# Cisco Catalyst Center (DNAC) MCP Server
MCP server providing intelligent wireless client management tools for Cisco Catalyst Center (DNA Center). This server exposes DNAC wireless client queries through the Model Context Protocol (MCP), enabling AI assistants like Claude to interact with your Catalyst Center infrastructure.
## Features
- **šÆ Smart Query Limiting**: Automatic result limiting with configurable thresholds
- **š Pagination Handling**: Transparent pagination for large result sets
- **š” Actionable Guidance**: Intelligent suggestions when results exceed limits
- **š Rich Filtering**: Filter by site, MAC, IP, SSID, band, hostname, and more
- **š„ Health Monitoring**: Detailed client health metrics and diagnostics
- **ā” Rate Limiting**: Built-in API throttling to prevent overload
- **š Secure**: Support for SSL verification and credential management
## Installation
### Prerequisites
- Python 3.10 or higher
- Access to Cisco Catalyst Center (DNAC) with API credentials
- Claude Desktop or another MCP client
### Install from Source
```bash
# Clone the repository
git clone https://github.com/robertbergman/dnac-mcp.git
cd dnac-mcp
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Install in development mode
pip install -e .
```
### Install for Development
```bash
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
pytest
# Format code
black src tests
# Lint code
ruff check src tests
```
## Configuration
### Option 1: Environment Variables (Recommended)
Set the following environment variables:
```bash
export DNAC_BASE_URL="https://dnac.example.com"
export DNAC_USERNAME="admin"
export DNAC_PASSWORD="your-password"
export DNAC_VERSION="2.3.7.6" # Optional
export DNAC_VERIFY="true" # Optional
export DNAC_MAX_RESULTS="100" # Optional
```
On Windows:
```powershell
$env:DNAC_BASE_URL="https://dnac.example.com"
$env:DNAC_USERNAME="admin"
$env:DNAC_PASSWORD="your-password"
```
### Option 2: Configuration File
Create a `config.json` file:
```json
{
"base_url": "https://dnac.example.com",
"username": "admin",
"password": "your-password",
"version": "2.3.7.6",
"verify": true,
"max_results": 100
}
```
Set the config file path:
```bash
export DNAC_CONFIG_FILE="/path/to/config.json"
```
### Option 3: Per-Request Credentials
Pass credentials with each tool call (see Usage examples below).
## Claude Desktop Configuration
Add to your Claude Desktop config file:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"dnac-wireless-clients": {
"command": "python",
"args": ["-m", "dnac_mcp.server"],
"env": {
"DNAC_BASE_URL": "https://dnac.example.com",
"DNAC_USERNAME": "admin",
"DNAC_PASSWORD": "your-password"
}
}
}
}
```
Or use the installed script:
```json
{
"mcpServers": {
"dnac-wireless-clients": {
"command": "dnac-mcp",
"env": {
"DNAC_BASE_URL": "https://dnac.example.com",
"DNAC_USERNAME": "admin",
"DNAC_PASSWORD": "your-password"
}
}
}
}
```
After updating the config, restart Claude Desktop.
## Usage
### Available Tools
#### 1. `query_wireless_clients`
Query wireless clients with smart filtering and limiting.
**Parameters:**
- `base_url` (required): Catalyst Center URL (e.g., `"https://dnac.example.com"`)
- `username` (required): DNAC username
- `password` (required): DNAC password
- `site_id` (optional): Filter by site UUID
- `mac_address` (optional): Filter by client MAC address
- `hostname` (optional): Filter by Access Point hostname
- `ip_address` (optional): Filter by client IP address
- `ssid` (optional): Filter by SSID name
- `band` (optional): Filter by frequency band (e.g., `"2.4GHz"`, `"5GHz"`)
- `max_results` (optional): Maximum clients to return (default: 100)
- `version` (optional): DNAC API version (default: `"2.3.7.6"`)
- `verify` (optional): Verify SSL certificates (default: `true`)
- `debug` (optional): Enable debug logging (default: `true`)
**Returns:**
- `clients`: List of client dictionaries
- `total_count`: Total matching clients
- `exceeded_limit`: Boolean if total > max_results
- `guidance`: Actionable tips to refine query
- `fetched_count`: Actual number returned
**Example Prompts for Claude:**
```
"Show me all wireless clients"
"Find wireless clients on SSID 'Corporate-WiFi'"
"Which clients are connected to AP 'AP-Floor2-East'?"
"Show me clients with MAC address AA:BB:CC:DD:EE:FF"
"List wireless clients at site abc-123-def-456"
"Find all 5GHz wireless clients"
```
#### 2. `get_client_health`
Get detailed health information for a specific client.
**Parameters:**
- `base_url` (required): Catalyst Center URL
- `username` (required): DNAC username
- `password` (required): DNAC password
- `mac_address` (required): Client MAC address
- `version` (optional): DNAC API version (default: `"2.3.7.6"`)
- `verify` (optional): Verify SSL certificates (default: `true`)
**Returns:**
- `health`: Detailed health metrics
- `response`: Full API response data
- `mac_address`: Queried MAC address
**Example Prompts for Claude:**
```
"Get health details for client AA:BB:CC:DD:EE:FF"
"What's the health status of MAC address 00:11:22:33:44:55?"
"Show me detailed metrics for client AA:BB:CC:DD:EE:FF"
```
## Development
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=src/dnac_mcp --cov-report=html
# Run specific test file
pytest tests/test_wireless_client_agent.py
# Run with verbose output
pytest -v
```
### Code Quality
```bash
# Format code
black src tests
# Lint code
ruff check src tests
# Type checking
mypy src
```
### Project Structure
```
dnac-mcp/
āāā src/
ā āāā dnac_mcp/
ā āāā __init__.py # Package initialization
ā āāā server.py # MCP server implementation
ā āāā wireless_client_agent.py # DNAC client agent
ā āāā config.py # Configuration management
āāā tests/
ā āāā __init__.py
ā āāā test_server.py
ā āāā test_wireless_client_agent.py
ā āāā test_config.py
āāā pyproject.toml # Project configuration
āāā requirements.txt # Core dependencies
āāā requirements-dev.txt # Development dependencies
āāā README.md # This file
```
## Troubleshooting
### Connection Issues
**Problem**: Cannot connect to DNAC
**Solution**:
- Verify `base_url` is correct (do not include `/api/` path)
- Check credentials
- For self-signed certificates, set `verify=false`
### SSL Certificate Errors
**Problem**: SSL verification fails
**Solution**:
```bash
export DNAC_VERIFY="false" # For testing only
```
Or in config.json:
```json
{
"verify": false
}
```
### No Results Returned
**Problem**: Query returns 0 clients
**Solution**:
- Verify filters are correct
- Check DNAC has clients matching criteria
- Try query without filters first
- Enable debug logging: `debug=true`
### API Version Mismatch
**Problem**: API calls fail with version errors
**Solution**: Update the version parameter to match your DNAC version:
```bash
export DNAC_VERSION="2.3.5.3" # Example
```
### Rate Limiting
**Problem**: Too many API requests
**Solution**: The server includes built-in rate limiting (0.5s delay between calls). Adjust if needed in [wireless_client_agent.py](src/dnac_mcp/wireless_client_agent.py).
## Security Best Practices
1. **Never commit credentials** to version control
2. **Use environment variables** or secrets manager for credentials
3. **Enable SSL verification** in production (`verify=true`)
4. **Use least privilege** DNAC accounts (read-only if possible)
5. **Rotate credentials** regularly
6. **Audit API access** through DNAC logs
## API Reference
### WirelessClientAgent Class
```python
from dnac_mcp import WirelessClientAgent
from dnacentersdk import api
# Initialize DNAC client
dnac = api.DNACenterAPI(
base_url="https://dnac.example.com",
username="admin",
password="password"
)
# Create agent
agent = WirelessClientAgent(
dnac_client=dnac,
max_results=100,
rate_limit_delay=0.5,
debug=True
)
# Query clients
result = agent.get_clients(ssid="Corporate-WiFi")
print(f"Found {result['fetched_count']} clients")
```
### Standalone Functions
```python
from dnac_mcp import query_wireless_clients, get_client_health
# Query clients
result = query_wireless_clients(
base_url="https://dnac.example.com",
username="admin",
password="password",
ssid="Corporate-WiFi",
max_results=50
)
# Get client health
health = get_client_health(
base_url="https://dnac.example.com",
username="admin",
password="password",
mac_address="AA:BB:CC:DD:EE:FF"
)
```
## Contributing
Contributions are welcome! Please follow these guidelines:
1. Fork the repository
2. Create a feature branch: `git checkout -b feature-name`
3. Follow TDD principles (write tests first!)
4. Follow SOLID principles in design
5. Format code: `black src tests`
6. Lint code: `ruff check src tests`
7. Run tests: `pytest`
8. Commit changes: `git commit -am 'Add feature'`
9. Push to branch: `git push origin feature-name`
10. Submit a Pull Request
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Support
- **Issues**: [GitHub Issues](https://github.com/robertbergman/dnac-mcp/issues)
- **Documentation**: [DNAC SDK Docs](https://dnacentersdk.readthedocs.io/)
- **MCP Spec**: [Model Context Protocol](https://modelcontextprotocol.io/)
## Acknowledgments
- Built with [dnacentersdk](https://github.com/cisco-en-programmability/dnacentersdk)
- Implements [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
- Inspired by Cisco DevNet community
## Roadmap
- [ ] Add support for wired clients
- [ ] Implement client troubleshooting tools
- [ ] Add network device queries
- [ ] Support for client statistics and trends
- [ ] Webhook notifications for client events
- [ ] GraphQL query support
- [ ] Multi-site aggregation
- [ ] Export to CSV/JSON
## Changelog
### v1.0.0 (2025-01-XX)
- Initial release
- Wireless client query with smart limiting
- Client health monitoring
- MCP server implementation
- Configuration management
- Comprehensive documentation