Cisco Secure Access MCP Server
A production-ready Model Context Protocol (MCP) 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)
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
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
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,deploymentsresource: resource slug (see lists below)operation:list,create,update,deleteresource_id: required for update/deleteresource_params: attributes dict for create/updateparams: 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
{"tool": "investigate_domain", "arguments": {"domain": "suspicious-site.com", "limit": 20}}
Get threat report for last 7 days
{"tool": "get_top_threats", "arguments": {"start_time": "7d", "end_time": "now", "limit": 50}}
List all deployment sites
{"tool": "manage_resource", "arguments": {"domain": "deployments", "resource": "sites", "operation": "list"}}
Block a malware domain
{"tool": "add_domain_to_block_list", "arguments": {"domain": "malware.example.com"}}
Create a new site definition
{
"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
{"tool": "disconnect_vpn_user", "arguments": {"user_id": "compromised-user"}}
Update a destination list
{
"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
- Never hardcode credentials. Always use
.envfiles or environment injection via Docker secrets, Kubernetes secrets, or cloud secret managers. - Rotate API keys regularly. Use
manage_resourcewith domain=admin, resource=api_keysto create/delete keys. - Use scoped API keys. Request only the permissions your use case needs.
- Run as non-root. The Docker image uses a dedicated
appuseraccount. - Restrict network access. Bind to
127.0.0.1if the MCP client runs locally, or use a VPN/firewall for remote access.
Deployment
- Use health checks. The
/healthendpoint enables container orchestration liveness checks. - Set resource limits. In docker-compose, add
deploy.resources.limitsfor CPU/memory. - Enable structured logging. Set
LOG_LEVEL=DEBUGfor troubleshooting,INFOfor production. - Monitor token usage. API key creation tracks scopes and usage patterns via
get_reportwithreport_type=api_usage.
Operational
- Prefer
manage_resourcefor CRUD. Covers 50+ endpoints with a single tool. Use dedicated tools only when convenience matters (e.g.,add_domain_to_block_list). - Use relative time offsets.
24h,7d,30mare simpler than ISO 8601 for most queries. - Paginate large result sets. Use
limitandoffsetparameters for list operations. - Handle rate limits gracefully. The server retries automatically, but design your workflow to space out high-volume queries.
- Backup destination lists. Before modifying block lists,
listthe 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
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






