AI Assistant (MCP)

3.8 AI assistant access with MCP

Since 3.1.43 replication-manager can expose its clusters to an AI assistant through the Model Context Protocol (MCP): Claude Code, Claude Desktop or any MCP client can list the clusters, read topology, alerts, logs, server status, backups, and, when allowed, run actions such as a switchover or a rolling restart.

Every MCP tool mirrors a REST endpoint and runs under the caller's own permissions: the assistant can do exactly what the account or token it uses can do through the API, nothing more. There is no separate MCP permission model.

3.8.1 Enabling the server

Setting Default Description
mcp-server false Start the MCP server.
mcp-transport api api: the MCP endpoints live on the API itself, /api/mcp/sse on the HTTP and HTTPS ports, so TLS and the public URL are the API's own. sse: a standalone plain-HTTP listener. stdio, both (sse + stdio).
mcp-bind-address / mcp-port localhost / 10007 Standalone sse transport only.
mcp-advertise-address Standalone sse transport only: public base URL announced to clients when it differs from the bind address.
mcp-auth-enabled true Require a bearer on the MCP endpoints and run every tool under that user's ACL.

All are server-wide settings, applied live, in the dashboard under Settings (global) → AI Assistant (MCP), or through the global settings API.

With the default api transport nothing else is exposed: the assistant connects to the same HTTPS URL as the dashboard and the API. The standalone sse transport is plain HTTP: keep it on localhost or behind a TLS proxy. The stdio transport carries no credential and only starts with mcp-auth-enabled = false, which runs every tool unrestricted.

3.8.2 Authenticating the assistant

Use an API token: it survives restarts, can be narrowed to the grants and clusters the assistant needs, and is revocable. Create it from your User Profile in the dashboard or from the CLI:

replication-manager-cli token create --label claude --grants "db-show cluster-show" --clusters belair --expire-days 90

Then point the client at the server with the token as bearer, for example in .mcp.json for Claude Code:

{
  "mcpServers": {
    "replication-manager": {
      "type": "sse",
      "url": "https://repman.example.com:10005/api/mcp/sse",
      "headers": { "Authorization": "Bearer ${REPLICATION_MANAGER_API_TOKEN}" }
    }
  }
}

An interactive login JWT from POST /api/login also works, but it expires after api-token-timeout hours and at every restart.

3.8.3 Demo

Claude Code driving replication-manager from the terminal with a token limited to db-show cluster-show on one cluster: the reads are answered, the switchover is refused by the cluster ACL, and the refusal lands in the security log.

Claude Code driving replication-manager through MCP

The recording is also available as an asciinema cast.

3.8.4 What the assistant may do

  • Only the clusters the account has access to are listed; a cluster-scoped token sees only its clusters.
  • Each tool is checked against the ACL of the REST endpoint it mirrors: reading server variables needs db-show-variables, a switchover needs cluster-switchover, changing a setting needs cluster-settings, and so on. A token narrowed to db-show can read but never act. There is no global read-only switch: read-only or read-write is decided per account or token.
  • Refusals are returned to the assistant as tool errors and written to the security log as mcp_denied; rejected connections as mcp_auth_failure.

3.8.5 Cloud18 from the assistant

The assistant can also connect the instance to Cloud18 and browse the marketplace. These tools are instance-wide, not per cluster: reads are open to any authenticated caller, actions need the global-admin-show grant, and a token must carry the "every cluster" scope.

  • get-cloud18-status: registered or not, URI, GitLab user, plan, state of a registration in progress.
  • cloud18-register (email, uri): starts the registration. The GitLab password is generated by replication-manager and never shown to the assistant; the person clicks the confirmation email, then get-cloud18-register-status reports complete. cloud18-register-confirm is the manual second step after a timeout. cloud18-unregister disconnects the instance.
  • list-cloud18-subscription-plans, get-cloud18-subscription, cloud18-change-subscription (plan).
  • list-cloud18-clusters-for-sale: the marketplace catalogue, and list-cloud18-infrastructures: the distinct provider infrastructures (one per api-public-url) with the clusters each offers.
  • Prompt cloud18-onboarding walks the assistant through the whole flow.

