domeneshop-mcp 1.1.2 → 1.1.4

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +123 -66
  3. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # domeneshop-mcp
2
2
 
3
+ ## 1.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#46](https://github.com/martinzachariassen/domeneshop-mcp/pull/46) [`46cbb8f`](https://github.com/martinzachariassen/domeneshop-mcp/commit/46cbb8f549be5d61f23cb71de542375930d0002a) Thanks [@martinzachariassen](https://github.com/martinzachariassen)! - GitHub Releases now include the npm tarball and SLSA build provenance (`multiple.intoto.jsonl`) for both the tarball and the Claude Desktop bundle. See SECURITY.md for how to verify them.
8
+
9
+ ## 1.1.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [#44](https://github.com/martinzachariassen/domeneshop-mcp/pull/44) [`a369442`](https://github.com/martinzachariassen/domeneshop-mcp/commit/a369442f0a0e50de5dee77c9ec220fc35a7818f6) Thanks [@martinzachariassen](https://github.com/martinzachariassen)! - README: add a short "New to MCP?" primer, expand the Claude Code quick start (read-only and scope flags, `/mcp` check), document the Claude Desktop bundle step by step, and add a configuration table and more troubleshooting.
14
+
3
15
  ## 1.1.2
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -5,12 +5,6 @@
5
5
  </picture>
6
6
  </p>
7
7
 
8
- <h1 align="center">domeneshop-mcp</h1>
9
-
10
- <p align="center">
11
- Manage your Domeneshop domains, DNS records, HTTP forwards, dynamic DNS and invoices from any AI assistant.
12
- </p>
13
-
14
8
  <p align="center">
15
9
  <a href="https://github.com/martinzachariassen/domeneshop-mcp/actions/workflows/ci.yml"><img src="https://github.com/martinzachariassen/domeneshop-mcp/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
16
10
  <a href="https://www.npmjs.com/package/domeneshop-mcp"><img src="https://img.shields.io/npm/v/domeneshop-mcp" alt="npm version"></a>
@@ -22,15 +16,17 @@
22
16
  </p>
23
17
 
24
18
  <p align="center">
25
- <a href="https://www.npmjs.com/package/domeneshop-mcp"><b>npm package</b></a>
19
+ <a href="#quick-start"><b>Quick start</b></a>
26
20
  &nbsp;·&nbsp;
27
- <a href="https://github.com/martinzachariassen/homebrew-tap"><b>Homebrew tap</b></a>
21
+ <a href="#client-setup"><b>Client setup</b></a>
28
22
  &nbsp;·&nbsp;
29
- <a href="https://api.domeneshop.no/docs/"><b>Domeneshop API</b></a>
23
+ <a href="#tools"><b>Tools</b></a>
30
24
  &nbsp;·&nbsp;
31
- <a href="https://www.domeneshop.no/admin?view=api"><b>Get API credentials</b></a>
25
+ <a href="#access-control"><b>Access control</b></a>
26
+ &nbsp;·&nbsp;
27
+ <a href="#troubleshooting"><b>Troubleshooting</b></a>
32
28
  &nbsp;·&nbsp;
33
- <a href="https://registry.modelcontextprotocol.io/v0/servers?search=io.github.martinzachariassen/domeneshop-mcp"><b>MCP Registry</b></a>
29
+ <a href="https://www.domeneshop.no/admin?view=api"><b>Get API credentials</b></a>
34
30
  </p>
35
31
 
