@yawlabs/caddy-mcp 1.2.6 → 1.2.8
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 +4 -4
- package/dist/index.js +23 -11
- package/dist/server.js +23 -11
- package/package.json +77 -77
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
Built and maintained by [Yaw Labs](https://yaw.sh).
|
|
10
10
|
|
|
11
|
-
[](yaw://install?name=Caddy&command=npx&args=-y%2C%40yawlabs%2Fcaddy-mcp&description=Manage%20Caddy%20web%20servers%20-%20config%2C%20routes%2C%20TLS%2C%20PKI&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Fcaddy-mcp)
|
|
12
12
|
|
|
13
|
-
One click adds this to your
|
|
13
|
+
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
|
|
14
14
|
|
|
15
15
|
## Why this one?
|
|
16
16
|
|
|
@@ -41,7 +41,7 @@ macOS / Linux / WSL:
|
|
|
41
41
|
"mcpServers": {
|
|
42
42
|
"caddy": {
|
|
43
43
|
"command": "npx",
|
|
44
|
-
"args": ["-y", "@yawlabs/caddy-mcp"]
|
|
44
|
+
"args": ["-y", "@yawlabs/caddy-mcp@latest"]
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -54,7 +54,7 @@ Windows:
|
|
|
54
54
|
"mcpServers": {
|
|
55
55
|
"caddy": {
|
|
56
56
|
"command": "cmd",
|
|
57
|
-
"args": ["/c", "npx", "-y", "@yawlabs/caddy-mcp"]
|
|
57
|
+
"args": ["/c", "npx", "-y", "@yawlabs/caddy-mcp@latest"]
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,23 @@ function setEtag(path, etag) {
|
|
|
21
21
|
}
|
|
22
22
|
etagCache.set(path, etag);
|
|
23
23
|
}
|
|
24
|
+
function invalidateRelated(path) {
|
|
25
|
+
etagCache.delete(path);
|
|
26
|
+
for (const key of Array.from(etagCache.keys())) {
|
|
27
|
+
if (key === path) continue;
|
|
28
|
+
if (path.startsWith(`${key}/`) || key.startsWith(`${path}/`)) {
|
|
29
|
+
etagCache.delete(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const isIdWrite = path.startsWith("/id/");
|
|
33
|
+
const isConfigWrite = path.startsWith("/config/");
|
|
34
|
+
if (isIdWrite || isConfigWrite) {
|
|
35
|
+
const otherNamespace = isIdWrite ? "/config/" : "/id/";
|
|
36
|
+
for (const key of Array.from(etagCache.keys())) {
|
|
37
|
+
if (key.startsWith(otherNamespace)) etagCache.delete(key);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
24
41
|
function getBaseUrl() {
|
|
25
42
|
return (process.env.CADDY_ADMIN_URL || DEFAULT_URL).replace(/\/+$/, "");
|
|
26
43
|
}
|
|
@@ -107,14 +124,9 @@ async function attemptRequest(method, path, body, contentType, timeout) {
|
|
|
107
124
|
setEtag(path, etag);
|
|
108
125
|
}
|
|
109
126
|
if (isWrite && res.ok && isConfigPath) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
} else {
|
|
114
|
-
etagCache.delete(path);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
etagCache.delete(path);
|
|
127
|
+
invalidateRelated(path);
|
|
128
|
+
if ((method === "PATCH" || method === "PUT") && etag) {
|
|
129
|
+
setEtag(path, etag);
|
|
118
130
|
}
|
|
119
131
|
}
|
|
120
132
|
if (!res.ok) {
|
|
@@ -428,7 +440,7 @@ function registerResources(server) {
|
|
|
428
440
|
contents: [
|
|
429
441
|
{
|
|
430
442
|
uri: "caddy://config",
|
|
431
|
-
mimeType: "application/json",
|
|
443
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
432
444
|
text: res.ok ? JSON.stringify(res.data, null, 2) : `Error: ${res.error}`
|
|
433
445
|
}
|
|
434
446
|
]
|
|
@@ -444,7 +456,7 @@ function registerResources(server) {
|
|
|
444
456
|
contents: [
|
|
445
457
|
{
|
|
446
458
|
uri: "caddy://upstreams",
|
|
447
|
-
mimeType: "application/json",
|
|
459
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
448
460
|
text: res.ok ? JSON.stringify(res.data, null, 2) : `Error: ${res.error}`
|
|
449
461
|
}
|
|
450
462
|
]
|
|
@@ -492,7 +504,7 @@ function registerResources(server) {
|
|
|
492
504
|
contents: [
|
|
493
505
|
{
|
|
494
506
|
uri: "caddy://servers",
|
|
495
|
-
mimeType: "application/json",
|
|
507
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
496
508
|
text: res.ok ? JSON.stringify(res.data ?? {}, null, 2) : `Error: ${res.error}`
|
|
497
509
|
}
|
|
498
510
|
]
|
package/dist/server.js
CHANGED
|
@@ -19,6 +19,23 @@ function setEtag(path, etag) {
|
|
|
19
19
|
}
|
|
20
20
|
etagCache.set(path, etag);
|
|
21
21
|
}
|
|
22
|
+
function invalidateRelated(path) {
|
|
23
|
+
etagCache.delete(path);
|
|
24
|
+
for (const key of Array.from(etagCache.keys())) {
|
|
25
|
+
if (key === path) continue;
|
|
26
|
+
if (path.startsWith(`${key}/`) || key.startsWith(`${path}/`)) {
|
|
27
|
+
etagCache.delete(key);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const isIdWrite = path.startsWith("/id/");
|
|
31
|
+
const isConfigWrite = path.startsWith("/config/");
|
|
32
|
+
if (isIdWrite || isConfigWrite) {
|
|
33
|
+
const otherNamespace = isIdWrite ? "/config/" : "/id/";
|
|
34
|
+
for (const key of Array.from(etagCache.keys())) {
|
|
35
|
+
if (key.startsWith(otherNamespace)) etagCache.delete(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
22
39
|
function getBaseUrl() {
|
|
23
40
|
return (process.env.CADDY_ADMIN_URL || DEFAULT_URL).replace(/\/+$/, "");
|
|
24
41
|
}
|
|
@@ -105,14 +122,9 @@ async function attemptRequest(method, path, body, contentType, timeout) {
|
|
|
105
122
|
setEtag(path, etag);
|
|
106
123
|
}
|
|
107
124
|
if (isWrite && res.ok && isConfigPath) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
} else {
|
|
112
|
-
etagCache.delete(path);
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
etagCache.delete(path);
|
|
125
|
+
invalidateRelated(path);
|
|
126
|
+
if ((method === "PATCH" || method === "PUT") && etag) {
|
|
127
|
+
setEtag(path, etag);
|
|
116
128
|
}
|
|
117
129
|
}
|
|
118
130
|
if (!res.ok) {
|
|
@@ -426,7 +438,7 @@ function registerResources(server) {
|
|
|
426
438
|
contents: [
|
|
427
439
|
{
|
|
428
440
|
uri: "caddy://config",
|
|
429
|
-
mimeType: "application/json",
|
|
441
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
430
442
|
text: res.ok ? JSON.stringify(res.data, null, 2) : `Error: ${res.error}`
|
|
431
443
|
}
|
|
432
444
|
]
|
|
@@ -442,7 +454,7 @@ function registerResources(server) {
|
|
|
442
454
|
contents: [
|
|
443
455
|
{
|
|
444
456
|
uri: "caddy://upstreams",
|
|
445
|
-
mimeType: "application/json",
|
|
457
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
446
458
|
text: res.ok ? JSON.stringify(res.data, null, 2) : `Error: ${res.error}`
|
|
447
459
|
}
|
|
448
460
|
]
|
|
@@ -490,7 +502,7 @@ function registerResources(server) {
|
|
|
490
502
|
contents: [
|
|
491
503
|
{
|
|
492
504
|
uri: "caddy://servers",
|
|
493
|
-
mimeType: "application/json",
|
|
505
|
+
mimeType: res.ok ? "application/json" : "text/plain",
|
|
494
506
|
text: res.ok ? JSON.stringify(res.data ?? {}, null, 2) : `Error: ${res.error}`
|
|
495
507
|
}
|
|
496
508
|
]
|
package/package.json
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@yawlabs/caddy-mcp",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"mcpName": "io.github.YawLabs/caddy-mcp",
|
|
5
|
-
"description": "MCP server for managing Caddy web servers via the admin API",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"author": "Yaw Labs <contact@yaw.sh> (https://yaw.sh)",
|
|
8
|
-
"type": "module",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"import": "./dist/server.js",
|
|
12
|
-
"types": "./dist/server.d.ts"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"main": "./dist/server.js",
|
|
16
|
-
"types": "./dist/server.d.ts",
|
|
17
|
-
"bin": {
|
|
18
|
-
"caddy-mcp": "
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"dist",
|
|
22
|
-
"!dist/**/*.test.*",
|
|
23
|
-
"README.md",
|
|
24
|
-
"LICENSE"
|
|
25
|
-
],
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "tsup",
|
|
28
|
-
"dev": "tsup --watch",
|
|
29
|
-
"test": "vitest run",
|
|
30
|
-
"lint": "biome check src/",
|
|
31
|
-
"lint:fix": "biome check --write src/",
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"test:ci": "npm run build && npm test",
|
|
34
|
-
"prepublishOnly": "npm run build",
|
|
35
|
-
"prepare": "git config core.hooksPath .githooks 2>/dev/null || true",
|
|
36
|
-
"start": "node dist/index.js"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
40
|
-
"zod": "^4.3.6"
|
|
41
|
-
},
|
|
42
|
-
"overrides": {
|
|
43
|
-
"hono": "^4.12.18",
|
|
44
|
-
"@hono/node-server": "^1.19.13",
|
|
45
|
-
"postcss": "^8.5.10",
|
|
46
|
-
"ip-address": "^10.1.1",
|
|
47
|
-
"fast-uri": "^3.1.2"
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@biomejs/biome": "^2.4.11",
|
|
51
|
-
"@types/node": "^25.6.0",
|
|
52
|
-
"tsup": "^8.4.0",
|
|
53
|
-
"typescript": "^6.0.2",
|
|
54
|
-
"vitest": "^4.1.4"
|
|
55
|
-
},
|
|
56
|
-
"engines": {
|
|
57
|
-
"node": ">=20"
|
|
58
|
-
},
|
|
59
|
-
"keywords": [
|
|
60
|
-
"mcp",
|
|
61
|
-
"model-context-protocol",
|
|
62
|
-
"caddy",
|
|
63
|
-
"reverse-proxy",
|
|
64
|
-
"web-server",
|
|
65
|
-
"mcp-server",
|
|
66
|
-
"devtools",
|
|
67
|
-
"ai"
|
|
68
|
-
],
|
|
69
|
-
"repository": {
|
|
70
|
-
"type": "git",
|
|
71
|
-
"url": "git+https://github.com/YawLabs/caddy-mcp.git"
|
|
72
|
-
},
|
|
73
|
-
"bugs": {
|
|
74
|
-
"url": "https://github.com/YawLabs/caddy-mcp/issues"
|
|
75
|
-
},
|
|
76
|
-
"homepage": "https://github.com/YawLabs/caddy-mcp"
|
|
77
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@yawlabs/caddy-mcp",
|
|
3
|
+
"version": "1.2.8",
|
|
4
|
+
"mcpName": "io.github.YawLabs/caddy-mcp",
|
|
5
|
+
"description": "MCP server for managing Caddy web servers via the admin API",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Yaw Labs <contact@yaw.sh> (https://yaw.sh)",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/server.js",
|
|
12
|
+
"types": "./dist/server.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/server.js",
|
|
16
|
+
"types": "./dist/server.d.ts",
|
|
17
|
+
"bin": {
|
|
18
|
+
"caddy-mcp": "dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"!dist/**/*.test.*",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"dev": "tsup --watch",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"lint": "biome check src/",
|
|
31
|
+
"lint:fix": "biome check --write src/",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"test:ci": "npm run build && npm test",
|
|
34
|
+
"prepublishOnly": "npm run build",
|
|
35
|
+
"prepare": "git config core.hooksPath .githooks 2>/dev/null || true",
|
|
36
|
+
"start": "node dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
40
|
+
"zod": "^4.3.6"
|
|
41
|
+
},
|
|
42
|
+
"overrides": {
|
|
43
|
+
"hono": "^4.12.18",
|
|
44
|
+
"@hono/node-server": "^1.19.13",
|
|
45
|
+
"postcss": "^8.5.10",
|
|
46
|
+
"ip-address": "^10.1.1",
|
|
47
|
+
"fast-uri": "^3.1.2"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@biomejs/biome": "^2.4.11",
|
|
51
|
+
"@types/node": "^25.6.0",
|
|
52
|
+
"tsup": "^8.4.0",
|
|
53
|
+
"typescript": "^6.0.2",
|
|
54
|
+
"vitest": "^4.1.4"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20"
|
|
58
|
+
},
|
|
59
|
+
"keywords": [
|
|
60
|
+
"mcp",
|
|
61
|
+
"model-context-protocol",
|
|
62
|
+
"caddy",
|
|
63
|
+
"reverse-proxy",
|
|
64
|
+
"web-server",
|
|
65
|
+
"mcp-server",
|
|
66
|
+
"devtools",
|
|
67
|
+
"ai"
|
|
68
|
+
],
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/YawLabs/caddy-mcp.git"
|
|
72
|
+
},
|
|
73
|
+
"bugs": {
|
|
74
|
+
"url": "https://github.com/YawLabs/caddy-mcp/issues"
|
|
75
|
+
},
|
|
76
|
+
"homepage": "https://github.com/YawLabs/caddy-mcp"
|
|
77
|
+
}
|