Creating a cluster on an infrastructure. When the provider has enabled self-service (see Registration, self-service clusters), the assistant can create a cluster there directly, with no subscription or email chain:

  • cloud18-create-cluster (infrastructure, cluster_name, db_image, db_count, proxy, apps, confirm). Without confirm it only returns the plan: the services it would create and the infrastructure's self-service status for your identity (enabled or the reason, per-user limit, remaining slots). With confirm=true it creates the cluster on the infrastructure's default unit plan (DBU / APU / BKU, no service plan to choose), sets the database image (default mariadb:lts, the latest MariaDB long-term-support release), adds the database nodes (default 2), the proxy (default haproxy), the apps from their templates (for example phpmyadmin), and provisions. Your instance's Cloud18 identity becomes the sponsor of that cluster; the provider is informed. This is billable consumption on the infrastructure. You are the identity. Your Cloud18 account is valid on every public instance, so a creation is yours wherever it happens, and the instance you talk to spends nothing of its own. Three steps:

  • get-cloud18-infrastructures: for each marketplace infrastructure, your self-service status there (may you create a cluster and why not, free DBU and APU of its plan pot, the default plan a cluster takes, the clusters you may still sponsor) and a ready-to-paste MCP server entry carrying your session on that infrastructure, the same login the dashboard's Enter opens, as you. No account and no token are written on the infrastructure, only that session. It expires with the login (api-token-timeout) and is a secret like a token. A local admin without a Cloud18 account acts as this instance's registered identity; a local user or an API token is refused with the way in.

  • Connect the assistant to the infrastructure's entry and run cloud18-create-cluster there, with no infrastructure argument: the infrastructure creates the cluster and makes you its sponsor, with the grants to populate, provision and manage it. Your account appears there, and only there.

  • cloud18-create-cluster-token, same place: your durable token for that cluster (120 days by default) and the final MCP entry. Only where you created something.

The infrastructure answers the status from a snapshot refreshed every cloud18-self-service-cache-seconds (10 by default): a burst of calls, or a brute force on GET /api/cloud18/self-service, costs it one computation per interval.

  • get-cloud18-cluster (infrastructure, cluster_name): state, servers, proxies and apps, to follow the provisioning.
  • cloud18-create-cluster-token (infrastructure, cluster_name, grants, expire_days): once the cluster exists, this is how the assistant gets to operate it. A token is valid on one replication-manager only, so the sponsor mints one on the infrastructure hosting the cluster, scoped to that cluster, and the tool returns it once together with the infrastructure's MCP endpoint configuration. Add it to the assistant as a second MCP server (one server per infrastructure) and the cluster's tools appear there, under the partner's ACL for your identity.

For example: "use infrastructure https://repman.example.io to create a cluster named blab, latest MariaDB LTS, HAProxy, with the latest phpMyAdmin app on it".

3.8.6 Tools

Tool names follow six rules, so that a new tool is named by rule and not by taste:

  1. A read is <verb>-<domain>-<object>: list- when the result has several entries, get- when it is one object (a status map, a settings object, statistics), check- when it answers yes or no with a reason.
  2. An action is <domain>-<verb>[-<object>], imperative: cluster-switchover, database-start, proxy-stop, cluster-archive-purge.
  3. The domains are the API's: cluster, database (one database server, as opposed to a proxy), proxy, cloud18. A cluster-scoped object carries cluster (list-cluster-local-backups), a server-scoped one carries database (database-backup-physical).
  4. Objects use the product's words, local backups and archive backups, never the name of the implementation behind them.
  5. Parameters are cluster_name, server_name (host:port), proxy_name, task_id.
  6. One tool is one REST route and needs that route's grant: reads the matching *-show grant, actions the grant named next to them (for example cluster-switchover).

Cluster

