Otto  background

From 18 to 80 Tools: Building the Most Complete AI Integration for Endpoint Management

80 tools, 6 workflow prompts, 18 modules, 9 resources, and enterprise-grade security for the Automox MCP Server

Connect With Us

See for yourself how policy-driven IT Automation saves time and eliminates risk.

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. Only dtstart is 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 ValidationError from echoing attacker-controlled input values back to the LLM

  • Applies 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_KEYS or AUTOMOX_MCP_API_KEY_FILE with --generate-key CLI (V-108). (2) OAuth 2.1/JWT auth via AUTOMOX_MCP_OAUTH_ISSUER with 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 headersX-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none'; frame-ancestors 'none', and Cache-Control: no-store on 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-bind opt-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. Literal type constraints, UUID validation, and bounds on pagination parameters (V-128). PolicyDefinition uses extra="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() before ToolError.

  • 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_uuid is 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 ForbidExtraModel

  • Read-only mode cannot be bypassed. Write tools are conditionally registered, not just gated.

  • Cross-organization access prevented. org_id is 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_call helpers – 17 duplicated error-handling envelopes across tool files replaced with a single call_tool_workflow() in utils/tooling.py (~500 lines removed).

  • Deduplicated_extract_list – Three identical implementations unified into extract_list() in utils/response.py.

  • Deduplicated_normalize_status – Two implementations (simple string-only and comprehensive Mapping/Sequence/string) were unified into normalize_status() in utils/response.py.

  • Extractedrequire_org_id helper – 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 refactoreddescribe_device – Three independent API calls now run concurrently via asyncio.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_AUDIENCE is mandatory when JWT auth is enabled, preventing token passthrough attacks.

  • Smoke test docstring clarified – Module docstring now explicitly documents the execute_device_command write 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.

Dive deeper into this topic