@themkn/gandi-mcp 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/gandi/client.d.ts +3 -2
- package/dist/gandi/client.d.ts.map +1 -1
- package/dist/gandi/client.js +16 -10
- package/dist/gandi/client.js.map +1 -1
- package/dist/gandi/types.d.ts +4 -0
- package/dist/gandi/types.d.ts.map +1 -1
- package/dist/tools/domains.d.ts.map +1 -1
- package/dist/tools/domains.js +40 -4
- package/dist/tools/domains.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Gandi replaced legacy API keys with Personal Access Tokens (PATs). To create one
|
|
|
25
25
|
3. Under **Personal Access Tokens**, click **Create a token**.
|
|
26
26
|
4. Give it a name (e.g. `gandi-mcp`) and pick an expiration (max 1 year — Gandi will email you when it nears expiry).
|
|
27
27
|
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.
|
|
28
|
-
6. **Permissions:**
|
|
28
|
+
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.
|
|
29
29
|
7. Click **Create**. **Copy the token immediately** — Gandi only shows it once. If you miss it, delete and create a new one.
|
|
30
30
|
|
|
31
31
|
That token is your `apiKey` value in the config below.
|
|
@@ -95,7 +95,7 @@ By default Claude Code prompts on every tool call. To allow all `gandi-mcp` tool
|
|
|
95
95
|
|
|
96
96
|
| Tool | What it does |
|
|
97
97
|
|------|--------------|
|
|
98
|
-
| `list_domains` | List
|
|
98
|
+
| `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. |
|
|
99
99
|
| `list_records` | List records for a domain, with optional `type` and `nameFilter` (anchored, case-insensitive glob — `*` = any, `?` = one) |
|
|
100
100
|
| `get_record` | Fetch a single record by name + type |
|
|
101
101
|
| `add_record` | Add a new record; auto-backup runs first |
|
package/dist/gandi/client.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { DnsRecord, Domain, RecordInput, Snapshot } from "./types.js";
|
|
1
|
+
import type { DnsRecord, Domain, Organization, RecordInput, Snapshot } from "./types.js";
|
|
2
2
|
export declare class GandiClient {
|
|
3
3
|
private readonly token;
|
|
4
4
|
constructor(token: string);
|
|
5
5
|
private request;
|
|
6
|
-
listDomains(): Promise<Domain[]>;
|
|
6
|
+
listDomains(sharingId?: string): Promise<Domain[]>;
|
|
7
|
+
listOrganizations(): Promise<Organization[]>;
|
|
7
8
|
listRecords(domain: string): Promise<DnsRecord[]>;
|
|
8
9
|
getRecord(domain: string, name: string, type: string): Promise<DnsRecord>;
|
|
9
10
|
addRecord(domain: string, input: RecordInput): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/gandi/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/gandi/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKzF,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;YAE5B,OAAO;IA8Bf,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMlD,iBAAiB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI5C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIjD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAMzE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY5D,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAa/D,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIlD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAQvE"}
|
package/dist/gandi/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GandiError } from "./errors.js";
|
|
2
|
-
const BASE_URL = "https://api.gandi.net/v5
|
|
2
|
+
const BASE_URL = "https://api.gandi.net/v5";
|
|
3
3
|
export class GandiClient {
|
|
4
4
|
token;
|
|
5
5
|
constructor(token) {
|
|
@@ -34,17 +34,23 @@ export class GandiClient {
|
|
|
34
34
|
return undefined;
|
|
35
35
|
return JSON.parse(text);
|
|
36
36
|
}
|
|
37
|
-
async listDomains() {
|
|
38
|
-
|
|
37
|
+
async listDomains(sharingId) {
|
|
38
|
+
const params = new URLSearchParams({ per_page: "1000" });
|
|
39
|
+
if (sharingId)
|
|
40
|
+
params.set("sharing_id", sharingId);
|
|
41
|
+
return this.request(`/livedns/domains?${params.toString()}`);
|
|
42
|
+
}
|
|
43
|
+
async listOrganizations() {
|
|
44
|
+
return this.request("/organization/organizations");
|
|
39
45
|
}
|
|
40
46
|
async listRecords(domain) {
|
|
41
|
-
return this.request(`/domains/${encodeURIComponent(domain)}/records`);
|
|
47
|
+
return this.request(`/livedns/domains/${encodeURIComponent(domain)}/records`);
|
|
42
48
|
}
|
|
43
49
|
async getRecord(domain, name, type) {
|
|
44
|
-
return this.request(`/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(name)}/${encodeURIComponent(type)}`);
|
|
50
|
+
return this.request(`/livedns/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(name)}/${encodeURIComponent(type)}`);
|
|
45
51
|
}
|
|
46
52
|
async addRecord(domain, input) {
|
|
47
|
-
await this.request(`/domains/${encodeURIComponent(domain)}/records`, {
|
|
53
|
+
await this.request(`/livedns/domains/${encodeURIComponent(domain)}/records`, {
|
|
48
54
|
method: "POST",
|
|
49
55
|
body: JSON.stringify({
|
|
50
56
|
rrset_name: input.name,
|
|
@@ -55,7 +61,7 @@ export class GandiClient {
|
|
|
55
61
|
});
|
|
56
62
|
}
|
|
57
63
|
async updateRecord(domain, input) {
|
|
58
|
-
await this.request(`/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(input.name)}/${encodeURIComponent(input.type)}`, {
|
|
64
|
+
await this.request(`/livedns/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(input.name)}/${encodeURIComponent(input.type)}`, {
|
|
59
65
|
method: "PUT",
|
|
60
66
|
body: JSON.stringify({
|
|
61
67
|
rrset_values: input.values,
|
|
@@ -64,16 +70,16 @@ export class GandiClient {
|
|
|
64
70
|
});
|
|
65
71
|
}
|
|
66
72
|
async deleteRecord(domain, name, type) {
|
|
67
|
-
await this.request(`/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(name)}/${encodeURIComponent(type)}`, { method: "DELETE" });
|
|
73
|
+
await this.request(`/livedns/domains/${encodeURIComponent(domain)}/records/${encodeURIComponent(name)}/${encodeURIComponent(type)}`, { method: "DELETE" });
|
|
68
74
|
}
|
|
69
75
|
async listSnapshots(domain) {
|
|
70
|
-
return this.request(`/domains/${encodeURIComponent(domain)}/snapshots`);
|
|
76
|
+
return this.request(`/livedns/domains/${encodeURIComponent(domain)}/snapshots`);
|
|
71
77
|
}
|
|
72
78
|
async createSnapshot(domain, name) {
|
|
73
79
|
const init = { method: "POST" };
|
|
74
80
|
if (name !== undefined)
|
|
75
81
|
init.body = JSON.stringify({ name });
|
|
76
|
-
return this.request(`/domains/${encodeURIComponent(domain)}/snapshots`, init);
|
|
82
|
+
return this.request(`/livedns/domains/${encodeURIComponent(domain)}/snapshots`, init);
|
|
77
83
|
}
|
|
78
84
|
}
|
|
79
85
|
//# sourceMappingURL=client.js.map
|
package/dist/gandi/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/gandi/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,QAAQ,GAAG,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/gandi/client.ts"],"names":[],"mappings":"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"}
|
package/dist/gandi/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gandi/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gandi/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/tools/domains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/tools/domains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD,eAAO,MAAM,WAAW,EAAE,cAAc,CAAC,OAAO,CAAC,EAiDhD,CAAC"}
|
package/dist/tools/domains.js
CHANGED
|
@@ -1,12 +1,48 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
2
|
+
import { GandiError } from "../gandi/errors.js";
|
|
3
|
+
const ListDomainsInput = z
|
|
4
|
+
.object({
|
|
5
|
+
sharing_id: z.string().min(1).optional(),
|
|
6
|
+
})
|
|
7
|
+
.strict();
|
|
3
8
|
export const domainTools = [
|
|
4
9
|
{
|
|
5
10
|
name: "list_domains",
|
|
6
|
-
description: "List all domains
|
|
11
|
+
description: "List all LiveDNS-managed domains the authenticated user can see, including domains owned by any organization the user belongs to. Without `sharing_id`, results are the union of the personal organization and every reachable organization. Pass `sharing_id` to scope to one organization.",
|
|
7
12
|
schema: ListDomainsInput,
|
|
8
|
-
handler: async (
|
|
9
|
-
|
|
13
|
+
handler: async (input, ctx) => {
|
|
14
|
+
const parsed = input;
|
|
15
|
+
if (parsed.sharing_id) {
|
|
16
|
+
return ctx.client.listDomains(parsed.sharing_id);
|
|
17
|
+
}
|
|
18
|
+
const personalDomains = await ctx.client.listDomains();
|
|
19
|
+
let orgs;
|
|
20
|
+
try {
|
|
21
|
+
orgs = await ctx.client.listOrganizations();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err instanceof GandiError && (err.status === 403 || err.status === 404)) {
|
|
25
|
+
return personalDomains;
|
|
26
|
+
}
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
const orgResults = await Promise.all(orgs.map((org) => ctx.client.listDomains(org.id).catch((err) => {
|
|
30
|
+
if (err instanceof GandiError && (err.status === 403 || err.status === 404)) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
throw err;
|
|
34
|
+
})));
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
const merged = [];
|
|
37
|
+
for (const list of [personalDomains, ...orgResults]) {
|
|
38
|
+
for (const d of list) {
|
|
39
|
+
if (!seen.has(d.fqdn)) {
|
|
40
|
+
seen.add(d.fqdn);
|
|
41
|
+
merged.push(d);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return merged;
|
|
10
46
|
},
|
|
11
47
|
},
|
|
12
48
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/tools/domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/tools/domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACzC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,WAAW,GAA8B;IACpD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,8RAA8R;QAChS,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,KAAyC,CAAC;YAEzD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,CAAC;YAED,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAEvD,IAAI,IAAoB,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;oBAC5E,OAAO,eAAe,CAAC;gBACzB,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACf,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACpD,IAAI,GAAG,YAAY,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;oBAC5E,OAAO,EAAc,CAAC;gBACxB,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC,CAAC,CACH,CACF,CAAC;YAEF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,CAAC,eAAe,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;gBACpD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;oBACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBACjB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACjB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themkn/gandi-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP server for Gandi LiveDNS — manage DNS records, domains, and zone snapshots from Claude Code or any MCP client.",
|
|
5
5
|
"keywords": ["mcp", "mcp-server", "model-context-protocol", "gandi", "dns", "livedns", "claude", "claude-code"],
|
|
6
6
|
"license": "MIT",
|