@serve.zone/dcrouter 15.2.5 → 15.3.1
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/deno.json +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +3 -1
- package/dist_ts/classes.dcrouter.js +6 -2
- package/dist_ts/opsserver/classes.mcpmanager.d.ts +28 -0
- package/dist_ts/opsserver/classes.mcpmanager.js +354 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +1 -0
- package/dist_ts/opsserver/classes.opsserver.js +7 -1
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +1 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +28 -1
- package/dist_ts/opsserver/index.d.ts +1 -0
- package/dist_ts/opsserver/index.js +2 -1
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts_oci_container/index.js +7 -6
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/package.json +3 -2
- package/readme.md +7 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +10 -2
- package/ts/opsserver/classes.mcpmanager.ts +393 -0
- package/ts/opsserver/classes.opsserver.ts +11 -0
- package/ts/opsserver/handlers/admin.handler.ts +33 -0
- package/ts/opsserver/index.ts +1 -0
- package/ts/plugins.ts +2 -1
- package/ts/readme.md +4 -1
- package/ts_apiclient/readme.md +4 -4
- package/ts_web/00_commitinfo_data.ts +1 -1
package/dist_ts/plugins.js
CHANGED
|
@@ -34,6 +34,7 @@ import * as smartguard from '@push.rocks/smartguard';
|
|
|
34
34
|
import * as smartjwt from '@push.rocks/smartjwt';
|
|
35
35
|
import * as smartlog from '@push.rocks/smartlog';
|
|
36
36
|
import * as smartmetrics from '@push.rocks/smartmetrics';
|
|
37
|
+
import * as smartmcp from '@push.rocks/smartmcp';
|
|
37
38
|
import * as smartmta from '@push.rocks/smartmta';
|
|
38
39
|
import * as smartdb from '@push.rocks/smartdb';
|
|
39
40
|
import * as smartnetwork from '@push.rocks/smartnetwork';
|
|
@@ -46,7 +47,7 @@ import * as smartrequest from '@push.rocks/smartrequest';
|
|
|
46
47
|
import * as smartrx from '@push.rocks/smartrx';
|
|
47
48
|
import * as smartunique from '@push.rocks/smartunique';
|
|
48
49
|
import * as taskbuffer from '@push.rocks/taskbuffer';
|
|
49
|
-
export { projectinfo, qenv, smartacme, smartchallenge, smartdata, smartdns, smartfs, smartguard, smartjwt, smartlog, smartmetrics, smartdb, smartmta, smartnetwork, smartpath, smartproxy, smartpromise, smartradius, smartrequest, smartrx, smartunique, smartvpn, taskbuffer };
|
|
50
|
+
export { projectinfo, qenv, smartacme, smartchallenge, smartdata, smartdns, smartfs, smartguard, smartjwt, smartlog, smartmetrics, smartmcp, smartdb, smartmta, smartnetwork, smartpath, smartproxy, smartpromise, smartradius, smartrequest, smartrx, smartunique, smartvpn, taskbuffer };
|
|
50
51
|
// apiclient.xyz scope
|
|
51
52
|
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
52
53
|
export { cloudflare, };
|
|
@@ -117,4 +118,4 @@ export const fsUtils = {
|
|
|
117
118
|
return JSON.parse(content);
|
|
118
119
|
},
|
|
119
120
|
};
|
|
120
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYztBQUNkLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBRWxDLE9BQU8sRUFDTCxHQUFHLEVBQ0gsRUFBRSxFQUNGLE1BQU0sRUFDTixJQUFJLEVBQ0osR0FBRyxFQUNILE1BQU0sRUFDTixFQUFFLEVBQ0YsSUFBSSxFQUNKLEdBQUcsRUFDSCxJQUFJLEdBQ0wsQ0FBQTtBQUVELG9CQUFvQjtBQUNwQixPQUFPLEtBQUssbUJBQW1CLE1BQU0sd0JBQXdCLENBQUM7QUFDOUQsT0FBTyxLQUFLLGFBQWEsTUFBTSwyQkFBMkIsQ0FBQztBQUUzRCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGFBQWEsR0FDZCxDQUFBO0FBRUQsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBRXZELE9BQU8sRUFDTCxZQUFZLEVBQ1osV0FBVyxFQUNYLFdBQVcsR0FD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
|
|
@@ -92,16 +92,17 @@ export function getOciContainerConfig() {
|
|
|
92
92
|
const maxConnectionsPerIP = process.env.DCROUTER_MAX_CONNECTIONS_PER_IP;
|
|
93
93
|
const connectionRateLimit = process.env.DCROUTER_CONNECTION_RATE_LIMIT;
|
|
94
94
|
if (maxConnections || maxConnectionsPerIP || connectionRateLimit) {
|
|
95
|
-
options.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
const currentProxyConfig = options.coreTrafficConfig || options.smartProxyConfig;
|
|
96
|
+
options.coreTrafficConfig = {
|
|
97
|
+
...currentProxyConfig,
|
|
98
|
+
routes: currentProxyConfig?.routes || [],
|
|
98
99
|
...(maxConnectionsPerIP ? { maxConnectionsPerIP: parseInt(maxConnectionsPerIP, 10) } : {}),
|
|
99
100
|
...(connectionRateLimit ? { connectionRateLimitPerMinute: parseInt(connectionRateLimit, 10) } : {}),
|
|
100
101
|
...(maxConnections ? {
|
|
101
102
|
defaults: {
|
|
102
|
-
...
|
|
103
|
+
...currentProxyConfig?.defaults,
|
|
103
104
|
security: {
|
|
104
|
-
...
|
|
105
|
+
...currentProxyConfig?.defaults?.security,
|
|
105
106
|
maxConnections: parseInt(maxConnections, 10),
|
|
106
107
|
},
|
|
107
108
|
},
|
|
@@ -110,4 +111,4 @@ export function getOciContainerConfig() {
|
|
|
110
111
|
}
|
|
111
112
|
return options;
|
|
112
113
|
}
|
|
113
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
114
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19vY2lfY29udGFpbmVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBMEI7SUFDckQsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUywwQkFBMEIsQ0FBQyxNQUEwQjtJQUM1RCxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLElBQUksT0FBTyxHQUFxQixFQUFFLENBQUM7SUFFbkMscUNBQXFDO0lBQ3JDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFDcEQsSUFBSSxVQUFVLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFV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
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '15.
|
|
6
|
+
version: '15.3.1',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/dcrouter",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.3.1",
|
|
5
5
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -45,13 +45,14 @@
|
|
|
45
45
|
"@push.rocks/smartguard": "^3.1.0",
|
|
46
46
|
"@push.rocks/smartjwt": "^2.2.2",
|
|
47
47
|
"@push.rocks/smartlog": "^3.2.2",
|
|
48
|
+
"@push.rocks/smartmcp": "^0.2.0",
|
|
48
49
|
"@push.rocks/smartmetrics": "^3.0.3",
|
|
49
50
|
"@push.rocks/smartmigration": "1.4.1",
|
|
50
51
|
"@push.rocks/smartmta": "^6.1.0",
|
|
51
52
|
"@push.rocks/smartnetwork": "^4.7.2",
|
|
52
53
|
"@push.rocks/smartpath": "^6.0.0",
|
|
53
54
|
"@push.rocks/smartpromise": "^4.2.4",
|
|
54
|
-
"@push.rocks/smartproxy": "^27.17.
|
|
55
|
+
"@push.rocks/smartproxy": "^27.17.5",
|
|
55
56
|
"@push.rocks/smartradius": "^1.3.0",
|
|
56
57
|
"@push.rocks/smartrequest": "^5.0.3",
|
|
57
58
|
"@push.rocks/smartrx": "^3.0.10",
|
package/readme.md
CHANGED
|
@@ -61,7 +61,7 @@ This starts the gateway on unprivileged ports and stores data under the default
|
|
|
61
61
|
import { DcRouter } from '@serve.zone/dcrouter';
|
|
62
62
|
|
|
63
63
|
const router = new DcRouter({
|
|
64
|
-
|
|
64
|
+
coreTrafficConfig: {
|
|
65
65
|
routes: [
|
|
66
66
|
{
|
|
67
67
|
name: 'local-app',
|
|
@@ -111,7 +111,7 @@ Bootstrap behavior:
|
|
|
111
111
|
| Option | Purpose |
|
|
112
112
|
| --- | --- |
|
|
113
113
|
| `baseDir` | Root directory for dcrouter runtime data. Defaults to `~/.serve.zone/dcrouter`. |
|
|
114
|
-
| `
|
|
114
|
+
| `coreTrafficConfig` | Main CoreTraffic route configuration for HTTP/HTTPS/TCP/SNI traffic. `smartProxyConfig` remains accepted as a legacy alias. |
|
|
115
115
|
| `emailConfig` | UnifiedEmailServer configuration: hostname, ports, domains, and mail routes. |
|
|
116
116
|
| `emailPortConfig` | External-to-internal email port mapping and received-email storage path. |
|
|
117
117
|
| `tls` | Legacy/static TLS and ACME contact settings used to seed certificate config. |
|
|
@@ -140,7 +140,7 @@ dcrouter keeps generated and operator-created routes separate so automation can
|
|
|
140
140
|
|
|
141
141
|
| Origin | Source | Mutability |
|
|
142
142
|
| --- | --- | --- |
|
|
143
|
-
| `config` | Constructor `
|
|
143
|
+
| `config` | Constructor `coreTrafficConfig.routes` and seed data | Toggle only |
|
|
144
144
|
| `email` | Email listener and email-domain generated routes | Toggle only |
|
|
145
145
|
| `dns` | Generated DNS-over-HTTPS and DNS-related routes | Toggle only |
|
|
146
146
|
| `api` | Ops UI or API client | Full CRUD |
|
|
@@ -288,7 +288,7 @@ import { DcRouter } from '@serve.zone/dcrouter';
|
|
|
288
288
|
|
|
289
289
|
const router = new DcRouter({
|
|
290
290
|
baseDir: '/var/lib/dcrouter',
|
|
291
|
-
|
|
291
|
+
coreTrafficConfig: {
|
|
292
292
|
routes: [
|
|
293
293
|
{
|
|
294
294
|
name: 'web-app',
|
|
@@ -362,6 +362,8 @@ const targetProfile = {
|
|
|
362
362
|
|
|
363
363
|
The OpsServer exposes TypedRequest handlers at `/typedrequest`. You can use raw contracts or the object-oriented API client.
|
|
364
364
|
|
|
365
|
+
It also exposes an admin-JWT authenticated read-only MCP endpoint at `/mcp`. The MCP tools return safe summaries for runtime status, routes, source and target profiles, network targets, DNS, email domains, RemoteIngress edges, and VPN clients without API tokens, logs, certificates, private keys, or provider credentials.
|
|
366
|
+
|
|
365
367
|
```bash
|
|
366
368
|
pnpm add @serve.zone/dcrouter-apiclient
|
|
367
369
|
```
|
|
@@ -384,7 +386,7 @@ const route = await client.routes.build()
|
|
|
384
386
|
await route.toggle(true);
|
|
385
387
|
```
|
|
386
388
|
|
|
387
|
-
Use `@serve.zone/dcrouter/interfaces` or `@serve.zone/dcrouter-interfaces` when you want
|
|
389
|
+
Use `@serve.zone/dcrouter/interfaces` or `@serve.zone/dcrouter-interfaces` when you want dcrouter-local raw TypedRequest contracts instead of resource managers. Use `@serve.zone/interfaces` for the canonical machine-facing gateway client route, DNS, and domain contracts shared with Onebox and Cloudly.
|
|
388
390
|
|
|
389
391
|
## OCI / Container Bootstrap
|
|
390
392
|
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/classes.dcrouter.ts
CHANGED
|
@@ -48,9 +48,12 @@ export interface IDcRouterOptions {
|
|
|
48
48
|
baseDir?: string;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* Direct
|
|
51
|
+
* Direct CoreTraffic configuration - gives full control over HTTP/HTTPS and TCP/SNI traffic
|
|
52
52
|
* This is the preferred way to configure HTTP/HTTPS and general TCP/SNI traffic
|
|
53
53
|
*/
|
|
54
|
+
coreTrafficConfig?: plugins.smartproxy.ISmartProxyOptions;
|
|
55
|
+
|
|
56
|
+
/** Legacy name for coreTrafficConfig. */
|
|
54
57
|
smartProxyConfig?: plugins.smartproxy.ISmartProxyOptions;
|
|
55
58
|
|
|
56
59
|
/**
|
|
@@ -347,9 +350,13 @@ export class DcRouter {
|
|
|
347
350
|
private qenv = new plugins.qenv.Qenv('./', '.nogit/');
|
|
348
351
|
|
|
349
352
|
constructor(optionsArg: IDcRouterOptions) {
|
|
353
|
+
const coreTrafficConfig = optionsArg.coreTrafficConfig || optionsArg.smartProxyConfig;
|
|
354
|
+
|
|
350
355
|
// Set defaults in options
|
|
351
356
|
this.options = {
|
|
352
|
-
...optionsArg
|
|
357
|
+
...optionsArg,
|
|
358
|
+
coreTrafficConfig,
|
|
359
|
+
smartProxyConfig: coreTrafficConfig,
|
|
353
360
|
};
|
|
354
361
|
|
|
355
362
|
// Resolve all data paths from baseDir
|
|
@@ -1544,6 +1551,7 @@ export class DcRouter {
|
|
|
1544
1551
|
}
|
|
1545
1552
|
|
|
1546
1553
|
// Update configuration
|
|
1554
|
+
this.options.coreTrafficConfig = config;
|
|
1547
1555
|
this.options.smartProxyConfig = config;
|
|
1548
1556
|
|
|
1549
1557
|
// Start new SmartProxy with updated configuration (rebuilds seed routes)
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import type { OpsServer } from './classes.opsserver.js';
|
|
3
|
+
import type * as interfaces from '../../ts_interfaces/index.js';
|
|
4
|
+
|
|
5
|
+
type TRouteTarget = NonNullable<interfaces.data.IDcRouterRouteConfig['action']['targets']>[number];
|
|
6
|
+
type TRouteTargetValue = TRouteTarget['host'] | TRouteTarget['port'];
|
|
7
|
+
|
|
8
|
+
interface IDnsRecordSummary {
|
|
9
|
+
id: string;
|
|
10
|
+
domainId: string;
|
|
11
|
+
domainName?: string;
|
|
12
|
+
name: string;
|
|
13
|
+
type: interfaces.data.TDnsRecordType;
|
|
14
|
+
value: string;
|
|
15
|
+
ttl: number;
|
|
16
|
+
proxied?: boolean;
|
|
17
|
+
source: interfaces.data.TDnsRecordSource;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class McpManager {
|
|
23
|
+
private handler: plugins.smartmcp.ISmartMcpHttpHandler;
|
|
24
|
+
|
|
25
|
+
constructor(private opsServerRef: OpsServer) {
|
|
26
|
+
this.handler = plugins.smartmcp.createSmartMcpHttpHandler({
|
|
27
|
+
name: 'dcrouter-mcp',
|
|
28
|
+
version: '1.0.0',
|
|
29
|
+
validateRequest: ({ request }) => this.validateRequest(request),
|
|
30
|
+
authorize: async ({ request }) => this.authorizeRequest(request),
|
|
31
|
+
tools: [
|
|
32
|
+
{
|
|
33
|
+
name: 'dcrouter_get_status',
|
|
34
|
+
description: 'Get dcrouter runtime inventory counts without logs, tokens, certificates, or credentials.',
|
|
35
|
+
handler: async () => ({
|
|
36
|
+
status: await this.getStatusSummary(),
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'dcrouter_list_routes',
|
|
41
|
+
description: 'List dcrouter route summaries without raw route secrets, logs, or certificates.',
|
|
42
|
+
handler: async () => ({
|
|
43
|
+
routes: this.getMergedRoutes().map((routeArg) => this.summarizeRoute(routeArg)),
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'dcrouter_list_source_profiles',
|
|
48
|
+
description: 'List source profile summaries without embedded credentials.',
|
|
49
|
+
handler: async () => ({
|
|
50
|
+
sourceProfiles: (this.opsServerRef.dcRouterRef.referenceResolver?.listProfiles() || []).map((profileArg) => this.summarizeSourceProfile(profileArg)),
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'dcrouter_list_target_profiles',
|
|
55
|
+
description: 'List target profile summaries for VPN and private access routing.',
|
|
56
|
+
handler: async () => ({
|
|
57
|
+
targetProfiles: (this.opsServerRef.dcRouterRef.targetProfileManager?.listProfiles() || []).map((profileArg) => this.summarizeTargetProfile(profileArg)),
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'dcrouter_list_network_targets',
|
|
62
|
+
description: 'List reusable network target summaries.',
|
|
63
|
+
handler: async () => ({
|
|
64
|
+
networkTargets: (this.opsServerRef.dcRouterRef.referenceResolver?.listTargets() || []).map((targetArg) => this.summarizeNetworkTarget(targetArg)),
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'dcrouter_list_domains',
|
|
69
|
+
description: 'List managed DNS domains without provider zone IDs or provider credentials.',
|
|
70
|
+
handler: async () => ({
|
|
71
|
+
domains: (await this.opsServerRef.dcRouterRef.dnsManager?.listDomains() || []).map((domainArg) => this.summarizeDomain(domainArg)),
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'dcrouter_list_dns_records',
|
|
76
|
+
description: 'List managed DNS record summaries without provider record IDs or provider credentials.',
|
|
77
|
+
handler: async () => ({
|
|
78
|
+
dnsRecords: await this.getDnsRecords(),
|
|
79
|
+
}),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'dcrouter_list_email_domains',
|
|
83
|
+
description: 'List email domain summaries without DKIM private keys, mailboxes, or message contents.',
|
|
84
|
+
handler: async () => ({
|
|
85
|
+
emailSettings: this.opsServerRef.dcRouterRef.emailSettingsManager?.getPublicSettings(),
|
|
86
|
+
emailDomains: (await this.opsServerRef.dcRouterRef.emailDomainManager?.getAll() || []).map((domainArg) => this.summarizeEmailDomain(domainArg)),
|
|
87
|
+
}),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'dcrouter_list_remote_ingress_edges',
|
|
91
|
+
description: 'List RemoteIngress edge summaries without edge secrets.',
|
|
92
|
+
handler: async () => ({
|
|
93
|
+
hubSettings: this.summarizeRemoteIngressHubSettings(this.opsServerRef.dcRouterRef.remoteIngressManager?.getHubSettings()),
|
|
94
|
+
edges: (this.opsServerRef.dcRouterRef.remoteIngressManager?.getAllEdges() || []).map((edgeArg) => this.summarizeRemoteIngressEdge(edgeArg)),
|
|
95
|
+
}),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'dcrouter_list_vpn_clients',
|
|
99
|
+
description: 'List VPN client summaries without private keys or exported configs.',
|
|
100
|
+
handler: async () => ({
|
|
101
|
+
running: this.opsServerRef.dcRouterRef.vpnManager?.running ?? false,
|
|
102
|
+
clients: (this.opsServerRef.dcRouterRef.vpnManager?.listClients() || []).map((clientArg) => this.summarizeVpnClient(clientArg)),
|
|
103
|
+
}),
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public async handleRequest(requestArg: Request): Promise<Response> {
|
|
110
|
+
return this.handler.handleRequest(requestArg);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public getHandler(): plugins.smartmcp.ISmartMcpHttpHandler {
|
|
114
|
+
return this.handler;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private validateRequest(requestArg: Request): Response | undefined {
|
|
118
|
+
const origin = requestArg.headers.get('origin');
|
|
119
|
+
if (origin && origin !== new URL(requestArg.url).origin) {
|
|
120
|
+
return new Response('Forbidden', { status: 403 });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private async authorizeRequest(requestArg: Request): Promise<Response | { token: string; clientId: string; scopes: string[] }> {
|
|
125
|
+
const jwt = this.extractBearerToken(requestArg);
|
|
126
|
+
if (!jwt) {
|
|
127
|
+
return new Response('Unauthorized', { status: 401 });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const identity = await this.opsServerRef.adminHandler.getVerifiedAdminIdentityFromJwt(jwt);
|
|
132
|
+
return {
|
|
133
|
+
token: jwt,
|
|
134
|
+
clientId: identity.userId,
|
|
135
|
+
scopes: ['admin', 'mcp', 'dcrouter:read'],
|
|
136
|
+
};
|
|
137
|
+
} catch {
|
|
138
|
+
return new Response('Unauthorized', { status: 401 });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private extractBearerToken(requestArg: Request): string | undefined {
|
|
143
|
+
const authHeader = requestArg.headers.get('authorization');
|
|
144
|
+
if (!authHeader) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
const [scheme, token] = authHeader.split(' ');
|
|
148
|
+
if (scheme?.toLowerCase() !== 'bearer' || !token) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
return token.trim() || undefined;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private async getStatusSummary() {
|
|
155
|
+
const routes = this.getMergedRoutes();
|
|
156
|
+
const domains = await this.opsServerRef.dcRouterRef.dnsManager?.listDomains().catch(() => []) || [];
|
|
157
|
+
const emailDomains = await this.opsServerRef.dcRouterRef.emailDomainManager?.getAll().catch(() => []) || [];
|
|
158
|
+
const edges = this.opsServerRef.dcRouterRef.remoteIngressManager?.getAllEdges() || [];
|
|
159
|
+
const vpnClients = this.opsServerRef.dcRouterRef.vpnManager?.listClients() || [];
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
smartProxyRunning: Boolean(this.opsServerRef.dcRouterRef.smartProxy),
|
|
163
|
+
emailEnabled: this.opsServerRef.dcRouterRef.emailSettingsManager?.getPublicSettings?.()?.enabled ?? Boolean(this.opsServerRef.dcRouterRef.emailServer),
|
|
164
|
+
dnsEnabled: Boolean(this.opsServerRef.dcRouterRef.dnsServer),
|
|
165
|
+
radiusEnabled: Boolean(this.opsServerRef.dcRouterRef.radiusServer),
|
|
166
|
+
remoteIngressEnabled: this.opsServerRef.dcRouterRef.remoteIngressManager?.getHubSettings?.()?.enabled ?? false,
|
|
167
|
+
vpnRunning: this.opsServerRef.dcRouterRef.vpnManager?.running ?? false,
|
|
168
|
+
routeCount: routes.length,
|
|
169
|
+
enabledRouteCount: routes.filter((routeArg) => routeArg.enabled !== false).length,
|
|
170
|
+
domainCount: domains.length,
|
|
171
|
+
emailDomainCount: emailDomains.length,
|
|
172
|
+
remoteIngressEdgeCount: edges.length,
|
|
173
|
+
vpnClientCount: vpnClients.length,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private getMergedRoutes(): interfaces.data.IMergedRoute[] {
|
|
178
|
+
return this.opsServerRef.dcRouterRef.routeConfigManager?.getMergedRoutes()?.routes || [];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private async getDnsRecords(): Promise<IDnsRecordSummary[]> {
|
|
182
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
183
|
+
if (!dnsManager?.listDomains || !dnsManager?.listRecordsForDomain) {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const domains = await dnsManager.listDomains();
|
|
188
|
+
const records: IDnsRecordSummary[] = [];
|
|
189
|
+
for (const domain of domains) {
|
|
190
|
+
const domainRecords = await dnsManager.listRecordsForDomain(domain.id);
|
|
191
|
+
records.push(...domainRecords.map((recordArg) => this.summarizeDnsRecord(recordArg, domain.name)));
|
|
192
|
+
}
|
|
193
|
+
return records;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private summarizeRoute(routeArg: interfaces.data.IMergedRoute) {
|
|
197
|
+
const route = routeArg.route || {};
|
|
198
|
+
const targets = route.action?.targets || [];
|
|
199
|
+
return {
|
|
200
|
+
id: routeArg.id,
|
|
201
|
+
name: route.name,
|
|
202
|
+
enabled: routeArg.enabled,
|
|
203
|
+
origin: routeArg.origin,
|
|
204
|
+
systemKey: routeArg.systemKey,
|
|
205
|
+
match: {
|
|
206
|
+
ports: route.match?.ports,
|
|
207
|
+
domains: route.match?.domains,
|
|
208
|
+
protocol: route.match?.protocol,
|
|
209
|
+
transport: route.match?.transport,
|
|
210
|
+
path: route.match?.path,
|
|
211
|
+
},
|
|
212
|
+
action: {
|
|
213
|
+
targetCount: targets.length,
|
|
214
|
+
targets: targets.map((targetArg) => this.summarizeRouteTarget(targetArg)),
|
|
215
|
+
},
|
|
216
|
+
remoteIngress: route.remoteIngress ? {
|
|
217
|
+
enabled: route.remoteIngress.enabled,
|
|
218
|
+
edgeFilter: route.remoteIngress.edgeFilter,
|
|
219
|
+
} : undefined,
|
|
220
|
+
vpnOnly: route.vpnOnly,
|
|
221
|
+
metadata: routeArg.metadata ? {
|
|
222
|
+
ownerType: routeArg.metadata.ownerType,
|
|
223
|
+
gatewayClientType: routeArg.metadata.gatewayClientType,
|
|
224
|
+
networkTargetName: routeArg.metadata.networkTargetName,
|
|
225
|
+
sourceBindingCount: routeArg.metadata.sourceBindings?.length || 0,
|
|
226
|
+
pathPolicyCount: routeArg.metadata.sourceBindings?.reduce((countArg, bindingArg) => countArg + (bindingArg.pathPolicies?.length || 0), 0) || 0,
|
|
227
|
+
} : undefined,
|
|
228
|
+
createdAt: routeArg.createdAt,
|
|
229
|
+
updatedAt: routeArg.updatedAt,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private summarizeRouteTarget(targetArg: TRouteTarget) {
|
|
234
|
+
return {
|
|
235
|
+
host: this.summarizeRouteTargetValue(targetArg.host),
|
|
236
|
+
port: this.summarizeRouteTargetValue(targetArg.port),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private summarizeRouteTargetValue(valueArg: TRouteTargetValue) {
|
|
241
|
+
return typeof valueArg === 'function' ? '[dynamic]' : valueArg;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private summarizeSourceProfile(profileArg: interfaces.data.ISourceProfile) {
|
|
245
|
+
return {
|
|
246
|
+
id: profileArg.id,
|
|
247
|
+
name: profileArg.name,
|
|
248
|
+
description: profileArg.description,
|
|
249
|
+
extendsProfiles: profileArg.extendsProfiles,
|
|
250
|
+
security: this.summarizeSecurity(profileArg.security),
|
|
251
|
+
createdAt: profileArg.createdAt,
|
|
252
|
+
updatedAt: profileArg.updatedAt,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private summarizeSecurity(securityArg: interfaces.data.IRouteSecurity) {
|
|
257
|
+
if (!securityArg) return undefined;
|
|
258
|
+
return {
|
|
259
|
+
ipAllowListCount: securityArg.ipAllowList?.length || 0,
|
|
260
|
+
ipBlockListCount: securityArg.ipBlockList?.length || 0,
|
|
261
|
+
rateLimitEnabled: Boolean(securityArg.rateLimit),
|
|
262
|
+
challengeEnabled: Boolean(securityArg.challenge),
|
|
263
|
+
maxConnections: securityArg.maxConnections,
|
|
264
|
+
requireVpnClient: securityArg.vpn?.required,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private summarizeTargetProfile(profileArg: interfaces.data.ITargetProfile) {
|
|
269
|
+
return {
|
|
270
|
+
id: profileArg.id,
|
|
271
|
+
name: profileArg.name,
|
|
272
|
+
description: profileArg.description,
|
|
273
|
+
domainCount: profileArg.domains?.length || 0,
|
|
274
|
+
domains: profileArg.domains,
|
|
275
|
+
targetCount: profileArg.targets?.length || 0,
|
|
276
|
+
routeRefCount: profileArg.routeRefs?.length || 0,
|
|
277
|
+
allowRoutesByClientSourceIp: profileArg.allowRoutesByClientSourceIp,
|
|
278
|
+
createdAt: profileArg.createdAt,
|
|
279
|
+
updatedAt: profileArg.updatedAt,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private summarizeNetworkTarget(targetArg: interfaces.data.INetworkTarget) {
|
|
284
|
+
return {
|
|
285
|
+
id: targetArg.id,
|
|
286
|
+
name: targetArg.name,
|
|
287
|
+
description: targetArg.description,
|
|
288
|
+
host: targetArg.host,
|
|
289
|
+
port: targetArg.port,
|
|
290
|
+
createdAt: targetArg.createdAt,
|
|
291
|
+
updatedAt: targetArg.updatedAt,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private summarizeDomain(domainArg: interfaces.data.IDomain) {
|
|
296
|
+
return {
|
|
297
|
+
id: domainArg.id,
|
|
298
|
+
name: domainArg.name,
|
|
299
|
+
source: domainArg.source,
|
|
300
|
+
providerId: domainArg.providerId,
|
|
301
|
+
authoritative: domainArg.authoritative,
|
|
302
|
+
nameservers: domainArg.nameservers,
|
|
303
|
+
lastSyncedAt: domainArg.lastSyncedAt,
|
|
304
|
+
description: domainArg.description,
|
|
305
|
+
createdAt: domainArg.createdAt,
|
|
306
|
+
updatedAt: domainArg.updatedAt,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private summarizeDnsRecord(recordArg: interfaces.data.IDnsRecord, domainNameArg?: string): IDnsRecordSummary {
|
|
311
|
+
return {
|
|
312
|
+
id: recordArg.id,
|
|
313
|
+
domainId: recordArg.domainId,
|
|
314
|
+
domainName: domainNameArg,
|
|
315
|
+
name: recordArg.name,
|
|
316
|
+
type: recordArg.type,
|
|
317
|
+
value: recordArg.value,
|
|
318
|
+
ttl: recordArg.ttl,
|
|
319
|
+
proxied: recordArg.proxied,
|
|
320
|
+
source: recordArg.source,
|
|
321
|
+
createdAt: recordArg.createdAt,
|
|
322
|
+
updatedAt: recordArg.updatedAt,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
private summarizeEmailDomain(domainArg: interfaces.data.IEmailDomain) {
|
|
327
|
+
return {
|
|
328
|
+
id: domainArg.id,
|
|
329
|
+
domain: domainArg.domain,
|
|
330
|
+
linkedDomainId: domainArg.linkedDomainId,
|
|
331
|
+
subdomain: domainArg.subdomain,
|
|
332
|
+
dkim: domainArg.dkim ? {
|
|
333
|
+
selector: domainArg.dkim.selector,
|
|
334
|
+
keySize: domainArg.dkim.keySize,
|
|
335
|
+
rotateKeys: domainArg.dkim.rotateKeys,
|
|
336
|
+
rotationIntervalDays: domainArg.dkim.rotationIntervalDays,
|
|
337
|
+
lastRotatedAt: domainArg.dkim.lastRotatedAt,
|
|
338
|
+
} : undefined,
|
|
339
|
+
dnsStatus: domainArg.dnsStatus,
|
|
340
|
+
rateLimits: domainArg.rateLimits,
|
|
341
|
+
createdAt: domainArg.createdAt,
|
|
342
|
+
updatedAt: domainArg.updatedAt,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
private summarizeRemoteIngressHubSettings(settingsArg: interfaces.data.IRemoteIngressHubSettings | undefined) {
|
|
347
|
+
if (!settingsArg) return undefined;
|
|
348
|
+
return {
|
|
349
|
+
enabled: settingsArg.enabled,
|
|
350
|
+
tunnelPort: settingsArg.tunnelPort,
|
|
351
|
+
hubDomain: settingsArg.hubDomain,
|
|
352
|
+
performance: settingsArg.performance,
|
|
353
|
+
updatedAt: settingsArg.updatedAt,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private summarizeRemoteIngressEdge(edgeArg: interfaces.data.IRemoteIngress) {
|
|
358
|
+
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
359
|
+
return {
|
|
360
|
+
id: edgeArg.id,
|
|
361
|
+
name: edgeArg.name,
|
|
362
|
+
enabled: edgeArg.enabled,
|
|
363
|
+
listenPorts: edgeArg.listenPorts,
|
|
364
|
+
listenPortsUdp: edgeArg.listenPortsUdp,
|
|
365
|
+
effectiveListenPorts: manager?.getEffectiveListenPorts(edgeArg),
|
|
366
|
+
effectiveListenPortsUdp: manager?.getEffectiveListenPortsUdp(edgeArg),
|
|
367
|
+
autoDerivePorts: edgeArg.autoDerivePorts,
|
|
368
|
+
tags: edgeArg.tags,
|
|
369
|
+
performance: edgeArg.performance,
|
|
370
|
+
createdAt: edgeArg.createdAt,
|
|
371
|
+
updatedAt: edgeArg.updatedAt,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private summarizeVpnClient(clientArg: interfaces.data.IVpnClient) {
|
|
376
|
+
return {
|
|
377
|
+
clientId: clientArg.clientId,
|
|
378
|
+
enabled: clientArg.enabled,
|
|
379
|
+
assignedIp: clientArg.assignedIp,
|
|
380
|
+
description: clientArg.description,
|
|
381
|
+
targetProfileIds: clientArg.targetProfileIds,
|
|
382
|
+
expiresAt: clientArg.expiresAt,
|
|
383
|
+
useHostIp: clientArg.useHostIp,
|
|
384
|
+
useDhcp: clientArg.useDhcp,
|
|
385
|
+
staticIp: clientArg.staticIp,
|
|
386
|
+
forceVlan: clientArg.forceVlan,
|
|
387
|
+
vlanId: clientArg.vlanId,
|
|
388
|
+
sourceIp: this.opsServerRef.dcRouterRef.vpnManager?.getClientSourceIp?.(clientArg.clientId),
|
|
389
|
+
createdAt: clientArg.createdAt,
|
|
390
|
+
updatedAt: clientArg.updatedAt,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
}
|
|
@@ -3,6 +3,7 @@ import * as plugins from '../plugins.js';
|
|
|
3
3
|
import * as paths from '../paths.js';
|
|
4
4
|
import * as handlers from './handlers/index.js';
|
|
5
5
|
import * as interfaces from '../../ts_interfaces/index.js';
|
|
6
|
+
import { McpManager } from './classes.mcpmanager.js';
|
|
6
7
|
|
|
7
8
|
export class OpsServer {
|
|
8
9
|
public dcRouterRef: DcRouter;
|
|
@@ -52,6 +53,7 @@ export class OpsServer {
|
|
|
52
53
|
domain: 'localhost',
|
|
53
54
|
feedMetadata: undefined,
|
|
54
55
|
serveDir: paths.distServe,
|
|
56
|
+
addCustomRoutes: async (typedserver) => this.registerCustomRoutes(typedserver),
|
|
55
57
|
});
|
|
56
58
|
|
|
57
59
|
// The server has a built-in typedrouter at /typedrequest
|
|
@@ -103,6 +105,15 @@ export class OpsServer {
|
|
|
103
105
|
console.log('✅ OpsServer TypedRequest handlers initialized');
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
private registerCustomRoutes(typedserver: plugins.typedserver.TypedServer): void {
|
|
109
|
+
const mcpManager = new McpManager(this);
|
|
110
|
+
typedserver.addRoute(
|
|
111
|
+
'/mcp',
|
|
112
|
+
'ALL',
|
|
113
|
+
async (ctx) => mcpManager.handleRequest(ctx.request),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
public async stop() {
|
|
107
118
|
if (this.adminHandler) {
|
|
108
119
|
await this.adminHandler.stop();
|