36
32
  An [MCP](https://modelcontextprotocol.io) server that turns the
@@ -41,6 +37,31 @@ forwarding, dynamic DNS and invoices.
41
37
  It talks MCP over stdio, so it works with **any MCP-compatible client**: Claude
42
38
  Code, Claude Desktop, Cursor, VS Code, Codex, Windsurf, Cline and others.
43
39
 
40
+ <details>
41
+ <summary><strong>New to MCP? Start here</strong></summary>
42
+
43
+ [MCP](https://modelcontextprotocol.io) (Model Context Protocol) is an open
44
+ standard that lets AI apps call outside tools. This package is an *MCP server*:
45
+ a small program your AI app starts in the background and talks to. Once it is
46
+ registered, you just ask in plain language — "point blog.example.no at
47
+ 203.0.113.10" — and the assistant picks the right tool, shows you what it is
48
+ about to do and asks before changing anything.
49
+
50
+ You never run the server yourself, and you do not need to know the tool names.
51
+ What you need:
52
+
53
+ - A **Domeneshop API token and secret**, a key pair that lets a program act on
54
+ your account. Treat them like a password.
55
+ - An **MCP client**, the app you chat with. Claude Code is used below; any
56
+ other works too (see [Client setup](#client-setup)).
57
+ - **Node.js 20.3+** ([download the LTS](https://nodejs.org)) or Homebrew. Not
58
+ needed for the Claude Desktop bundle.
59
+
60
+ If you are unsure about letting an assistant change live DNS, start in
61
+ [read-only mode](#access-control): it can look at everything but change nothing.
62
+
63
+ </details>
64
+
44
65
  ## Quick start
45
66
 
46
67
  You need a Domeneshop account, plus either Node.js 20.3 or newer (for `npx`) or
@@ -49,16 +70,23 @@ You need a Domeneshop account, plus either Node.js 20.3 or newer (for `npx`) or
49
70
  **1. Create an API token and secret** at
50
71
  [domeneshop.no/admin?view=api](https://www.domeneshop.no/admin?view=api).
51
72
 
52
- **2. Register the server.** In Claude Code:
73
+ **2. Register the server** in [Claude Code](https://claude.com/claude-code),
74
+ replacing the placeholders with your token and secret:
53
75
 
54
76
  ```sh
55
77
  claude mcp add domeneshop \
56
- --env DOMENESHOP_API_TOKEN=your-token \
57
- --env DOMENESHOP_API_SECRET=your-secret \
78
+ --env DOMENESHOP_API_TOKEN=<your-api-token> \
79
+ --env DOMENESHOP_API_SECRET=<your-api-secret> \
58
80
  -- npx -y domeneshop-mcp
59
81
  ```
60
82
 
61
- **3. Ask for something.** "List my domains" is enough to confirm the tools loaded.
83
+ Add `--env DOMENESHOP_READ_ONLY=true` to start with read-only tools only, and
84
+ `--scope user` to make it available in every project (the default is the
85
+ current project only).
86
+
87
+ **3. Ask for something.** Start a new `claude` session and try "List my
88
+ Domeneshop domains". Running `/mcp` inside Claude Code shows whether the server
89
+ connected.
62
90
 
63
91
  **Using Homebrew instead of npx?** Install once, then register the binary in
64
92
  step 2 with `-- domeneshop-mcp` in place of `-- npx -y domeneshop-mcp`:
@@ -67,31 +95,33 @@ step 2 with `-- domeneshop-mcp` in place of `-- npx -y domeneshop-mcp`:
67
95
  brew install martinzachariassen/tap/domeneshop-mcp
68
96
  ```
69
97
 
70
- Using a different client? See [Client setup](#client-setup) below.
71
-
72
- ## Client setup
98
+ **Using a different client?** Claude Desktop has a one-click bundle that needs
99
+ no Node.js; Cursor, VS Code, Codex and others take a short config block. See
100
+ [Client setup](#client-setup).
73
101
 
74
- The server is launched by your client rather than run by hand, and reads its
75
- credentials from two environment variables:
102
+ ## What you can ask for
76
103
 
77
- | Variable | Description |
104
+ | Area | Example prompt |
78
105
  | --- | --- |
79
- | `DOMENESHOP_API_TOKEN` | API token from the Domeneshop control panel |
80
- | `DOMENESHOP_API_SECRET` | The matching API secret |
106
+ | Domains | "Which domains are on my account, and when do they renew?" |
107
+ | DNS | "Show every DNS record for example.no" |
108
+ | DNS | "Point blog.example.no at 203.0.113.10" |
109
+ | DNS | "Lower the TTL on the www record for example.no to 5 minutes" |
110
+ | DNS | "Add the TXT record Google gave me for domain verification" |
111
+ | DNS | "Set up Fastmail's MX records on example.no" |
112
+ | Forwarding | "Forward old.example.no to https://example.no" |
113
+ | Dynamic DNS | "Update home.example.no to my current IP" |
114
+ | Invoices | "List my unpaid Domeneshop invoices" |
81
115
 
82
- Optional settings (see [Access control](#access-control) and
83
- [Troubleshooting](#troubleshooting)):
116
+ ## Client setup
84
117
 
85
- | Variable | Description |
86
- | --- | --- |
87
- | `DOMENESHOP_READ_ONLY` | `true` to expose only read-only tools |
88
- | `DOMENESHOP_TOOLS` | Comma-separated allowlist of tool names to expose |
89
- | `DOMENESHOP_DISABLED_TOOLS` | Comma-separated tool names to hide |
90
- | `DOMENESHOP_TIMEOUT_MS` | Per-request timeout in milliseconds (default `30000`) |
91
- | `DOMENESHOP_DEBUG` | `true` to log every API request to stderr |
118
+ The server is launched by your client rather than run by hand. It needs two
119
+ environment variables, `DOMENESHOP_API_TOKEN` and `DOMENESHOP_API_SECRET`; the
120
+ optional ones are listed under [Configuration](#configuration).
92
121
 
93
- Most clients take the same **standard config**. Swap in your real token and
94
- secret wherever you see the placeholders.
122
+ Most clients take the same **standard config**. Replace the placeholders with
123
+ your token and secret, and if the file already lists other servers, add the
124
+ `"domeneshop"` entry inside the existing `"mcpServers"` object:
95
125
 
96
126
  ```json
97
127
  {
@@ -100,8 +130,8 @@ secret wherever you see the placeholders.
100
130
  "command": "npx",
101
131
  "args": ["-y", "domeneshop-mcp"],
102
132
  "env": {
103
- "DOMENESHOP_API_TOKEN": "your-token",
104
- "DOMENESHOP_API_SECRET": "your-secret"
133
+ "DOMENESHOP_API_TOKEN": "<your-api-token>",
134
+ "DOMENESHOP_API_SECRET": "<your-api-secret>"
105
135
  }
106
136
  }
107
137
  }
@@ -123,23 +153,29 @@ write `<your-project>/.mcp.json` instead, shared via version control, or
123
153
  You can also pass the standard config as raw JSON:
124
154
 
125
155
  ```sh
126
- claude mcp add-json domeneshop '{"command":"npx","args":["-y","domeneshop-mcp"],"env":{"DOMENESHOP_API_TOKEN":"your-token","DOMENESHOP_API_SECRET":"your-secret"}}'
156
+ claude mcp add-json domeneshop '{"command":"npx","args":["-y","domeneshop-mcp"],"env":{"DOMENESHOP_API_TOKEN":"<your-api-token>","DOMENESHOP_API_SECRET":"<your-api-secret>"}}'
127
157
  ```
128
158
 
129
159
  Or write the standard config straight into `<your-project>/.mcp.json`.
160
+ `claude mcp list` shows registered servers and whether they connect.
130
161
 
131
162
  </details>
132
163
 
133
164
  <details>
134
165
  <summary><strong>Claude Desktop</strong></summary>
135
166
 
136
- The easiest route is the one-click bundle: download `domeneshop-mcp-<version>.mcpb`
137
- from the [latest release](https://github.com/martinzachariassen/domeneshop-mcp/releases/latest)
138
- and open it. Claude Desktop asks for your token and secret, stores them securely,
139
- and offers a read-only toggle.
167
+ The easiest route is the one-click bundle, which needs no Node.js:
140
168
 
141
- To configure it by hand instead, add the standard config to `claude_desktop_config.json`, reachable from
142
- Settings → Developer → Edit Config:
169
+ 1. Download `domeneshop-mcp-<version>.mcpb` from the
170
+ [latest release](https://github.com/martinzachariassen/domeneshop-mcp/releases/latest).
171
+ 2. Open it (double-click, or drag it into Claude Desktop).
172
+ 3. Paste your token and secret, optionally turn on read-only mode, and install.
173
+
174
+ Claude Desktop stores the credentials securely.
175
+
176
+ To configure it by hand instead, add the standard config to
177
+ `claude_desktop_config.json`, reachable from Settings → Developer → Edit Config,
178
+ then restart Claude Desktop:
143
179
 
144
180
  | Platform | Full path |
145
181
  | --- | --- |
@@ -176,8 +212,8 @@ VS Code uses a `servers` key instead of `mcpServers`, and wants an explicit
176
212
  "command": "npx",
177
213
  "args": ["-y", "domeneshop-mcp"],
178
214
  "env": {
179
- "DOMENESHOP_API_TOKEN": "your-token",
180
- "DOMENESHOP_API_SECRET": "your-secret"
215
+ "DOMENESHOP_API_TOKEN": "<your-api-token>",
216
+ "DOMENESHOP_API_SECRET": "<your-api-secret>"
181
217
  }
182
218
  }
183
219
  }
@@ -188,7 +224,7 @@ For every project, run the command palette action **MCP: Open User
188
224
  Configuration** and add the same block there, or register it in one line:
189
225
 
190
226
  ```sh
191
- code --add-mcp '{"name":"domeneshop","command":"npx","args":["-y","domeneshop-mcp"],"env":{"DOMENESHOP_API_TOKEN":"your-token","DOMENESHOP_API_SECRET":"your-secret"}}'
227
+ code --add-mcp '{"name":"domeneshop","command":"npx","args":["-y","domeneshop-mcp"],"env":{"DOMENESHOP_API_TOKEN":"<your-api-token>","DOMENESHOP_API_SECRET":"<your-api-secret>"}}'
192
228
  ```
193
229
 
194
230
  </details>
@@ -207,7 +243,7 @@ Codex CLI reads MCP servers from `mcp_servers` in its config file:
207
243
  [mcp_servers.domeneshop]
208
244
  command = "npx"
209
245
  args = ["-y", "domeneshop-mcp"]
210
- env = { DOMENESHOP_API_TOKEN = "your-token", DOMENESHOP_API_SECRET = "your-secret" }
246
+ env = { DOMENESHOP_API_TOKEN = "<your-api-token>", DOMENESHOP_API_SECRET = "<your-api-secret>" }
211
247
  ```
212
248
 
213
249
  `codex mcp add domeneshop -- npx -y domeneshop-mcp` registers it from the
@@ -258,8 +294,8 @@ Desktop usually do not see Homebrew's `PATH`, so give them the full path
258
294
  "domeneshop": {
259
295
  "command": "/opt/homebrew/bin/domeneshop-mcp",
260
296
  "env": {
261
- "DOMENESHOP_API_TOKEN": "your-token",
262
- "DOMENESHOP_API_SECRET": "your-secret"
297
+ "DOMENESHOP_API_TOKEN": "<your-api-token>",
298
+ "DOMENESHOP_API_SECRET": "<your-api-secret>"
263
299
  }
264
300
  }
265
301
  }
@@ -268,19 +304,20 @@ Desktop usually do not see Homebrew's `PATH`, so give them the full path
268
304
 
269
305
  </details>
270
306
 
271
- ## What you can ask for
307
+ ## Configuration
272
308
 
273
- | Area | Example prompt |
274
- | --- | --- |
275
- | Domains | "Which domains are on my account, and when do they renew?" |
276
- | DNS | "Show every DNS record for example.no" |
277
- | DNS | "Point blog.example.no at 203.0.113.10" |
278
- | DNS | "Lower the TTL on the www record for example.no to 5 minutes" |
279
- | DNS | "Add the TXT record Google gave me for domain verification" |
280
- | DNS | "Set up Fastmail's MX records on example.no" |
281
- | Forwarding | "Forward old.example.no to https://example.no" |
282
- | Dynamic DNS | "Update home.example.no to my current IP" |
283
- | Invoices | "List my unpaid Domeneshop invoices" |
309
+ All settings are environment variables, passed with `--env` in Claude Code or
310
+ in the `env` block of the config above. Only the first two are required.
311
+
312
+ | Variable | Required | Description |
313
+ | --- | --- | --- |
314
+ | `DOMENESHOP_API_TOKEN` | Yes | API token from the Domeneshop control panel |
315
+ | `DOMENESHOP_API_SECRET` | Yes | The matching API secret |
316
+ | `DOMENESHOP_READ_ONLY` | No | `true` to expose only read-only tools |
317
+ | `DOMENESHOP_TOOLS` | No | Comma-separated allowlist of tool names to expose |
318
+ | `DOMENESHOP_DISABLED_TOOLS` | No | Comma-separated tool names to hide |
319
+ | `DOMENESHOP_TIMEOUT_MS` | No | Per-request timeout in milliseconds (default `30000`) |
320
+ | `DOMENESHOP_DEBUG` | No | `true` to log every API request to stderr |
284
321
 
285
322
  ## Tools
286
323
 
@@ -346,7 +383,7 @@ Hidden tools are not registered at all, so the model never sees them.
346
383
 
347
384
  - **Read-only mode.** Set `DOMENESHOP_READ_ONLY=true` to expose only the eight
348
385
  read-only tools. This is a good default if you mainly ask questions about your
349
- domains, DNS and invoices.
386
+ domains, DNS and invoices, or are trying the server out for the first time.
350
387
  - **Allowlist.** Set `DOMENESHOP_TOOLS=list_domains,list_dns_records,patch_dns_record`
351
388
  to expose exactly those tools.
352
389
  - **Denylist.** Set `DOMENESHOP_DISABLED_TOOLS=delete_dns_record,delete_forward`
@@ -359,8 +396,17 @@ Most clients ask before running a tool not annotated read-only. Keep that
359
396
  confirmation on for this server: write tools change live DNS, and a wrong
360
397
  record can take a site or mailbox offline.
361
398
 
399
+ Credentials are only ever sent to `api.domeneshop.no` and are never logged. To
400
+ revoke access, delete the token in the Domeneshop control panel.
401
+
362
402
  ## Troubleshooting
363
403
 
404
+ - **The tools do not show up**: restart the client (most only load servers at
405
+ startup) or, in Claude Code, check `/mcp`. Run `npx -y domeneshop-mcp --version`
406
+ to check that Node.js 20.3+ and npx work. If you edited a JSON config by hand,
407
+ make sure it is still valid JSON. With `DOMENESHOP_DEBUG=true` the server logs
408
+ every API request (method, path, status and duration, never credentials) to
409
+ stderr, which most clients capture in their MCP logs.
364
410
  - **`API returned status 401`**: the token or secret is wrong. Copy both again
365
411
  from [domeneshop.no/admin?view=api](https://www.domeneshop.no/admin?view=api).
366
412
  Surrounding whitespace is trimmed automatically.
@@ -369,10 +415,11 @@ record can take a site or mailbox offline.
369
415
  - **Timeouts**: requests give up after 30 seconds. Idempotent requests are
370
416
  retried on rate limiting and temporary errors. Raise the limit with
371
417
  `DOMENESHOP_TIMEOUT_MS` if needed.
372
- - **The tools do not show up**: run `npx -y domeneshop-mcp --version` to check
373
- that Node.js 20.3+ and npx work, then check your client's MCP logs. With
374
- `DOMENESHOP_DEBUG=true` the server logs every API request (method, path,
375
- status and duration, never credentials) to stderr, which most clients capture.
418
+ - **A DNS change does not show up**: DNS is cached for the record's TTL (3600
419
+ seconds by default), so other resolvers may serve the old value for up to an
420
+ hour. Ask the assistant to show the record to confirm Domeneshop stored it.
421
+
422
+ Still stuck? [Open an issue](https://github.com/martinzachariassen/domeneshop-mcp/issues/new/choose).
376
423
 
377
424
  ## Reference
378
425
 
@@ -414,6 +461,16 @@ spec, but are supported and used by their own client libraries:
414
461
 
415
462
  </details>
416
463
 
464
+ <details>
465
+ <summary><strong>Distribution</strong></summary>
466
+
467
+ - [npm package](https://www.npmjs.com/package/domeneshop-mcp)
468
+ - [Homebrew tap](https://github.com/martinzachariassen/homebrew-tap)
469
+ - [MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.martinzachariassen/domeneshop-mcp)
470
+ - [Claude Desktop bundle](https://github.com/martinzachariassen/domeneshop-mcp/releases/latest) (`.mcpb` on each release)
471
+
472
+ </details>
473
+
417
474
  ## Development
418
475
 
419
476
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domeneshop-mcp",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "MCP server exposing the Domeneshop API — manage domains, DNS records, HTTP forwards, dynamic DNS and invoices from an AI assistant.",
5
5
  "mcpName": "io.github.martinzachariassen/domeneshop-mcp",
6
6
  "type": "module",
@@ -76,6 +76,7 @@
76
76
  "@changesets/cli": "^3.0.2",
77
77
  "@types/node": "^26.5.0",
78
78
  "@vitest/coverage-v8": "^5.0.0",
79
+ "fast-check": "^4.10.2",
79
80
  "husky": "^9.1.7",
80
81
  "lint-staged": "^17.5.0",
81
82
  "tsx": "^4.23.13",