action1-mcp-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@action1-mcp-serverlist endpoints offline for more than 24 hours"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
action1-mcp-server
A production-grade Model Context Protocol (MCP) server for the Action1 RMM REST API. Wraps the entire Action1 API surface so that Claude (or any other MCP host) can run PowerShell on Windows, Bash on macOS, deploy updates, reboot endpoints, search audit trails, build CVE remediation plans, and more — all via natural language and with a three-layer destructive guard so the LLM cannot accidentally mutate production state.
Status: v0.5.0 — 100 % coverage of the pinned Action1 OpenAPI 3.1.0 spec, exposed as 166 tools (33 curated incl. 6 workflow wrappers + 133 auto-generated) with pinned SHA, hybrid architecture, three-layer destructive guard, stdio and Streamable HTTP transports, Docker image, MCPB bundle, CI. Full conformance pass against the Anthropic
mcp-builderskill best practices (server name, tool annotations, response_format, output schemas, Markdown rendering, character limits, evaluation suite).
Why this project
Action1 has a clean REST API but a thick layer of LLM-unfriendly quirks that, if unhandled, silently produce wrong results:
macOS Bash actions need a ten-field
run_scriptpayload the API returnsnot applicable to Mac platformfor any field that is missing.Windows PowerShell actions need a non-empty
success_exit_codes.last_seenisYYYY-MM-DD_HH-MM-SS(UTC), not ISO-8601 —Date.parsereturnsNaN(we render it human-readable in Markdown output).The
selfURL of a list-endpoint includes a/generalsegment that is not a real REST resource.The script-output stream is interleaved with
Starting/Waiting/Completedlifecycle markers that need to be filtered.OSis upper-case,platformis lower-case, both can carry the platform string; we normalise via a single detector.
This server encodes all of those. See
docs/api-coverage-gaps.md §"Cross-repo
comparison" for what other Action1 MCP projects miss.
Related MCP server: action1-mcp
Highlights
100 % API coverage — every operation in the pinned Action1 OpenAPI 3.1.0 spec is reachable through exactly one MCP tool. Mapping in
docs/api-coverage.md. The pin is enforced by a unit test (tests/unit/specSha.test.ts) so an upstream spec change fails the build instead of silently rotting the surface.Hybrid architecture — hand-curated tools that encode the quirks above + auto-generated tools from the spec + high-level workflow wrappers (CVE remediation plan, audit log search, software inventory, recurring schedules, report export, group resolver).
MCP-protocol completeness — beyond tools, the server also ships:
7 Resources (
action1://me,://orgs,://templates,://reports,://endpoints/{orgId},://groups/{orgId},://vulnerabilities/{orgId}) for hosts that pre-fetch context. All list-shaped resources are capped to fit the 1 MB host limit and emit a truncation note when the cap fires.6 Slash-Prompts (
/patch-windows-fleet,/audit-vulnerabilities,/triage-offline-endpoints,/run-script-fleetwide,/software-inventory-sweep,/check-my-permissions) for one-click workflows.logging/setLevel— clients can dynamically bump or lower verbosity at runtime.Cancellation propagation — long-running tools (
auto_paginate,wait_for_automation,execute_and_wait) honour the host's AbortSignal.outputSchemadeclared on every list-shaped read tool for client-side validation.
Skill-conformant tools — every tool emits
response_format(markdowndefault,jsonopt-in), a structured description withArgs / Returns / Examples / Error Handlingsections, all four annotations (readOnlyHint,destructiveHint,idempotentHint,openWorldHint) explicitly set, andtotal/count/next_cursor/has_moreon every paginated response.Markdown rendering with humanised values — Action1 timestamps (
YYYY-MM-DD_HH-MM-SS) render asYYYY-MM-DD HH:MM:SS UTC; ID columns lead the table; per-toolCHARACTER_LIMIT = 25_000keeps agent context lean.Three-layer destructive guard —
ACTION1_ALLOW_DESTRUCTIVEenv switch + per-callconfirm: "YES"+dry_run: true(default). The LLM cannot accidentally mutate production state. OptionalACTION1_DESTRUCTIVE_AUTO_CONFIRMfor isolated single-operator setups (still requires the env switch).Sound auth — OAuth2 client-credentials with proactive 5-minute refresh, in-flight deduplication of concurrent token requests, and refresh_token-first fallback when re-acquiring.
Robust transport — retry with exponential backoff for DNS hiccups, HTTP 5xx, and 429 (honors
Retry-After). Pagination walkslimit/fromtransparently with caller-supplied caps.Both transports — stdio (default; for local Claude Code / Cursor / Claude Desktop) + Streamable HTTP, stateless (for hosted Claude.ai custom connectors / team setups). HTTP transport supports bearer-token auth via
MCP_HTTP_TOKEN(constant-time compare), a 1 MB body limit, and hard-fails on non-loopback bind without an Origin allowlist.Distribution — Docker image,
compose.yml, MCPB bundle for Claude Desktop one-click install, npm publish-ready.Observability — structured JSON-line logs to stderr with auto-redaction of
Bearer …,api-key-…, and any property whose key looks sensitive (authorization,*_token,*_secret,password, …). Stdout reserved for MCP JSON-RPC.Strict TypeScript with Zod input schemas on every tool. 527 tests across 4 categories (unit / integration / security / performance).
Quickstart
git clone https://github.com/mguttmann/action1-mcp.git
cd action1-mcp
npm install
cp .env.example .env # edit with your Action1 credentials
npm run build
npm run inspector # opens MCP Inspector against the built serverOr with Docker (build locally until the first tagged release populates GHCR):
docker build -t action1-mcp:local .
docker run --rm -i --env-file .env action1-mcp:local
# or for HTTP: docker compose up -d (after editing compose.yml's `image:`)Or attach directly to Claude Code:
claude mcp add action1 -- node --env-file=$(pwd)/.env $(pwd)/dist/index.jsFor the full installation walkthrough — including Claude Desktop, Claude.ai,
Cursor, Continue.dev, and Cody — see docs/INSTALLATION.md.
Architecture
┌──────────────────────────────────────────────────────────────────────┐
│ Curated tools + Workflow wrappers │
│ • script execution (Win + Mac + OS-aware) │
│ • execute_and_wait (POST + poll + filtered output) │
│ • get_endpoint with /general → canonical path + list-fallback │
│ • CVE remediation plan, audit log search, software inventory, … │
├──────────────────────────────────────────────────────────────────────┤
│ Auto-generated tools │
│ • one tool per remaining spec operation, verb-first snake_case names │
│ • shared runtime: pagination, destructive guard, error mapping │
│ • Action1 OpenAPI 3.1.0 pinned at SHA af75f1cc… │
├──────────────────────────────────────────────────────────────────────┤
│ Shared infrastructure │
│ • Action1Client (auth, retry, pagination, error mapping) │
│ • TokenProvider (refresh_token fallback, 5-min proactive refresh) │
│ • OrgResolver (fuzzy name match, session cache) │
│ • Three-layer destructive guard (env + confirm + dry_run) │
│ • Structured stderr logger with auto-key redaction │
│ • Markdown auto-table renderer (humanises Action1 timestamps) │
│ • Per-tool CHARACTER_LIMIT = 25_000 + WIRE_LIMIT_BYTES = 400_000 │
└──────────────────────────────────────────────────────────────────────┘When a curated tool and an auto-generated tool address the same path, the
curated one wins by name and the auto-generated one is suppressed via
src/codegen/curated-overrides.ts. See
docs/api-coverage.md for the full mapping.
Configuration
All configuration is via environment variables; copy
.env.example to .env and fill in.
Variable | Required | Default | Description |
| yes | — | Region-specific instance, e.g. |
| yes | — | OAuth2 client id from Action1 → Settings → API Credentials. |
| yes | — | OAuth2 client secret. Shown once at credential creation. |
| recommended | — | Default org UUID. Each tool can override via |
| no |
| Per-action timeout (PowerShell, etc.). |
| no |
| Window during which Action1 retries when an endpoint is offline. |
| no |
| One of |
| no |
| Minutes since |
| no |
| Set to |
| no |
| Single-operator only: waives the per-call |
| no |
| HTTP transport port. |
| no |
| HTTP transport host. |
| no | unset | Required |
| no | unset | Comma-separated allowlist for browser |
| no |
| Reverse-proxy hop trust for correct client IPs in rate-limiting. One of |
Connecting to MCP hosts
Host | Transport | Doc |
Claude Code (CLI) | stdio | |
Claude Desktop (macOS / Windows) | stdio | |
Claude.ai (web) | Streamable HTTP | |
Cursor | stdio | |
Continue.dev / Cody | stdio |
Tools
See docs/USAGE.md for the full tool reference and
docs/EXAMPLES.md for end-to-end recipes.
A summary of the curated layer (the auto-generated layer is the long
tail and is documented operation-by-operation in docs/api-coverage.md):
Discovery (read-only)
action1_list_organizations, action1_list_endpoints,
action1_endpoints_summary (server-side aggregation: ~1 KB regardless
of fleet size), action1_get_endpoint (with /general → canonical
path fallback, plus derived platform and connectivity.online),
action1_search_endpoints (substring filter on hostname / user / OS /
status), action1_list_action_templates, action1_get_action_template,
action1_list_missing_updates, action1_list_vulnerabilities (graceful
403 if scope absent), action1_list_recent_automations,
action1_automations_summary.
Execution (destructive — guard required)
action1_run_powershell (Windows; auto-fills success_exit_codes),
action1_run_bash_macos (macOS; auto-fills the ten run_script fields),
action1_run_script (auto-routes by OS), action1_reboot_endpoint,
action1_deploy_update (spec-conformant {scope, packages, reboot_options}),
action1_deploy_package, action1_uninstall_program,
action1_run_data_collection. All accept target_type: "Endpoint" (default)
or "EndpointGroup" for bulk fan-out.
Polling / results (read-only)
action1_get_automation_status, action1_get_automation_results,
action1_get_automation_output (filters Starting/Waiting/Completed),
action1_wait_for_automation.
Workflows (destructive)
action1_execute_and_wait — start an action, poll until it terminates,
return the filtered output. Auto-routes by OS for mode: "script" or runs
a named template for mode: "template".
High-level wrappers
action1_endpoint_groups_resolve (fuzzy name → UUID),
action1_software_inventory_for_endpoint, action1_recurring_schedules,
action1_audit_log_search, action1_report_export,
action1_cve_remediation_plan.
Auto-generated
Every remaining Action1 API operation as a verb-first snake_case tool.
See docs/api-coverage.md. All input parameter
names are normalised to snake_case for consistency with the curated
layer.
Resources
Seven MCP resources for hosts that pre-fetch context:
URI | Purpose |
| The authenticated identity / role / permissions. Use this as a startup probe to know which tool families will 403. |
| All visible organizations. |
| Action template catalog. |
| Report catalog. |
| Live endpoint snapshot per org. Pass |
| Endpoint groups. |
| Org-wide CVE rollup. May 403 if the role lacks |
All list-shaped resources are capped at ~400 KB and emit a truncation note when the cap fires; the equivalent paginated tool gives unbounded data via cursor chaining.
Slash-prompts
Six host-surfaced workflows for the most common day-to-day jobs:
Prompt | Args | What it does |
|
| Resolves the group, lists missing updates, previews and (after confirmation) deploys. |
|
| Surveys org-wide vulnerabilities, ranks the worst, presents a remediation plan. |
|
| Walks the inventory, surfaces endpoints whose |
|
| Validates the script is read-only, dispatches via OS-aware routing, streams output. |
|
| Searches every endpoint's installed software for a substring match. |
| — | Reads |
Destructive guard
Every tool flagged destructiveHint: true enforces three independent gates:
ACTION1_ALLOW_DESTRUCTIVE=true ← server env, restart-required
AND
confirm: "YES" ← exact, case-sensitive
AND
dry_run: false ← default is true → preview-only// Preview only (default)
{ "tool": "action1_run_powershell",
"arguments": { "endpoint_id": "<uuid>", "script_text": "Get-Date" } }
// → returns { "dry_run": true, "would_send": { method, path, body } }
// Actually execute (server env: ACTION1_ALLOW_DESTRUCTIVE=true)
{ "tool": "action1_run_powershell",
"arguments": { "endpoint_id": "<uuid>", "script_text": "Get-Date",
"dry_run": false, "confirm": "YES" } }Single-operator setups can opt into ACTION1_DESTRUCTIVE_AUTO_CONFIRM=true,
which waives only the per-call confirm: "YES" requirement — dry_run
still defaults to true, so a bare call is still a preview; pass
dry_run: false to execute. The env switch is still required, and the
server logs a loud warning at start-up when this mode is on.
See docs/SECURITY.md for the full threat model.
Examples
Three quick workflows; many more in docs/EXAMPLES.md:
# 1. Fleet health check
> "How many endpoints are online and how many need a reboot?"
agent → action1_endpoints_summary
result → { total: 1247, fresh_last_seen: 1130, reboot_required: 38, ... }
# 2. Run a read-only PowerShell on a specific Win11 host
> "What's the OS build of <hostname>? Run `Get-ComputerInfo OsBuildNumber`."
agent → action1_search_endpoints { query: "<hostname>", fields: ["hostname"] }
agent → action1_run_powershell {
endpoint_id: <uuid>,
script_text: "Get-ComputerInfo OsBuildNumber",
dry_run: false, confirm: "YES" }
agent → action1_wait_for_automation { instance_id: <id>, endpoint_id: <uuid> }
# 3. Build a CVE remediation plan
> "What's needed to remediate CVE-2024-XXXX?"
agent → action1_cve_remediation_plan { cve_id: "CVE-2024-XXXX" }
result → { plan: [{ cve, affected_endpoints, candidate_packages }], ... }
agent → action1_deploy_update { ... } (after operator confirmation)Rate limits
Action1's REST API does not publish a hard rate-limit ceiling. In practice we observe ~10 requests per second sustained without 429s on the EU instance. If you do hit 429:
The retry wrapper honours
Retry-Afterautomatically.Token-bucket-style throttling on
auto_paginatecalls keeps a multi-page list walk under ~5 RPS.For mass-fan-out actions, prefer
target_type: "EndpointGroup"over individual per-endpoint POSTs — Action1 fans out server-side.
The server does NOT pre-emptively cache list responses; consecutive
calls always hit the API. See src/client/retry.ts
for the retry policy.
Required Action1 permissions
The MCP server's tool surface respects whatever role the API key carries. Common scopes:
Tool family | Required permission |
Discovery (orgs, endpoints, templates, automations) |
|
Software inventory |
|
Missing updates |
|
Vulnerabilities |
|
Audit log |
|
Reports |
|
Execute scripts / deploy / reboot |
|
Manage schedules |
|
Use action1://me or the /check-my-permissions slash prompt to
confirm what the configured key can do before the agent starts
attempting destructive operations.
Documentation
File | What it covers |
Step-by-step for every supported MCP host, plus install FAQ. | |
Cross-topic FAQ + how-to recipes. | |
Tool reference for curated + wrapper layers, plus Resources, Prompts, output-format, cancellation, logging. | |
End-to-end recipes (patching, triage, CVE remediation, etc.). | |
stdio / HTTP / Docker / systemd / MCPB / Cloudflare Workers, plus the production checklist. | |
Threat model, destructive guard, credential rotation, redaction, rate limits. | |
Common failure modes and fixes. | |
Codegen workflow, test layout, commit conventions. | |
The full operation-to-tool mapping (166 tools over the pinned spec). | |
Cross-repo comparison and capability gaps. | |
Why | |
Skill-format evaluation suite (12 multi-hop questions, harness-runnable). | |
Unit / integration / security / performance tests, smoke tests, live-run results (anonymised). |
Development
npm run dev # tsx watch (stdio)
npm run typecheck
npm run lint
npm test # 527 tests across all categories
npm run test:unit # 37 files
npm run test:integration # MCP-protocol round-trip tests
npm run test:security # destructive-guard truth table, redaction matrix
npm run test:performance # capItemList / markdownTable scaling
npm run codegen # regenerate src/tools/generated/index.ts from the spec
npm run inspector # MCP Inspector against the built stdio serverThe macOS payload-builder unit tests are intentionally strict — they protect against silent regressions of the reverse-engineered field set. If you change the payload, update the snapshot.
Roadmap
Tracked in docs/api-coverage-gaps.md §
"Recommended second-wave roadmap":
Endpoint groups CRUD + targeting (mostly delivered via auto-gen + the
target_typeparameter on curated tools).Reports surface (delivered via the auto-gen +
action1_report_exportwrapper).Software inventory per endpoint (delivered via
action1_software_inventory_for_endpoint).CVE-based remediation builder (delivered via
action1_cve_remediation_plan).Recurring automations CRUD (delivered via auto-gen).
Open candidates:
Streamable HTTP "Sampling" / "Elicitation" support if user demand appears.
Cloudflare Workers reference deployment.
Bundle the generated
_coverage_table.mdinto the npm package.
Security
See docs/SECURITY.md. Report vulnerabilities via the
private security advisory at
https://github.com/mguttmann/action1-mcp/security/advisories/new.
License
MIT © 2026 mguttmann
Acknowledgements
The Action1 team for shipping a clean OpenAPI bundle.
The MCP community at https://modelcontextprotocol.io.
The Anthropic
mcp-builderskill, whose Quality Checklist this server follows.The four sibling projects whose code I read while scoping this one:
dimer47/action1-cli,pts211/action1-mcp-server,ghively/Action1MCP,DavidS-GPC/mcp-action1. Cross-repo notes indocs/api-coverage-gaps.md.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mguttmann/action1-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server