Tool Kind Parameters What it does
check-cluster-error-state read cluster_name*, error_code* Check whether a specific error or warning code is currently active for a cluster
get-cluster-alerts read cluster_name*, module Get the open errors and warnings of a cluster, per module
get-cluster-archive-stats read cluster_name* Get Restic repository statistics
get-cluster-health read cluster_name* Get the high-level health status of a cluster
get-cluster-tools read cluster_name* The command line tools replication-manager found for the cluster (database client, dump and binlog clients, mydumper, sysbench, restic) with their versions; they belong to the replication-manager host, /api/monitor lists them globally
get-cluster-last-crash-lost-event read cluster_name*, server_name*, file Get the lost events of the last crash of a server
get-cluster-local-backup-stats read cluster_name* Get aggregated backup statistics for a cluster
get-cluster-price read cluster_name* Get what a cluster costs this month on this infrastructure, in EUR, as the resource manager integrates it per monitoring period
get-cluster-settings read cluster_name* Get the full configuration for a cluster
get-cluster-topology read cluster_name* Get the full topology of a cluster
list-app-templates read cluster_name* List the app templates this replication-manager can deploy on a cluster
list-cluster-apps read cluster_name* List the applications of a cluster with their state, template, image, provisioning state and URL (https on the primary route of the app once provisioned, the internal address otherwise)
list-cluster-archive-backups read cluster_name* List all Restic snapshots stored in the cluster's Restic repository
list-cluster-archive-tasks read cluster_name* Get the current Restic task queue for a cluster
list-cluster-crashes read cluster_name* Get the history of crash and failover events for a cluster
list-cluster-local-backups read cluster_name* List all registered physical and logical backups for a cluster
list-cluster-logs read cluster_name*, log_type, level, module, limit List recent log entries of a cluster, newest first, from one of its logs
list-clusters read List the names of all database clusters currently monitored by replication-manager
app-start action cluster_name*, app_name*, node Start a provisioned application on the orchestrator (all its nodes, or one node)
app-stop action cluster_name*, app_name*, node Stop a running application; the service stays provisioned
app-restart action cluster_name*, app_name*, node Restart a running application
app-resize action cluster_name*, app_name*, units* Resize the plan of an application in whole units (APU, DBU when stateful); cores, memory and disk follow the ratio; reprovision (app-unprovision, app-provision) applies it
app-add action cluster_name*, template*, name, port Add an application to a cluster from a template (list-app-templates); the answer carries the app's db object (schema, user) when the template asked the cluster for a database
cluster-archive-fetch action cluster_name* Refresh the local snapshot metadata cache from the Restic repository
cluster-archive-init action cluster_name* Initialize a new Restic repository for the cluster at the configured repository path (local or S3)
cluster-archive-purge action cluster_name*, snapshot_id* Delete a specific Restic snapshot by ID and run 'restic prune' to reclaim disk space
cluster-archive-task-cancel action cluster_name*, task_id* Cancel a pending or running Restic task by its integer task ID
cluster-archive-task-queue-pause action cluster_name* Pause the Restic task queue, preventing new backup tasks from starting
cluster-archive-task-queue-resume action cluster_name* Resume the Restic task queue after it was paused with cluster-archive-task-queue-pause
cluster-archive-unlock action cluster_name* Remove stale lock files from the Restic repository
cluster-bootstrap-replication action cluster_name*, clean Configure replication between cluster nodes for the first time, or after a cluster-cleanup-replication
cluster-checksum-tables action cluster_name* Run CHECKSUM TABLE on all user tables across the cluster to verify data consistency between master and replicas
cluster-cleanup-replication action cluster_name* Remove all replication configuration from all cluster nodes
cluster-failover action cluster_name* Trigger an emergency failover
cluster-optimize action cluster_name* Run OPTIMIZE TABLE on all user tables across all nodes in the cluster
cluster-physical-backup action cluster_name* Trigger a physical (binary-level) backup on the master node using the configured backup tool (Mariabackup, xtrabackup)
cluster-reset-failover-control action cluster_name* Reset the failover counter and cooldown timer for the cluster
cluster-reset-sla action cluster_name* Reset the SLA (Service Level Agreement) uptime counters for the cluster
cluster-rolling-jobs-upgrade action cluster_name* Upgrade the jobs sidecar (the container running backups, restores and database jobs) of every node, one at a time
cluster-rolling-reprov action cluster_name* Reprovision every database node of the cluster one at a time, preserving availability
cluster-rolling-restart action cluster_name* Restart all database nodes in the cluster one at a time, preserving availability
cluster-rolling-upgrade action cluster_name*, target, version, confirm Upgrade the database engine of every node one at a time, preserving availability, to a target taken from the image list of the configurator (never a registry lookup)
cluster-rotate-passwords action cluster_name* Rotate all internal database account passwords (replication user, monitoring user, etc.) across the cluster
cluster-set-setting action cluster_name*, setting_name*, setting_value* Set a named configuration key to a specific value for a cluster
cluster-start-traffic action cluster_name* Re-enable application traffic to the cluster by opening the proxy backends
cluster-stop-traffic action cluster_name* Halt application traffic to the cluster by draining the proxy backends
cluster-switch-setting action cluster_name*, setting_name* Toggle a boolean configuration key for the cluster (true→false or false→true)
cluster-switchover action cluster_name*, preferred_master Perform a planned, zero-data-loss master change
cluster-create-staging action cluster_name*, name, db_image, db_count, confirm Create a staging cluster of this cluster, seeded from its latest logical backup, one replica detached for the dev team; confirm false returns the plan
cluster-create-child action cluster_name*, name, db_image, db_count, confirm Create a child cluster replicating live from this cluster, to test a migration (another release) under its writes; confirm false returns the plan
cluster-alter-engine action cluster_name*, engine_from*, engine_to*, schema_name, confirm Switch every table of one storage engine to another with ALTER TABLE on the master; other engines untouched; confirm false returns the plan
cluster-alter-table-engine action cluster_name*, schema_name*, table_name*, engine_to*, confirm Switch one table to another storage engine; confirm false returns the plan
cluster-sysbench-cleanup action cluster_name* Drop the sysbench benchmark schema and data from the cluster
cluster-sysbench-run action cluster_name*, test, time, threads Run a sysbench benchmark against the cluster through its proxy (a proxy must be configured)

