{
  "schemaVersion": "1.0",
  "item": {
    "slug": "gandi-skill",
    "name": "Gandi - Registrar & DNS",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/chrisagiddings/gandi-skill",
    "canonicalUrl": "https://clawhub.ai/chrisagiddings/gandi-skill",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/gandi-skill",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=gandi-skill",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CHANGELOG.md",
      "SCRIPTS.md",
      "SKILL.md",
      "config/domain-checker-defaults.json",
      "config.schema.json",
      "references/api-overview.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/gandi-skill"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/gandi-skill",
    "agentPageUrl": "https://openagent3.xyz/skills/gandi-skill/agent",
    "manifestUrl": "https://openagent3.xyz/skills/gandi-skill/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/gandi-skill/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Gandi Domain Registrar Skill",
        "body": "Comprehensive Gandi domain registrar integration for Moltbot.\n\nStatus: ✅ Phase 2 Complete - DNS modification & snapshots functional"
      },
      {
        "title": "⚠️ Security Warning",
        "body": "This skill can perform DESTRUCTIVE operations on your Gandi account:\n\nDNS Modification: Add, update, or delete DNS records (can break websites/email)\nEmail Management: Create, modify, or delete email forwards (can intercept emails)\nDomain Registration: Register domains (creates financial transactions)\nBulk Operations: Replace all DNS records at once (cannot be undone except via snapshots)\n\nBefore running ANY script:\n\nReview the script code to understand what it does\nCreate DNS snapshots before bulk changes (create-snapshot.js)\nUse read-only Personal Access Tokens where possible\nTest on non-production domains first\nUnderstand that some operations cannot be undone\n\nDestructive scripts (⚠️ modify or delete data):\n\nadd-dns-record.js, delete-dns-record.js, update-dns-bulk.js\nadd-email-forward.js, update-email-forward.js, delete-email-forward.js\nrestore-snapshot.js (replaces current DNS)\n\nRead-only scripts (✅ safe, no modifications):\n\nlist-domains.js, list-dns.js, list-snapshots.js\nlist-email-forwards.js, check-domain.js, check-ssl.js\n\n📖 For complete script documentation: See SCRIPTS.md for detailed information about:\n\nWhat each script does\nNetwork operations and API calls\nSecurity implications\nUndo/recovery procedures\nAudit workflow recommendations"
      },
      {
        "title": "Phase 1 (Complete)",
        "body": "✅ Personal Access Token authentication\n✅ List domains in your account\n✅ Get domain details (expiration, status, services)\n✅ List DNS records for domains\n✅ View domain and DNS information\n✅ Domain availability checking (#4)\n✅ Smart domain suggestions with variations (#4)\n✅ SSL certificate status checker\n✅ Error handling and validation"
      },
      {
        "title": "Phase 2 (Complete)",
        "body": "✅ Add/update DNS records (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR)\n✅ Delete DNS records\n✅ Bulk DNS operations (replace all records at once)\n✅ DNS zone snapshots (create, list, restore)\n✅ Email forwarding (create, list, update, delete forwards including catch-all)\n✅ Record validation (automatic validation for each record type)\n✅ Safety features (automatic snapshots before bulk changes, confirmation prompts)"
      },
      {
        "title": "Coming Soon (Phase 3+)",
        "body": "Domain registration\nMulti-organization support (#1)\nGateway Console configuration (#3)\nDomain renewal management\nDNSSEC configuration\nCertificate management\nEmail mailbox management (beyond forwarding)"
      },
      {
        "title": "Step 1: Create Personal Access Token",
        "body": "⚠️ Security Recommendation: Use the minimum required scopes for your use case.\n\nGo to Gandi Admin → Personal Access Tokens\n\n\nClick \"Create a token\"\n\n\nSelect your organization\n\n\nChoose scopes:\nRead-Only (Recommended for viewing only):\n\n✅ Domain: read (required for listing domains)\n✅ LiveDNS: read (required for viewing DNS records)\n✅ Email: read (required for viewing email forwards)\n\nWrite Access (Required for modifications - use with caution):\n\n⚠️ LiveDNS: write (enables DNS modification, deletion, bulk operations)\n⚠️ Email: write (enables email forward creation, updates, deletions)\n\n\n\nCopy the token (you won't see it again!)\n\nSecurity Best Practices:\n\nCreate separate tokens for read-only vs. write operations\nUse read-only tokens for routine checks/monitoring\nOnly use write tokens when actively making changes\nRotate tokens regularly (every 90 days recommended)\nDelete unused tokens immediately\nNever share or commit tokens to version control"
      },
      {
        "title": "Step 2: Store Token",
        "body": "Scripts check for credentials in priority order:\n\nGANDI_API_TOKEN environment variable (checked first)\n~/.config/gandi/api_token file (fallback if env var not set)\n\nChoose the method that fits your workflow:\n\nOption A: Environment Variable (Recommended for CI/CD)\n\n# Set environment variable (replace YOUR_PAT with actual token)\nexport GANDI_API_TOKEN=\"YOUR_PERSONAL_ACCESS_TOKEN\"\n\n# Add to shell profile for persistence (~/.bashrc, ~/.zshrc, etc.)\necho 'export GANDI_API_TOKEN=\"YOUR_PERSONAL_ACCESS_TOKEN\"' >> ~/.bashrc\n\nBenefits:\n\n✅ CI/CD friendly (standard pattern for automation)\n✅ Container-ready (no file mounts needed)\n✅ Works with secret management tools (1Password, Vault, etc.)\n✅ Easy to switch between multiple tokens\n\nOption B: File-based (Recommended for local development)\n\n# Create config directory\nmkdir -p ~/.config/gandi\n\n# Store your token (replace YOUR_PAT with actual token)\necho \"YOUR_PERSONAL_ACCESS_TOKEN\" > ~/.config/gandi/api_token\n\n# Secure the file (owner read-only)\nchmod 600 ~/.config/gandi/api_token\n\nBenefits:\n\n✅ Token persists across shell sessions\n✅ Secure file permissions (0600 = owner read-only)\n✅ No risk of exposing token in process list\n✅ Works offline (no external dependencies)"
      },
      {
        "title": "Step 3: Install Dependencies",
        "body": "Required: Node.js >= 18.0.0\n\ncd gandi-skill/scripts\n\n# Install npm dependencies\nnpm install\n\n# Verify installation\nnpm list --depth=0\n\nExpected packages:\n\naxios (HTTP client for Gandi API)\nAny other dependencies listed in package.json\n\nTroubleshooting:\n\nIf node or npm not found: Install Node.js from nodejs.org\nIf permission errors: Don't use sudo - fix npm permissions or use nvm\nIf package errors: Delete node_modules/ and package-lock.json, then npm install again"
      },
      {
        "title": "Step 4: Test Authentication",
        "body": "cd gandi-skill/scripts\nnode test-auth.js\n\nExpected output:\n\n✅ Authentication successful!\n\nYour organizations:\n  1. Personal Account (uuid-here)\n     Type: individual\n\n🎉 You're ready to use the Gandi skill!"
      },
      {
        "title": "Step 5: Setup Contact Information (Optional, for Domain Registration)",
        "body": "If you plan to register domains, save your contact information once for reuse:\n\ncd gandi-skill/scripts\nnode setup-contact.js\n\nThe script will prompt for:\n\nName (first and last)\nEmail address\nPhone number (international format: +1.5551234567)\nStreet address\nCity\nState/Province (for US: 2-letter code like OH, automatically formatted to US-OH)\nZIP/Postal code\nCountry (2-letter code: US, FR, etc.)\nType (individual or company)\nPrivacy preference: Retain or auto-purge contact after registration\n\nContact information is saved to:\n\n~/.config/gandi/contact.json\nPermissions: 600 (owner read-write only)\nOutside the skill directory (never committed to git)\n\nPrivacy Options:\n\nRETAIN (default): Keep contact saved for future registrations\n\nBest for frequent domain registrations\nSetup once, use forever\nDelete manually anytime with delete-contact.js\n\n\n\nPURGE: Auto-delete contact after each registration\n\nBest for privacy-conscious users\nContact info only exists during registration\nMust re-enter for next registration\n\nManaging saved contact:\n\n# View current contact\nnode view-contact.js\n\n# Update contact info or privacy preference\nnode setup-contact.js\n\n# Delete saved contact manually\nnode delete-contact.js\n\n# Delete without confirmation\nnode delete-contact.js --force\n\nOne-time purge override:\n\n# Register and delete contact (even if preference is \"retain\")\nnode register-domain.js example.com --purge-contact"
      },
      {
        "title": "List Your Domains",
        "body": "node list-domains.js\n\nOutput shows:\n\nDomain names\nExpiration dates\nAuto-renewal status\nServices (LiveDNS, Email, etc.)\nOrganization ownership"
      },
      {
        "title": "List DNS Records",
        "body": "node list-dns.js example.com\n\nOutput shows:\n\nAll DNS records grouped by type\nTTL values\nRecord names and values\nNameservers"
      },
      {
        "title": "Using from Moltbot",
        "body": "Once configured, you can use natural language:\n\n\"List my Gandi domains\"\n\n\"Show DNS records for example.com\"\n\n\"When does example.com expire?\"\n\n\"Is auto-renewal enabled for example.com?\""
      },
      {
        "title": "Check Single Domain",
        "body": "Check if a specific domain is available for registration:\n\nnode check-domain.js example.com\n\nFeatures:\n\nShows availability status (available/unavailable/pending/error)\nDisplays pricing information (registration, renewal, transfer)\nLists supported features (DNSSEC, LiveDNS, etc.)\nShows TLD information\n\nExample Output:\n\n🔍 Checking availability for: example.com\n\nDomain: example.com\n\n✅ Status: AVAILABLE\n\n💰 Pricing:\n  1 year: 12.00 EUR (+ 2.40 tax)\n  2 years: 24.00 EUR (+ 4.80 tax)\n\n📋 Supported Features:\n  • create\n  • dnssec\n  • livedns\n\n🌐 TLD Information:\n  Extension: com"
      },
      {
        "title": "Smart Domain Suggestions",
        "body": "Find available alternatives with TLD variations and name modifications:\n\n# Check all configured TLDs + variations\nnode suggest-domains.js example\n\n# Check specific TLDs only\nnode suggest-domains.js example --tlds com,net,io\n\n# Skip name variations (only check TLDs)\nnode suggest-domains.js example --no-variations\n\n# Output as JSON\nnode suggest-domains.js example --json\n\nName Variation Patterns:\n\nHyphenated: Adds hyphens between word boundaries (example → ex-ample)\nAbbreviated: Removes vowels (example → exmpl)\nPrefix: Adds common prefixes (example → get-example, my-example)\nSuffix: Adds common suffixes (example → example-app, example-hub)\nNumbers: Appends numbers (example → example2, example3)\n\nExample Output:\n\n🔍 Checking availability for: example\n\n📊 Checking 13 TLDs and generating variations...\n\n═══════════════════════════════════════════════════════\n📋 EXACT MATCHES (Different TLDs)\n═══════════════════════════════════════════════════════\n\n✅ Available:\n\n  example.net                    12.00 EUR\n  example.io                     39.00 EUR\n  example.dev                    15.00 EUR\n\n❌ Unavailable:\n\n  example.com                    (unavailable)\n  example.org                    (unavailable)\n\n═══════════════════════════════════════════════════════\n🎨 NAME VARIATIONS\n═══════════════════════════════════════════════════════\n\nHyphenated:\n\n  ✅ ex-ample.com                12.00 EUR\n\nPrefix:\n\n  ✅ get-example.com             12.00 EUR\n  ✅ my-example.com              12.00 EUR\n\nSuffix:\n\n  ✅ example-app.com             12.00 EUR\n  ✅ example-io.com              12.00 EUR\n\n═══════════════════════════════════════════════════════\n📊 SUMMARY: 8 available domains found\n═══════════════════════════════════════════════════════"
      },
      {
        "title": "Configuration",
        "body": "Domain checker configuration is stored in gandi-skill/config/domain-checker-defaults.json.\n\nStructure:\n\n{\n  \"tlds\": {\n    \"mode\": \"extend\",\n    \"defaults\": [\"com\", \"net\", \"org\", \"info\", \"io\", \"dev\", \"app\", \"ai\", \"tech\"],\n    \"custom\": []\n  },\n  \"variations\": {\n    \"enabled\": true,\n    \"patterns\": [\"hyphenated\", \"abbreviated\", \"prefix\", \"suffix\", \"numbers\"],\n    \"prefixes\": [\"get\", \"my\", \"the\", \"try\"],\n    \"suffixes\": [\"app\", \"hub\", \"io\", \"ly\", \"ai\", \"hq\"],\n    \"maxNumbers\": 3\n  },\n  \"rateLimit\": {\n    \"maxConcurrent\": 3,\n    \"delayMs\": 200,\n    \"maxRequestsPerMinute\": 100\n  },\n  \"limits\": {\n    \"maxTlds\": 5,\n    \"maxVariations\": 10\n  }\n}\n\nRate Limiting & Limits:\n\nmaxConcurrent: Maximum concurrent API requests (default: 3)\ndelayMs: Delay between requests in milliseconds (default: 200ms)\nmaxRequestsPerMinute: Hard limit on requests per minute (default: 100, Gandi allows 1000)\nmaxTlds: Maximum TLDs to check in suggest-domains.js (default: 5)\nmaxVariations: Maximum name variations to generate (default: 10)\n\nThese limits ensure good API citizenship and prevent overwhelming Gandi's API.\n\nTLD Modes:\n\n\"extend\": Use defaults + custom TLDs (merged list)\n\"replace\": Use only custom TLDs (ignore defaults)\n\nGateway Console Integration:\n\nWhen Gateway Console support is added (#3), configuration will be available at:\n\nskills:\n  entries:\n    gandi:\n      config:\n        domainChecker:\n          tlds:\n            mode: extend\n            defaults: [...]\n            custom: [...]\n          variations:\n            enabled: true\n            patterns: [...]\n\nSee docs/gateway-config-design.md for complete configuration architecture."
      },
      {
        "title": "Add or Update DNS Records",
        "body": "Create or update individual DNS records:\n\n# Add an A record for root domain\nnode add-dns-record.js example.com @ A 192.168.1.1\n\n# Add www subdomain pointing to root\nnode add-dns-record.js example.com www CNAME @\n\n# Add MX record for email\nnode add-dns-record.js example.com @ MX \"10 mail.example.com.\"\n\n# Add TXT record for SPF\nnode add-dns-record.js example.com @ TXT \"v=spf1 include:_spf.google.com ~all\"\n\n# Add with custom TTL (5 minutes)\nnode add-dns-record.js example.com api A 192.168.1.10 300\n\nSupported record types: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR"
      },
      {
        "title": "Delete DNS Records",
        "body": "Remove specific DNS records:\n\n# Delete old A record\nnode delete-dns-record.js example.com old A\n\n# Delete with confirmation prompt\nnode delete-dns-record.js example.com test CNAME\n\n# Delete without confirmation\nnode delete-dns-record.js example.com old A --force"
      },
      {
        "title": "Bulk DNS Operations",
        "body": "Replace all DNS records at once:\n\n# From JSON file\nnode update-dns-bulk.js example.com new-records.json\n\n# From stdin\ncat records.json | node update-dns-bulk.js example.com\n\n# Skip automatic snapshot\nnode update-dns-bulk.js example.com records.json --no-snapshot\n\n# Skip confirmation\nnode update-dns-bulk.js example.com records.json --force\n\nJSON format:\n\n[\n  {\n    \"rrset_name\": \"@\",\n    \"rrset_type\": \"A\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"192.168.1.1\"]\n  },\n  {\n    \"rrset_name\": \"www\",\n    \"rrset_type\": \"CNAME\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"@\"]\n  },\n  {\n    \"rrset_name\": \"@\",\n    \"rrset_type\": \"MX\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"10 mail.example.com.\", \"20 mail2.example.com.\"]\n  }\n]"
      },
      {
        "title": "DNS Zone Snapshots",
        "body": "Create safety backups before making changes:\n\n# Create a snapshot\nnode create-snapshot.js example.com \"Before migration\"\n\n# List all snapshots\nnode list-snapshots.js example.com\n\n# Restore from a snapshot\nnode restore-snapshot.js example.com abc123-def456-ghi789\n\n# Restore without confirmation\nnode restore-snapshot.js example.com abc123-def456-ghi789 --force\n\nAutomatic snapshots:\n\nBulk updates automatically create snapshots (unless --no-snapshot)\nSnapshots are named with timestamp\nUse snapshots for easy rollback"
      },
      {
        "title": "Common DNS Configuration Examples",
        "body": "Basic Website Setup\n\n# Root domain\nnode add-dns-record.js example.com @ A 192.168.1.1\n\n# WWW subdomain\nnode add-dns-record.js example.com www CNAME @\n\nEmail Configuration (Google Workspace)\n\n# MX records\nnode add-dns-record.js example.com @ MX \"1 ASPMX.L.GOOGLE.COM.\"\nnode add-dns-record.js example.com @ MX \"5 ALT1.ASPMX.L.GOOGLE.COM.\"\nnode add-dns-record.js example.com @ MX \"5 ALT2.ASPMX.L.GOOGLE.COM.\"\n\n# SPF record\nnode add-dns-record.js example.com @ TXT \"v=spf1 include:_spf.google.com ~all\"\n\nDomain Redirect Setup\n\nTo redirect one domain to another:\n\n# Point root domain to same server\nnode add-dns-record.js old-domain.com @ A 192.168.1.1\n\n# Point www to same CNAME\nnode add-dns-record.js old-domain.com www CNAME @\n\nThen configure HTTP 301 redirect at the server level.\n\nSubdomain Setup\n\n# API subdomain\nnode add-dns-record.js example.com api A 192.168.1.10\n\n# Staging subdomain\nnode add-dns-record.js example.com staging A 192.168.1.20\n\n# Wildcard subdomain\nnode add-dns-record.js example.com \"*\" A 192.168.1.100"
      },
      {
        "title": "List Email Forwards",
        "body": "See all email forwards configured for a domain:\n\nnode list-email-forwards.js example.com"
      },
      {
        "title": "Create Email Forwards",
        "body": "Forward emails to one or more destinations:\n\n# Simple forward\nnode add-email-forward.js example.com hello you@personal.com\n\n# Forward to multiple destinations\nnode add-email-forward.js example.com support team1@example.com team2@example.com\n\n# Catch-all forward (forwards all unmatched emails)\nnode add-email-forward.js example.com @ catchall@example.com"
      },
      {
        "title": "Update Email Forwards",
        "body": "Change the destination(s) for an existing forward:\n\n# Update single destination\nnode update-email-forward.js example.com hello newemail@personal.com\n\n# Update to multiple destinations\nnode update-email-forward.js example.com support new1@example.com new2@example.com\n\nNote: This replaces all existing destinations with the new ones."
      },
      {
        "title": "Delete Email Forwards",
        "body": "Remove email forwards:\n\n# Delete with confirmation prompt\nnode delete-email-forward.js example.com old\n\n# Delete without confirmation\nnode delete-email-forward.js example.com old --force\n\n# Delete catch-all forward\nnode delete-email-forward.js example.com @ --force"
      },
      {
        "title": "Common Email Forwarding Use Cases",
        "body": "Basic Email Forwarding\n\n# Forward contact@ to your personal email\nnode add-email-forward.js example.com contact you@gmail.com\n\n# Forward sales@ to team\nnode add-email-forward.js example.com sales team@example.com\n\nDomain Migration Email Forwarding\n\n# Forward all email from old domain to new domain\n# Preserves the local part (username before @)\n\n# First, list existing forwards on old domain\nnode list-email-forwards.js old-domain.com\n\n# Then create matching forwards on new domain\nnode add-email-forward.js old-domain.com contact contact@new-domain.com\nnode add-email-forward.js old-domain.com support support@new-domain.com\n\n# Or use catch-all to forward everything\nnode add-email-forward.js old-domain.com @ admin@new-domain.com\n\nTeam Distribution Lists\n\n# Forward to entire team\nnode add-email-forward.js example.com team alice@example.com bob@example.com charlie@example.com\n\n# Update team members\nnode update-email-forward.js example.com team alice@example.com dave@example.com\n\nCatch-All Configuration\n\n# Forward all unmatched emails to one address\nnode add-email-forward.js example.com @ catchall@example.com\n\n# Forward all unmatched emails to multiple addresses\nnode add-email-forward.js example.com @ admin1@example.com admin2@example.com\n\nNote: Catch-all forwards only apply to email addresses that don't have specific forwards configured."
      },
      {
        "title": "Email Forward Management Tips",
        "body": "Test after creating: Send a test email to verify forwarding works\nUse specific forwards over catch-all: More control and easier to manage\nMultiple destinations: Email is sent to all destinations (not round-robin)\nOrder doesn't matter: Gandi processes most specific match first\nCheck spam folders: Forwarded emails may be filtered by recipient's spam filter"
      },
      {
        "title": "Example: Complete Domain Email Setup",
        "body": "# 1. Set up MX records (if not already done)\nnode add-dns-record.js example.com @ MX \"10 spool.mail.gandi.net.\"\nnode add-dns-record.js example.com @ MX \"50 fb.mail.gandi.net.\"\n\n# 2. Create specific forwards\nnode add-email-forward.js example.com hello you@personal.com\nnode add-email-forward.js example.com support team@example.com\nnode add-email-forward.js example.com sales sales-team@example.com\n\n# 3. Set up catch-all for everything else\nnode add-email-forward.js example.com @ admin@example.com\n\n# 4. List all forwards to verify\nnode list-email-forwards.js example.com"
      },
      {
        "title": "Helper Scripts",
        "body": "All scripts are in gandi-skill/scripts/:"
      },
      {
        "title": "Authentication & Setup",
        "body": "ScriptPurposetest-auth.jsVerify authentication workssetup-contact.jsSave contact info for domain registration (run once)view-contact.jsView saved contact informationdelete-contact.jsDelete saved contact (with optional --force)"
      },
      {
        "title": "Domain & DNS Viewing",
        "body": "ScriptPurposelist-domains.jsShow all domains in accountlist-dns.js <domain>Show DNS records for domaincheck-domain.js <domain>Check single domain availability + pricingsuggest-domains.js <name>Smart domain suggestions with variationscheck-ssl.jsCheck SSL certificate status for all domains"
      },
      {
        "title": "DNS Modification (Phase 2)",
        "body": "ScriptPurposeadd-dns-record.js <domain> <name> <type> <value> [ttl]Add or update a DNS recorddelete-dns-record.js <domain> <name> <type> [--force]Delete a DNS recordupdate-dns-bulk.js <domain> <records.json> [--no-snapshot] [--force]Bulk update all DNS recordslist-snapshots.js <domain>List DNS zone snapshotscreate-snapshot.js <domain> [name]Create a DNS zone snapshotrestore-snapshot.js <domain> <snapshot-id> [--force]Restore DNS zone from snapshot"
      },
      {
        "title": "Email Forwarding (Phase 2)",
        "body": "ScriptPurposelist-email-forwards.js <domain>List all email forwards for a domainadd-email-forward.js <domain> <mailbox> <destination> [dest2...]Create email forward (use @ for catch-all)update-email-forward.js <domain> <mailbox> <destination> [dest2...]Update email forward destinationsdelete-email-forward.js <domain> <mailbox> [--force]Delete email forward"
      },
      {
        "title": "Core Library",
        "body": "ScriptPurposegandi-api.jsCore API client (importable)"
      },
      {
        "title": "Default Configuration",
        "body": "Token file: ~/.config/gandi/api_token (API authentication)\nContact file: ~/.config/gandi/contact.json (domain registration info, optional)\nAPI URL: https://api.gandi.net (production)"
      },
      {
        "title": "Sandbox Testing",
        "body": "To use Gandi's sandbox environment:\n\n# Create sandbox token at: https://admin.sandbox.gandi.net\necho \"YOUR_SANDBOX_TOKEN\" > ~/.config/gandi/api_token\necho \"https://api.sandbox.gandi.net\" > ~/.config/gandi/api_url"
      },
      {
        "title": "Token Not Found",
        "body": "# Verify file exists\nls -la ~/.config/gandi/api_token\n\n# Should show: -rw------- (600 permissions)"
      },
      {
        "title": "Authentication Failed (401)",
        "body": "Token is incorrect or expired\nCreate new token at Gandi Admin\nUpdate stored token file"
      },
      {
        "title": "Permission Denied (403)",
        "body": "Token doesn't have required scopes\nCreate new token with Domain:read and LiveDNS:read\nVerify organization membership"
      },
      {
        "title": "Domain Not Using LiveDNS",
        "body": "If you get \"not using Gandi LiveDNS\" error:\n\nLog in to Gandi Admin\nGo to domain management\nAttach LiveDNS service to the domain"
      },
      {
        "title": "Rate Limit (429)",
        "body": "Gandi allows 1000 requests/minute. If exceeded:\n\nWait 60 seconds\nReduce frequency of API calls"
      },
      {
        "title": "API Reference",
        "body": "The skill provides importable functions:\n\nimport { \n  testAuth,\n  listDomains,\n  getDomain,\n  listDnsRecords,\n  getDnsRecord,\n  checkAvailability\n} from './gandi-api.js';\n\n// Test authentication\nconst auth = await testAuth();\n\n// List domains\nconst domains = await listDomains();\n\n// Get domain info\nconst domain = await getDomain('example.com');\n\n// List DNS records\nconst records = await listDnsRecords('example.com');\n\n// Get specific DNS record\nconst record = await getDnsRecord('example.com', '@', 'A');\n\n// Check availability\nconst available = await checkAvailability(['example.com', 'example.net']);"
      },
      {
        "title": "Token Storage",
        "body": "✅ DO:\n\nStore at ~/.config/gandi/api_token\nUse 600 permissions (owner read-only)\nRotate tokens regularly\nUse minimal required scopes\n\n❌ DON'T:\n\nCommit tokens to repositories\nShare tokens between users\nGive tokens unnecessary permissions\nStore tokens in scripts"
      },
      {
        "title": "Token Scopes",
        "body": "Phase 1 (current):\n\nDomain: read\nLiveDNS: read\n\nPhase 2+ (future):\n\nDomain: read, write (for registration, renewal)\nLiveDNS: read, write (for DNS modifications)\nCertificate: read (optional, for SSL certs)\nEmail: read, write (optional, for email config)"
      },
      {
        "title": "Architecture",
        "body": "gandi-skill/\n├── SKILL.md                 # This file\n├── references/              # API documentation\n│   ├── api-overview.md\n│   ├── authentication.md\n│   ├── domains.md\n│   ├── livedns.md\n│   └── setup.md\n└── scripts/                 # Helper utilities\n    ├── package.json\n    ├── gandi-api.js         # Core API client\n    ├── test-auth.js         # Test authentication\n    ├── list-domains.js      # List domains\n    └── list-dns.js          # List DNS records"
      },
      {
        "title": "Development Roadmap",
        "body": "Phase 1: Read Operations (✅ Current)\n\nAuthentication with PAT\nList domains\nGet domain details\nList DNS records\nBasic error handling\n\nPhase 2: DNS Modifications\n\nAdd DNS records\nUpdate DNS records\nDelete DNS records\nBulk DNS operations\n\nPhase 3: Domain Management\n\nDomain registration\nDomain renewal\nAuto-renewal configuration\nNameserver management\n\nPhase 4: Multi-Organization (#1)\n\nProfile-based token management\nOrganization selection\nMultiple token support\n\nPhase 5: Advanced Features\n\nDNSSEC management\nCertificate management\nEmail/mailbox configuration\nDomain transfer operations"
      },
      {
        "title": "Contributing",
        "body": "See Contributing Guide in the main README."
      },
      {
        "title": "Support",
        "body": "Issues: GitHub Issues\nDocumentation: Reference Guides\nGandi Support: help.gandi.net"
      },
      {
        "title": "License",
        "body": "MIT License - See LICENSE"
      }
    ],
    "body": "Gandi Domain Registrar Skill\n\nComprehensive Gandi domain registrar integration for Moltbot.\n\nStatus: ✅ Phase 2 Complete - DNS modification & snapshots functional\n\n⚠️ Security Warning\n\nThis skill can perform DESTRUCTIVE operations on your Gandi account:\n\nDNS Modification: Add, update, or delete DNS records (can break websites/email)\nEmail Management: Create, modify, or delete email forwards (can intercept emails)\nDomain Registration: Register domains (creates financial transactions)\nBulk Operations: Replace all DNS records at once (cannot be undone except via snapshots)\n\nBefore running ANY script:\n\nReview the script code to understand what it does\nCreate DNS snapshots before bulk changes (create-snapshot.js)\nUse read-only Personal Access Tokens where possible\nTest on non-production domains first\nUnderstand that some operations cannot be undone\n\nDestructive scripts (⚠️ modify or delete data):\n\nadd-dns-record.js, delete-dns-record.js, update-dns-bulk.js\nadd-email-forward.js, update-email-forward.js, delete-email-forward.js\nrestore-snapshot.js (replaces current DNS)\n\nRead-only scripts (✅ safe, no modifications):\n\nlist-domains.js, list-dns.js, list-snapshots.js\nlist-email-forwards.js, check-domain.js, check-ssl.js\n\n📖 For complete script documentation: See SCRIPTS.md for detailed information about:\n\nWhat each script does\nNetwork operations and API calls\nSecurity implications\nUndo/recovery procedures\nAudit workflow recommendations\nCurrent Capabilities\nPhase 1 (Complete)\n✅ Personal Access Token authentication\n✅ List domains in your account\n✅ Get domain details (expiration, status, services)\n✅ List DNS records for domains\n✅ View domain and DNS information\n✅ Domain availability checking (#4)\n✅ Smart domain suggestions with variations (#4)\n✅ SSL certificate status checker\n✅ Error handling and validation\nPhase 2 (Complete)\n✅ Add/update DNS records (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR)\n✅ Delete DNS records\n✅ Bulk DNS operations (replace all records at once)\n✅ DNS zone snapshots (create, list, restore)\n✅ Email forwarding (create, list, update, delete forwards including catch-all)\n✅ Record validation (automatic validation for each record type)\n✅ Safety features (automatic snapshots before bulk changes, confirmation prompts)\nComing Soon (Phase 3+)\nDomain registration\nMulti-organization support (#1)\nGateway Console configuration (#3)\nDomain renewal management\nDNSSEC configuration\nCertificate management\nEmail mailbox management (beyond forwarding)\nSetup\nStep 1: Create Personal Access Token\n\n⚠️ Security Recommendation: Use the minimum required scopes for your use case.\n\nGo to Gandi Admin → Personal Access Tokens\n\nClick \"Create a token\"\n\nSelect your organization\n\nChoose scopes:\n\nRead-Only (Recommended for viewing only):\n\n✅ Domain: read (required for listing domains)\n✅ LiveDNS: read (required for viewing DNS records)\n✅ Email: read (required for viewing email forwards)\n\nWrite Access (Required for modifications - use with caution):\n\n⚠️ LiveDNS: write (enables DNS modification, deletion, bulk operations)\n⚠️ Email: write (enables email forward creation, updates, deletions)\n\nCopy the token (you won't see it again!)\n\nSecurity Best Practices:\n\nCreate separate tokens for read-only vs. write operations\nUse read-only tokens for routine checks/monitoring\nOnly use write tokens when actively making changes\nRotate tokens regularly (every 90 days recommended)\nDelete unused tokens immediately\nNever share or commit tokens to version control\nStep 2: Store Token\n\nScripts check for credentials in priority order:\n\nGANDI_API_TOKEN environment variable (checked first)\n~/.config/gandi/api_token file (fallback if env var not set)\n\nChoose the method that fits your workflow:\n\nOption A: Environment Variable (Recommended for CI/CD)\n# Set environment variable (replace YOUR_PAT with actual token)\nexport GANDI_API_TOKEN=\"YOUR_PERSONAL_ACCESS_TOKEN\"\n\n# Add to shell profile for persistence (~/.bashrc, ~/.zshrc, etc.)\necho 'export GANDI_API_TOKEN=\"YOUR_PERSONAL_ACCESS_TOKEN\"' >> ~/.bashrc\n\n\nBenefits:\n\n✅ CI/CD friendly (standard pattern for automation)\n✅ Container-ready (no file mounts needed)\n✅ Works with secret management tools (1Password, Vault, etc.)\n✅ Easy to switch between multiple tokens\nOption B: File-based (Recommended for local development)\n# Create config directory\nmkdir -p ~/.config/gandi\n\n# Store your token (replace YOUR_PAT with actual token)\necho \"YOUR_PERSONAL_ACCESS_TOKEN\" > ~/.config/gandi/api_token\n\n# Secure the file (owner read-only)\nchmod 600 ~/.config/gandi/api_token\n\n\nBenefits:\n\n✅ Token persists across shell sessions\n✅ Secure file permissions (0600 = owner read-only)\n✅ No risk of exposing token in process list\n✅ Works offline (no external dependencies)\nStep 3: Install Dependencies\n\nRequired: Node.js >= 18.0.0\n\ncd gandi-skill/scripts\n\n# Install npm dependencies\nnpm install\n\n# Verify installation\nnpm list --depth=0\n\n\nExpected packages:\n\naxios (HTTP client for Gandi API)\nAny other dependencies listed in package.json\n\nTroubleshooting:\n\nIf node or npm not found: Install Node.js from nodejs.org\nIf permission errors: Don't use sudo - fix npm permissions or use nvm\nIf package errors: Delete node_modules/ and package-lock.json, then npm install again\nStep 4: Test Authentication\ncd gandi-skill/scripts\nnode test-auth.js\n\n\nExpected output:\n\n✅ Authentication successful!\n\nYour organizations:\n  1. Personal Account (uuid-here)\n     Type: individual\n\n🎉 You're ready to use the Gandi skill!\n\nStep 5: Setup Contact Information (Optional, for Domain Registration)\n\nIf you plan to register domains, save your contact information once for reuse:\n\ncd gandi-skill/scripts\nnode setup-contact.js\n\n\nThe script will prompt for:\n\nName (first and last)\nEmail address\nPhone number (international format: +1.5551234567)\nStreet address\nCity\nState/Province (for US: 2-letter code like OH, automatically formatted to US-OH)\nZIP/Postal code\nCountry (2-letter code: US, FR, etc.)\nType (individual or company)\nPrivacy preference: Retain or auto-purge contact after registration\n\nContact information is saved to:\n\n~/.config/gandi/contact.json\nPermissions: 600 (owner read-write only)\nOutside the skill directory (never committed to git)\n\nPrivacy Options:\n\nRETAIN (default): Keep contact saved for future registrations\n\nBest for frequent domain registrations\nSetup once, use forever\nDelete manually anytime with delete-contact.js\n\nPURGE: Auto-delete contact after each registration\n\nBest for privacy-conscious users\nContact info only exists during registration\nMust re-enter for next registration\n\nManaging saved contact:\n\n# View current contact\nnode view-contact.js\n\n# Update contact info or privacy preference\nnode setup-contact.js\n\n# Delete saved contact manually\nnode delete-contact.js\n\n# Delete without confirmation\nnode delete-contact.js --force\n\n\nOne-time purge override:\n\n# Register and delete contact (even if preference is \"retain\")\nnode register-domain.js example.com --purge-contact\n\nUsage Examples\nList Your Domains\nnode list-domains.js\n\n\nOutput shows:\n\nDomain names\nExpiration dates\nAuto-renewal status\nServices (LiveDNS, Email, etc.)\nOrganization ownership\nList DNS Records\nnode list-dns.js example.com\n\n\nOutput shows:\n\nAll DNS records grouped by type\nTTL values\nRecord names and values\nNameservers\nUsing from Moltbot\n\nOnce configured, you can use natural language:\n\n\"List my Gandi domains\"\n\n\"Show DNS records for example.com\"\n\n\"When does example.com expire?\"\n\n\"Is auto-renewal enabled for example.com?\"\n\nDomain Availability Checking\nCheck Single Domain\n\nCheck if a specific domain is available for registration:\n\nnode check-domain.js example.com\n\n\nFeatures:\n\nShows availability status (available/unavailable/pending/error)\nDisplays pricing information (registration, renewal, transfer)\nLists supported features (DNSSEC, LiveDNS, etc.)\nShows TLD information\n\nExample Output:\n\n🔍 Checking availability for: example.com\n\nDomain: example.com\n\n✅ Status: AVAILABLE\n\n💰 Pricing:\n  1 year: 12.00 EUR (+ 2.40 tax)\n  2 years: 24.00 EUR (+ 4.80 tax)\n\n📋 Supported Features:\n  • create\n  • dnssec\n  • livedns\n\n🌐 TLD Information:\n  Extension: com\n\nSmart Domain Suggestions\n\nFind available alternatives with TLD variations and name modifications:\n\n# Check all configured TLDs + variations\nnode suggest-domains.js example\n\n# Check specific TLDs only\nnode suggest-domains.js example --tlds com,net,io\n\n# Skip name variations (only check TLDs)\nnode suggest-domains.js example --no-variations\n\n# Output as JSON\nnode suggest-domains.js example --json\n\n\nName Variation Patterns:\n\nHyphenated: Adds hyphens between word boundaries (example → ex-ample)\nAbbreviated: Removes vowels (example → exmpl)\nPrefix: Adds common prefixes (example → get-example, my-example)\nSuffix: Adds common suffixes (example → example-app, example-hub)\nNumbers: Appends numbers (example → example2, example3)\n\nExample Output:\n\n🔍 Checking availability for: example\n\n📊 Checking 13 TLDs and generating variations...\n\n═══════════════════════════════════════════════════════\n📋 EXACT MATCHES (Different TLDs)\n═══════════════════════════════════════════════════════\n\n✅ Available:\n\n  example.net                    12.00 EUR\n  example.io                     39.00 EUR\n  example.dev                    15.00 EUR\n\n❌ Unavailable:\n\n  example.com                    (unavailable)\n  example.org                    (unavailable)\n\n═══════════════════════════════════════════════════════\n🎨 NAME VARIATIONS\n═══════════════════════════════════════════════════════\n\nHyphenated:\n\n  ✅ ex-ample.com                12.00 EUR\n\nPrefix:\n\n  ✅ get-example.com             12.00 EUR\n  ✅ my-example.com              12.00 EUR\n\nSuffix:\n\n  ✅ example-app.com             12.00 EUR\n  ✅ example-io.com              12.00 EUR\n\n═══════════════════════════════════════════════════════\n📊 SUMMARY: 8 available domains found\n═══════════════════════════════════════════════════════\n\nConfiguration\n\nDomain checker configuration is stored in gandi-skill/config/domain-checker-defaults.json.\n\nStructure:\n\n{\n  \"tlds\": {\n    \"mode\": \"extend\",\n    \"defaults\": [\"com\", \"net\", \"org\", \"info\", \"io\", \"dev\", \"app\", \"ai\", \"tech\"],\n    \"custom\": []\n  },\n  \"variations\": {\n    \"enabled\": true,\n    \"patterns\": [\"hyphenated\", \"abbreviated\", \"prefix\", \"suffix\", \"numbers\"],\n    \"prefixes\": [\"get\", \"my\", \"the\", \"try\"],\n    \"suffixes\": [\"app\", \"hub\", \"io\", \"ly\", \"ai\", \"hq\"],\n    \"maxNumbers\": 3\n  },\n  \"rateLimit\": {\n    \"maxConcurrent\": 3,\n    \"delayMs\": 200,\n    \"maxRequestsPerMinute\": 100\n  },\n  \"limits\": {\n    \"maxTlds\": 5,\n    \"maxVariations\": 10\n  }\n}\n\n\nRate Limiting & Limits:\n\nmaxConcurrent: Maximum concurrent API requests (default: 3)\ndelayMs: Delay between requests in milliseconds (default: 200ms)\nmaxRequestsPerMinute: Hard limit on requests per minute (default: 100, Gandi allows 1000)\nmaxTlds: Maximum TLDs to check in suggest-domains.js (default: 5)\nmaxVariations: Maximum name variations to generate (default: 10)\n\nThese limits ensure good API citizenship and prevent overwhelming Gandi's API.\n\nTLD Modes:\n\n\"extend\": Use defaults + custom TLDs (merged list)\n\"replace\": Use only custom TLDs (ignore defaults)\n\nGateway Console Integration:\n\nWhen Gateway Console support is added (#3), configuration will be available at:\n\nskills:\n  entries:\n    gandi:\n      config:\n        domainChecker:\n          tlds:\n            mode: extend\n            defaults: [...]\n            custom: [...]\n          variations:\n            enabled: true\n            patterns: [...]\n\n\nSee docs/gateway-config-design.md for complete configuration architecture.\n\nDNS Management (Phase 2)\nAdd or Update DNS Records\n\nCreate or update individual DNS records:\n\n# Add an A record for root domain\nnode add-dns-record.js example.com @ A 192.168.1.1\n\n# Add www subdomain pointing to root\nnode add-dns-record.js example.com www CNAME @\n\n# Add MX record for email\nnode add-dns-record.js example.com @ MX \"10 mail.example.com.\"\n\n# Add TXT record for SPF\nnode add-dns-record.js example.com @ TXT \"v=spf1 include:_spf.google.com ~all\"\n\n# Add with custom TTL (5 minutes)\nnode add-dns-record.js example.com api A 192.168.1.10 300\n\n\nSupported record types: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR\n\nDelete DNS Records\n\nRemove specific DNS records:\n\n# Delete old A record\nnode delete-dns-record.js example.com old A\n\n# Delete with confirmation prompt\nnode delete-dns-record.js example.com test CNAME\n\n# Delete without confirmation\nnode delete-dns-record.js example.com old A --force\n\nBulk DNS Operations\n\nReplace all DNS records at once:\n\n# From JSON file\nnode update-dns-bulk.js example.com new-records.json\n\n# From stdin\ncat records.json | node update-dns-bulk.js example.com\n\n# Skip automatic snapshot\nnode update-dns-bulk.js example.com records.json --no-snapshot\n\n# Skip confirmation\nnode update-dns-bulk.js example.com records.json --force\n\n\nJSON format:\n\n[\n  {\n    \"rrset_name\": \"@\",\n    \"rrset_type\": \"A\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"192.168.1.1\"]\n  },\n  {\n    \"rrset_name\": \"www\",\n    \"rrset_type\": \"CNAME\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"@\"]\n  },\n  {\n    \"rrset_name\": \"@\",\n    \"rrset_type\": \"MX\",\n    \"rrset_ttl\": 10800,\n    \"rrset_values\": [\"10 mail.example.com.\", \"20 mail2.example.com.\"]\n  }\n]\n\nDNS Zone Snapshots\n\nCreate safety backups before making changes:\n\n# Create a snapshot\nnode create-snapshot.js example.com \"Before migration\"\n\n# List all snapshots\nnode list-snapshots.js example.com\n\n# Restore from a snapshot\nnode restore-snapshot.js example.com abc123-def456-ghi789\n\n# Restore without confirmation\nnode restore-snapshot.js example.com abc123-def456-ghi789 --force\n\n\nAutomatic snapshots:\n\nBulk updates automatically create snapshots (unless --no-snapshot)\nSnapshots are named with timestamp\nUse snapshots for easy rollback\nCommon DNS Configuration Examples\nBasic Website Setup\n# Root domain\nnode add-dns-record.js example.com @ A 192.168.1.1\n\n# WWW subdomain\nnode add-dns-record.js example.com www CNAME @\n\nEmail Configuration (Google Workspace)\n# MX records\nnode add-dns-record.js example.com @ MX \"1 ASPMX.L.GOOGLE.COM.\"\nnode add-dns-record.js example.com @ MX \"5 ALT1.ASPMX.L.GOOGLE.COM.\"\nnode add-dns-record.js example.com @ MX \"5 ALT2.ASPMX.L.GOOGLE.COM.\"\n\n# SPF record\nnode add-dns-record.js example.com @ TXT \"v=spf1 include:_spf.google.com ~all\"\n\nDomain Redirect Setup\n\nTo redirect one domain to another:\n\n# Point root domain to same server\nnode add-dns-record.js old-domain.com @ A 192.168.1.1\n\n# Point www to same CNAME\nnode add-dns-record.js old-domain.com www CNAME @\n\n\nThen configure HTTP 301 redirect at the server level.\n\nSubdomain Setup\n# API subdomain\nnode add-dns-record.js example.com api A 192.168.1.10\n\n# Staging subdomain\nnode add-dns-record.js example.com staging A 192.168.1.20\n\n# Wildcard subdomain\nnode add-dns-record.js example.com \"*\" A 192.168.1.100\n\nEmail Forwarding (Phase 2)\nList Email Forwards\n\nSee all email forwards configured for a domain:\n\nnode list-email-forwards.js example.com\n\nCreate Email Forwards\n\nForward emails to one or more destinations:\n\n# Simple forward\nnode add-email-forward.js example.com hello you@personal.com\n\n# Forward to multiple destinations\nnode add-email-forward.js example.com support team1@example.com team2@example.com\n\n# Catch-all forward (forwards all unmatched emails)\nnode add-email-forward.js example.com @ catchall@example.com\n\nUpdate Email Forwards\n\nChange the destination(s) for an existing forward:\n\n# Update single destination\nnode update-email-forward.js example.com hello newemail@personal.com\n\n# Update to multiple destinations\nnode update-email-forward.js example.com support new1@example.com new2@example.com\n\n\nNote: This replaces all existing destinations with the new ones.\n\nDelete Email Forwards\n\nRemove email forwards:\n\n# Delete with confirmation prompt\nnode delete-email-forward.js example.com old\n\n# Delete without confirmation\nnode delete-email-forward.js example.com old --force\n\n# Delete catch-all forward\nnode delete-email-forward.js example.com @ --force\n\nCommon Email Forwarding Use Cases\nBasic Email Forwarding\n# Forward contact@ to your personal email\nnode add-email-forward.js example.com contact you@gmail.com\n\n# Forward sales@ to team\nnode add-email-forward.js example.com sales team@example.com\n\nDomain Migration Email Forwarding\n# Forward all email from old domain to new domain\n# Preserves the local part (username before @)\n\n# First, list existing forwards on old domain\nnode list-email-forwards.js old-domain.com\n\n# Then create matching forwards on new domain\nnode add-email-forward.js old-domain.com contact contact@new-domain.com\nnode add-email-forward.js old-domain.com support support@new-domain.com\n\n# Or use catch-all to forward everything\nnode add-email-forward.js old-domain.com @ admin@new-domain.com\n\nTeam Distribution Lists\n# Forward to entire team\nnode add-email-forward.js example.com team alice@example.com bob@example.com charlie@example.com\n\n# Update team members\nnode update-email-forward.js example.com team alice@example.com dave@example.com\n\nCatch-All Configuration\n# Forward all unmatched emails to one address\nnode add-email-forward.js example.com @ catchall@example.com\n\n# Forward all unmatched emails to multiple addresses\nnode add-email-forward.js example.com @ admin1@example.com admin2@example.com\n\n\nNote: Catch-all forwards only apply to email addresses that don't have specific forwards configured.\n\nEmail Forward Management Tips\nTest after creating: Send a test email to verify forwarding works\nUse specific forwards over catch-all: More control and easier to manage\nMultiple destinations: Email is sent to all destinations (not round-robin)\nOrder doesn't matter: Gandi processes most specific match first\nCheck spam folders: Forwarded emails may be filtered by recipient's spam filter\nExample: Complete Domain Email Setup\n# 1. Set up MX records (if not already done)\nnode add-dns-record.js example.com @ MX \"10 spool.mail.gandi.net.\"\nnode add-dns-record.js example.com @ MX \"50 fb.mail.gandi.net.\"\n\n# 2. Create specific forwards\nnode add-email-forward.js example.com hello you@personal.com\nnode add-email-forward.js example.com support team@example.com\nnode add-email-forward.js example.com sales sales-team@example.com\n\n# 3. Set up catch-all for everything else\nnode add-email-forward.js example.com @ admin@example.com\n\n# 4. List all forwards to verify\nnode list-email-forwards.js example.com\n\nHelper Scripts\n\nAll scripts are in gandi-skill/scripts/:\n\nAuthentication & Setup\nScript\tPurpose\ntest-auth.js\tVerify authentication works\nsetup-contact.js\tSave contact info for domain registration (run once)\nview-contact.js\tView saved contact information\ndelete-contact.js\tDelete saved contact (with optional --force)\nDomain & DNS Viewing\nScript\tPurpose\nlist-domains.js\tShow all domains in account\nlist-dns.js <domain>\tShow DNS records for domain\ncheck-domain.js <domain>\tCheck single domain availability + pricing\nsuggest-domains.js <name>\tSmart domain suggestions with variations\ncheck-ssl.js\tCheck SSL certificate status for all domains\nDNS Modification (Phase 2)\nScript\tPurpose\nadd-dns-record.js <domain> <name> <type> <value> [ttl]\tAdd or update a DNS record\ndelete-dns-record.js <domain> <name> <type> [--force]\tDelete a DNS record\nupdate-dns-bulk.js <domain> <records.json> [--no-snapshot] [--force]\tBulk update all DNS records\nlist-snapshots.js <domain>\tList DNS zone snapshots\ncreate-snapshot.js <domain> [name]\tCreate a DNS zone snapshot\nrestore-snapshot.js <domain> <snapshot-id> [--force]\tRestore DNS zone from snapshot\nEmail Forwarding (Phase 2)\nScript\tPurpose\nlist-email-forwards.js <domain>\tList all email forwards for a domain\nadd-email-forward.js <domain> <mailbox> <destination> [dest2...]\tCreate email forward (use @ for catch-all)\nupdate-email-forward.js <domain> <mailbox> <destination> [dest2...]\tUpdate email forward destinations\ndelete-email-forward.js <domain> <mailbox> [--force]\tDelete email forward\nCore Library\nScript\tPurpose\ngandi-api.js\tCore API client (importable)\nConfiguration\nDefault Configuration\nToken file: ~/.config/gandi/api_token (API authentication)\nContact file: ~/.config/gandi/contact.json (domain registration info, optional)\nAPI URL: https://api.gandi.net (production)\nSandbox Testing\n\nTo use Gandi's sandbox environment:\n\n# Create sandbox token at: https://admin.sandbox.gandi.net\necho \"YOUR_SANDBOX_TOKEN\" > ~/.config/gandi/api_token\necho \"https://api.sandbox.gandi.net\" > ~/.config/gandi/api_url\n\nTroubleshooting\nToken Not Found\n# Verify file exists\nls -la ~/.config/gandi/api_token\n\n# Should show: -rw------- (600 permissions)\n\nAuthentication Failed (401)\nToken is incorrect or expired\nCreate new token at Gandi Admin\nUpdate stored token file\nPermission Denied (403)\nToken doesn't have required scopes\nCreate new token with Domain:read and LiveDNS:read\nVerify organization membership\nDomain Not Using LiveDNS\n\nIf you get \"not using Gandi LiveDNS\" error:\n\nLog in to Gandi Admin\nGo to domain management\nAttach LiveDNS service to the domain\nRate Limit (429)\n\nGandi allows 1000 requests/minute. If exceeded:\n\nWait 60 seconds\nReduce frequency of API calls\nAPI Reference\n\nThe skill provides importable functions:\n\nimport { \n  testAuth,\n  listDomains,\n  getDomain,\n  listDnsRecords,\n  getDnsRecord,\n  checkAvailability\n} from './gandi-api.js';\n\n// Test authentication\nconst auth = await testAuth();\n\n// List domains\nconst domains = await listDomains();\n\n// Get domain info\nconst domain = await getDomain('example.com');\n\n// List DNS records\nconst records = await listDnsRecords('example.com');\n\n// Get specific DNS record\nconst record = await getDnsRecord('example.com', '@', 'A');\n\n// Check availability\nconst available = await checkAvailability(['example.com', 'example.net']);\n\nSecurity\nToken Storage\n\n✅ DO:\n\nStore at ~/.config/gandi/api_token\nUse 600 permissions (owner read-only)\nRotate tokens regularly\nUse minimal required scopes\n\n❌ DON'T:\n\nCommit tokens to repositories\nShare tokens between users\nGive tokens unnecessary permissions\nStore tokens in scripts\nToken Scopes\n\nPhase 1 (current):\n\nDomain: read\nLiveDNS: read\n\nPhase 2+ (future):\n\nDomain: read, write (for registration, renewal)\nLiveDNS: read, write (for DNS modifications)\nCertificate: read (optional, for SSL certs)\nEmail: read, write (optional, for email config)\nArchitecture\ngandi-skill/\n├── SKILL.md                 # This file\n├── references/              # API documentation\n│   ├── api-overview.md\n│   ├── authentication.md\n│   ├── domains.md\n│   ├── livedns.md\n│   └── setup.md\n└── scripts/                 # Helper utilities\n    ├── package.json\n    ├── gandi-api.js         # Core API client\n    ├── test-auth.js         # Test authentication\n    ├── list-domains.js      # List domains\n    └── list-dns.js          # List DNS records\n\nDevelopment Roadmap\n\nPhase 1: Read Operations (✅ Current)\n\nAuthentication with PAT\nList domains\nGet domain details\nList DNS records\nBasic error handling\n\nPhase 2: DNS Modifications\n\nAdd DNS records\nUpdate DNS records\nDelete DNS records\nBulk DNS operations\n\nPhase 3: Domain Management\n\nDomain registration\nDomain renewal\nAuto-renewal configuration\nNameserver management\n\nPhase 4: Multi-Organization (#1)\n\nProfile-based token management\nOrganization selection\nMultiple token support\n\nPhase 5: Advanced Features\n\nDNSSEC management\nCertificate management\nEmail/mailbox configuration\nDomain transfer operations\nContributing\n\nSee Contributing Guide in the main README.\n\nSupport\nIssues: GitHub Issues\nDocumentation: Reference Guides\nGandi Support: help.gandi.net\nLicense\n\nMIT License - See LICENSE"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/chrisagiddings/gandi-skill",
    "publisherUrl": "https://clawhub.ai/chrisagiddings/gandi-skill",
    "owner": "chrisagiddings",
    "version": "0.2.7",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/gandi-skill",
    "downloadUrl": "https://openagent3.xyz/downloads/gandi-skill",
    "agentUrl": "https://openagent3.xyz/skills/gandi-skill/agent",
    "manifestUrl": "https://openagent3.xyz/skills/gandi-skill/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/gandi-skill/agent.md"
  }
}