The Automox MCP Server has gone from 18 tools to 80 – with 6 guided workflow prompts, 18 modules, 9 MCP resources, and enterprise-grade security hardened against both the official MCP Security Best Practices specification and industry best practices. Coverage spans:
Device management and advanced device search
Policy lifecycle and policy execution analytics
Patch compliance and vulnerability remediation
Server groups and webhooks
Worklet discovery
Audit trails (including OCSF-formatted events)
Data extracts
Maintenance/exclusion windows
Fleet-wide reporting
Two authentication strategies secure remote HTTP/SSE deployments: static Bearer-token keys and OAuth 2.1/JWT with RFC 9728 Protected Resource Metadata. DNS rebinding protection and security response headers are enabled by default. It's the most complete AI integration surface for endpoint management available today.
| Metric | Initial Release | Current |
|---|---|---|
| Tools | 18 | 80 |
| Workflow Prompts | 0 | 6 |
| Modules | 4 | 18 |
| MCP Resources | 4 | 9 |
| Webhook Event Types | 0 | 39 |
| Test Coverage | ~45 tests (basic) | 91% (999 unit tests + 56 production smoke tests) |
| Configuration Options | 3 | 20 |
| Security Hardening Items | Basic (rate limiting, field redaction) | 98 documented items (V-001 – V-180, S-001 – S-006) |
| Dependency CVEs Resolved | – | 16 across 11 packages |
| Bugs Fixed | – | 131 |
| Lines Changed | – | +34,267 / -7,954 across 651 files |
Guided workflows: AI that knows the playbook
The biggest addition in the latest release is workflow prompts – pre-built, multi-step templates that guide an AI assistant through common admin tasks with a proven sequence of operations. Instead of hoping the LLM figures out the right approach, workflow prompts provide the playbook.
Six prompts ship today:
| Prompt | What It Does |
|---|---|
| Investigate a non-compliant device | Pulls device detail, inventory, installed packages, policy assignments, and recent execution history to diagnose why a device is out of compliance |
| Prepare for Patch Tuesday | Runs the pre-patch readiness report, reviews pending approvals, checks policy schedules, and identifies devices that need attention before the maintenance window |
| Audit a policy's execution history | Drills into a policy's run history using v2 analytics – execution counts, success/failure trends, per-device results, and time-range comparisons |
| Onboard a new device group | Walks through group creation, policy assignment, device verification, and initial scan – ensuring nothing is missed during onboarding |
| Triage a failed policy run | Pulls the failed run's results, identifies which devices failed and why, checks device connectivity, and surfaces related events for root cause analysis |
| Review fleet security posture | Generates a comprehensive posture assessment – compliance rates, health metrics, non-compliant device breakdown, stale devices, and policy coverage gaps |
This pattern – pioneered by Jamf's MCP server with 12 workflow templates – reduces hallucination risk. The LLM doesn't have to invent an investigation workflow. It follows one that's been validated.
> "Investigate why DESKTOP-4R2 is non-compliant."
The assistant follows the workflow prompt. It pulls device detail, checks 6 inventory categories, and lists 47 installed packages with patch status. It identifies 3 assigned policies, finds 2 recent failures in execution history, and surfaces the root cause – a failed Firefox update blocked by a pending reboot.
One question, one answer: compound workflows
Three compound tools combine multiple API calls into single, comprehensive responses – eliminating the back-and-forth that makes traditional API integrations slow and token-heavy.
Patch Tuesday Readiness – "Are we ready for Patch Tuesday?" returns devices needing patches (with per-device severity from CVE data), pending approvals, and active patch policy schedules in a single call.
Compliance Snapshot – "What's our compliance posture?" returns compliance rate, non-compliant devices with failing policies identified, device health breakdown, stale device detection, and policy summary by type.
Full Device Profile – "Give me everything on this device" returns device details, hardware/software inventory summarized by category, installed packages, policy assignments, pending commands, and device facts – all in one call.
Find any device: search and discovery
Advanced device search (new)
Six new tools expose the Server Groups API v2 for structured device queries that go far beyond simple hostname or IP search:
advanced_device_search– Execute structured queries with field-level filtering. Find all Windows devices not seen in 30 days, all devices with a specific software version, or any combination of metadata fields.list_saved_searches– Access pre-built search definitions for repeatable queries.device_search_typeahead– Get field-aware autocomplete suggestions as you build queries.get_device_metadata_fields– Discover all searchable fields and their types.get_device_assignments– See which policies and groups a device belongs to.get_device_by_uuid– Look up devices by UUID through the v2 API.
> "Find all Windows 10 devices that haven't checked in for more than 7 days and show their group assignments."
The assistant uses advanced_device_search with the right field filters, then enriches with get_device_assignments – returning a targeted list without scanning the entire fleet.
Device inventory: deep endpoint profiling
get_device_inventory– Hardware specs, network interfaces, security configuration, running services, system details, and user accounts. Filter by category (Hardware, Health, Network, Security, Services, Summary, System, Users) to get exactly what you need.get_device_inventory_categories– Discover what inventory categories are available for a specific device (categories are dynamic per endpoint).
Policy lifecycle: complete management and analytics
Policy CRUD
The policy management surface is complete:
apply_policy_changes– Create or update policies with automatic format correction. Normalizes friendly schedule blocks ({"days": ["monday"], "time": "02:00"}) into Automox bitmasks, auto-detects patch rules from filter fields, and ensures required fields are present.clone_policy– Clone with optional name and server group overrides.delete_policy– Permanent deletion by ID.execute_policy_now– Immediate execution for all devices or a specific target.policy_compliance_stats– Per-policy compliant vs. non-compliant device counts.
Policy History v2 (new)
Six new tools expose the Policy History API for richer execution analytics than the original timeline tools:
policy_runs_v2– List execution runs with time-range and status filters. "Show me all failed runs from last week."policy_run_count– Aggregate execution counts for trend analysis. "How many times did this policy run last month?"policy_runs_by_policy– Runs grouped by policy for cross-policy comparison. "Which policies have the most failures?"policy_runs_for_policy– All runs for a specific policy with filtering.policy_history_detail– Deep detail on a specific policy's history by UUID.policy_run_detail_v2– Per-device results for a specific run with UUID-based queries.
> "Compare failure rates across all patch policies for the last 30 days, then drill into the worst performer."
The assistant uses policy_runs_by_policy to compare across policies and identifies the highest failure rate. It then uses policy_run_detail_v2 to get per-device results for the most recent failed run.
Maintenance windows: schedule and protect
Nine new tools expose the Policy Windows API for managing maintenance and exclusion windows – time periods during which policy execution is suspended on specified device groups. This is critical for protecting change-sensitive environments (backup windows, month-end processing, production freezes) from unintended patching.
CRUD
create_policy_window– Create a maintenance window with RFC 5545 RRULE scheduling. Supports recurring windows (e.g., every Monday 2-4 AM) and one-time windows (e.g., a specific Saturday for a migration).get_policy_window– Retrieve full details for a specific window by UUID.update_policy_window– Partial update of an existing window. Onlydtstartis required, and all other fields are optional.delete_policy_window– Permanently remove a maintenance window.
Search and status
search_policy_windows– List and filter windows by group, status (active/inactive), and recurrence type (recurring/once). Supports pagination for organizations with many windows.check_group_exclusion_status– Check whether one or more server groups are currently within an active exclusion window. Returns a per-group boolean – essential before triggering manual policy runs.check_window_active– Check whether a specific window is currently active (status is "active", has groups assigned, and current time falls within an exclusion period).
Scheduling
get_group_scheduled_windows– Get upcoming maintenance periods for a server group with start/end times and window types.get_device_scheduled_windows– Get upcoming maintenance periods for a specific device.
> "Are any of our production groups currently in a maintenance window? If not, when is the next one?"
The assistant uses check_group_exclusion_status with the production group UUIDs and finds they're not currently excluded. It then calls get_group_scheduled_windows to show the next upcoming maintenance periods – answering the question in two calls.
Vulnerability management: CVE to patch (new)
Seven new tools expose the Vulnerability Sync API for end-to-end CVE-to-patch remediation workflows – a capability not found in competing endpoint management MCP servers:
list_remediation_action_sets– List all vulnerability remediation action sets with status and summary.get_action_set_detail– Detailed view of a specific action set.get_action_set_actions– The specific remediation actions (patches, updates) within an action set.get_action_set_issues– The CVEs and vulnerability issues that an action set addresses.get_action_set_solutions– Available solutions for the vulnerabilities in an action set.get_upload_formats– Supported CSV formats for uploading remediation data.upload_action_set– Upload CSV-based remediation data from vulnerability scanners.
> "Show me all open remediation action sets, then drill into the one with the most critical CVEs and list the affected devices."
The assistant lists action sets and identifies the highest-severity set. It pulls the issues to show the CVE list and pulls the actions to show which patches resolve them – connecting vulnerability data to remediation in a single conversation.
Audit and compliance
Audit v2: OCSF-formatted events (new)
The new audit_events_ocsf tool exposes the Audit Service v2 with industry-standard OCSF (Open Cybersecurity Schema Framework) formatted events. This provides richer audit data than the original /events endpoint:
Event categories: Authentication, account changes, entity management, user access, web resource activity
Cursor-based pagination for efficient traversal of large event sets
Category filtering to focus on specific event types
This aligns Automox audit data with the same schema used by CrowdStrike, AWS, and other OCSF adopters – enabling cross-platform audit correlation.
Events and reports
list_events– Organization events filtered by policy, device, user, or date range.audit_trail_user_activity– User-specific activity events by date.prepatch_report– Devices with pending patches before the next maintenance window.noncompliant_report– Devices that need attention right now.
Combined with device_health_metrics and policy_health_overview, your AI assistant generates comprehensive compliance reports on demand.
Operations and automation
Worklet catalog (new)
Two tools expose the community worklet catalog for discovering and inspecting pre-built automation scripts:
search_worklet_catalog– Search community worklets by keyword, OS, or category. "Find a worklet that checks disk encryption status on macOS."get_worklet_detail– View the full worklet including evaluation and remediation code before deploying.
Data extracts (new)
Three tools for bulk reporting workflows:
list_data_extracts– List available and completed data extracts.get_data_extract– Get extract details and download information.create_data_extract– Request a new data extract for large-scale reporting.
Webhook management
8 tools for the full webhook lifecycle. Create subscriptions with specific event types and HTTPS endpoints. Test connectivity before going live. Rotate signing secrets when credentials need rotation. Browse all 39 event types across device, policy, worklet, group, organization, and audit categories.
> "Set up a webhook that notifies our Slack channel when any device goes non-compliant or disconnects."
The assistant looks up the right event types, creates the webhook, saves the signing secret, and tests the endpoint – one interaction, start to finish.
Server group management
Full CRUD. List all groups with device counts and policy assignments. Create groups with parent hierarchies and refresh intervals. Update configurations and restructure as your environment evolves.
Package and patch visibility
list_device_packages shows exactly what's installed on a specific device – versions, patch status, and severity ratings. search_org_packages searches packages across your entire organization, filtered by managed status or packages awaiting installation.
Account management
Invite users with zone assignments, remove users by UUID, and list organization API keys (names and IDs only – secrets are never exposed).
Enterprise features
Correlation IDs
Every tool invocation is assigned a UUID that flows through to Automox API calls (via X-Correlation-ID header) and appears in response metadata. Structured logs record tool name, status, and latency at INFO level. This answers the enterprise question: "What did the agent do, and when?"
Idempotency keys
All write tools accept an optional request_id parameter. If an agent retries a failed request with the same request_id, the server returns the cached response instead of re-executing. No double-patching, no duplicate policy creation, no accidental webhook deletions. The async-safe cache automatically strips webhook secrets to avoid persisting one-time credentials in memory.
Token budget estimation
Responses are automatically checked against a configurable token budget (default ~4000 tokens). Oversized responses get a warning in metadata and list data is auto-truncated with a count of total available items. Set AUTOMOX_MCP_TOKEN_BUDGET to tune for your context window. Invalid values fall back gracefully to the default.
Markdown table output
List tools accept output_format=markdown to return compact Markdown tables instead of JSON. Saves 30-40% tokens for tabular data – meaningful when your agent is working within a context window.
Capability discovery
The discover_capabilities tool returns available tools by domain. An agent can ask "what can you do for devices?" without needing all 80 tool descriptions loaded. Always available regardless of module filtering.
MCP endpoint authentication
For remote HTTP/SSE deployments, the server supports two authentication strategies. Static API keys take priority when both are configured.
Option 1: Static API Keys – Simple bearer tokens for trusted clients:
# Generate a cryptographically secure API key
automox-mcp --generate-key
# amx_mcp_a1b2c3d4e5f6...
# Set via environment variable (comma-separated for multiple keys)
AUTOMOX_MCP_API_KEYS="alice:amx_mcp_abc123,bob:amx_mcp_def456"
# Or via key file (one per line, supports # comments and label:key format)
AUTOMOX_MCP_API_KEY_FILE=/etc/automox-mcp/keys.txt
Labelled keys (alice:amx_mcp_...) produce named client IDs that appear in logs for audit trail attribution.
Option 2: OAuth 2.1 / JWT – Validate JWTs from external IdPs (Keycloak, Auth0, Azure AD, Okta) with audience binding, issuer validation, and automatic JWKS key rotation:
AUTOMOX_MCP_OAUTH_ISSUER="https://auth.example.com/realms/main"
AUTOMOX_MCP_OAUTH_JWKS_URI="https://auth.example.com/realms/main/protocol/openid-connect/certs"
AUTOMOX_MCP_OAUTH_AUDIENCE="https://mcp.example.com"
AUTOMOX_MCP_OAUTH_SERVER_URL="https://mcp.example.com" # enables RFC 9728 metadata
AUTOMOX_MCP_OAUTH_SCOPES="mcp:tools" # optional
When AUTOMOX_MCP_OAUTH_SERVER_URL is set, the server serves RFC 9728 Protected Resource Metadata at /.well-known/oauth-protected-resource/<path> and returns proper WWW-Authenticate headers with resource_metadata URLs on 401/403 responses – enabling MCP clients to discover the authorization server automatically.
The audience binding (AUTOMOX_MCP_OAUTH_AUDIENCE) is required when JWT authentication is enabled (V-136). Without audience binding, any valid token from the configured issuer would be accepted, enabling cross-service token reuse – the confused deputy attack described in the MCP Security Best Practices. The server refuses to start if AUTOMOX_MCP_OAUTH_ISSUER is set without AUTOMOX_MCP_OAUTH_AUDIENCE.
Both options are independent of the Automox API key (AUTOMOX_API_KEY) and have no effect on stdio transport.
This closes and exceeds the gap with CrowdStrike's Falcon MCP, which uses self-generated API keys but does not yet support OAuth 2.1/JWT or RFC 9728 metadata.
DNS rebinding protection
The server validates Host and Origin headers on all HTTP/SSE connections to prevent DNS rebinding attacks, as required by the MCP transport specification. Enabled by default with no configuration needed – the server automatically allows the bound host:port and loopback aliases. Missing Host headers receive 400 Bad Request (V-123). Invalid Host headers receive 421 Misdirected Request. Invalid Origins receive 403 Forbidden.
# Add additional allowed origins (e.g., your web dashboard)
AUTOMOX_MCP_ALLOWED_ORIGINS="https://app.example.com,https://dashboard.example.com"
# Add additional allowed hosts
AUTOMOX_MCP_ALLOWED_HOSTS="proxy.internal:443"
Security response headers
All HTTP responses include security headers by default: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none'; frame-ancestors 'none', Cache-Control: no-store, Referrer-Policy: strict-origin-when-cross-origin, and Permissions-Policy. These prevent clickjacking, MIME sniffing, and caching of sensitive API responses.
Structured JSON logging
Enable AUTOMOX_MCP_LOG_FORMAT=json and every log line becomes a structured JSON object with timestamp, level, correlation_id, tool_name, event, latency_ms, and status. Forward directly to your SIEM for audit trail analysis, anomaly detection, and compliance reporting.
Tool name prefixing
Running multiple MCP servers side by side? Set AUTOMOX_MCP_TOOL_PREFIX=automox and all 80 tools are renamed (e.g., automox_list_devices, automox_policy_catalog). Prevents tool name collisions when your agent has access to Automox alongside CrowdStrike, Okta, or other MCP servers.
Prompt injection sanitization
Every tool response passes through sanitize_for_llm() before reaching the LLM. This centralized sanitization layer:
Strips markdown link and image syntax that could exfiltrate data via embedded URLs
Removes fenced code blocks containing shell or script commands
Detects and removes instruction-like prefixes (IMPORTANT:, SYSTEM:, IGNORE PREVIOUS, EXECUTE:, TOOL_CALL:, etc. – 20+ patterns) from free-text fields like notes and descriptions
Preserves legitimate names and tags where users commonly use words like "IMPORTANT" or "SYSTEM"
Redacts data at depth limits instead of passing deeply nested structures through unsanitized
Escapes remaining triple backticks to prevent breaking out of data context
Sanitizes validation error messages (V-124) to prevent Pydantic
ValidationErrorfrom echoing attacker-controlled input values back to the LLMApplies Unicode NFKC normalization (V-108a) and strips zero-width/invisible characters before pattern matching, defeating homoglyph bypass attacks
Configurable via AUTOMOX_MCP_SANITIZE_RESPONSES (default: enabled). For environments where prompt injection risk is handled at the gateway layer, disable to pass through raw API data.
Supply chain security: Sigstore and SBOM
Every release is signed with Sigstore using GitHub's OIDC identity – no long-lived signing keys to manage or rotate. Consumers verify provenance with a single command:
pip install sigstore
python -m sigstore verify identity \
--cert-identity "https://github.com/AutomoxCommunity/automox-mcp/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
--cert-oidc-issuer "https://token.actions.githubusercontent.com" \
automox_mcp-X.Y.Z.tar.gz
Each release also includes a CycloneDX SBOM (sbom.cdx.json) listing all dependencies – meeting SLSA Build Level 1 and enabling software composition analysis before deployment.
Dependabot monitors both GitHub Actions and Python dependencies with weekly update checks.
Configuration: precise control
| Variable | Purpose |
|---|---|
AUTOMOX_MCP_READ_ONLY |
Disable all write tools (read-only tools remain) |
AUTOMOX_MCP_MODULES |
Load only specific domains (e.g., devices,policies,vuln_sync,policy_windows). Warns on unrecognized names. |
AUTOMOX_MCP_TOKEN_BUDGET |
Set token budget threshold for response warnings (default: 4000) |
AUTOMOX_MCP_SANITIZE_RESPONSES |
Enable/disable prompt injection sanitization (default: true) |
AUTOMOX_MCP_TOOL_PREFIX |
Prefix all tool names to prevent cross-server collisions |
AUTOMOX_MCP_LOG_FORMAT |
Log format: text (default) or json for SIEM integration |
AUTOMOX_MCP_TRANSPORT |
Transport: stdio (default), http, or sse |
AUTOMOX_MCP_HOST |
Bind address for HTTP/SSE (default: 127.0.0.1) |
AUTOMOX_MCP_PORT |
Port for HTTP/SSE (default: 8000) |
AUTOMOX_MCP_API_KEYS |
Comma-separated MCP endpoint API keys for HTTP/SSE Bearer-token auth (e.g., key1,label:key2) |
AUTOMOX_MCP_API_KEY_FILE |
Path to a file containing MCP endpoint API keys (one per line, supports # comments and label:key format) |
AUTOMOX_MCP_OAUTH_ISSUER |
OIDC issuer URL for JWT auth (e.g., https://auth.example.com/realms/main) |
AUTOMOX_MCP_OAUTH_JWKS_URI |
JWKS endpoint for JWT key rotation (auto-derived from issuer if omitted) |
AUTOMOX_MCP_OAUTH_AUDIENCE |
Expected JWT audience claim. Required when AUTOMOX_MCP_OAUTH_ISSUER is set (V-136). |
AUTOMOX_MCP_OAUTH_SERVER_URL |
Canonical server URL. Enables RFC 9728 Protected Resource Metadata. |
AUTOMOX_MCP_OAUTH_SCOPES |
Comma-separated required OAuth scopes |
AUTOMOX_MCP_ALLOWED_ORIGINS |
Extra allowed Origin headers for DNS rebinding protection (comma-separated) |
AUTOMOX_MCP_ALLOWED_HOSTS |
Extra allowed Host headers for DNS rebinding protection (comma-separated) |
AUTOMOX_MCP_DNS_REBINDING_PROTECTION |
Enable/disable DNS rebinding protection (default: true) |
AUTOMOX_MCP_ALLOW_REMOTE_BIND |
Allow binding to non-loopback addresses (default: false) |
Both AUTOMOX_MCP_READ_ONLY and AUTOMOX_MCP_MODULES compose naturally – AUTOMOX_MCP_READ_ONLY=true with AUTOMOX_MCP_MODULES=devices,policies gives you a focused, read-only device and policy dashboard.
The discover_capabilities meta-tool is always available regardless of module filtering.
9 MCP resources
Reference data available without tool calls – improving LLM reasoning quality and reducing round-trips:
| Resource | What It Provides |
|---|---|
resource://policies/quick-start |
Copy-paste policy creation templates |
resource://policies/schema |
Full policy schema for create/update |
resource://policies/schedule-syntax |
Schedule bitmask reference |
resource://servergroups/list |
Live group ID-to-name mapping |
resource://webhooks/event-types |
All 39 event types by category |
resource://filters/syntax |
Device filtering reference |
resource://patches/categories |
Severity levels, patch rules, package fields |
resource://platform/supported-os |
OS matrix with versions and architectures |
resource://api/rate-limits |
Rate limiter config and efficiency tips |
Security
The server implements layered security benchmarked against the official MCP Security Best Practices specification, the MCP Authorization specification, and the Wiz MCP Security Best Practices cheat sheet, with 98 documented hardening items:
MCP endpoint authentication – Two strategies. (1) Static Bearer-token auth via
AUTOMOX_MCP_API_KEYSorAUTOMOX_MCP_API_KEY_FILEwith--generate-keyCLI (V-108). (2) OAuth 2.1/JWT auth viaAUTOMOX_MCP_OAUTH_ISSUERwith JWKS key rotation, audience binding, and RFC 9728 Protected Resource Metadata (V-122). Static keys take priority when both are configured.DNS rebinding protection – Origin and Host header validation on all HTTP/SSE connections per the MCP transport specification. Missing Host headers are rejected with 400 (V-123). Invalid Host headers receive 421. Invalid Origins receive 403. Enabled by default (V-120).
Security response headers –
X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Content-Security-Policy: default-src 'none'; frame-ancestors 'none', andCache-Control: no-storeon all HTTP responses (V-121).Token passthrough prevention – JWT audience binding is mandatory when JWT auth is enabled (V-136). Tokens must be specifically issued for this server, preventing the confused deputy attack described in the MCP Security Best Practices.
Read-only mode – One env var disables all 22 write operations.
Prompt injection sanitization – All tool responses are sanitized via
sanitize_for_llm()before reaching the LLM. The sanitizer strips markdown exfiltration vectors, code blocks, and instruction prefixes. Validation error messages are sanitized to prevent input echo (V-124). Unicode NFKC normalization defeats homoglyph bypass (V-108a). Configurable via env var.SSRF prevention – Webhook URLs are validated against private/loopback/link-local IPs and cloud metadata endpoints (169.254.169.254, fd00::, etc.) with best-effort DNS resolution to catch hostnames that resolve to private addresses (V-126). DNS resolution runs in a ThreadPoolExecutor to avoid blocking the event loop (V-165). Unresolvable hostnames are rejected fail-closed (S-006).
Remote bind protection – Non-loopback HTTP/SSE binding requires explicit
--allow-remote-bindopt-in. The server exits with an error otherwise. Warnings distinguish auth-enabled vs auth-disabled deployments.Input validation – Pydantic models with
extra="forbid"on every tool.Literaltype constraints, UUID validation, and bounds on pagination parameters (V-128).PolicyDefinitionusesextra="ignore"to drop unknown fields. Unbounded dict payloads are capped at 50KB (V-159).HTTPS enforcement – Webhook URLs are validated via
urllib.parse.urlparse()to verify https scheme, require a valid hostname, and reject URLs containing userinfo (user:pass@host). OAuth issuer URL is validated for HTTPS scheme (V-137). JWKS URI is validated for HTTPS scheme (V-173).Sensitive field redaction – 10 keyword patterns (
token,secret,key,password,credential,auth,bearer,passwd,api-key,apikey) scrub sensitive data from error responses and audit payloads. Presigned download URLs are redacted to prevent credential leakage (V-169).API key file security – World-readable key files are refused at startup. Group-readable files produce a warning (V-127).
Authentication rate limiting – Blocks IPs after 10 failed auth attempts within 60 seconds with a 5-minute block period (V-140). Periodic cleanup prevents memory exhaustion from IP rotation attacks (V-153).
Rate limiting – Sliding window (30 calls/60s) with async lock.
Pagination safety – Auto-pagination loops capped at 50 pages to prevent runaway API calls.
Private API key storage – Bearer token injected per-request, never stored in shared headers. Whitespace is auto-stripped.
__repr__and__slots__prevent accidental exposure in debug output (V-146).Generic error messages – Unexpected exceptions are logged server-side. Only generic messages are returned to MCP clients (no file paths, stack traces, or internal details). Error messages are sanitized through
sanitize_for_llm()beforeToolError.Idempotency cache security – Webhook secrets are stripped from cached responses after creation. Atomic reservation prevents TOCTOU duplicate writes (V-170). Expired entries are proactively cleaned.
Path injection prevention – UUID format validation on all API-derived values before URL path interpolation (V-156, V-168, V-171).
account_uuidis validated at client construction time.Depth-limit redaction – Deeply nested data is redacted at sanitization depth limit instead of passed through unsanitized. Recursion depth is capped at 10 to 20 levels across merge, redaction, and status normalization functions (V-167).
Sigstore-signed releases – CycloneDX SBOM attached to each release (SLSA Build Level 1)
Dependabot – Monitors both GitHub Actions and Python dependencies
Bandit – Static security analysis in pre-commit hooks
Security documentation
SECURITY.md – Threat model covering 6 attack surfaces (supply chain, credential exposure, prompt injection, privilege escalation, network exposure, denial of service) with mitigations for each. Vulnerability disclosure process. Security features reference table mapping all 98 hardening items to affected files.
Deployment Security Guide covers:
Container hardening (non-root, multi-stage, read-only filesystem)
Kubernetes pod security (seccomp, capabilities, resource quotas, egress network policy)
MCP gateway configuration (mTLS, audit logging, inline guardrails)
Authentication/authorization patterns by transport (static keys and OAuth 2.1/JWT with RFC 9728)
DNS rebinding protection configuration
Security response headers
Compliance mapping (ISO 42001, SOC 2, GDPR Art. 32)
Pre-production checklist
Security scan results
Multiple rounds of vulnerability scanning using git archaeology, dangerous pattern scanning, and algorithmic reasoning identified findings across 6 patch releases (1.0.1 – 1.0.6) – all remediated:
No command/code injection, path traversal, SSRF, or deserialization risks
No hardcoded secrets in code or git history
Proper input validation on all 80 tool parameters via Pydantic with
ForbidExtraModelRead-only mode cannot be bypassed. Write tools are conditionally registered, not just gated.
Cross-organization access prevented.
org_idis injected from environment, not user-controllable.Race conditions mitigated. Idempotency cache is protected by atomic reservation with
asyncio.Lock(V-170).Denial of service prevented. All pagination limits are bounded (max 500), rate limiter enforced, recursion depth capped, and unbounded payloads rejected (V-159).
Validation error messages sanitized before reaching the LLM (V-124)
Webhook URLs checked via non-blocking DNS resolution against private IP ranges (V-126, V-165)
World-readable API key files blocked at startup (V-127)
JWT algorithm confusion attacks prevented – HMAC algorithms rejected with JWKS (V-150)
Presigned cloud storage URLs redacted to prevent credential leakage (V-169)
MCP prompt parameters validated to prevent prompt injection (V-163)
Post-release hardening: 1.0.1 through 1.0.11
Eleven patch releases following the initial 1.0.0 launch addressed 131 bugs, resolved 16 dependency CVEs across 11 packages, and expanded security hardening from 41 to 98 documented items. The fixes were driven by three sources: automated vulnerability scanning, manual code review, and production smoke testing.
Code review
An external code review of the 1.0.0 release identified 8 improvement areas – all resolved:
Consolidated
_callhelpers – 17 duplicated error-handling envelopes across tool files replaced with a singlecall_tool_workflow()inutils/tooling.py(~500 lines removed).Deduplicated
_extract_list– Three identical implementations unified intoextract_list()inutils/response.py.Deduplicated
_normalize_status– Two implementations (simple string-only and comprehensive Mapping/Sequence/string) were unified intonormalize_status()inutils/response.py.Extracted
require_org_idhelper – 17 instances of 3-line org_id resolution boilerplate replaced with a shared helper (with improved None-check semantics, fixing V-157).Removed orphaned schemas – ~40 unused schema classes (~305 lines) deleted from
schemas.py.Parallelized and refactored
describe_device– Three independent API calls now run concurrently viaasyncio.gather. Core field assembly extracted into_build_device_core()helper, reducing the function from 264 to ~200 lines.JWT audience enforcement hardened – Upgraded from a startup warning to a hard requirement (V-136):
AUTOMOX_MCP_OAUTH_AUDIENCEis mandatory when JWT auth is enabled, preventing token passthrough attacks.Smoke test docstring clarified – Module docstring now explicitly documents the
execute_device_commandwrite operation and its idempotent nature.
Notable security fixes (1.0.1 – 1.0.11)
| Version | Key Fixes |
|---|---|
| 1.0.1 | Webhook PATCH semantics, pagination flag accuracy, org_id no longer required at startup |
| 1.0.2 | Report pagination, org_id whitespace handling, token budget edge cases |
| 1.0.3 | Audit actor resolution (V-129), IPv6 DNS rebinding (V-130 – V-131), 14 workflow bugs |
| 1.0.4 | URL path injection (V-132), HTML/script stripping (V-133), JWT audience required (V-136), auth rate limiting (V-140), HSTS (V-141), input bounds on 20+ schemas (V-148) |
| 1.0.5 | HMAC+JWKS key confusion (V-150), sanitization bypass (V-151), memory DoS in auth limiter (V-153), prompt injection via MCP prompts (V-163), confirmation gates on destructive actions (V-164) |
| 1.0.6 | Non-blocking DNS resolution (V-165), presigned URL redaction (V-169), atomic idempotency (V-170), account_uuid validation (V-171) |
| 1.0.7 | OIDC discovery (V-172), JWKS HTTPS enforcement (V-173), public key file validation (V-174), bitmask fixes (V-175 – V-177), null-safe group policies (V-178), rate limiter eviction (V-179), sanitizer catch-all (V-180) |
| 1.0.8 | E501 lint failures, mypy CI configuration (exclude tests, fix 3 src type errors) |
| 1.0.9 | CI coverage gate (89.35% to 90.75%): 23 new tests for AuthRateLimitMiddleware, _env_flag, IPv6 parsing, events edge cases |
| 1.0.10 | Upgraded fastmcp from 2.x to 3.x. Resolved 16 dependency CVEs across 11 packages (authlib, cryptography, fastmcp, jaraco-context, mcp, pygments, pyjwt, python-multipart, requests, urllib3, diskcache). |
| 1.0.11 | Fixed mcp-scanner v4.x CI compatibility (subcommand, arg ordering, output parsing). Fixed flaky rate-limit tests using shared module state. Fixed release workflow (cyclonedx-bom v7 CLI flags, Sigstore/PyPI step ordering). |
All 999 tests continue to pass at 91% coverage. Ruff and mypy remain clean across all source files.
Get started
Already running the Automox MCP Server? Update to the latest version:
# uvx (Quick Start method) -- force a cache refresh
uvx --refresh automox-mcp
# uv tool install
uv tool upgrade automox-mcp
# pip
pip install --upgrade automox-mcp
Note:uvx automatically refreshes its cache roughly every 7 days, so most users will pick up new releases without action. Run uvx --refresh to get the latest immediately.
New to MCP? Get started in one command:
uvx --env-file .env automox-mcp
For remote deployments with static key authentication:
# Generate an API key
automox-mcp --generate-key
# Run with HTTP transport and endpoint auth
AUTOMOX_MCP_API_KEYS="amx_mcp_..." uvx --env-file .env automox-mcp --transport http --allow-remote-bind
For enterprise deployments with OAuth/JWT:
AUTOMOX_MCP_OAUTH_ISSUER="https://auth.example.com/realms/main" \
AUTOMOX_MCP_OAUTH_AUDIENCE="https://mcp.example.com" \
AUTOMOX_MCP_OAUTH_SERVER_URL="https://mcp.example.com" \
uvx --env-file .env automox-mcp --transport http --allow-remote-bind
Full setup instructions, editor integrations, and configuration details are in the README.

)
)
)
)
)