Database servers

Tool Kind Parameters What it does
check-database-is-late read cluster_name*, server_name* Check if a replica has replication lag above the failover-max-slave-delay threshold
check-database-is-master read cluster_name*, server_name* Check whether a specific server is currently the active master (read-write primary) for the cluster
check-database-is-slave read cluster_name*, server_name* Check whether a specific server is currently an active replica (read-only, replicating from master)
get-database-replication read cluster_name*, server_name* Get the replication picture of a server
get-database-status read cluster_name*, server_name* Get all SHOW STATUS variables for a specific server
get-database-variables read cluster_name*, server_name* Get all SHOW VARIABLES for a specific server
get-database-version read cluster_name*, server_name* Get the database engine and version of a server
list-database-error-log read cluster_name*, server_name* Get the MariaDB/MySQL error log buffer for a specific server
list-database-processes read cluster_name*, server_name* Get the current process list (SHOW FULL PROCESSLIST) for a server
list-database-slow-queries read cluster_name*, server_name* Get slow query digest entries from Performance Schema (events_statements_summary_by_digest)
list-database-tables read cluster_name*, server_name* Get the list of all user tables across all databases on a server, with metadata (engine, row count, data size, index size)
database-backup-logical action cluster_name*, server_name* Trigger a logical backup (mysqldump or mydumper, as configured by backup-logical-type) on a specific server, preferably a replica
database-backup-physical action cluster_name*, server_name* Trigger a physical backup on a specific server (not necessarily the master)
database-kill-query action cluster_name*, server_name*, process_id* Kill a specific query or connection on a server by process ID (KILL QUERY )
database-logical-backup-splitdump action cluster_name*, server_name* Trigger a logical mysqldump backup in splitdump format (one directory with one file per table, mydumper-like, restorable in parallel) on a specific server
database-optimize action cluster_name*, server_name* Run OPTIMIZE TABLE on all user tables on a specific server
database-restart action cluster_name*, server_name* Restart a specific database server
database-restore-logical-backup action cluster_name*, server_name* Restore (reseed) a server from the cluster's last logical backup
database-restore-physical-backup action cluster_name*, server_name* Restore (reseed) a server from the cluster's last physical backup (Mariabackup/xtrabackup)
database-set-ignored-master action cluster_name*, server_name* Mark a database server as ignored for the master election
database-set-maintenance action cluster_name*, server_name* Toggle maintenance mode for a server (on/off)
database-set-prefered-master action cluster_name*, server_name* Mark a database server as a preferred master
database-set-read-only action cluster_name*, server_name* Set a server to read-only mode (SET GLOBAL read_only=ON)
database-set-read-write action cluster_name*, server_name* Set a server to read-write mode (SET GLOBAL read_only=OFF)
database-set-unrated-master action cluster_name*, server_name* Remove a database server from both the preferred and the ignored lists of the master election, back to an ordinary candidate
database-start action cluster_name*, server_name* Start a stopped database server in the cluster
database-stop action cluster_name*, server_name* Stop a running database server

