@otwa/444host-mcp 1.0.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/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/client/errors.js +64 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/http.js +79 -0
- package/dist/client/http.js.map +1 -0
- package/dist/guards/confirm.js +16 -0
- package/dist/guards/confirm.js.map +1 -0
- package/dist/http/index.js +142 -0
- package/dist/http/index.js.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +17 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/_helpers.js +28 -0
- package/dist/tools/_helpers.js.map +1 -0
- package/dist/tools/_register.js +22 -0
- package/dist/tools/_register.js.map +1 -0
- package/dist/tools/account.js +12 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/billing.js +23 -0
- package/dist/tools/billing.js.map +1 -0
- package/dist/tools/domains.js +22 -0
- package/dist/tools/domains.js.map +1 -0
- package/dist/tools/hosting.js +40 -0
- package/dist/tools/hosting.js.map +1 -0
- package/dist/tools/orders.js +50 -0
- package/dist/tools/orders.js.map +1 -0
- package/dist/tools/servers.js +80 -0
- package/dist/tools/servers.js.map +1 -0
- package/dist/tools/tickets.js +26 -0
- package/dist/tools/tickets.js.map +1 -0
- package/dist/tools/webhooks.js +47 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/util/env.js +22 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/version.js +22 -0
- package/dist/util/version.js.map +1 -0
- package/package.json +45 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
- Initial release.
|
|
6
|
+
- 42 tools across account, ordering (real wallet-debited orders with
|
|
7
|
+
double-confirm), vps (read/write/destroy incl. reverse DNS), hosting
|
|
8
|
+
(read/write/destroy incl. suspend), domains, billing, tickets, webhooks.
|
|
9
|
+
- Two transports: stdio (`444host-mcp`) and stateless Streamable HTTP
|
|
10
|
+
(`444host-mcp-http`), hosted at `https://api.444host.com/mcp`.
|
|
11
|
+
- Bearer auth with `h444_…` API keys.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 444host.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @otwa/444host-mcp
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@otwa/444host-mcp)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
6
|
+
|
|
7
|
+
Model Context Protocol server for [444host.com](https://444host.com). Manage
|
|
8
|
+
your VPS fleet, web hosting, domains, billing, support tickets and webhooks —
|
|
9
|
+
and place real orders — from Claude Code, Claude Desktop, Cursor, VS Code and
|
|
10
|
+
other MCP-capable AI tools, just by talking to them.
|
|
11
|
+
|
|
12
|
+
## Quick start (hosted — recommended)
|
|
13
|
+
|
|
14
|
+
No install. Point your client at the hosted Streamable-HTTP endpoint with an
|
|
15
|
+
API key from [444host.com/account/api-keys](https://444host.com/account/api-keys):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
claude mcp add --transport http 444host https://api.444host.com/mcp \
|
|
19
|
+
--header "Authorization: Bearer h444_…"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
OAuth-capable clients can connect without pasting a key — approve in the
|
|
23
|
+
browser via the RFC 8628 device-code flow (AS metadata at
|
|
24
|
+
`api.444host.com/.well-known/oauth-authorization-server`).
|
|
25
|
+
|
|
26
|
+
## Quick start (local / stdio)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
H444_API_KEY=h444_… npx -y @otwa/444host-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or in a client config:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"444host": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "@otwa/444host-mcp"],
|
|
40
|
+
"env": { "H444_API_KEY": "h444_…" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Environment:
|
|
47
|
+
|
|
48
|
+
| Variable | Required | Default | Purpose |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| `H444_API_KEY` | yes | — | Your `h444_…` API key |
|
|
51
|
+
| `H444_API_BASE` | no | `https://api.444host.com` | Override for staging |
|
|
52
|
+
|
|
53
|
+
## Tools
|
|
54
|
+
|
|
55
|
+
42 tools, each gated by your key's scopes:
|
|
56
|
+
|
|
57
|
+
- **account** — `h444_get_account`
|
|
58
|
+
- **ordering** — list plans at YOUR prices / OS templates; order VPS + hosting (`orders:write`, double-confirm + idempotent)
|
|
59
|
+
- **vps** — list / get / stats / IPs+reverse-DNS; power, rename, set/clear PTR (`vps:write`); reinstall, terminate (`vps:destroy`, confirm + data-loss acknowledgement)
|
|
60
|
+
- **hosting** — list / get; PHP version, SSL re-issue, suspend/unsuspend (`hosting:write`); terminate (`hosting:destroy`)
|
|
61
|
+
- **domains** — list / get; update auto-renew / lock / WHOIS / nameservers (`domains:write`)
|
|
62
|
+
- **billing** — invoices, wallet, transactions (`billing:read`)
|
|
63
|
+
- **tickets** — list / get; open / reply / close (`tickets:write`)
|
|
64
|
+
- **webhooks** — list / get / deliveries; create / update / delete / rotate-secret / redeliver (`webhooks:write`)
|
|
65
|
+
|
|
66
|
+
Destructive operations require the opt-in `vps:destroy` / `hosting:destroy`
|
|
67
|
+
scopes; ordering requires the opt-in `orders:write` scope (it spends your
|
|
68
|
+
wallet). Orders, reinstalls and ticket-creates carry an automatic
|
|
69
|
+
`Idempotency-Key` so a retried LLM call can't act twice.
|
|
70
|
+
|
|
71
|
+
## Docs
|
|
72
|
+
|
|
73
|
+
Full API reference, scopes and changelog: **https://444host.com/developers**
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Host444ApiError = void 0;
|
|
4
|
+
exports.mapHttpError = mapHttpError;
|
|
5
|
+
class Host444ApiError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
code;
|
|
8
|
+
body;
|
|
9
|
+
name = 'Host444ApiError';
|
|
10
|
+
constructor(message, status, code, body) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.body = body;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.Host444ApiError = Host444ApiError;
|
|
18
|
+
const KEYS_URL = 'https://444host.com/account/api-keys';
|
|
19
|
+
/** Translate an HTTP response from the 444host.com API into a message the LLM
|
|
20
|
+
* can act on — always saying what to do next, not just what went wrong. */
|
|
21
|
+
function mapHttpError(status, body, requestId) {
|
|
22
|
+
const bodyMessage = extractMessage(body);
|
|
23
|
+
if (status === 401) {
|
|
24
|
+
return new Host444ApiError(`H444_API_KEY is invalid, expired, or revoked. Ask the user to create a fresh key at ${KEYS_URL}, ` +
|
|
25
|
+
'update the H444_API_KEY env var, and restart this MCP server.', status, 'unauthorized', body);
|
|
26
|
+
}
|
|
27
|
+
if (status === 403) {
|
|
28
|
+
return new Host444ApiError(bodyMessage ||
|
|
29
|
+
`Forbidden — the API key is missing a required scope. Re-issue a key with the right scopes at ${KEYS_URL}.`, status, 'forbidden', body);
|
|
30
|
+
}
|
|
31
|
+
if (status === 402) {
|
|
32
|
+
return new Host444ApiError('Account balance is too low for this operation. Tell the user to top up their wallet at https://444host.com/account/wallet.', status, 'payment_required', body);
|
|
33
|
+
}
|
|
34
|
+
if (status === 404) {
|
|
35
|
+
return new Host444ApiError(bodyMessage || 'Resource not found. If this is a server id, call h444_list_servers to see what exists.', status, 'not_found', body);
|
|
36
|
+
}
|
|
37
|
+
if (status === 409) {
|
|
38
|
+
return new Host444ApiError(bodyMessage || 'Conflict — the resource is already in the target state, or the operation is in progress.', status, 'conflict', body);
|
|
39
|
+
}
|
|
40
|
+
if (status === 422 || status === 400) {
|
|
41
|
+
return new Host444ApiError(bodyMessage || 'Validation failed. Check the field constraints and call again.', status, 'validation_failed', body);
|
|
42
|
+
}
|
|
43
|
+
if (status === 429) {
|
|
44
|
+
return new Host444ApiError('Rate-limited (120 req/min per key). Wait a few seconds before retrying — see the Retry-After header.', status, 'rate_limited', body);
|
|
45
|
+
}
|
|
46
|
+
if (status >= 500) {
|
|
47
|
+
const trace = requestId ? ` Request id: ${requestId}.` : '';
|
|
48
|
+
return new Host444ApiError(`The 444host.com API returned ${status}. Retry once, then open a ticket if it persists.${trace}`, status, 'upstream_error', body);
|
|
49
|
+
}
|
|
50
|
+
return new Host444ApiError(bodyMessage || `Unexpected HTTP ${status} from the 444host.com API.`, status, 'unknown', body);
|
|
51
|
+
}
|
|
52
|
+
function extractMessage(body) {
|
|
53
|
+
if (!body || typeof body !== 'object')
|
|
54
|
+
return null;
|
|
55
|
+
const b = body;
|
|
56
|
+
if (typeof b.message === 'string')
|
|
57
|
+
return b.message;
|
|
58
|
+
if (Array.isArray(b.message))
|
|
59
|
+
return b.message.join('; ');
|
|
60
|
+
if (typeof b.error === 'string')
|
|
61
|
+
return b.error;
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/client/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Host444Client = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
const version_1 = require("../util/version");
|
|
7
|
+
class Host444Client {
|
|
8
|
+
opts;
|
|
9
|
+
userAgent;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.opts = opts;
|
|
12
|
+
const pkg = (0, version_1.packageInfo)();
|
|
13
|
+
this.userAgent = `${pkg.name}/${pkg.version} (+https://444host.com/developers)`;
|
|
14
|
+
}
|
|
15
|
+
async request(path, options = {}) {
|
|
16
|
+
const url = this.buildUrl(path, options.query);
|
|
17
|
+
const headers = {
|
|
18
|
+
'Authorization': `Bearer ${this.opts.apiKey}`,
|
|
19
|
+
'Accept': 'application/json',
|
|
20
|
+
'User-Agent': this.userAgent,
|
|
21
|
+
};
|
|
22
|
+
if (options.body !== undefined)
|
|
23
|
+
headers['Content-Type'] = 'application/json';
|
|
24
|
+
if (options.idempotent)
|
|
25
|
+
headers['Idempotency-Key'] = `mcp-${(0, crypto_1.randomUUID)()}`;
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeoutMs = options.timeoutMs ?? this.opts.timeoutMs ?? 30_000;
|
|
28
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
29
|
+
let res;
|
|
30
|
+
try {
|
|
31
|
+
res = await fetch(url, {
|
|
32
|
+
method: options.method || 'GET',
|
|
33
|
+
headers,
|
|
34
|
+
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
|
35
|
+
signal: controller.signal,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
if (msg.includes('aborted')) {
|
|
42
|
+
throw new errors_1.Host444ApiError(`Request to ${path} timed out after ${timeoutMs}ms. Retry shortly.`, 0, 'timeout');
|
|
43
|
+
}
|
|
44
|
+
throw new errors_1.Host444ApiError(`Network error contacting the 444host.com API at ${this.opts.apiBase}: ${msg}`, 0, 'network_error');
|
|
45
|
+
}
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
if (res.status === 204)
|
|
48
|
+
return { ok: true };
|
|
49
|
+
const body = await safeReadJson(res);
|
|
50
|
+
if (!res.ok)
|
|
51
|
+
throw (0, errors_1.mapHttpError)(res.status, body, res.headers.get('x-request-id') || undefined);
|
|
52
|
+
return body;
|
|
53
|
+
}
|
|
54
|
+
buildUrl(path, query) {
|
|
55
|
+
const normalised = path.startsWith('/') ? path : `/${path}`;
|
|
56
|
+
const url = new URL(`${this.opts.apiBase}${normalised}`);
|
|
57
|
+
if (query) {
|
|
58
|
+
for (const [k, v] of Object.entries(query)) {
|
|
59
|
+
if (v === undefined || v === null || v === '')
|
|
60
|
+
continue;
|
|
61
|
+
url.searchParams.set(k, String(v));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return url.toString();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.Host444Client = Host444Client;
|
|
68
|
+
async function safeReadJson(res) {
|
|
69
|
+
const text = await res.text();
|
|
70
|
+
if (!text)
|
|
71
|
+
return null;
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(text);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return { message: text };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mediumConfirm = exports.destructiveConfirm = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/** Guard fragment for data-destroying operations (reinstall, snapshot revert,
|
|
6
|
+
* terminate). Forces the LLM to set two explicit flags, surfacing the call in
|
|
7
|
+
* the model's reasoning; the backend `servers:destroy` scope is the real gate. */
|
|
8
|
+
exports.destructiveConfirm = {
|
|
9
|
+
confirm: zod_1.z.literal(true).describe('Must be exactly `true`. Confirms the user was shown what will happen and explicitly approved it.'),
|
|
10
|
+
iAcknowledgeDataLoss: zod_1.z.literal(true).describe('Must be exactly `true`. The operation permanently destroys data on the disk.'),
|
|
11
|
+
};
|
|
12
|
+
/** Guard fragment for medium-risk operations (stop/reboot, password reset). */
|
|
13
|
+
exports.mediumConfirm = {
|
|
14
|
+
confirm: zod_1.z.literal(true).describe('Must be exactly `true`. This interrupts the running workload — confirm with the user first.'),
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=confirm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/guards/confirm.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB;;mFAEmF;AACtE,QAAA,kBAAkB,GAAG;IAChC,OAAO,EAAE,OAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAC/B,kGAAkG,CACnG;IACD,oBAAoB,EAAE,OAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAC5C,8EAA8E,CAC/E;CACF,CAAC;AAEF,+EAA+E;AAClE,QAAA,aAAa,GAAG;IAC3B,OAAO,EAAE,OAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAC/B,6FAA6F,CAC9F;CACF,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
10
|
+
const server_1 = require("../server");
|
|
11
|
+
const version_1 = require("../util/version");
|
|
12
|
+
const PORT = parseInt(process.env.PORT || '3315', 10);
|
|
13
|
+
const HOST = process.env.HOST || '127.0.0.1';
|
|
14
|
+
const API_BASE = (process.env.H444_API_BASE?.trim() || 'https://api.444host.com').replace(/\/+$/, '');
|
|
15
|
+
// Public hostname this server is exposed under — used in the RFC 9728 metadata
|
|
16
|
+
// + WWW-Authenticate challenge. Override for staging.
|
|
17
|
+
const PUBLIC_BASE = (process.env.MCP_PUBLIC_BASE?.trim() || 'https://api.444host.com').replace(/\/+$/, '');
|
|
18
|
+
// OAuth 2.0 Authorization Server clients should talk to (the 444host.com API
|
|
19
|
+
// host that issues keys + device-code tokens). Clients that support OAuth
|
|
20
|
+
// discover the endpoints via the AS metadata there.
|
|
21
|
+
const OAUTH_AS = (process.env.H444_OAUTH_AS?.trim() || 'https://api.444host.com').replace(/\/+$/, '');
|
|
22
|
+
const app = (0, express_1.default)();
|
|
23
|
+
app.disable('x-powered-by');
|
|
24
|
+
app.set('trust proxy', 'loopback');
|
|
25
|
+
app.use(express_1.default.json({ limit: '1mb' }));
|
|
26
|
+
const pkg = (0, version_1.packageInfo)();
|
|
27
|
+
app.get('/healthz', (_req, res) => {
|
|
28
|
+
res.json({ ok: true, service: pkg.name, version: pkg.version, apiBase: API_BASE });
|
|
29
|
+
});
|
|
30
|
+
// RFC 9728 Protected Resource Metadata — announces this MCP server is an
|
|
31
|
+
// OAuth-protected resource served by the 444host.com authorization server.
|
|
32
|
+
// Purely additive: Bearer API-key callers keep working unchanged.
|
|
33
|
+
const protectedResourceMetadata = () => ({
|
|
34
|
+
resource: `${PUBLIC_BASE}/mcp`,
|
|
35
|
+
authorization_servers: [OAUTH_AS],
|
|
36
|
+
bearer_methods_supported: ['header'],
|
|
37
|
+
scopes_supported: [
|
|
38
|
+
'account:read',
|
|
39
|
+
'vps:read', 'vps:write', 'vps:destroy',
|
|
40
|
+
'hosting:read', 'hosting:write', 'hosting:destroy',
|
|
41
|
+
'domains:read', 'domains:write',
|
|
42
|
+
'billing:read',
|
|
43
|
+
'tickets:read', 'tickets:write',
|
|
44
|
+
'webhooks:read', 'webhooks:write',
|
|
45
|
+
'orders:write',
|
|
46
|
+
],
|
|
47
|
+
resource_name: '444host-mcp',
|
|
48
|
+
resource_documentation: 'https://444host.com/developers',
|
|
49
|
+
});
|
|
50
|
+
app.get('/.well-known/oauth-protected-resource', (_req, res) => {
|
|
51
|
+
res.set('Cache-Control', 'public, max-age=3600').json(protectedResourceMetadata());
|
|
52
|
+
});
|
|
53
|
+
app.get('/.well-known/oauth-protected-resource/mcp', (_req, res) => {
|
|
54
|
+
res.set('Cache-Control', 'public, max-age=3600').json(protectedResourceMetadata());
|
|
55
|
+
});
|
|
56
|
+
const WWW_AUTH_HEADER = `Bearer realm="444host-mcp", resource_metadata="${PUBLIC_BASE}/.well-known/oauth-protected-resource"`;
|
|
57
|
+
app.get('/', (_req, res) => {
|
|
58
|
+
res.json({
|
|
59
|
+
name: pkg.name,
|
|
60
|
+
version: pkg.version,
|
|
61
|
+
transport: 'streamable-http',
|
|
62
|
+
docs: 'https://444host.com/developers',
|
|
63
|
+
endpoints: { mcp: 'POST /mcp', health: 'GET /healthz' },
|
|
64
|
+
auth: 'Bearer h444_… (from https://444host.com/account/api-keys) or an OAuth access token',
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
function extractBearer(req) {
|
|
68
|
+
const raw = req.header('authorization') || req.header('Authorization');
|
|
69
|
+
if (!raw)
|
|
70
|
+
return null;
|
|
71
|
+
const m = /^Bearer\s+(.+)$/.exec(raw.trim());
|
|
72
|
+
return m && m[1] ? m[1].trim() : null;
|
|
73
|
+
}
|
|
74
|
+
/** Stateless Streamable HTTP — fresh McpServer + transport per request, scoped
|
|
75
|
+
* to the caller's bearer token. Accepts `h444_…` API keys and `h444_at_…` OAuth
|
|
76
|
+
* access tokens (both validated upstream by the 444host.com API). */
|
|
77
|
+
app.post('/mcp', async (req, res) => {
|
|
78
|
+
const token = extractBearer(req);
|
|
79
|
+
if (!token) {
|
|
80
|
+
res.set('WWW-Authenticate', WWW_AUTH_HEADER).status(401).json({
|
|
81
|
+
jsonrpc: '2.0',
|
|
82
|
+
error: { code: -32001, message: 'Missing Authorization header. Set "Authorization: Bearer h444_…" with a key from https://444host.com/account/api-keys' },
|
|
83
|
+
id: null,
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!token.startsWith('h444_')) {
|
|
88
|
+
res.set('WWW-Authenticate', WWW_AUTH_HEADER).status(401).json({
|
|
89
|
+
jsonrpc: '2.0',
|
|
90
|
+
error: { code: -32001, message: 'Bearer token does not look like a 444host.com credential (expected prefix "h444_").' },
|
|
91
|
+
id: null,
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({
|
|
96
|
+
sessionIdGenerator: undefined,
|
|
97
|
+
enableJsonResponse: true,
|
|
98
|
+
});
|
|
99
|
+
const server = (0, server_1.createServer)({ apiKey: token, apiBase: API_BASE });
|
|
100
|
+
res.on('close', () => {
|
|
101
|
+
transport.close().catch(() => { });
|
|
102
|
+
server.close().catch(() => { });
|
|
103
|
+
});
|
|
104
|
+
try {
|
|
105
|
+
await server.connect(transport);
|
|
106
|
+
await transport.handleRequest(req, res, req.body);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
110
|
+
process.stderr.write(`[444host-mcp-http] handler error: ${msg}\n`);
|
|
111
|
+
if (!res.headersSent) {
|
|
112
|
+
res.status(500).json({ jsonrpc: '2.0', error: { code: -32603, message: `Internal error: ${msg}` }, id: null });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// Stateless — refuse the session-oriented GET/DELETE forms per spec.
|
|
117
|
+
app.get('/mcp', (_req, res) => {
|
|
118
|
+
res.status(405).json({ jsonrpc: '2.0', error: { code: -32000, message: 'Method Not Allowed. This server is stateless — use POST /mcp.' }, id: null });
|
|
119
|
+
});
|
|
120
|
+
app.delete('/mcp', (_req, res) => {
|
|
121
|
+
res.status(405).json({ jsonrpc: '2.0', error: { code: -32000, message: 'Method Not Allowed. This server is stateless.' }, id: null });
|
|
122
|
+
});
|
|
123
|
+
app.use((req, res) => {
|
|
124
|
+
res.status(404).json({ error: 'not_found', path: req.path });
|
|
125
|
+
});
|
|
126
|
+
app.use((err, req, res, _next) => {
|
|
127
|
+
const id = (0, crypto_1.randomUUID)();
|
|
128
|
+
process.stderr.write(`[444host-mcp-http] ${id} ${req.method} ${req.path}: ${err.stack || err.message}\n`);
|
|
129
|
+
if (!res.headersSent)
|
|
130
|
+
res.status(500).json({ error: 'internal_error', requestId: id });
|
|
131
|
+
});
|
|
132
|
+
const httpServer = app.listen(PORT, HOST, () => {
|
|
133
|
+
process.stdout.write(`[444host-mcp-http] ${pkg.name} ${pkg.version} listening on ${HOST}:${PORT} (API base: ${API_BASE})\n`);
|
|
134
|
+
});
|
|
135
|
+
const shutdown = (signal) => {
|
|
136
|
+
process.stderr.write(`[444host-mcp-http] shutdown on ${signal}\n`);
|
|
137
|
+
httpServer.close(() => process.exit(0));
|
|
138
|
+
setTimeout(() => process.exit(1), 5_000).unref();
|
|
139
|
+
};
|
|
140
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
141
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const server_1 = require("./server");
|
|
6
|
+
const env_1 = require("./util/env");
|
|
7
|
+
const version_1 = require("./util/version");
|
|
8
|
+
async function main() {
|
|
9
|
+
const argv = process.argv.slice(2);
|
|
10
|
+
if (argv.includes('--version') || argv.includes('-v')) {
|
|
11
|
+
const pkg = (0, version_1.packageInfo)();
|
|
12
|
+
process.stdout.write(`${pkg.name} ${pkg.version}\n`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
16
|
+
printHelp();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let env;
|
|
20
|
+
try {
|
|
21
|
+
env = (0, env_1.readEnv)();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
25
|
+
process.stderr.write(`[444host-mcp] ${msg}\n`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const server = (0, server_1.createServer)(env);
|
|
29
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
30
|
+
await server.connect(transport);
|
|
31
|
+
const shutdown = async (signal) => {
|
|
32
|
+
try {
|
|
33
|
+
await server.close();
|
|
34
|
+
}
|
|
35
|
+
catch { /* best-effort */ }
|
|
36
|
+
process.stderr.write(`[444host-mcp] shutdown on ${signal}\n`);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
};
|
|
39
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
40
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
41
|
+
}
|
|
42
|
+
function printHelp() {
|
|
43
|
+
const pkg = (0, version_1.packageInfo)();
|
|
44
|
+
process.stdout.write(`${pkg.name} ${pkg.version}\n\n` +
|
|
45
|
+
'Model Context Protocol server for 444host.com.\n\n' +
|
|
46
|
+
'Usage:\n' +
|
|
47
|
+
' 444host-mcp Start the stdio MCP server (spawned by Claude Code, Cursor, etc.)\n' +
|
|
48
|
+
' 444host-mcp --version Print version and exit\n' +
|
|
49
|
+
' 444host-mcp --help Show this help\n\n' +
|
|
50
|
+
'Environment:\n' +
|
|
51
|
+
' H444_API_KEY Required. Generate at https://444host.com/account/api-keys\n' +
|
|
52
|
+
' H444_API_BASE Optional. Default https://api.444host.com\n\n' +
|
|
53
|
+
'Docs: https://444host.com/developers\n');
|
|
54
|
+
}
|
|
55
|
+
main().catch((err) => {
|
|
56
|
+
const msg = err instanceof Error ? err.stack || err.message : String(err);
|
|
57
|
+
process.stderr.write(`[444host-mcp] fatal: ${msg}\n`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,wEAAiF;AACjF,qCAAwC;AACxC,oCAAqC;AACrC,4CAA6C;AAE7C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,IAAA,qBAAW,GAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,aAAO,GAAE,CAAC;IAClB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,GAAG,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,MAAM,IAAI,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,GAAG,GAAG,IAAA,qBAAW,GAAE,CAAC;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,MAAM;QAC9B,oDAAoD;QACpD,UAAU;QACV,8FAA8F;QAC9F,mDAAmD;QACnD,6CAA6C;QAC7C,gBAAgB;QAChB,+EAA+E;QAC/E,gEAAgE;QAChE,wCAAwC,CAC3C,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createServer = createServer;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const http_1 = require("./client/http");
|
|
6
|
+
const _register_1 = require("./tools/_register");
|
|
7
|
+
const version_1 = require("./util/version");
|
|
8
|
+
/** Build a fresh McpServer wired to a Host444Client scoped to one API key.
|
|
9
|
+
* The HTTP transport calls this per-request (stateless); stdio calls it once. */
|
|
10
|
+
function createServer(env) {
|
|
11
|
+
const pkg = (0, version_1.packageInfo)();
|
|
12
|
+
const server = new mcp_js_1.McpServer({ name: pkg.name, version: pkg.version });
|
|
13
|
+
const client = new http_1.Host444Client({ apiKey: env.apiKey, apiBase: env.apiBase });
|
|
14
|
+
(0, _register_1.registerAllTools)(server, client);
|
|
15
|
+
return server;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;AAQA,oCAMC;AAdD,oEAAoE;AACpE,wCAA8C;AAC9C,iDAAqD;AACrD,4CAA6C;AAG7C;kFACkF;AAClF,SAAgB,YAAY,CAAC,GAAe;IAC1C,MAAM,GAAG,GAAG,IAAA,qBAAW,GAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,kBAAS,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,oBAAa,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,IAAA,4BAAgB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jsonResult = jsonResult;
|
|
4
|
+
exports.textResult = textResult;
|
|
5
|
+
exports.safeHandler = safeHandler;
|
|
6
|
+
const errors_1 = require("../client/errors");
|
|
7
|
+
/** Format a JSON value as a single pretty-printed text block. */
|
|
8
|
+
function jsonResult(value) {
|
|
9
|
+
return { content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] };
|
|
10
|
+
}
|
|
11
|
+
/** Format a plain prose response (no JSON). */
|
|
12
|
+
function textResult(text) {
|
|
13
|
+
return { content: [{ type: 'text', text }] };
|
|
14
|
+
}
|
|
15
|
+
/** Wrap a tool handler so any throw becomes a structured error result instead
|
|
16
|
+
* of crashing the transport. */
|
|
17
|
+
function safeHandler(fn) {
|
|
18
|
+
return async (args) => {
|
|
19
|
+
try {
|
|
20
|
+
return await fn(args);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const message = err instanceof errors_1.Host444ApiError ? err.message : err instanceof Error ? err.message : String(err);
|
|
24
|
+
return { isError: true, content: [{ type: 'text', text: message }] };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=_helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../src/tools/_helpers.ts"],"names":[],"mappings":";;AAIA,gCAEC;AAGD,gCAEC;AAID,kCAYC;AA1BD,6CAAmD;AAEnD,iEAAiE;AACjE,SAAgB,UAAU,CAAC,KAAc;IACvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,+CAA+C;AAC/C,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED;iCACiC;AACjC,SAAgB,WAAW,CACzB,EAA4C;IAE5C,OAAO,KAAK,EAAE,IAAW,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GACX,GAAG,YAAY,wBAAe,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACvE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerAllTools = registerAllTools;
|
|
4
|
+
const account_1 = require("./account");
|
|
5
|
+
const orders_1 = require("./orders");
|
|
6
|
+
const servers_1 = require("./servers");
|
|
7
|
+
const hosting_1 = require("./hosting");
|
|
8
|
+
const domains_1 = require("./domains");
|
|
9
|
+
const billing_1 = require("./billing");
|
|
10
|
+
const tickets_1 = require("./tickets");
|
|
11
|
+
const webhooks_1 = require("./webhooks");
|
|
12
|
+
function registerAllTools(server, client) {
|
|
13
|
+
(0, account_1.registerAccountTools)(server, client);
|
|
14
|
+
(0, orders_1.registerOrderTools)(server, client);
|
|
15
|
+
(0, servers_1.registerServerTools)(server, client);
|
|
16
|
+
(0, hosting_1.registerHostingTools)(server, client);
|
|
17
|
+
(0, domains_1.registerDomainTools)(server, client);
|
|
18
|
+
(0, billing_1.registerBillingTools)(server, client);
|
|
19
|
+
(0, tickets_1.registerTicketTools)(server, client);
|
|
20
|
+
(0, webhooks_1.registerWebhookTools)(server, client);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=_register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_register.js","sourceRoot":"","sources":["../../src/tools/_register.ts"],"names":[],"mappings":";;AAWA,4CASC;AAlBD,uCAAiD;AACjD,qCAA8C;AAC9C,uCAAgD;AAChD,uCAAiD;AACjD,uCAAgD;AAChD,uCAAiD;AACjD,uCAAgD;AAChD,yCAAkD;AAElD,SAAgB,gBAAgB,CAAC,MAAiB,EAAE,MAAqB;IACvE,IAAA,8BAAoB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAA,2BAAkB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,IAAA,6BAAmB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAA,8BAAoB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAA,6BAAmB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAA,8BAAoB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAA,6BAAmB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAA,+BAAoB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerAccountTools = registerAccountTools;
|
|
4
|
+
const _helpers_1 = require("./_helpers");
|
|
5
|
+
function registerAccountTools(server, client) {
|
|
6
|
+
server.registerTool('h444_get_account', {
|
|
7
|
+
title: 'Get account profile',
|
|
8
|
+
description: 'Returns the authenticated 444host.com account profile (id, email, name, country, verification, created date).',
|
|
9
|
+
inputSchema: {},
|
|
10
|
+
}, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/account'))));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":";;AAIA,oDAUC;AAZD,yCAAqD;AAErD,SAAgB,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,+GAA+G;QAC5H,WAAW,EAAE,EAAE;KAChB,EACD,IAAA,sBAAW,EAAC,KAAK,IAAI,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerBillingTools = registerBillingTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _helpers_1 = require("./_helpers");
|
|
6
|
+
function registerBillingTools(server, client) {
|
|
7
|
+
server.registerTool('h444_list_invoices', {
|
|
8
|
+
title: 'List invoices',
|
|
9
|
+
description: 'Paginated invoice list.',
|
|
10
|
+
inputSchema: {
|
|
11
|
+
page: zod_1.z.number().int().min(1).optional().describe('Page number (default 1).'),
|
|
12
|
+
limit: zod_1.z.number().int().min(1).max(100).optional().describe('Page size (default 50).'),
|
|
13
|
+
},
|
|
14
|
+
}, (0, _helpers_1.safeHandler)(async ({ page, limit }) => (0, _helpers_1.jsonResult)(await client.request('/v1/billing/invoices', { query: { page, limit } }))));
|
|
15
|
+
server.registerTool('h444_get_invoice', { title: 'Get an invoice', description: 'A single invoice with line items.', inputSchema: { id: zod_1.z.string().describe('Invoice id.') } }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/billing/invoices/${encodeURIComponent(id)}`))));
|
|
16
|
+
server.registerTool('h444_get_wallet', { title: 'Get wallet balance', description: 'Prepaid wallet balance and state.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/billing/wallet'))));
|
|
17
|
+
server.registerTool('h444_list_wallet_transactions', {
|
|
18
|
+
title: 'List wallet transactions',
|
|
19
|
+
description: 'Recent wallet transactions.',
|
|
20
|
+
inputSchema: { limit: zod_1.z.number().int().min(1).max(100).optional().describe('How many (default 20).') },
|
|
21
|
+
}, (0, _helpers_1.safeHandler)(async ({ limit }) => (0, _helpers_1.jsonResult)(await client.request('/v1/billing/wallet/transactions', { query: { limit } }))));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=billing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/tools/billing.ts"],"names":[],"mappings":";;AAKA,oDAqCC;AAzCD,6BAAwB;AAExB,yCAAqD;AAErD,SAAgB,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,yBAAyB;QACtC,WAAW,EAAE;YACX,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC7E,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;SACvF;KACF,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CACpC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CACxF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,mCAAmC,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,EAAE,EACtI,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,wBAAwB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAClH,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB,EAAE,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,mCAAmC,EAAE,WAAW,EAAE,EAAE,EAAE,EAClG,IAAA,sBAAW,EAAC,KAAK,IAAI,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAChF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,+BAA+B,EAC/B;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,6BAA6B;QAC1C,WAAW,EAAE,EAAE,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE;KACvG,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAC9B,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAC7F,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerDomainTools = registerDomainTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _helpers_1 = require("./_helpers");
|
|
6
|
+
const idArg = { id: zod_1.z.string().describe('Domain UUID. Retrieve via h444_list_domains.') };
|
|
7
|
+
function registerDomainTools(server, client) {
|
|
8
|
+
server.registerTool('h444_list_domains', { title: 'List domains', description: 'Every registered domain on the account.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/domains'))));
|
|
9
|
+
server.registerTool('h444_get_domain', { title: 'Get a domain', description: 'Detail for one domain (status, expiry, nameservers, lock/privacy/auto-renew).', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/domains/${encodeURIComponent(id)}`))));
|
|
10
|
+
server.registerTool('h444_update_domain', {
|
|
11
|
+
title: 'Update domain settings',
|
|
12
|
+
description: 'Update auto-renew, transfer lock, WHOIS privacy, and/or nameservers. Only the provided fields change.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
...idArg,
|
|
15
|
+
auto_renew: zod_1.z.boolean().optional().describe('Enable/disable auto-renew.'),
|
|
16
|
+
transfer_lock: zod_1.z.boolean().optional().describe('Enable/disable the registrar transfer lock.'),
|
|
17
|
+
whois_privacy: zod_1.z.boolean().optional().describe('Enable/disable WHOIS privacy.'),
|
|
18
|
+
nameservers: zod_1.z.array(zod_1.z.string()).max(6).optional().describe('Up to 6 nameservers (replaces the set).'),
|
|
19
|
+
},
|
|
20
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, ...body }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/domains/${encodeURIComponent(id)}`, { method: 'PATCH', body }))));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/tools/domains.ts"],"names":[],"mappings":";;AAOA,kDA6BC;AAnCD,6BAAwB;AAExB,yCAAqD;AAErD,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC,EAAE,CAAC;AAE1F,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,MAAqB;IAC1E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,yCAAyC,EAAE,WAAW,EAAE,EAAE,EAAE,EAClG,IAAA,sBAAW,EAAC,KAAK,IAAI,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CACzE,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,+EAA+E,EAAE,WAAW,EAAE,KAAK,EAAE,EAC3I,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACzG,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,uGAAuG;QACpH,WAAW,EAAE;YACX,GAAG,KAAK;YACR,UAAU,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACzE,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YAC7F,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC/E,WAAW,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SACvG;KACF,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CACpC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CACxG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerHostingTools = registerHostingTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const confirm_1 = require("../guards/confirm");
|
|
6
|
+
const _helpers_1 = require("./_helpers");
|
|
7
|
+
const idArg = { id: zod_1.z.string().describe('Hosting account UUID. Retrieve via h444_list_hosting.') };
|
|
8
|
+
function registerHostingTools(server, client) {
|
|
9
|
+
server.registerTool('h444_list_hosting', { title: 'List hosting accounts', description: 'Every web-hosting account: status, quota, usage, connection hosts. Passwords are never returned on the API.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/hosting'))));
|
|
10
|
+
server.registerTool('h444_get_hosting', { title: 'Get a hosting account', description: 'Detail for one hosting account.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}`))));
|
|
11
|
+
server.registerTool('h444_set_hosting_php', {
|
|
12
|
+
title: 'Set hosting PHP version',
|
|
13
|
+
description: 'Switch the account\'s PHP-FPM version (7.4 / 8.1 / 8.3). Briefly restarts the PHP pool — set confirm:true.',
|
|
14
|
+
inputSchema: { ...idArg, php_version: zod_1.z.enum(['7.4', '8.1', '8.3']), ...confirm_1.mediumConfirm },
|
|
15
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, php_version }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}/php`, { method: 'PUT', body: { php_version } }))));
|
|
16
|
+
server.registerTool('h444_retry_hosting_ssl', { title: 'Re-issue hosting SSL', description: 'Retry the Let\'s Encrypt certificate issue for the account\'s domain now (e.g. after pointing DNS).', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}/ssl/retry`, { method: 'POST' }))));
|
|
17
|
+
server.registerTool('h444_suspend_hosting', {
|
|
18
|
+
title: 'Suspend hosting',
|
|
19
|
+
description: 'Suspend the account — site and databases stop serving. Reversible. Set confirm:true.',
|
|
20
|
+
inputSchema: { ...idArg, ...confirm_1.mediumConfirm },
|
|
21
|
+
}, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}/suspend`, { method: 'POST' }))));
|
|
22
|
+
server.registerTool('h444_unsuspend_hosting', { title: 'Unsuspend hosting', description: 'Lift a suspension and restore service.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}/unsuspend`, { method: 'POST' }))));
|
|
23
|
+
server.registerTool('h444_terminate_hosting', {
|
|
24
|
+
title: 'Terminate hosting (DESTRUCTIVE)',
|
|
25
|
+
description: 'Permanently removes the site, databases, and mail; the username becomes reusable. Requires the hosting:destroy scope. Call h444_get_hosting first and confirm the domain with the user.',
|
|
26
|
+
inputSchema: {
|
|
27
|
+
...idArg,
|
|
28
|
+
expectedDomain: zod_1.z.string().describe('The account\'s current domain, as a typo-guard.'),
|
|
29
|
+
...confirm_1.destructiveConfirm,
|
|
30
|
+
},
|
|
31
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, expectedDomain }) => {
|
|
32
|
+
const detail = await client.request(`/v1/hosting/${encodeURIComponent(id)}`);
|
|
33
|
+
const actual = detail?.domain || '';
|
|
34
|
+
if (expectedDomain && actual && expectedDomain.trim().toLowerCase() !== actual.trim().toLowerCase()) {
|
|
35
|
+
return { isError: true, content: [{ type: 'text', text: `Refusing to terminate: expectedDomain "${expectedDomain}" does not match the account's domain "${actual}".` }] };
|
|
36
|
+
}
|
|
37
|
+
return (0, _helpers_1.jsonResult)(await client.request(`/v1/hosting/${encodeURIComponent(id)}`, { method: 'DELETE' }));
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=hosting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosting.js","sourceRoot":"","sources":["../../src/tools/hosting.ts"],"names":[],"mappings":";;AAQA,oDAqEC;AA5ED,6BAAwB;AAExB,+CAAsE;AACtE,yCAAqD;AAErD,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC,EAAE,CAAC;AAEnG,SAAgB,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB,EAAE,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,6GAA6G,EAAE,WAAW,EAAE,EAAE,EAAE,EAC/K,IAAA,sBAAW,EAAC,KAAK,IAAI,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CACzE,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB,EAAE,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,iCAAiC,EAAE,WAAW,EAAE,KAAK,EAAE,EACtG,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACzG,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,4GAA4G;QACzH,WAAW,EAAE,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,uBAAa,EAAE;KACxF,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CACxC,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAC3H,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB,EAAE,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,qGAAqG,EAAE,WAAW,EAAE,KAAK,EAAE,EACzK,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAC3B,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAC3G,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,sFAAsF;QACnG,WAAW,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,uBAAa,EAAE;KAC5C,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAC3B,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CACzG,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,wCAAwC,EAAE,WAAW,EAAE,KAAK,EAAE,EACzG,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAC3B,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAC3G,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,yLAAyL;QACtM,WAAW,EAAE;YACX,GAAG,KAAK;YACR,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;YACtF,GAAG,4BAAkB;SACtB;KACF,EACD,IAAA,sBAAW,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAsB,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClG,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;QACpC,IAAI,cAAc,IAAI,MAAM,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACpG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,0CAA0C,cAAc,0CAA0C,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5K,CAAC;QACD,OAAO,IAAA,qBAAU,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACzG,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerOrderTools = registerOrderTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _helpers_1 = require("./_helpers");
|
|
6
|
+
/** Ordering tools — these SPEND the wallet (opt-in `orders:write` scope on the
|
|
7
|
+
* key is the real gate). Both carry an explicit double-confirm: the model
|
|
8
|
+
* must show the user the plan + the price it fetched before calling. */
|
|
9
|
+
const spendConfirm = {
|
|
10
|
+
confirm: zod_1.z.literal(true).describe('Must be exactly `true`. Confirms the user saw the plan and the exact price (from h444_list_products) and approved the purchase.'),
|
|
11
|
+
iAcknowledgeWalletCharge: zod_1.z.literal(true).describe('Must be exactly `true`. The order immediately debits the account wallet at the listed your_monthly_usd_cents price.'),
|
|
12
|
+
};
|
|
13
|
+
function registerOrderTools(server, client) {
|
|
14
|
+
server.registerTool('h444_list_products', { title: 'List plans & your prices', description: 'Orderable VPS and hosting plans with retail and YOUR effective price (reseller discount applied). Always show the user your_monthly_usd_cents before ordering.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/products'))));
|
|
15
|
+
server.registerTool('h444_list_os_templates', { title: 'List OS templates', description: 'Installable OS templates for VPS orders and reinstalls.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/os-templates'))));
|
|
16
|
+
server.registerTool('h444_order_vps', {
|
|
17
|
+
title: 'Order a VPS (SPENDS WALLET)',
|
|
18
|
+
description: 'Places a real VPS order: debits the wallet at your effective price, provisions, and returns the server + its initial root password (summarise — do not paste the password into chat). Provisioning failure auto-refunds.',
|
|
19
|
+
inputSchema: {
|
|
20
|
+
plan_slug: zod_1.z.string().describe('Plan slug from h444_list_products (category vps).'),
|
|
21
|
+
label: zod_1.z.string().describe('Display label, e.g. web-1.'),
|
|
22
|
+
hostname: zod_1.z.string().describe('DNS-safe hostname.'),
|
|
23
|
+
os_family: zod_1.z.string().describe('OS family from h444_list_os_templates, e.g. ubuntu.'),
|
|
24
|
+
os_template: zod_1.z.string().describe('OS template id, e.g. ubuntu-22.04.'),
|
|
25
|
+
...spendConfirm,
|
|
26
|
+
},
|
|
27
|
+
}, (0, _helpers_1.safeHandler)(async ({ plan_slug, label, hostname, os_family, os_template }) => (0, _helpers_1.jsonResult)(await client.request('/v1/vps', {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
body: { plan_slug, label, hostname, os_family, os_template },
|
|
30
|
+
idempotent: true,
|
|
31
|
+
timeoutMs: 180_000,
|
|
32
|
+
}))));
|
|
33
|
+
server.registerTool('h444_order_hosting', {
|
|
34
|
+
title: 'Order web hosting (SPENDS WALLET)',
|
|
35
|
+
description: 'Places a real hosting order: debits the wallet at your effective price and provisions. Returns the account + SFTP/DB passwords (summarise — do not paste them into chat). Provisioning failure auto-refunds.',
|
|
36
|
+
inputSchema: {
|
|
37
|
+
plan_slug: zod_1.z.string().describe('Plan slug from h444_list_products (category hosting).'),
|
|
38
|
+
domain: zod_1.z.string().describe('FQDN the account will serve, e.g. example.com.'),
|
|
39
|
+
username: zod_1.z.string().describe('Lowercase a-z0-9_ username, 3-32 chars, starts with a letter.'),
|
|
40
|
+
php_version: zod_1.z.enum(['7.4', '8.1', '8.3']).optional().describe('Defaults to 8.3.'),
|
|
41
|
+
...spendConfirm,
|
|
42
|
+
},
|
|
43
|
+
}, (0, _helpers_1.safeHandler)(async ({ plan_slug, domain, username, php_version }) => (0, _helpers_1.jsonResult)(await client.request('/v1/hosting', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
body: { plan_slug, domain, username, php_version },
|
|
46
|
+
idempotent: true,
|
|
47
|
+
timeoutMs: 180_000,
|
|
48
|
+
}))));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../../src/tools/orders.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerServerTools = registerServerTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const confirm_1 = require("../guards/confirm");
|
|
6
|
+
const _helpers_1 = require("./_helpers");
|
|
7
|
+
const idArg = { id: zod_1.z.string().describe('VPS UUID. Retrieve via h444_list_vps.') };
|
|
8
|
+
function registerServerTools(server, client) {
|
|
9
|
+
// ── Reads ──────────────────────────────────────────────────────────────
|
|
10
|
+
server.registerTool('h444_list_vps', { title: 'List VPS', description: 'Every VPS on the account (id, label, status, IP, plan specs). Use the id with per-server tools.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/vps'))));
|
|
11
|
+
server.registerTool('h444_get_vps', { title: 'Get a VPS', description: 'Full detail for one VPS. Always call this before any destructive op so the user can confirm against the current label.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}`))));
|
|
12
|
+
server.registerTool('h444_get_vps_stats', { title: 'Live VPS stats', description: 'Latest CPU / memory / network / disk usage for a VPS.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/stats`))));
|
|
13
|
+
server.registerTool('h444_list_vps_ips', { title: 'List VPS IPs & reverse DNS', description: 'Every IP on a VPS with its current PTR (reverse DNS) record. zoneHosted:false means the PTR cannot be managed here.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/ips`))));
|
|
14
|
+
// ── Writes (vps:write) ───────────────────────────────────────────────────
|
|
15
|
+
server.registerTool('h444_power_vps', {
|
|
16
|
+
title: 'Power action on a VPS',
|
|
17
|
+
description: 'Start, stop, or reboot a VPS. stop/reboot interrupt the workload — set confirm:true.',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
...idArg,
|
|
20
|
+
action: zod_1.z.enum(['start', 'stop', 'reboot']).describe('Power action.'),
|
|
21
|
+
...confirm_1.mediumConfirm,
|
|
22
|
+
},
|
|
23
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, action }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/power/${action}`, { method: 'POST' }))));
|
|
24
|
+
server.registerTool('h444_rename_vps', {
|
|
25
|
+
title: 'Rename a VPS',
|
|
26
|
+
description: 'Change the display label.',
|
|
27
|
+
inputSchema: { ...idArg, label: zod_1.z.string().describe('New label.') },
|
|
28
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, label }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/label`, { method: 'PATCH', body: { label } }))));
|
|
29
|
+
server.registerTool('h444_set_vps_ptr', {
|
|
30
|
+
title: 'Set reverse DNS (PTR)',
|
|
31
|
+
description: 'Point an IP\'s PTR record at a hostname (e.g. mail.example.com). Affects mail deliverability — set confirm:true after telling the user the IP and hostname.',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
...idArg,
|
|
34
|
+
ip: zod_1.z.string().describe('IP address on the VPS (from h444_list_vps_ips).'),
|
|
35
|
+
hostname: zod_1.z.string().describe('Hostname the IP should resolve to, e.g. mail.example.com.'),
|
|
36
|
+
...confirm_1.mediumConfirm,
|
|
37
|
+
},
|
|
38
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, ip, hostname }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/ips/${encodeURIComponent(ip)}/ptr`, {
|
|
39
|
+
method: 'PUT', body: { hostname },
|
|
40
|
+
}))));
|
|
41
|
+
server.registerTool('h444_delete_vps_ptr', {
|
|
42
|
+
title: 'Clear reverse DNS (PTR)',
|
|
43
|
+
description: 'Remove the PTR record for an IP. Affects mail deliverability — set confirm:true.',
|
|
44
|
+
inputSchema: {
|
|
45
|
+
...idArg,
|
|
46
|
+
ip: zod_1.z.string().describe('IP address on the VPS (from h444_list_vps_ips).'),
|
|
47
|
+
...confirm_1.mediumConfirm,
|
|
48
|
+
},
|
|
49
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, ip }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/ips/${encodeURIComponent(ip)}/ptr`, { method: 'DELETE' }))));
|
|
50
|
+
// ── Destructive (vps:destroy) ────────────────────────────────────────────
|
|
51
|
+
server.registerTool('h444_reinstall_vps', {
|
|
52
|
+
title: 'Reinstall a VPS (DESTRUCTIVE)',
|
|
53
|
+
description: 'Wipe the disk and rebuild from an OS template (see h444_list_os_templates). Destroys all data. Requires the vps:destroy scope. Idempotent.',
|
|
54
|
+
inputSchema: {
|
|
55
|
+
...idArg,
|
|
56
|
+
os: zod_1.z.string().describe('OS family, e.g. ubuntu.'),
|
|
57
|
+
osTemplate: zod_1.z.string().describe('OS template id to install.'),
|
|
58
|
+
...confirm_1.destructiveConfirm,
|
|
59
|
+
},
|
|
60
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, os, osTemplate }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}/reinstall`, {
|
|
61
|
+
method: 'POST', idempotent: true, body: { os, osTemplate },
|
|
62
|
+
}))));
|
|
63
|
+
server.registerTool('h444_terminate_vps', {
|
|
64
|
+
title: 'Terminate a VPS (DESTRUCTIVE)',
|
|
65
|
+
description: 'Permanently terminate a VPS. Irreversible. Requires the vps:destroy scope. Call h444_get_vps first and confirm the label with the user.',
|
|
66
|
+
inputSchema: {
|
|
67
|
+
...idArg,
|
|
68
|
+
expectedLabel: zod_1.z.string().describe('The current VPS label, as a typo-guard. Must match the server being terminated.'),
|
|
69
|
+
...confirm_1.destructiveConfirm,
|
|
70
|
+
},
|
|
71
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, expectedLabel }) => {
|
|
72
|
+
const detail = await client.request(`/v1/vps/${encodeURIComponent(id)}`);
|
|
73
|
+
const actual = detail?.label || detail?.hostname || '';
|
|
74
|
+
if (expectedLabel && actual && expectedLabel.trim() !== actual.trim()) {
|
|
75
|
+
return { isError: true, content: [{ type: 'text', text: `Refusing to terminate: expectedLabel "${expectedLabel}" does not match the VPS's current label "${actual}".` }] };
|
|
76
|
+
}
|
|
77
|
+
return (0, _helpers_1.jsonResult)(await client.request(`/v1/vps/${encodeURIComponent(id)}`, { method: 'DELETE' }));
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../src/tools/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTicketTools = registerTicketTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _helpers_1 = require("./_helpers");
|
|
6
|
+
function registerTicketTools(server, client) {
|
|
7
|
+
server.registerTool('h444_list_tickets', { title: 'List support tickets', description: 'Every support ticket on the account.', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/tickets'))));
|
|
8
|
+
server.registerTool('h444_get_ticket', { title: 'Get a ticket', description: 'Ticket detail with the message thread.', inputSchema: { id: zod_1.z.string().describe('Ticket UUID.') } }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/tickets/${encodeURIComponent(id)}`))));
|
|
9
|
+
server.registerTool('h444_open_ticket', {
|
|
10
|
+
title: 'Open a support ticket',
|
|
11
|
+
description: 'Open a new support ticket. Idempotent per call.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
subject: zod_1.z.string().min(3).max(255).describe('Ticket subject.'),
|
|
14
|
+
message: zod_1.z.string().min(10).describe('The opening message body.'),
|
|
15
|
+
department: zod_1.z.enum(['billing', 'technical', 'sales', 'abuse', 'other']).optional().describe('Department (default other).'),
|
|
16
|
+
priority: zod_1.z.enum(['low', 'medium', 'high', 'urgent']).optional().describe('Priority (default medium).'),
|
|
17
|
+
},
|
|
18
|
+
}, (0, _helpers_1.safeHandler)(async (body) => (0, _helpers_1.jsonResult)(await client.request('/v1/tickets', { method: 'POST', idempotent: true, body }))));
|
|
19
|
+
server.registerTool('h444_reply_ticket', {
|
|
20
|
+
title: 'Reply to a ticket',
|
|
21
|
+
description: 'Post a customer reply on an existing ticket.',
|
|
22
|
+
inputSchema: { id: zod_1.z.string().describe('Ticket UUID.'), body: zod_1.z.string().min(1).describe('Reply text.') },
|
|
23
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, body }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/tickets/${encodeURIComponent(id)}/reply`, { method: 'POST', body: { body } }))));
|
|
24
|
+
server.registerTool('h444_close_ticket', { title: 'Close a ticket', description: 'Close a support ticket.', inputSchema: { id: zod_1.z.string().describe('Ticket UUID.') } }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/tickets/${encodeURIComponent(id)}/close`, { method: 'POST' }))));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=tickets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.js","sourceRoot":"","sources":["../../src/tools/tickets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerWebhookTools = registerWebhookTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _helpers_1 = require("./_helpers");
|
|
6
|
+
const idArg = { id: zod_1.z.string().describe('Webhook subscription UUID.') };
|
|
7
|
+
function registerWebhookTools(server, client) {
|
|
8
|
+
server.registerTool('h444_list_webhooks', { title: 'List webhooks', description: 'Every webhook subscription on the account (secrets masked).', inputSchema: {} }, (0, _helpers_1.safeHandler)(async () => (0, _helpers_1.jsonResult)(await client.request('/v1/webhooks'))));
|
|
9
|
+
server.registerTool('h444_get_webhook', { title: 'Get a webhook', description: 'Detail for one webhook subscription.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}`))));
|
|
10
|
+
server.registerTool('h444_list_webhook_deliveries', {
|
|
11
|
+
title: 'List webhook deliveries',
|
|
12
|
+
description: 'Recent delivery attempts for a webhook subscription.',
|
|
13
|
+
inputSchema: { ...idArg, limit: zod_1.z.number().int().min(1).max(200).optional().describe('How many (default 50).') },
|
|
14
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, limit }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}/deliveries`, { query: { limit } }))));
|
|
15
|
+
server.registerTool('h444_create_webhook', {
|
|
16
|
+
title: 'Create a webhook',
|
|
17
|
+
description: 'Subscribe a URL to events. The signing secret is returned ONCE here — summarise it to the user to store securely.',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
url: zod_1.z.string().describe('HTTPS URL to receive POSTs.'),
|
|
20
|
+
events: zod_1.z.array(zod_1.z.string()).min(1).describe('Event names, or ["*"] for all. e.g. ["server.created","invoice.paid"].'),
|
|
21
|
+
description: zod_1.z.string().optional().describe('Optional label.'),
|
|
22
|
+
},
|
|
23
|
+
}, (0, _helpers_1.safeHandler)(async (body) => (0, _helpers_1.jsonResult)(await client.request('/v1/webhooks', { method: 'POST', body }))));
|
|
24
|
+
server.registerTool('h444_update_webhook', {
|
|
25
|
+
title: 'Update a webhook',
|
|
26
|
+
description: 'Change url, events, description, or pause/resume (is_active). Only provided fields change.',
|
|
27
|
+
inputSchema: {
|
|
28
|
+
...idArg,
|
|
29
|
+
url: zod_1.z.string().optional(),
|
|
30
|
+
events: zod_1.z.array(zod_1.z.string()).min(1).optional(),
|
|
31
|
+
description: zod_1.z.string().optional(),
|
|
32
|
+
is_active: zod_1.z.boolean().optional().describe('false pauses delivery, true resumes.'),
|
|
33
|
+
},
|
|
34
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, ...body }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}`, { method: 'PATCH', body }))));
|
|
35
|
+
server.registerTool('h444_delete_webhook', { title: 'Delete a webhook', description: 'Delete a webhook subscription.', inputSchema: idArg }, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}`, { method: 'DELETE' }))));
|
|
36
|
+
server.registerTool('h444_rotate_webhook_secret', {
|
|
37
|
+
title: 'Rotate a webhook secret',
|
|
38
|
+
description: 'Issue a fresh signing secret (returned ONCE). The old secret stops working immediately.',
|
|
39
|
+
inputSchema: idArg,
|
|
40
|
+
}, (0, _helpers_1.safeHandler)(async ({ id }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}/rotate-secret`, { method: 'POST' }))));
|
|
41
|
+
server.registerTool('h444_redeliver_webhook', {
|
|
42
|
+
title: 'Redeliver a webhook event',
|
|
43
|
+
description: 'Re-queue a past delivery for another attempt.',
|
|
44
|
+
inputSchema: { ...idArg, deliveryId: zod_1.z.string().describe('Delivery id from h444_list_webhook_deliveries.') },
|
|
45
|
+
}, (0, _helpers_1.safeHandler)(async ({ id, deliveryId }) => (0, _helpers_1.jsonResult)(await client.request(`/v1/webhooks/${encodeURIComponent(id)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`, { method: 'POST' }))));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"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"}
|
package/dist/util/env.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readEnv = readEnv;
|
|
4
|
+
const KEYS_URL = 'https://444host.com/account/api-keys';
|
|
5
|
+
/** Read + validate the env for the stdio transport. The hosted HTTP transport
|
|
6
|
+
* reads the key per-request instead (see src/http/index.ts). */
|
|
7
|
+
function readEnv() {
|
|
8
|
+
const apiKey = process.env.H444_API_KEY?.trim() || '';
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
throw new Error(`H444_API_KEY is not set. Create one at ${KEYS_URL} and set the H444_API_KEY ` +
|
|
11
|
+
'environment variable, then restart this MCP server.');
|
|
12
|
+
}
|
|
13
|
+
if (!apiKey.startsWith('h444_')) {
|
|
14
|
+
throw new Error(`H444_API_KEY does not look like a 444host.com API key (expected prefix "h444_"). ` +
|
|
15
|
+
`Generate a new key at ${KEYS_URL}.`);
|
|
16
|
+
}
|
|
17
|
+
// The public API is served directly at https://api.444host.com/v1/* (the edge
|
|
18
|
+
// rewrites /v1 → the in-app /api/v1). So the base is the host; tools call /v1/*.
|
|
19
|
+
const apiBase = (process.env.H444_API_BASE?.trim() || 'https://api.444host.com').replace(/\/+$/, '');
|
|
20
|
+
return { apiKey, apiBase };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/util/env.ts"],"names":[],"mappings":";;AASA,0BAkBC;AAtBD,MAAM,QAAQ,GAAG,sCAAsC,CAAC;AAExD;iEACiE;AACjE,SAAgB,OAAO;IACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,0CAA0C,QAAQ,4BAA4B;YAC5E,qDAAqD,CACxD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,mFAAmF;YACjF,yBAAyB,QAAQ,GAAG,CACvC,CAAC;IACJ,CAAC;IACD,8EAA8E;IAC9E,iFAAiF;IACjF,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,yBAAyB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACrG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.packageInfo = packageInfo;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
let cached = null;
|
|
7
|
+
function packageInfo() {
|
|
8
|
+
if (cached)
|
|
9
|
+
return cached;
|
|
10
|
+
try {
|
|
11
|
+
const raw = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', '..', 'package.json'), 'utf-8');
|
|
12
|
+
const pkg = JSON.parse(raw);
|
|
13
|
+
// Fallbacks are brand-neutral on purpose — the published package uses the
|
|
14
|
+
// public 444host scope; keep the internal workspace scope out of dist.
|
|
15
|
+
cached = { name: pkg.name || '444host-mcp', version: pkg.version || '0.0.0' };
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
cached = { name: '444host-mcp', version: '0.0.0' };
|
|
19
|
+
}
|
|
20
|
+
return cached;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/util/version.ts"],"names":[],"mappings":";;AAKA,kCAYC;AAjBD,2BAAkC;AAClC,+BAA4B;AAE5B,IAAI,MAAM,GAA6C,IAAI,CAAC;AAE5D,SAAgB,WAAW;IACzB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwC,CAAC;QACnE,0EAA0E;QAC1E,uEAAuE;QACvE,MAAM,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,aAAa,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@otwa/444host-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Model Context Protocol server for 444host.com — manage VPS, hosting, domains, billing, tickets and webhooks, and place real orders, from Claude and other MCP-capable AI tools.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://444host.com/developers",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mcp",
|
|
9
|
+
"model-context-protocol",
|
|
10
|
+
"444host",
|
|
11
|
+
"vps",
|
|
12
|
+
"cloud",
|
|
13
|
+
"hosting",
|
|
14
|
+
"claude",
|
|
15
|
+
"cursor",
|
|
16
|
+
"ai"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"type": "commonjs",
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"bin": {
|
|
24
|
+
"444host-mcp": "dist/index.js",
|
|
25
|
+
"444host-mcp-http": "dist/http/index.js"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/otwacloud/444host-mcp.git"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"CHANGELOG.md"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.21.0",
|
|
42
|
+
"express": "^4.21.0",
|
|
43
|
+
"zod": "4.3.6"
|
|
44
|
+
}
|
|
45
|
+
}
|