
Acronis Cyber Protect Cloud
io.github.WYRE-AIPublished by GitHub account WYRE-AIv1.0.1Updated Nov 7, 2026
Acronis Cyber Protect Cloud MCP: alerts, policies, resources, agents, tenants and EDR incidents.
Overview
Read-mostly MCP access to Acronis Cyber Protect Cloud: alerts, EDR incidents, protection policies, resources, agents and tenants.
- What you can do
- Query alerts: list, fetch, counters, categories, alert types, grouped by scope or customer, resources with top-severity alerts
- Inspect protection policies and resources: policies, policy applications, issue statistics, resources, resource protection status
- Review agents and EDR incidents: list and fetch agents, list and fetch incidents, response action status
- Look up tenants and users: tenant, tenant children, tenant users, user info, MFA status, usages, search
- Optional write tools (off by default): mark an alert as false positive, update investigation state, execute a protection policy
- When to use it
- Useful when an assistant should triage Acronis backup and security posture — checking active alerts, EDR incidents, policy application failures or unprotected resources — without opening the Acronis console. Also handy for multi-tenant service providers reviewing tenant usage and MFA status.
- Requirements
- Runs as a local process (stdio) or as an HTTP container; Node.js 22 or newer for local use. Needs an Acronis API client with client_credentials: ACRONIS_BASE_URL (https, host ending in .acronis.com), ACRONIS_CLIENT_ID and ACRONIS_CLIENT_SECRET. Outbound HTTPS to the Acronis datacenter is required. HTTP mode additionally needs CONDUIT_S2S_SECRET and X-Gateway-S2S signing; gateway mode takes credentials from X-Acronis-* headers.
Installation
In SourceWeft
- Open Acronis Cyber Protect Cloud in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
acronis-mcp
WYRE-AI hosted wrapper around the vendor's own MCP server for Acronis Cyber Protect Cloud
(@acronis-platform/mcp, pinned to the
exact version 1.0.1). The wrapper adds what the upstream server does not have:
- a curated, tiered tool allowlist (34 read tools, 3 opt-in write tools out of upstream's 159),
- per-tenant process isolation, hosted dual-era HTTP serving (2025-era
initializehandshake and 2026-07-28 stateless envelope), andX-Gateway-S2Sverification, - response sanitising (size cap, secret/token redaction, uniform error shape),
- an SSRF guard on the Acronis base URL (WYREAI-454).
tools/list is static (generated at build time), so it works without credentials and without
starting any child process. Only tools/call starts an upstream child.
Upstream pinning policy
@acronis-platform/mcp is pinned to an exact version in package.json (no ^/~; a test
enforces 1.0.1). Bumps happen by pull request only. Renovate/Dependabot may propose one, but it
must not auto-merge: a bump needs a human to
- diff the upstream
tools/listagainstresearch/upstream-tools-1.0.1.json(new, renamed or duplicated tools), - regenerate
src/generated/tools.tswithnpm run gen-tools, - re-review
research/tiers.jsonand the integration test.
Upstream 1.0.1 ships three duplicated tool names (device_authorization_approval,
fetch_registration_tokens, create_registration_token); none are allowlisted, and the generator
refuses any allowlisted name that is missing or duplicated upstream.
Why one child process per tenant
One upstream process holds one privileged client_credentials token and uses it for every caller.
Sharing a process between tenants would let one tenant's request run with another tenant's token.
So src/upstream-pool.ts spawns one child per distinct credential tuple
(key = sha256(baseUrl, clientId, clientSecret); raw values are never logged) over stdio, using
@modelcontextprotocol/client, and routes each call to its own tenant's child.
- Child binary:
require.resolve('@acronis-platform/mcp/package.json')→bin/cli.js, run withprocess.execPath. - Child environment is built from scratch (the parent env is not inherited, so
CONDUIT_S2S_SECRETetc. cannot leak):PATH,NODE_ENV,API_BASE_URL,OAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,MCP_TRANSPORT=stdio,MCP_TOOLS_INCLUDE=<allowlist for enabled tiers>. (The MCP client SDK additionally adds its own non-secret defaults:HOME,LOGNAME,SHELL,TERM,USER.) - LRU limit
ACRONIS_POOL_MAX(default 50), idle TTLACRONIS_POOL_IDLE_MS(default 10 min), and every child is closed on shutdown. An evicted child that is mid-call is closed when the call ends.
Known upstream behaviours to be aware of:
- Upstream 1.0.1 fetches an OAuth token eagerly at startup, so a child with bad credentials (or
no route to the datacenter) exits immediately. The caller then gets an
{error:{code:"upstream_unavailable",…}}result; the first call per tenant pays the token round trip. - Each tenant child runs with its own private, throwaway
HOME(mkdtemp, mode 0700, removed when the child exits), so the upstream token cache below is never shared between tenants. - Upstream caches the access token on disk under
~/.mcp/token-cache(mode 0600, AES-256-GCM, keyed from the client secret). - Upstream registers an extra built-in tool,
get_acronis_skill, that is not filtered byMCP_TOOLS_INCLUDE. The wrapper never lists or forwards it (the allowlist is enforced a second time in the call handler).
Tools
Tool names are acronis_ + the upstream name. A tool that is not in research/tiers.json is never
listed and never callable. This is enforced twice: MCP_TOOLS_INCLUDE on the child, and an allowlist
check in our tools/call handler.
- read tools are always available (
readOnlyHint: true). - write tools appear and work only when
ACRONIS_ENABLE_WRITES=true(defaultfalse); annotatedreadOnlyHint: false,destructiveHint: false.
Input schemas are taken verbatim from upstream. Because 37 tools exceeds the fleet's ~25 flat-tool
threshold, descriptions are cut to the first sentence (max 300 chars) with the
[Account Management API 2]-style prefix removed. Tool definitions live in
src/generated/tools.ts, produced by scripts/gen-tools.mjs (npm run gen-tools) from
research/upstream-tools-1.0.1.json filtered by research/tiers.json.
tools/list payload size (JSON bytes):
(Schemas dominate the payload and are kept from upstream, so description trimming saves ~5%.)
Excluded categories
Not exposed and not callable, whatever the environment:
- tenant / user / API-client create and delete, and all other deletes
- pricing, offering items, usage updates, editions (money)
- tokens, one-time tokens (OTT), device authorization, IdP / OpenID configuration
- registration tokens
- branding
- EDR
initiate_response_action - everything else not named in
research/tiers.json
Response sanitising
Every upstream result passes through src/sanitize.ts: text is capped at 100 KB with a truncation
marker; values under keys matching secret|password|token|access_token|refresh_token|api[_-]?key|authorization|client_secret
are redacted in JSON; Bearer tokens and JWT-looking strings are redacted anywhere; non-text blocks
are dropped. Errors reach the caller as {"error":{"code","message"}} with the message capped at
500 chars and the tenant's credentials scrubbed.
Credentials
Copy .env.example. Leave CONDUIT_S2S_SECRET empty in that file.
- Local / stdio (Claude Desktop, CLI): set
ACRONIS_BASE_URL,ACRONIS_CLIENT_ID,ACRONIS_CLIENT_SECRET(an Acronis API client withclient_credentials). stdio does not useCONDUIT_S2S_SECRET. - Hosted / gateway (
AUTH_MODE=gateway): credentials arrive per request and never fall back to the environment.
Base URL validation (SSRF guard): https only, hostname must end with .acronis.com, no
userinfo, no non-default port, no path/query/fragment. Anything else is rejected (401 in gateway
mode, no child spawned).
Environment variables
/health and /healthz stay unauthenticated and do not read credentials.
X-Gateway-S2S signing
With MCP_TRANSPORT=http and CONDUIT_S2S_SECRET set, every /mcp request must include X-Gateway-S2S:
v1 is HMAC-SHA256 over the ASCII message t=<unix seconds>, keyed with CONDUIT_S2S_SECRET, hex-encoded. The timestamp must be within 300 seconds of the server clock. A missing or invalid header returns 401. The secret is never logged.
In AUTH_MODE=gateway, /mcp also requires the three X-Acronis-* headers. A request missing any of them (or carrying an invalid base URL) returns 401 and does not fall back to ACRONIS_*.
Run locally (stdio)
Requires Node >= 22.
Run as HTTP (gateway / hosted)
Local HTTP without a secret is development-only. It binds 127.0.0.1 and logs a warning:
Docker
The image (node:26-alpine, runs as user acronis) listens on 0.0.0.0 inside the container and
defaults to AUTH_MODE=gateway. No registry auth or build secret is needed. The container needs
outbound HTTPS to the Acronis datacenters.
Compose refuses to start when CONDUIT_S2S_SECRET is unset and does not inject ACRONIS_*:
Development
The integration test spawns the real pinned package. Upstream 1.0.1 needs a token endpoint before it
answers tools/list, so the test points OAUTH_TOKEN_URL (and a temp HOME) at a local fake while
keeping API_BASE_URL=https://example.acronis.com and dummy credentials.
License
Apache-2.0
Source: README.md at commit c07e384
Tools
0Version history
1- v1.0.1LatestNov 7, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.