Proxies

Tool Kind Parameters What it does
get-proxy read cluster_name*, proxy_name* Get detailed configuration and status for a specific proxy
list-proxies read cluster_name* List all load balancers and routers configured for a cluster (ProxySQL, MaxScale, HAProxy, etc.)
proxy-provision action cluster_name*, proxy_name* Provision a proxy service from scratch
proxy-start action cluster_name*, proxy_name* Start a stopped proxy service
proxy-stop action cluster_name*, proxy_name* Stop a running proxy service
proxy-unprovision action cluster_name*, proxy_name* Remove a provisioned proxy service

Cloud18

Tool Kind Parameters What it does
get-cloud18-cluster read infrastructure, cluster_name* Read a cluster on a Cloud18 infrastructure as this instance's Cloud18 identity
get-cloud18-infrastructures read Your access to every marketplace infrastructure as yourself: an MCP entry carrying your session there, and your self-service status (may you create, free DBU and APU, default plan, remaining clusters)
get-cloud18-cluster-price read infrastructure, cluster_name* Get what a cluster costs this month on a Cloud18 infrastructure, in EUR, as that infrastructure's resource manager integrates it per monitoring period
get-cloud18-register-status read State of the Cloud18 registration started with cloud18-register
get-cloud18-status read Whether this replication-manager instance is registered with Signal18 Cloud18, its URI (domain.subdomain.zone), GitLab user, subscription plan, the CRM API in use, the state of a registration in progress, and whether peers and the marketplace are disabled
get-cloud18-subscription read The current subscription plan of this instance as known by the CRM (the instance must be registered)
list-cloud18-clusters-for-sale read The Cloud18 marketplace catalogue
list-cloud18-infrastructures read The infrastructures of the Cloud18 marketplace
list-cloud18-subscription-plans read The instance subscription plans offered by Signal18 (free, support, support-services, partner) with what each unlocks, as published by the CRM
cloud18-change-subscription action plan* Change the subscription plan of this instance
cloud18-create-cluster action infrastructure, cluster_name*, db_image, db_count, proxy, apps, confirm Create a database cluster on a Cloud18 infrastructure (self-service), as yourself; empty infrastructure = this instance
cloud18-create-cluster-token action infrastructure, cluster_name*, label, grants, expire_days Mint, on a Cloud18 infrastructure and as this instance's Cloud18 identity (the sponsor of the cluster), an API token scoped to one cluster there, and return the infrastructure's MCP endpoint configuration to add as a second MCP server
cloud18-register action email*, uri* Register this instance with Signal18 Cloud18 (free plan)
cloud18-register-confirm action email*, uri* Manual second step of the registration
cloud18-unregister action Disconnect this instance from Cloud18

