Architecture
Internal architecture of Qualys MCP Server v0.1.0 — layered workflow design, caching, concurrency, and request deduplication.
System Overview
Qualys MCP v0.1.0 uses a four-layer architecture: 7 MCP tool wrappers dispatch to 5 workflow modules, which orchestrate 42 aggregator functions, which call the Qualys APIs through a shared HTTP + caching layer.
AI Assistant (Claude, etc.)
|
v MCP tool call (one of 7 tools)
FastMCP Server (qualys_mcp.py)
|
+-- 7 @mcp.tool() wrappers
| investigate, assess_risk, check_compliance,
| plan_remediation, security_overview, reports, cache_status
|
+-- qualys/workflows/ (5 workflow modules)
| investigate.py, assess_risk.py, compliance.py,
| remediation.py, overview.py
|
+-- qualys/aggregators.py (42 aggregator functions)
| Each aggregator wraps one or more Qualys API calls
|
+-- qualys/api.py (HTTP + caching)
_run_concurrent() -- ThreadPoolExecutor(max_workers=8)
_get_or_fetch() -- request deduplication
Tiered in-memory caches
Workflow Layer
Each workflow module receives parameters from its MCP tool wrapper and orchestrates multiple aggregator calls in parallel. The workflow handles:
- Intent classification — determines which aggregators to call based on parameters (e.g., target="CVE-2024-3400" triggers CVE investigation aggregators)
- Parallel dispatch — fires multiple aggregators concurrently via
_run_concurrent() - Cross-source correlation — identifies connections across data sources (e.g., a CVE affecting assets that also have cloud misconfigurations)
- Response envelope assembly — structures results into summary, data, correlations, and actions sections
Workflow Modules
| Module | MCP Tool | Scope |
|---|---|---|
workflows/investigate.py | investigate | CVE deep-dive, threat actors, asset investigation, EDR/FIM events, KB search |
workflows/assess_risk.py | assess_risk | VMs, cloud, containers, web apps, certificates, assets |
workflows/compliance.py | check_compliance | Framework posture, failing controls, risk acceptances |
workflows/remediation.py | plan_remediation | Patch priorities, deployment status, mitigation coverage |
workflows/overview.py | security_overview | Daily/weekly/monthly briefing, scanner health, ETM findings |
Aggregator Layer
The 42 aggregator functions in qualys/aggregators.py are the building blocks of every workflow. Each aggregator wraps one or more Qualys API calls, normalizes the response data, and returns a structured dict. Aggregators are stateless and composable — any workflow can call any aggregator.
Cache Architecture
Tiered in-memory cache with TTLs matched to data volatility:
| Cache | TTL | Key Strategy |
|---|---|---|
| Bearer token | 3.5 hours | Single global token |
| KB entries | 1 hour | Per-QID |
| VMDR detections | 5 minutes | Per severity_days_qds_min |
| QDS scores | 5 minutes | Per-QID |
| WAS findings | 10 minutes | Per query params |
| Scanner list | 5 minutes | Single global list |
| ETM results | 1 hour | Single global (unfiltered) |
Cache warmup runs on startup via a background thread (_warmup_vmdr_cache()) so the first real query hits warm caches.
Request Deduplication
The _get_or_fetch() helper uses per-key locks to ensure that when multiple aggregators request the same data concurrently, only one thread makes the API call while others wait for the result:
def _get_or_fetch(cache_key, fetch_fn, ttl=300):
# Fast path -- cache hit
hit, data = _cache_get(cache_key)
if hit:
return data
# Slow path -- per-key lock, double-check
with FETCH_LOCKS[cache_key]:
hit, data = _cache_get(cache_key)
if hit:
return data
data = fetch_fn()
_cache_set(cache_key, data, ttl)
return data
Concurrency Model
ThreadPoolExecutor(max_workers=8) via _run_concurrent() parallelizes independent API calls within a single workflow invocation. Each workflow dispatches its aggregator calls concurrently, and cloud provider fetches (AWS, Azure, GCP) run in parallel rather than sequentially.
Performance Budget
Target: all tool responses under 15 seconds. Measured performance:
| Tool | Typical Latency | Notes |
|---|---|---|
security_overview (quick) | ~1.7s | CSAM-heavy, all cached |
check_compliance (cached) | ~2ms | Cached compliance data |
assess_risk (containers) | ~3s | Container image scan |
investigate (CVE, standard) | ~8-15s | KB + CSAM + threat intel |
investigate (CVE, deep) | ~15-45s | All sources + summary |