relayer-mcp
# @xns-cloud/relayer-mcp
[](https://www.npmjs.com/package/@xns-cloud/relayer-mcp)
[](./LICENSE)
[](https://nodejs.org/)
MCP server for [XNS Relayer](https://xns.tech) — S3-compatible decentralized object storage. Provides 15 tools that let an AI agent drive the complete Relayer setup and day-2 management conversationally over stdio transport.
```bash
npx @xns-cloud/relayer-mcp@latest
```
**Pricing:** [$6.00 per TB per month](https://xns.tech/pricing) — one rate, protection included, [$0 egress uncapped](https://xns.tech/pricing), [30-day minimum retention](https://xns.tech/pricing) with no separate early-delete fee.
## Requirements
On Ubuntu 24.04 or Debian 12, one command sets up everything:
```bash
curl -fsSL https://releases.scpri.me/relayer/install.sh | sh
```
The script installs Docker Engine and the compose plugin, adds you to the `docker` group, starts the Relayer in `/opt/xns-relayer`, and waits for the dashboard at `http://localhost:8888`. If Claude Code is present, it also installs Node.js 20 when Node is missing or older and registers this MCP. Log out and back in afterwards so the `docker` group applies. On macOS or Windows it installs nothing and points you to Docker Desktop.
Without the script, the MCP needs:
- **Node.js 20+** — see [Installing Node.js 20](#installing-nodejs-20) if your distro ships an older version.
- **Docker Engine** — on the same machine that runs the MCP. `install_relayer` refuses when the Docker daemon is on another machine (see [Remote Docker hosts](#remote-docker-hosts)).
### Installing Node.js 20
Ubuntu's default apt repository only ships Node 18, which is too old. Two ways to get Node 20:
**nvm** (recommended — no root required):
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
\. "$HOME/.nvm/nvm.sh" && nvm install 20
```
**NodeSource** (system-wide): follow <https://github.com/nodesource/distributions#installation-instructions>.
If you start the MCP on an older Node, it exits immediately with this same guidance instead of a dependency stack trace.
## Environment
The Relayer runs as a Docker container and persists its data in a Docker volume. If the MCP is running inside an ephemeral environment (a sandbox container, a CI runner, or a throwaway VM), any installation performed there will be lost when that environment exits. `check_prerequisites` detects this automatically and reports it as a warning with a concrete next step — it never blocks the flow.
**If your environment is ephemeral**, run the MCP on a persistent Docker host instead (install Node.js 20 there and point your MCP client at it). Alternatively, hand the install step to a human operator on the target machine and continue onboarding from `check_relayer_health` onwards.
## Install
On Ubuntu 24.04 or Debian 12, one command installs the Relayer and registers this MCP when Claude Code is present:
```bash
curl -fsSL https://releases.scpri.me/relayer/install.sh | sh
```
To register the MCP by hand instead:
**Claude Code** (one command, if you registered nothing yet):
```bash
claude mcp add --scope user relayer -- npx @xns-cloud/relayer-mcp@latest
```
**Claude Desktop / any MCP client** — add to your `claude_desktop_config.json` (or equivalent):
```json
{
"mcpServers": {
"relayer": {
"command": "npx",
"args": ["@xns-cloud/relayer-mcp@latest"]
}
}
}
```
**Cursor** — add to `.cursor/mcp.json`:
```json
{
"mcpServers": {
"relayer": {
"command": "npx",
"args": ["@xns-cloud/relayer-mcp@latest"]
}
}
}
```
No separate install step required — npx fetches the package on demand.
## Tools
| # | Tool | Purpose |
|---|------|---------|
| 1 | `check_prerequisites` | Verify Docker (local or remote), the compose plugin, Docker socket access (when it is denied, whether the `docker` group membership is missing or not yet live), ports (8888, 9000, 9443), an existing installation, free disk (10 GB on the Docker root and the install directory), and network connectivity. Each failure names the command that fixes it; ports held by a running `xns-relayer` pass. |
| 2 | `start_registration` | Get the browser sign-up URL for creating an XNS account — the agent never handles credentials. |
| 3 | `check_email_verified` | Poll email verification status (15s interval, 30-min timeout). |
| 4 | `install_relayer` | Fetch the canonical release channel bundle — relayer + Prometheus/Grafana monitoring stack (`https://releases.scpri.me/relayer/release/docker-compose.yml` and its `.env`, anonymous pull, no `docker login`) — add the ports to that `.env`, and start the containers. Falls back to a bundled service-parity copy if either fetch fails. A failure names its cause (port in use, image pull refused, Docker stopped, out of disk, Docker socket permission) and the fix. **Fresh installs only** — see [Fresh installs vs. existing deployments](#fresh-installs-vs-existing-deployments). The user authors nothing; `compose_url` is an optional override for custom installs. |
| 5 | `check_relayer_health` | Poll UI, S3, HostIO, and the monitoring sidecars (10s interval, 300s timeout). A missing monitoring stack reports as degraded without blocking the flow. Targets the Docker host automatically. |
| 6 | `start_claim` | Initiate a claim session — returns a URL for browser confirmation. |
| 7 | `check_claim_status` | Poll claim state (STATE_1 / STATE_2 / STATE_3). |
| 8 | `get_host_tags` | Retrieve available host tags for VPD configuration, plus the currently applied data/parity selection (read-back with an `is_default` flag). |
| 9 | `configure_vpd` | Set data/parity host selection via CEL expressions. `dry_run: true` previews the matched host counts without applying (requires a Relayer build with the HostIO evaluate endpoint; older builds report `preview_supported: false`). |
| 10 | `verify_storage` | Round-trip S3 test (create bucket, put object, get object) against the S3 gateway. Provisions a temporary scoped IAM credential automatically from your OIDC session — no manual key management needed. The tool attempts to remove test data and the throwaway credential after the test; a `cleanup_warning` is reported if any resource could not be removed. `relayer_ui_url` must point at a loopback or private-network host. |
| 11 | `setup_cli_credentials` | Provision S3 IAM credentials and write `~/.xns/credentials` so the XNS CLI works without further configuration. |
| 12 | `describe_settings` | List the adjustable settings — worker/concurrency tuning, backup schedule, cost center (CCID) — with current values, defaults, and guidance. The MCP deliberately exposes only this curated set, never the full advanced catalog. |
| 13 | `update_settings` | Apply a map of setting changes (whitelist-enforced). Returns `require_restart`. **Requires relayer-ui >= 3.43.3** — older servers can clobber the database password on config round-trips. |
| 14 | `restart_service` | Restart `hostio`, `gateway`, `s3gateway`, `database`, or all services. Disruptive; pairs with `check_relayer_health` to verify recovery. |
| 15 | `manage_backups` | List / start / restore / delete configuration backups. Restore is destructive and supports selective components (`db`, `conf`, `hostio`, `samba`). |
## Onboarding Flow
1. Agent checks prerequisites (Tool 1).
2. Agent gets the browser sign-up URL; user creates an account in the browser (Tool 2).
3. User clicks email verification link; agent polls (Tool 3).
4. Agent installs and starts Relayer containers (Tool 4) — it writes the
released compose + `.env` itself; the user is never asked for a compose URL.
5. Agent polls health until UI + S3 are up (Tool 5).
6. Agent initiates claim; user opens claim URL in browser (Tools 6 + 7).
7. Agent signs in via OIDC to configure host preferences (Tools 8 + 9).
8. Agent verifies S3 storage is working (Tool 10).
9. Optionally, agent provisions CLI credentials (Tool 11).
The operator's only required actions are: clicking one email link, completing one browser sign-in, and confirming one claim.
## Day-2 Management
After onboarding, tools 12-15 cover routine adjustments: `describe_settings` → `update_settings` → `restart_service` for tuning (workers, concurrency, backup schedule, cost center), and `manage_backups` for the backup lifecycle. All four use the same OIDC session as tools 8-9. Destructive operations (restore, restart, changing the cost center) are agent-confirmed with the operator before execution — the tool descriptions and responses carry the warnings.
## Fresh installs vs. existing deployments
`install_relayer` performs **fresh installs only** — it does not upgrade an existing deployment in place. Docker container names are unique per daemon, so any existing `xns-relayer` container (running **or stopped**, any channel — including an alpha-channel install from `releases.scpri.me`) blocks the install. Both `check_prerequisites` and `install_relayer` detect this and tell you before anything breaks.
To replace an existing deployment:
```bash
docker stop xns-relayer && docker rm xns-relayer # does NOT delete the data directory
```
then run `install_relayer` again. To keep the existing deployment, skip `install_relayer` and continue onboarding against it (`check_relayer_health` onwards).
## Remote Docker hosts
`install_relayer` writes `docker-compose.yml` and `.env` on the machine running the MCP, then runs `docker compose up` against whichever daemon the Docker CLI points at. When that daemon is on another machine (`DOCKER_HOST=ssh://…` or `tcp://…`, or an SSH Docker context), it refuses before writing or starting anything, and the error names the Docker host.
To install, run the MCP on the Docker host (Node.js 20 there, MCP client pointed at it) and run `install_relayer` again. Or unset `DOCKER_HOST` / switch to the default Docker context to install on the machine running the MCP.
`check_prerequisites` reports the same condition as a failed `install_file_location` check. Health checks still work against a remote daemon: the MCP honors `DOCKER_HOST` and the active Docker context, `check_relayer_health` and `verify_storage` probe the remote host's ports 8888/9000 instead of localhost, and `check_prerequisites` skips the local port probes. `check_relayer_health` accepts a `host` override, and `verify_storage` an `endpoint` override, for setups the auto-detection can't see (port forwards, NAT).
## Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| MCP exits with "requires Node.js 20 or newer" | Distro Node is too old (Ubuntu apt ships Node 18) | [Installing Node.js 20](#installing-nodejs-20) |
| `install_relayer` reports an existing `xns-relayer` container | A previous deployment (any channel) owns the container name | [Fresh installs vs. existing deployments](#fresh-installs-vs-existing-deployments) |
| Port 8888/9000 already in use | Another service on the Docker host (another S3-compatible service squatting 9000) | Stop it, or install with custom ports: `install_relayer` `ui_port` / `s3_port` (health checks accept the same). After a failed `install_relayer`, remove the leftover container with `docker rm -f xns-relayer` before retrying |
| Port 9443 already in use | Another service on the Docker host holds the S3 HTTPS port the release compose publishes | Stop that service (`sudo ss -ltnp 'sport = :9443'` names it); `ui_port` / `s3_port` do not move 9443. Then `docker rm -f xns-relayer` and retry |
| Docker socket permission denied | You were added to the `docker` group after this session started, or not at all | `sudo usermod -aG docker $USER` if needed, then log out and back in |
| Docker is not running | The Docker daemon is stopped | `sudo systemctl start docker` |
| Not enough disk space | Under 10 GB free on the Docker root or the install directory | Free space there, then re-run |
| Image pull refused | `releases.scpri.me` unreachable, or a stale registry login | Check the connection; `docker logout releases.scpri.me` |
| Health checks fail but containers run on a remote Docker host | Ports 8888/9000 not reachable from the management node | Open them, or pass `host` / `endpoint` overrides |
| `install_relayer` fails with "The Docker daemon is on <host>, not this machine" | `DOCKER_HOST` or an SSH/TCP Docker context points at another machine, and the install files would be written here instead | Run the MCP on that host and re-run, or unset `DOCKER_HOST` / use the default Docker context ([Remote Docker hosts](#remote-docker-hosts)) |
| `install_relayer` fails with "Failed to create directory …" | The install path needs root on the machine running the MCP (common on macOS/Windows workstations for paths under `/opt`), or a regular file sits at or along it | Pass a writable `install_path`; the exact OS error is in the MCP server's stderr log |
## Authentication
Tools 8-9 and 12-15 require an OIDC token to access the Relayer API and HostIO proxy. The MCP acquires one automatically using Authorization Code + PKCE (S256) flow against the `scprime` Keycloak realm with the `relayer-native` public client. The user completes a browser sign-in; the MCP captures the code on a local `127.0.0.1` loopback listener and exchanges it for a token.
**Prerequisite:** The `relayer-native` public client must be registered on the Keycloak `scprime` realm (PKCE S256, redirect `http://127.0.0.1:*`).
## Development
```bash
npm install
npm test
```
Requires Node.js 20+.
## Note on `relayer-native` client
This package uses the `relayer-native` Keycloak client ID for OIDC authentication. The same client ID is intended for reuse by a future standalone Relayer CLI (`@xns-cloud/relayer-cli`), with the OIDC module (`src/lib/oidcAuth.js`) extracted to a shared `@xns-cloud/relayer-auth` package.
## Privacy Policy
Canonical policy: **<https://xns.tech/privacy-policy/>**. Product-specific detail for this
server is in [PRIVACY.md](./PRIVACY.md).
The short version:
- **No telemetry.** No analytics, crash reporting, or usage counters. It does not phone home.
- **Tokens live in memory only.** OIDC access tokens are never written to disk; they are discarded when the process exits.
- **The agent never sees your password.** Sign-in happens in your own browser against `auth.xns.tech`.
- **Private network only.** No tool can be pointed at a public Relayer: the ones taking a host argument run it through an allowlist (`localhost`, loopback, RFC 1918, `*.local`), and the rest expose no URL parameter and are fixed to `localhost`. The three XNS services it contacts are `auth.xns.tech`, `console.xns.tech`, and `releases.scpri.me`.
- **Your stored objects never pass through it.** The Relayer you host handles your data directly.
## Desktop extension (MCPB)
The same server ships as an [MCP Bundle](https://github.com/anthropics/mcpb) for one-click install in Claude Desktop. Build it from a clean checkout:
```bash
npm run bundle
```
That reinstalls production-only dependencies, validates the manifest, and writes the `.mcpb`. The MCPB CLI version is pinned in the script — do not invoke it unversioned, or the bundle you ship is not the bundle that was validated. Run `npm ci` afterwards to get the dev dependencies back for testing.
To validate the manifest alone without repacking:
```bash
npm run bundle:validate
```
`manifest.json` at the repo root is the bundle manifest. `mcpbManifest.test.js` pins its `version` and tool list to `package.json`, `server.json`, and the running server, so drift fails the suite rather than shipping.
## License
Apache-2.0 © SCP Corp. See [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
TDQS
Scored across 15 tools
Each tool targets a distinct phase or action in the relayer lifecycle: prerequisites, account, install, health, claim, VPD, storage, CLI, settings, restart, backups. There is no overlap or ambiguity between tools.
All tool names follow a consistent verb_noun pattern with snake_case (e.g., check_prerequisites, start_claim, update_settings). The verbs clearly indicate the action and the noun indicates the target, making the naming predictable and readable.
With 15 tools, the set covers the full installation and management workflow without being bloated. Each tool serves a specific, necessary function in the operator's journey, and the count is within the well-scoped range for a server with this purpose.
The tool set covers the entire lifecycle from prerequisites to installation, claiming, configuration, verification, settings tuning, restart, and backups. There are no obvious dead ends or missing operations for the intended use case of installing and managing an XNS Relayer.