* required parameter. Reads need the matching *-show grant, actions the grant of their REST route (for example cluster-switchover, db-restore, cluster-bench); every tool is one route, see the ACL table in the server.

3.8.7 Application templates

app-add deploys an application next to the database from a template; list-app-templates returns the names the running replication-manager knows (they come from the public cloud18-templates repository). The template name is <directory>/<file>, for example postgres/postgres-standby. Every app gets its plan (cores, memory, disk) from its units, its database access from the cluster ({{app.db.*}}: a schema and a user created for it), a generated password when the template asks for one ({{app.randompassword}}) and an https route on the gateway.

Category Template What it deploys
Infrastructure
RDBMS (cluster databases) MariaDB, MySQL and Percona Server are the cluster's own databases, provisioned through database-add / cloud18-create-cluster, never as apps
postgres/postgres PostgreSQL primary, sized by its plan (memory, vacuum), monitored as a server of a pg-* cluster (active-passive)
postgres/postgres-standby PostgreSQL standby of the cluster's primary (WAL streaming, seeded automatically)
postgres/postgres-peer A second independent PostgreSQL instance, for logical replication
mssql/mssql Microsoft SQL Server, one instance that owns its data (failover topology)
NoSQL and caches valkey/valkey Valkey (the Redis fork), persisted dataset that moves with the instance
memcached/memcached Memcached, volatile cache, one instance per agent (flex topology)
Proxies (cluster proxies) HAProxy, ProxySQL, MaxScale, added with proxy-add, routed to the primary and the replicas
Queueing rabbitmq/rabbitmq RabbitMQ broker, queues persisted on a volume that moves with it
Object storage rustfs/rustfs RustFS, S3 object storage (Apache 2.0, MinIO compatible): the cluster's S3 provider
minio/minio MinIO (upstream community edition archived in 2026, kept for existing deployments)
nginx/nginx-minio Nginx front for an object store
Productivity
ERP dolibarr/dolibarr Dolibarr ERP/CRM
erpnext/erpnext-backend, erpnext-frontend, erpnext-scheduler, erpnext-worker, erpnext-websocket ERPNext (frappe) as linked single-process apps, one container each
Framework wordpress/wordpress WordPress on the cluster's MariaDB or MySQL, wp-content on a volume that moves with it
grav/grav Grav, the flat-file CMS, no database
Chat mattermost/mattermost Mattermost Team Edition on the cluster's PostgreSQL, its database and role created for it
Ticketing freescout/freescout FreeScout help desk and shared mailbox
glpi/glpi GLPI, IT asset and service management
osticket/osticket osTicket support tickets, attachments in the database, no volume
Development
Tools forgejo/forgejo Forgejo, the git forge, one instance that owns its repositories
phpmyadmin/phpmyadmin phpMyAdmin on the cluster's database
adminer/adminer Adminer, the https sidecar that manages a database of the cluster (MariaDB, MySQL, PostgreSQL, SQL Server)
Code (your code from a git repository) php/php PHP 8.4 on the signal18/php-fpm-84 image (nginx, PHP-FPM, Composer, antivirus)
java/java Java 21 (maven:3.9-eclipse-temurin-21), built at start
nextjs/nextjs Next.js / React on node:22-alpine
python/python Python 3.12 (python:3.12-slim)
go/go Go 1.24 (golang:1.24), compiled at start
dotnet/dotnet .NET 8 on Linux (mcr.microsoft.com/dotnet/sdk:8.0)
nginx/nginx Nginx serving static content and configuration cloned from git

Each code runtime template clones a git repository in an init container at start: the public cloud18-template-code repository holds a "hello world, I'm connected to database server id N" sample for every language, and cloud18-template-config the matching server configuration. An assistant deploying your own code gives app-add the template and, through the app's settings, your repository instead.