gandi-mcp — Gandi LiveDNS MCP Server

npm license

An MCP server for Gandi LiveDNS. Manage DNS records, list domains, and take zone snapshots — directly from Claude Code or any MCP-compatible client.

What this gives you

  • 8 MCP tools: list_domains, list_records, get_record, add_record, update_record, delete_record, list_snapshots, create_snapshot
  • Safety by default: every add/update/delete writes a timestamped local JSON backup of the full zone before mutating. Configurable.
  • One-JSON config: no env vars, one file with strict 0600 perms

Prerequisites

  • A Gandi account
  • Node.js 24+

Get a Gandi Personal Access Token

Gandi replaced legacy API keys with Personal Access Tokens (PATs). To create one for gandi-mcp:

  1. Sign in at admin.gandi.net.
  2. Top-right menu → User settingsAuthentication options (or visit account.gandi.net/security).
  3. Under Personal Access Tokens, click Create a token.
  4. Give it a name (e.g. gandi-mcp) and pick an expiration (max 1 year — Gandi will email you when it nears expiry).
  5. Scope — which domains: pick Specific organizations or Specific domains and select the ones you want this MCP to manage. Don't grant access to the whole account if you don't need it.
  6. Permissions: enable "Manage domain technical configurations" (covers LiveDNS read + write). If any of your domains are owned by a Gandi organization (not your personal account), also enable "View organization information" so list_domains can discover them — otherwise it will silently fall back to your personal-org domains only. Everything else (billing, transfers, etc.) can stay unchecked.
  7. Click Create. Copy the token immediately — Gandi only shows it once. If you miss it, delete and create a new one.

That token is your apiKey value in the config below.

Install

npm install -g @themkn/gandi-mcp

The binary is gandi-mcp regardless of the scoped package name.

Configure

The server reads a JSON config from ~/.gandi-mcp/config.json. Create it with 0600:

mkdir -p ~/.gandi-mcp
chmod 700 ~/.gandi-mcp
cat > ~/.gandi-mcp/config.json <<'EOF'
{
  "apiKey": "YOUR_GANDI_PAT",
  "defaultDomain": "example.com"
}
EOF
chmod 600 ~/.gandi-mcp/config.json

Full config reference

Field Required Default Description
apiKey yes Your Gandi Personal Access Token
defaultDomain no none Used when a tool call omits domain
autoBackup no true Write local zone backup before each mutation
backupDir no ~/.gandi-mcp/backups Where backup files land

The server refuses to start if the config file is group- or world-readable.

Hook into Claude Code

Add this to your .mcp.json (project-scoped) or ~/.config/claude/mcp.json (global):

{
  "mcpServers": {
    "gandi": {
      "command": "gandi-mcp"
    }
  }
}

Recommended permissions

By default Claude Code asks for permission on every Gandi tool call. A blanket mcp__gandi__* allow works, but it also auto-approves irreversible live DNS changes like delete_record and update_record. A tiered policy keeps the inspection flow frictionless while making destructive zone edits explicit.

Add this to your ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "mcp__gandi__list_domains",
      "mcp__gandi__list_records",
      "mcp__gandi__get_record",
      "mcp__gandi__list_snapshots",
      "mcp__gandi__create_snapshot",
      "mcp__gandi__add_record"
    ]
  }
}

What this does:

  • Reads (list_domains, list_records, get_record, list_snapshots) run without prompting — they can't change anything.
  • Additive writes (create_snapshot, add_record) also run without prompting. Snapshots are purely additive, and the server takes an automatic local zone backup before every record mutation, so a stray add_record is easy to recover from.
  • Destructive writes (update_record, delete_record) are not listed, so Claude Code will prompt before each call. The auto-backup helps recover the previous record values, but DNS caches still propagate — a bad change can break a live site for as long as the old TTL lasts. These should be deliberate.

If you want a stricter setup, keep a wildcard allow and add a deny block for the destructive tools — deny blocks the call entirely (no prompt, no override):

{
  "permissions": {
    "allow": ["mcp__gandi__*"],
    "deny": [
      "mcp__gandi__update_record",
      "mcp__gandi__delete_record"
    ]
  }
}

Tool reference

Tool What it does
list_domains List LiveDNS-managed domains. Auto-discovers organizations the user belongs to and unions their domains with the personal-org list, deduped by FQDN. Pass sharing_id to scope to a single organization.
list_records List records for a domain, with optional type and nameFilter (anchored, case-insensitive glob — * = any, ? = one)
get_record Fetch a single record by name + type
add_record Add a new record; auto-backup runs first
update_record Replace values/TTL on an existing record; auto-backup runs first
delete_record Delete a record; auto-backup runs first
list_snapshots List Gandi server-side zone snapshots
create_snapshot Create a server-side zone snapshot on Gandi

Mutation tools return the local backup path in their response — reference it if you need to roll back manually.

Backups

Each mutation writes ~/.gandi-mcp/backups/<domain>-<timestamp>.json:

{
  "domain": "example.com",
  "date": "2026-04-24T11:47:03.123Z",
  "records": [ /* full zone */ ]
}

Format matches the gandi CLI's backup shape. Disable via "autoBackup": false in config.

Development

git clone [email protected]:themkn/gandi-mcp.git
cd gandi-mcp
pnpm install
pnpm test
pnpm build

License

MIT