@kognar/nginx-manager-mcp-server 0.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 +86 -0
- package/dist/client.d.ts +26 -0
- package/dist/client.js +93 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/accessLists.d.ts +2 -0
- package/dist/tools/accessLists.js +80 -0
- package/dist/tools/accessLists.js.map +1 -0
- package/dist/tools/certificates.d.ts +2 -0
- package/dist/tools/certificates.js +109 -0
- package/dist/tools/certificates.js.map +1 -0
- package/dist/tools/deadHosts.d.ts +2 -0
- package/dist/tools/deadHosts.js +100 -0
- package/dist/tools/deadHosts.js.map +1 -0
- package/dist/tools/misc.d.ts +2 -0
- package/dist/tools/misc.js +84 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/proxyHosts.d.ts +2 -0
- package/dist/tools/proxyHosts.js +116 -0
- package/dist/tools/proxyHosts.js.map +1 -0
- package/dist/tools/redirectionHosts.d.ts +2 -0
- package/dist/tools/redirectionHosts.js +105 -0
- package/dist/tools/redirectionHosts.js.map +1 -0
- package/dist/tools/shared.d.ts +25 -0
- package/dist/tools/shared.js +32 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/streams.d.ts +2 -0
- package/dist/tools/streams.js +99 -0
- package/dist/tools/streams.js.map +1 -0
- package/dist/tools/users.d.ts +2 -0
- package/dist/tools/users.js +135 -0
- package/dist/tools/users.js.map +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# nginx-manager-mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server que abstrai chamadas à API do [Nginx Proxy Manager](https://github.com/NginxProxyManager/nginx-proxy-manager).
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Configuração
|
|
13
|
+
|
|
14
|
+
Aceita via **argumentos de CLI** ou **variáveis de ambiente** (CLI tem precedência):
|
|
15
|
+
|
|
16
|
+
| flag | env | descrição |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `--base-url` (ou `--url`) | `NPM_BASE_URL` | URL completa da API do NPM (use como está — não adicione porta) |
|
|
19
|
+
| `--email` (ou `--user`) | `NPM_EMAIL` | email de login |
|
|
20
|
+
| `--password` (ou `--pass`)| `NPM_PASSWORD` | senha |
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @kognar-tools/nginx-manager-mcp-server \
|
|
24
|
+
--base-url https://npm.example.com \
|
|
25
|
+
--email admin@example.com \
|
|
26
|
+
--password changeme
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso com Claude Code / Desktop
|
|
30
|
+
|
|
31
|
+
Adicione no `claude_desktop_config.json` (ou `.mcp.json`):
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"mcpServers": {
|
|
36
|
+
"nginx-manager": {
|
|
37
|
+
"command": "npx",
|
|
38
|
+
"args": [
|
|
39
|
+
"-y",
|
|
40
|
+
"@kognar-tools/nginx-manager-mcp-server",
|
|
41
|
+
"--base-url", "https://npm.example.com",
|
|
42
|
+
"--email", "admin@example.com",
|
|
43
|
+
"--password", "changeme"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Alternativa com env vars:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"nginx-manager": {
|
|
56
|
+
"command": "npx",
|
|
57
|
+
"args": ["-y", "@kognar-tools/nginx-manager-mcp-server"],
|
|
58
|
+
"env": {
|
|
59
|
+
"NPM_BASE_URL": "https://npm.example.com",
|
|
60
|
+
"NPM_EMAIL": "admin@example.com",
|
|
61
|
+
"NPM_PASSWORD": "changeme"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Tools disponíveis
|
|
69
|
+
|
|
70
|
+
- **Proxy hosts** — `npm_list_proxy_hosts`, `npm_get_proxy_host`, `npm_create_proxy_host`, `npm_update_proxy_host`, `npm_delete_proxy_host`, `npm_enable_proxy_host`, `npm_disable_proxy_host`
|
|
71
|
+
- **Redirection hosts** — idem com `redirection_host`
|
|
72
|
+
- **404 hosts** — idem com `dead_host`
|
|
73
|
+
- **Streams** — idem com `stream`
|
|
74
|
+
- **Certificates** — `npm_list_certificates`, `npm_get_certificate`, `npm_create_certificate_letsencrypt`, `npm_create_certificate_custom`, `npm_renew_certificate`, `npm_test_certificate_http_reach`, `npm_delete_certificate`
|
|
75
|
+
- **Access lists** — `npm_list_access_lists`, `npm_get_access_list`, `npm_create_access_list`, `npm_update_access_list`, `npm_delete_access_list`
|
|
76
|
+
- **Users** — `npm_list_users`, `npm_get_user`, `npm_get_me`, `npm_create_user`, `npm_update_user`, `npm_set_user_password`, `npm_set_user_permissions`, `npm_delete_user`
|
|
77
|
+
- **Misc** — `npm_get_settings`, `npm_get_setting`, `npm_update_setting`, `npm_get_audit_log`, `npm_get_reports_hosts`, `npm_health`
|
|
78
|
+
|
|
79
|
+
## Desenvolvimento
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npm run dev # executa via tsx
|
|
83
|
+
npm run typecheck # valida tipos sem emitir
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Autenticação usa `POST /api/tokens` com cache em memória e refresh automático 1 min antes da expiração.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class NpmApiError extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
body: unknown;
|
|
4
|
+
constructor(message: string, status: number, body: unknown);
|
|
5
|
+
}
|
|
6
|
+
export declare class NpmClient {
|
|
7
|
+
private baseUrl;
|
|
8
|
+
private email;
|
|
9
|
+
private password;
|
|
10
|
+
private tokenState;
|
|
11
|
+
constructor(opts: {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
email: string;
|
|
14
|
+
password: string;
|
|
15
|
+
});
|
|
16
|
+
private authenticate;
|
|
17
|
+
private getToken;
|
|
18
|
+
request<T = unknown>(method: string, path: string, opts?: {
|
|
19
|
+
query?: Record<string, unknown>;
|
|
20
|
+
body?: unknown;
|
|
21
|
+
}): Promise<T>;
|
|
22
|
+
get<T = unknown>(path: string, query?: Record<string, unknown>): Promise<T>;
|
|
23
|
+
post<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
24
|
+
put<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
25
|
+
delete<T = unknown>(path: string): Promise<T>;
|
|
26
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export class NpmApiError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
body;
|
|
4
|
+
constructor(message, status, body) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.body = body;
|
|
8
|
+
this.name = "NpmApiError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class NpmClient {
|
|
12
|
+
baseUrl;
|
|
13
|
+
email;
|
|
14
|
+
password;
|
|
15
|
+
tokenState = null;
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
18
|
+
this.email = opts.email;
|
|
19
|
+
this.password = opts.password;
|
|
20
|
+
}
|
|
21
|
+
async authenticate() {
|
|
22
|
+
const res = await fetch(`${this.baseUrl}/api/tokens`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
body: JSON.stringify({ identity: this.email, secret: this.password }),
|
|
26
|
+
});
|
|
27
|
+
if (!res.ok) {
|
|
28
|
+
const body = await res.text();
|
|
29
|
+
throw new NpmApiError(`Authentication failed (${res.status})`, res.status, body);
|
|
30
|
+
}
|
|
31
|
+
const data = (await res.json());
|
|
32
|
+
this.tokenState = {
|
|
33
|
+
token: data.token,
|
|
34
|
+
expires: new Date(data.expires).getTime(),
|
|
35
|
+
};
|
|
36
|
+
return data.token;
|
|
37
|
+
}
|
|
38
|
+
async getToken() {
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
if (!this.tokenState || this.tokenState.expires - now < 60_000) {
|
|
41
|
+
return this.authenticate();
|
|
42
|
+
}
|
|
43
|
+
return this.tokenState.token;
|
|
44
|
+
}
|
|
45
|
+
async request(method, path, opts = {}) {
|
|
46
|
+
const token = await this.getToken();
|
|
47
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
48
|
+
if (opts.query) {
|
|
49
|
+
for (const [k, v] of Object.entries(opts.query)) {
|
|
50
|
+
if (v === undefined || v === null)
|
|
51
|
+
continue;
|
|
52
|
+
url.searchParams.set(k, String(v));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const headers = {
|
|
56
|
+
Authorization: `Bearer ${token}`,
|
|
57
|
+
Accept: "application/json",
|
|
58
|
+
};
|
|
59
|
+
let body;
|
|
60
|
+
if (opts.body !== undefined) {
|
|
61
|
+
headers["Content-Type"] = "application/json";
|
|
62
|
+
body = JSON.stringify(opts.body);
|
|
63
|
+
}
|
|
64
|
+
const res = await fetch(url.toString(), { method, headers, body });
|
|
65
|
+
const text = await res.text();
|
|
66
|
+
const parsed = text ? safeJson(text) : null;
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
throw new NpmApiError(`NPM API ${method} ${path} failed (${res.status})`, res.status, parsed ?? text);
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
72
|
+
get(path, query) {
|
|
73
|
+
return this.request("GET", path, { query });
|
|
74
|
+
}
|
|
75
|
+
post(path, body) {
|
|
76
|
+
return this.request("POST", path, { body });
|
|
77
|
+
}
|
|
78
|
+
put(path, body) {
|
|
79
|
+
return this.request("PUT", path, { body });
|
|
80
|
+
}
|
|
81
|
+
delete(path) {
|
|
82
|
+
return this.request("DELETE", path);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function safeJson(text) {
|
|
86
|
+
try {
|
|
87
|
+
return JSON.parse(text);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return text;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { NpmClient } from "./client.js";
|
|
5
|
+
import { registerProxyHosts } from "./tools/proxyHosts.js";
|
|
6
|
+
import { registerRedirectionHosts } from "./tools/redirectionHosts.js";
|
|
7
|
+
import { registerDeadHosts } from "./tools/deadHosts.js";
|
|
8
|
+
import { registerStreams } from "./tools/streams.js";
|
|
9
|
+
import { registerCertificates } from "./tools/certificates.js";
|
|
10
|
+
import { registerAccessLists } from "./tools/accessLists.js";
|
|
11
|
+
import { registerUsers } from "./tools/users.js";
|
|
12
|
+
import { registerMisc } from "./tools/misc.js";
|
|
13
|
+
function parseArgs(argv) {
|
|
14
|
+
const out = {};
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (!a.startsWith("--"))
|
|
18
|
+
continue;
|
|
19
|
+
const eq = a.indexOf("=");
|
|
20
|
+
let key;
|
|
21
|
+
let val;
|
|
22
|
+
if (eq !== -1) {
|
|
23
|
+
key = a.slice(2, eq);
|
|
24
|
+
val = a.slice(eq + 1);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
key = a.slice(2);
|
|
28
|
+
const next = argv[i + 1];
|
|
29
|
+
if (next && !next.startsWith("--")) {
|
|
30
|
+
val = next;
|
|
31
|
+
i++;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
val = "true";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
out[key.replace(/-/g, "_")] = val;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function resolveConfig() {
|
|
42
|
+
const args = parseArgs(process.argv.slice(2));
|
|
43
|
+
if (args.help || args.h) {
|
|
44
|
+
console.error(`nginx-manager-mcp-server
|
|
45
|
+
|
|
46
|
+
Usage:
|
|
47
|
+
npx @kognar-tools/nginx-manager-mcp-server \\
|
|
48
|
+
--base-url <url> --email <email> --password <password>
|
|
49
|
+
|
|
50
|
+
Options (fallback to env vars NPM_BASE_URL / NPM_EMAIL / NPM_PASSWORD):
|
|
51
|
+
--base-url, --url NPM base URL (used as-is, no port appended)
|
|
52
|
+
--email, --user NPM login email
|
|
53
|
+
--password, --pass NPM password
|
|
54
|
+
--help, -h Show this help
|
|
55
|
+
`);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
const baseUrl = args.base_url ?? args.url ?? process.env.NPM_BASE_URL;
|
|
59
|
+
const email = args.email ?? args.user ?? process.env.NPM_EMAIL;
|
|
60
|
+
const password = args.password ?? args.pass ?? process.env.NPM_PASSWORD;
|
|
61
|
+
const missing = [
|
|
62
|
+
!baseUrl && "--base-url / NPM_BASE_URL",
|
|
63
|
+
!email && "--email / NPM_EMAIL",
|
|
64
|
+
!password && "--password / NPM_PASSWORD",
|
|
65
|
+
].filter(Boolean);
|
|
66
|
+
if (missing.length) {
|
|
67
|
+
console.error(`[nginx-manager-mcp] Missing required config: ${missing.join(", ")}\nRun with --help for usage.`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
return { baseUrl: baseUrl, email: email, password: password };
|
|
71
|
+
}
|
|
72
|
+
async function main() {
|
|
73
|
+
const { baseUrl, email, password } = resolveConfig();
|
|
74
|
+
const client = new NpmClient({ baseUrl, email, password });
|
|
75
|
+
const server = new McpServer({
|
|
76
|
+
name: "nginx-manager-mcp-server",
|
|
77
|
+
version: "0.1.0",
|
|
78
|
+
});
|
|
79
|
+
const ctx = { server, client };
|
|
80
|
+
registerProxyHosts(ctx);
|
|
81
|
+
registerRedirectionHosts(ctx);
|
|
82
|
+
registerDeadHosts(ctx);
|
|
83
|
+
registerStreams(ctx);
|
|
84
|
+
registerCertificates(ctx);
|
|
85
|
+
registerAccessLists(ctx);
|
|
86
|
+
registerUsers(ctx);
|
|
87
|
+
registerMisc(ctx);
|
|
88
|
+
const transport = new StdioServerTransport();
|
|
89
|
+
await server.connect(transport);
|
|
90
|
+
console.error("[nginx-manager-mcp] ready on stdio");
|
|
91
|
+
}
|
|
92
|
+
main().catch((e) => {
|
|
93
|
+
console.error("[nginx-manager-mcp] fatal:", e);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ok, err, buildExpand, expandQuery, idSchema } from "./shared.js";
|
|
3
|
+
const BASE = "/api/nginx/access-lists";
|
|
4
|
+
const body = z.object({
|
|
5
|
+
name: z.string(),
|
|
6
|
+
satisfy_any: z.boolean().optional(),
|
|
7
|
+
pass_auth: z.boolean().optional(),
|
|
8
|
+
items: z
|
|
9
|
+
.array(z.object({ username: z.string(), password: z.string() }))
|
|
10
|
+
.optional(),
|
|
11
|
+
clients: z
|
|
12
|
+
.array(z.object({
|
|
13
|
+
address: z.string(),
|
|
14
|
+
directive: z.enum(["allow", "deny"]),
|
|
15
|
+
}))
|
|
16
|
+
.optional(),
|
|
17
|
+
});
|
|
18
|
+
export function registerAccessLists({ server, client }) {
|
|
19
|
+
server.registerTool("npm_list_access_lists", {
|
|
20
|
+
title: "List access lists",
|
|
21
|
+
description: "List all access lists.",
|
|
22
|
+
inputSchema: { expand: expandQuery },
|
|
23
|
+
}, async ({ expand }) => {
|
|
24
|
+
try {
|
|
25
|
+
return ok(await client.get(BASE, buildExpand(expand)));
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return err(e);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
server.registerTool("npm_get_access_list", {
|
|
32
|
+
title: "Get access list",
|
|
33
|
+
description: "Get an access list by ID.",
|
|
34
|
+
inputSchema: { id: idSchema, expand: expandQuery },
|
|
35
|
+
}, async ({ id, expand }) => {
|
|
36
|
+
try {
|
|
37
|
+
return ok(await client.get(`${BASE}/${id}`, buildExpand(expand)));
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
return err(e);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
server.registerTool("npm_create_access_list", {
|
|
44
|
+
title: "Create access list",
|
|
45
|
+
description: "Create an access list.",
|
|
46
|
+
inputSchema: body.shape,
|
|
47
|
+
}, async (input) => {
|
|
48
|
+
try {
|
|
49
|
+
return ok(await client.post(BASE, input));
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return err(e);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.registerTool("npm_update_access_list", {
|
|
56
|
+
title: "Update access list",
|
|
57
|
+
description: "Update an access list.",
|
|
58
|
+
inputSchema: { id: idSchema, ...body.partial().shape },
|
|
59
|
+
}, async ({ id, ...data }) => {
|
|
60
|
+
try {
|
|
61
|
+
return ok(await client.put(`${BASE}/${id}`, data));
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
return err(e);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
server.registerTool("npm_delete_access_list", {
|
|
68
|
+
title: "Delete access list",
|
|
69
|
+
description: "Delete an access list.",
|
|
70
|
+
inputSchema: { id: idSchema },
|
|
71
|
+
}, async ({ id }) => {
|
|
72
|
+
try {
|
|
73
|
+
return ok(await client.delete(`${BASE}/${id}`));
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
return err(e);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=accessLists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessLists.js","sourceRoot":"","sources":["../../src/tools/accessLists.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ok, err, buildExpand, expandQuery, idSchema } from "./shared.js";
|
|
3
|
+
const BASE = "/api/nginx/certificates";
|
|
4
|
+
export function registerCertificates({ server, client }) {
|
|
5
|
+
server.registerTool("npm_list_certificates", {
|
|
6
|
+
title: "List certificates",
|
|
7
|
+
description: "List all SSL certificates.",
|
|
8
|
+
inputSchema: { expand: expandQuery },
|
|
9
|
+
}, async ({ expand }) => {
|
|
10
|
+
try {
|
|
11
|
+
return ok(await client.get(BASE, buildExpand(expand)));
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
return err(e);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
server.registerTool("npm_get_certificate", {
|
|
18
|
+
title: "Get certificate",
|
|
19
|
+
description: "Get a certificate by ID.",
|
|
20
|
+
inputSchema: { id: idSchema, expand: expandQuery },
|
|
21
|
+
}, async ({ id, expand }) => {
|
|
22
|
+
try {
|
|
23
|
+
return ok(await client.get(`${BASE}/${id}`, buildExpand(expand)));
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
return err(e);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
server.registerTool("npm_create_certificate_letsencrypt", {
|
|
30
|
+
title: "Request Let's Encrypt certificate",
|
|
31
|
+
description: "Request a new Let's Encrypt certificate for the given domain names.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
domain_names: z.array(z.string()).min(1),
|
|
34
|
+
meta: z.object({
|
|
35
|
+
letsencrypt_agree: z.boolean(),
|
|
36
|
+
letsencrypt_email: z.string().email(),
|
|
37
|
+
dns_challenge: z.boolean().optional(),
|
|
38
|
+
dns_provider: z.string().optional(),
|
|
39
|
+
dns_provider_credentials: z.string().optional(),
|
|
40
|
+
propagation_seconds: z.number().int().optional(),
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
}, async ({ domain_names, meta }) => {
|
|
44
|
+
try {
|
|
45
|
+
return ok(await client.post(BASE, {
|
|
46
|
+
provider: "letsencrypt",
|
|
47
|
+
domain_names,
|
|
48
|
+
meta,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return err(e);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.registerTool("npm_create_certificate_custom", {
|
|
56
|
+
title: "Upload custom certificate (metadata only)",
|
|
57
|
+
description: "Create a custom certificate record. File upload must follow via npm_upload_certificate.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
nice_name: z.string(),
|
|
60
|
+
domain_names: z.array(z.string()).min(1),
|
|
61
|
+
},
|
|
62
|
+
}, async (input) => {
|
|
63
|
+
try {
|
|
64
|
+
return ok(await client.post(BASE, { provider: "other", ...input }));
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
return err(e);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
server.registerTool("npm_renew_certificate", {
|
|
71
|
+
title: "Renew certificate",
|
|
72
|
+
description: "Renew a Let's Encrypt certificate.",
|
|
73
|
+
inputSchema: { id: idSchema },
|
|
74
|
+
}, async ({ id }) => {
|
|
75
|
+
try {
|
|
76
|
+
return ok(await client.post(`${BASE}/${id}/renew`));
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
return err(e);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
server.registerTool("npm_test_certificate_http_reach", {
|
|
83
|
+
title: "Test HTTP reachability",
|
|
84
|
+
description: "Test whether domains are HTTP-reachable before requesting a cert.",
|
|
85
|
+
inputSchema: { domains: z.array(z.string()).min(1) },
|
|
86
|
+
}, async ({ domains }) => {
|
|
87
|
+
try {
|
|
88
|
+
return ok(await client.get(`${BASE}/test-http`, {
|
|
89
|
+
domains: JSON.stringify(domains),
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
return err(e);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
server.registerTool("npm_delete_certificate", {
|
|
97
|
+
title: "Delete certificate",
|
|
98
|
+
description: "Delete a certificate by ID.",
|
|
99
|
+
inputSchema: { id: idSchema },
|
|
100
|
+
}, async ({ id }) => {
|
|
101
|
+
try {
|
|
102
|
+
return ok(await client.delete(`${BASE}/${id}`));
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
return err(e);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=certificates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificates.js","sourceRoot":"","sources":["../../src/tools/certificates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ok, err, buildExpand, expandQuery, idSchema } from "./shared.js";
|
|
3
|
+
const BASE = "/api/nginx/dead-hosts";
|
|
4
|
+
const body = z.object({
|
|
5
|
+
domain_names: z.array(z.string()).min(1),
|
|
6
|
+
certificate_id: z.union([z.number().int(), z.literal("new")]).optional(),
|
|
7
|
+
ssl_forced: z.boolean().optional(),
|
|
8
|
+
hsts_enabled: z.boolean().optional(),
|
|
9
|
+
hsts_subdomains: z.boolean().optional(),
|
|
10
|
+
http2_support: z.boolean().optional(),
|
|
11
|
+
advanced_config: z.string().optional(),
|
|
12
|
+
meta: z.record(z.unknown()).optional(),
|
|
13
|
+
});
|
|
14
|
+
export function registerDeadHosts({ server, client }) {
|
|
15
|
+
server.registerTool("npm_list_dead_hosts", {
|
|
16
|
+
title: "List 404 hosts",
|
|
17
|
+
description: "List all 404 (dead) hosts.",
|
|
18
|
+
inputSchema: { expand: expandQuery },
|
|
19
|
+
}, async ({ expand }) => {
|
|
20
|
+
try {
|
|
21
|
+
return ok(await client.get(BASE, buildExpand(expand)));
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
return err(e);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
server.registerTool("npm_get_dead_host", {
|
|
28
|
+
title: "Get 404 host",
|
|
29
|
+
description: "Get a 404 host by ID.",
|
|
30
|
+
inputSchema: { id: idSchema, expand: expandQuery },
|
|
31
|
+
}, async ({ id, expand }) => {
|
|
32
|
+
try {
|
|
33
|
+
return ok(await client.get(`${BASE}/${id}`, buildExpand(expand)));
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return err(e);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
server.registerTool("npm_create_dead_host", {
|
|
40
|
+
title: "Create 404 host",
|
|
41
|
+
description: "Create a 404 host.",
|
|
42
|
+
inputSchema: body.shape,
|
|
43
|
+
}, async (input) => {
|
|
44
|
+
try {
|
|
45
|
+
return ok(await client.post(BASE, input));
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
return err(e);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
server.registerTool("npm_update_dead_host", {
|
|
52
|
+
title: "Update 404 host",
|
|
53
|
+
description: "Update a 404 host.",
|
|
54
|
+
inputSchema: { id: idSchema, ...body.partial().shape },
|
|
55
|
+
}, async ({ id, ...data }) => {
|
|
56
|
+
try {
|
|
57
|
+
return ok(await client.put(`${BASE}/${id}`, data));
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
return err(e);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
server.registerTool("npm_delete_dead_host", {
|
|
64
|
+
title: "Delete 404 host",
|
|
65
|
+
description: "Delete a 404 host.",
|
|
66
|
+
inputSchema: { id: idSchema },
|
|
67
|
+
}, async ({ id }) => {
|
|
68
|
+
try {
|
|
69
|
+
return ok(await client.delete(`${BASE}/${id}`));
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
return err(e);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
server.registerTool("npm_enable_dead_host", {
|
|
76
|
+
title: "Enable 404 host",
|
|
77
|
+
description: "Enable a 404 host.",
|
|
78
|
+
inputSchema: { id: idSchema },
|
|
79
|
+
}, async ({ id }) => {
|
|
80
|
+
try {
|
|
81
|
+
return ok(await client.post(`${BASE}/${id}/enable`));
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
return err(e);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
server.registerTool("npm_disable_dead_host", {
|
|
88
|
+
title: "Disable 404 host",
|
|
89
|
+
description: "Disable a 404 host.",
|
|
90
|
+
inputSchema: { id: idSchema },
|
|
91
|
+
}, async ({ id }) => {
|
|
92
|
+
try {
|
|
93
|
+
return ok(await client.post(`${BASE}/${id}/disable`));
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return err(e);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=deadHosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadHosts.js","sourceRoot":"","sources":["../../src/tools/deadHosts.ts"],"names":[],"mappings":"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"}
|