Cisco Secure Access MCP Server
by ACSmith1337
README.md
# Cisco Secure Access MCP Server
A production-ready [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that wraps the Cisco Secure Access REST API. Enables AI agents to investigate threats, pull reports, manage security policies, and administer deployment infrastructure through a standardized interface.
## Summary
Cisco Secure Access (formerly Cisco Umbrella / Secure Web Gateway) provides DNS-layer security, web filtering, and Zero Trust network access. This MCP server bridges that platform to AI agents, enabling:
- **Threat Investigation** -- Look up domains, IPs, URLs, and user activity observed by Cisco's DNS resolvers
- **Security Reports** -- Pull activity, threat, and destination analytics with flexible time ranges
- **Policy Management** -- Create/update destination lists, access rules, security profiles, and DLP policies
- **Domain Blocking** -- One-tool block/unblock domains with automatic list management
- **VPN & Device Control** -- List active VPN sessions, disconnect users, revoke device certificates
- **Infrastructure Admin** -- Manage sites, networks, connectors, tunnel groups, and identity endpoints
The server implements the **Streamable HTTP** transport per the MCP specification, runs as a single Python process, and handles OAuth 2.0 token management automatically.
## Time Format (IMPORTANT)
**Cisco Secure Access API uses Unix epoch timestamps in milliseconds.** This server converts automatically.
All time-accepting tools support three input formats:
| Format | Example | Converted to |
|---|---|---|
| ISO 8601 | `2025-01-15T08:30:00Z` | `1736928600000` |
| Relative | `24h`, `7d`, `30m`, `900s` | epoch ms from now |
| Keyword | `now` | current epoch ms |
| Epoch ms | `1735689600000` | passed through |
## Architecture
```
+-------------+ JSON-RPC 2.0 +------------------+ OAuth2 + REST +--------------------+
| MCP Client | <----------------> | MCP Server | <----------------> | Cisco Secure Access|
| (AI Agent) | Streamable HTTP | FastAPI + | api.sse.cisco.com| API |
| | POST /mcp | Tool Handlers | | |
+-------------+ +------------------+ +--------------------+
|
+------------+
| Token Cache|
| per session|
+------------+
```
## Quick Start
### Option 1: Docker Compose (Recommended)
```bash
cd cisco-secure-access-mcp
# Configure credentials
cp .env.example .env
# Edit .env with your Cisco API key and secret
# Build and run
docker compose up --build -d
# Check health
curl http://localhost:3000/health
```
### Option 2: Direct Docker
```bash
docker build -t cisco-mcp-server .
docker run -d --name cisco-mcp \
-p 3000:3000 \
-e CISCO_API_KEY=your_key_here \
-e CISCO_API_SECRET=your_secret_here \
cisco-mcp-server
```
### Option 3: Native Python
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export CISCO_API_KEY=your_key_here
export CISCO_API_SECRET=your_secret_here
python server.py
```
## Configuration
| Variable | Required | Description | Default |
|---|---|---|---|
| `CISCO_API_KEY` | Yes | OAuth client ID from Cisco portal | -- |
| `CISCO_API_SECRET` | Yes | OAuth client secret | -- |
| `CISCO_ORG_ID` | No | Child org ID for multi-org setups | Parent org |
| `MCP_SERVER_PORT` | No | Listen port | `3000` |
| `MCP_SERVER_HOST` | No | Bind address | `0.0.0.0` |
| `LOG_LEVEL` | No | DEBUG, INFO, WARNING, ERROR | `INFO` |
Get credentials from the Cisco Secure Access portal: **Admin > API Keys > Create New Key**.
## Available Tools (18)
### Investigation & Forensics
| Tool | Description |
|---|---|
| `investigate_domain` | DNS query history, IPs, threats for a domain |
| `investigate_ip` | Domains, threats, geo-location for an IP address |
| `investigate_url` | Categorization, threat status for a specific URL |
| `investigate_user_activity` | Complete user history: DNS, web, blocks, threats |
### Reports & Analytics
| Tool | Description |
|---|---|
| `get_activity_report` | DNS queries, web requests, connection data |
| `get_top_threats` | Most frequent threat categories and sources |
| `get_top_destinations` | Most visited domains, IPs, and URLs |
| `get_top_identities` | Most active users by request volume |
| `get_top_ips` | Most contacted external IP addresses |
| `get_summary_report` | Aggregate traffic volume and threat counts |
| `get_threat_types` | Breakdown: malware, phishing, C2, etc. |
| `get_report` | Generic handler: app_discovery, metering, api_usage, dlp_events |
### Domain Blocking
| Tool | Description |
|---|---|
| `add_domain_to_block_list` | Block a domain (creates list if needed) |
| `remove_domain_from_block_list` | Unblock a domain from a list |
### VPN & Device Management
| Tool | Description |
|---|---|
| `list_vpn_connections` | Current VPN user sessions |
| `disconnect_vpn_user` | Terminate a specific VPN session |
| `revoke_device_certificates` | Revoke device access certificates |
### Generic Resource Management
| Tool | Description |
|---|---|
| `manage_resource` | CRUD for all Admin/Policies/Deployments resources |
`manage_resource` accepts:
- `domain`: `admin`, `policies`, `deployments`
- `resource`: resource slug (see lists below)
- `operation`: `list`, `create`, `update`, `delete`
- `resource_id`: required for update/delete
- `resource_params`: attributes dict for create/update
- `params`: query parameters for list operations
Available resources per domain:
**admin**: api_keys, user_devices, vpn_connections, integrations, alert_rules, tenants, threat_intel_feeds, tenant_controls, s3_bucket_key
**policies**: destination_lists, application_lists, access_rules, network_objects, security_feeds, security_profiles, content_categories, application_categories, ips_profiles, dlp_rules, do_not_decrypt, private_resources
**deployments**: tunnel_groups, tunnel_regions, connector_groups, connectors, roaming_computers, swg_device_settings, internal_domains, sites, networks, internal_networks, network_devices, dns_forwarders, identity_endpoints, virtual_appliances
## Usage Examples
### Investigate a suspicious domain
```json
{"tool": "investigate_domain", "arguments": {"domain": "suspicious-site.com", "limit": 20}}
```
### Get threat report for last 7 days
```json
{"tool": "get_top_threats", "arguments": {"start_time": "7d", "end_time": "now", "limit": 50}}
```
### List all deployment sites
```json
{"tool": "manage_resource", "arguments": {"domain": "deployments", "resource": "sites", "operation": "list"}}
```
### Block a malware domain
```json
{"tool": "add_domain_to_block_list", "arguments": {"domain": "malware.example.com"}}
```
### Create a new site definition
```json
{
"tool": "manage_resource",
"arguments": {
"domain": "deployments",
"resource": "sites",
"operation": "create",
"resource_params": {"name": "office-1", "ipAddresses": ["10.0.0.0/24"]}
}
}
```
### Disconnect a compromised user VPN
```json
{"tool": "disconnect_vpn_user", "arguments": {"user_id": "compromised-user"}}
```
### Update a destination list
```json
{
"tool": "manage_resource",
"arguments": {
"domain": "policies",
"resource": "destination_lists",
"operation": "update",
"resource_id": "list-abc123",
"resource_params": {"name": "blocked-sites", "entries": ["bad.com"]}
}
}
```
## Error Handling
- **429 Rate Limited**: Automatic exponential backoff retry (up to 3 attempts)
- **5xx Server Errors**: Automatic retry with backoff (up to 3 attempts)
- **401/403 Auth Errors**: Returned immediately with clear diagnostic message
- **Token Expiry**: Automatic refresh 5 minutes before TTL expires
- **Connection Pooling**: httpx client with 20 max connections, 10 keepalive
## Best Practices
### Security
1. **Never hardcode credentials**. Always use `.env` files or environment injection via Docker secrets, Kubernetes secrets, or cloud secret managers.
2. **Rotate API keys regularly**. Use `manage_resource` with domain=`admin`, resource=`api_keys` to create/delete keys.
3. **Use scoped API keys**. Request only the permissions your use case needs.
4. **Run as non-root**. The Docker image uses a dedicated `appuser` account.
5. **Restrict network access**. Bind to `127.0.0.1` if the MCP client runs locally, or use a VPN/firewall for remote access.
### Deployment
1. **Use health checks**. The `/health` endpoint enables container orchestration liveness checks.
2. **Set resource limits**. In docker-compose, add `deploy.resources.limits` for CPU/memory.
3. **Enable structured logging**. Set `LOG_LEVEL=DEBUG` for troubleshooting, `INFO` for production.
4. **Monitor token usage**. API key creation tracks scopes and usage patterns via `get_report` with `report_type=api_usage`.
### Operational
1. **Prefer `manage_resource` for CRUD**. Covers 50+ endpoints with a single tool. Use dedicated tools only when convenience matters (e.g., `add_domain_to_block_list`).
2. **Use relative time offsets**. `24h`, `7d`, `30m` are simpler than ISO 8601 for most queries.
3. **Paginate large result sets**. Use `limit` and `offset` parameters for list operations.
4. **Handle rate limits gracefully**. The server retries automatically, but design your workflow to space out high-volume queries.
5. **Backup destination lists**. Before modifying block lists, `list` the current entries first.
### Multi-Org Support
For organizations with child orgs, set `CISCO_ORG_ID` to the child organization's ID. The server adds the `X-Umbrella-OrgId` header automatically to all API requests.
## Testing
```bash
pip install pytest pytest-asyncio
pytest test_server.py -v
```
Covers: epoch time conversion, tool registration, endpoint mapping, API retry logic, token caching, transport layer, and all 18 tool handlers.
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues